diff --git a/src/agent/src/mount.rs b/src/agent/src/mount.rs index 1b04b58f7a..b4794f27e0 100644 --- a/src/agent/src/mount.rs +++ b/src/agent/src/mount.rs @@ -7,7 +7,7 @@ use std::collections::HashMap; use std::ffi::CString; use std::fs; use std::io; -use std::os::unix::fs::PermissionsExt; +use std::os::unix::fs::{MetadataExt, PermissionsExt}; use std::path::Path; use std::ptr::null; @@ -245,7 +245,35 @@ async fn ephemeral_storage_handler( } fs::create_dir_all(Path::new(&storage.mount_point))?; - common_storage_handler(logger, storage)?; + + // By now we only support one option field: "fsGroup" which + // isn't an valid mount option, thus we should remove it when + // do mount. + if storage.options.len() > 0 { + // ephemeral_storage didn't support mount options except fsGroup. + let mut new_storage = storage.clone(); + new_storage.options = protobuf::RepeatedField::default(); + common_storage_handler(logger, &new_storage)?; + + let opts_vec: Vec = storage.options.to_vec(); + + let opts = parse_options(opts_vec); + + if let Some(fsgid) = opts.get(FS_GID) { + let gid = fsgid.parse::()?; + + nix::unistd::chown(storage.mount_point.as_str(), None, Some(Gid::from_raw(gid)))?; + + let meta = fs::metadata(&storage.mount_point)?; + let mut permission = meta.permissions(); + + let o_mode = meta.mode() | 0o2000; + permission.set_mode(o_mode); + fs::set_permissions(&storage.mount_point, permission)?; + } + } else { + common_storage_handler(logger, &storage)?; + } Ok("".to_string()) } diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go index 665d6c6c80..c58684e0cf 100644 --- a/src/runtime/virtcontainers/kata_agent.go +++ b/src/runtime/virtcontainers/kata_agent.go @@ -1314,7 +1314,11 @@ func (k *kataAgent) createContainer(ctx context.Context, sandbox *Sandbox, c *Co k.handleShm(ociSpec.Mounts, sandbox) - epheStorages := k.handleEphemeralStorage(ociSpec.Mounts) + epheStorages, err := k.handleEphemeralStorage(ociSpec.Mounts) + if err != nil { + return nil, err + } + ctrStorages = append(ctrStorages, epheStorages...) localStorages, err := k.handleLocalStorage(ociSpec.Mounts, sandbox.id, c.rootfsSuffix) @@ -1395,10 +1399,27 @@ func buildProcessFromExecID(token string) (*Process, error) { // handleEphemeralStorage handles ephemeral storages by // creating a Storage from corresponding source of the mount point -func (k *kataAgent) handleEphemeralStorage(mounts []specs.Mount) []*grpc.Storage { +func (k *kataAgent) handleEphemeralStorage(mounts []specs.Mount) ([]*grpc.Storage, error) { var epheStorages []*grpc.Storage for idx, mnt := range mounts { if mnt.Type == KataEphemeralDevType { + origin_src := mounts[idx].Source + stat := syscall.Stat_t{} + err := syscall.Stat(origin_src, &stat) + if err != nil { + k.Logger().WithError(err).Errorf("failed to stat %s", origin_src) + return nil, err + } + + var dir_options []string + + // if volume's gid isn't root group(default group), this means there's + // an specific fsGroup is set on this local volume, then it should pass + // to guest. + if stat.Gid != 0 { + dir_options = append(dir_options, fmt.Sprintf("%s=%d", fsGid, stat.Gid)) + } + // Set the mount source path to a path that resides inside the VM mounts[idx].Source = filepath.Join(ephemeralPath(), filepath.Base(mnt.Source)) // Set the mount type to "bind" @@ -1411,11 +1432,12 @@ func (k *kataAgent) handleEphemeralStorage(mounts []specs.Mount) []*grpc.Storage Source: "tmpfs", Fstype: "tmpfs", MountPoint: mounts[idx].Source, + Options: dir_options, } epheStorages = append(epheStorages, epheStorage) } } - return epheStorages + return epheStorages, nil } // handleLocalStorage handles local storage within the VM diff --git a/src/runtime/virtcontainers/kata_agent_test.go b/src/runtime/virtcontainers/kata_agent_test.go index 523ef5b32e..ef52299423 100644 --- a/src/runtime/virtcontainers/kata_agent_test.go +++ b/src/runtime/virtcontainers/kata_agent_test.go @@ -184,6 +184,7 @@ func TestHandleEphemeralStorage(t *testing.T) { k := kataAgent{} var ociMounts []specs.Mount mountSource := "/tmp/mountPoint" + os.Mkdir(mountSource, 0755) mount := specs.Mount{ Type: KataEphemeralDevType, @@ -191,7 +192,8 @@ func TestHandleEphemeralStorage(t *testing.T) { } ociMounts = append(ociMounts, mount) - epheStorages := k.handleEphemeralStorage(ociMounts) + epheStorages, err := k.handleEphemeralStorage(ociMounts) + assert.Nil(t, err) epheMountPoint := epheStorages[0].MountPoint expected := filepath.Join(ephemeralPath(), filepath.Base(mountSource)) @@ -652,6 +654,7 @@ func TestHandleShm(t *testing.T) { // shared with the sandbox shm. ociMounts[0].Type = KataEphemeralDevType mountSource := "/tmp/mountPoint" + os.Mkdir(mountSource, 0755) ociMounts[0].Source = mountSource k.handleShm(ociMounts, sandbox) @@ -659,7 +662,9 @@ func TestHandleShm(t *testing.T) { assert.Equal(ociMounts[0].Type, KataEphemeralDevType) assert.NotEmpty(ociMounts[0].Source, mountSource) - epheStorages := k.handleEphemeralStorage(ociMounts) + epheStorages, err := k.handleEphemeralStorage(ociMounts) + assert.Nil(err) + epheMountPoint := epheStorages[0].MountPoint expected := filepath.Join(ephemeralPath(), filepath.Base(mountSource)) assert.Equal(epheMountPoint, expected,