Merge pull request #1603 from lifupan/fix_fsgroup

Fix fsgroup
This commit is contained in:
Peng Tao
2021-04-06 11:35:03 +08:00
committed by GitHub
3 changed files with 51 additions and 9 deletions

View File

@@ -17,6 +17,7 @@ use tokio::sync::Mutex;
use libc::{c_void, mount}; use libc::{c_void, mount};
use nix::mount::{self, MsFlags}; use nix::mount::{self, MsFlags};
use nix::unistd::Gid;
use regex::Regex; use regex::Regex;
use std::fs::File; use std::fs::File;
@@ -45,6 +46,9 @@ pub const TYPE_ROOTFS: &str = "rootfs";
pub const MOUNT_GUEST_TAG: &str = "kataShared"; pub const MOUNT_GUEST_TAG: &str = "kataShared";
// Allocating an FSGroup that owns the pod's volumes
const FS_GID: &str = "fsgid";
#[rustfmt::skip] #[rustfmt::skip]
lazy_static! { lazy_static! {
pub static ref FLAGS: HashMap<&'static str, (bool, MsFlags)> = { pub static ref FLAGS: HashMap<&'static str, (bool, MsFlags)> = {
@@ -266,11 +270,24 @@ async fn local_storage_handler(
let opts_vec: Vec<String> = storage.options.to_vec(); let opts_vec: Vec<String> = storage.options.to_vec();
let opts = parse_options(opts_vec); let opts = parse_options(opts_vec);
let mode = opts.get("mode");
if let Some(mode) = mode { let mut need_set_fsgid = false;
if let Some(fsgid) = opts.get(FS_GID) {
let gid = fsgid.parse::<u32>()?;
nix::unistd::chown(storage.mount_point.as_str(), None, Some(Gid::from_raw(gid)))?;
need_set_fsgid = true;
}
if let Some(mode) = opts.get("mode") {
let mut permission = fs::metadata(&storage.mount_point)?.permissions(); let mut permission = fs::metadata(&storage.mount_point)?.permissions();
let o_mode = u32::from_str_radix(mode, 8)?; let mut o_mode = u32::from_str_radix(mode, 8)?;
if need_set_fsgid {
// set SetGid mode mask.
o_mode |= 0o2000;
}
permission.set_mode(o_mode); permission.set_mode(o_mode);
fs::set_permissions(&storage.mount_point, permission)?; fs::set_permissions(&storage.mount_point, permission)?;

View File

@@ -51,6 +51,9 @@ const (
// containers. // containers.
KataLocalDevType = "local" KataLocalDevType = "local"
// Allocating an FSGroup that owns the pod's volumes
fsGid = "fsgid"
// path to vfio devices // path to vfio devices
vfioPath = "/dev/vfio/" vfioPath = "/dev/vfio/"
@@ -1320,7 +1323,11 @@ func (k *kataAgent) createContainer(ctx context.Context, sandbox *Sandbox, c *Co
epheStorages := k.handleEphemeralStorage(ociSpec.Mounts) epheStorages := k.handleEphemeralStorage(ociSpec.Mounts)
ctrStorages = append(ctrStorages, epheStorages...) ctrStorages = append(ctrStorages, epheStorages...)
localStorages := k.handleLocalStorage(ociSpec.Mounts, sandbox.id, c.rootfsSuffix) localStorages, err := k.handleLocalStorage(ociSpec.Mounts, sandbox.id, c.rootfsSuffix)
if err != nil {
return nil, err
}
ctrStorages = append(ctrStorages, localStorages...) ctrStorages = append(ctrStorages, localStorages...)
// We replace all OCI mount sources that match our container mount // We replace all OCI mount sources that match our container mount
@@ -1419,10 +1426,27 @@ func (k *kataAgent) handleEphemeralStorage(mounts []specs.Mount) []*grpc.Storage
// handleLocalStorage handles local storage within the VM // handleLocalStorage handles local storage within the VM
// by creating a directory in the VM from the source of the mount point. // by creating a directory in the VM from the source of the mount point.
func (k *kataAgent) handleLocalStorage(mounts []specs.Mount, sandboxID string, rootfsSuffix string) []*grpc.Storage { func (k *kataAgent) handleLocalStorage(mounts []specs.Mount, sandboxID string, rootfsSuffix string) ([]*grpc.Storage, error) {
var localStorages []*grpc.Storage var localStorages []*grpc.Storage
for idx, mnt := range mounts { for idx, mnt := range mounts {
if mnt.Type == KataLocalDevType { if mnt.Type == KataLocalDevType {
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
}
dir_options := localDirOptions
// 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 the desired directory point in the VM. // Set the mount source path to a the desired directory point in the VM.
// In this case it is located in the sandbox directory. // In this case it is located in the sandbox directory.
// We rely on the fact that the first container in the VM has the same ID as the sandbox ID. // We rely on the fact that the first container in the VM has the same ID as the sandbox ID.
@@ -1437,12 +1461,12 @@ func (k *kataAgent) handleLocalStorage(mounts []specs.Mount, sandboxID string, r
Source: KataLocalDevType, Source: KataLocalDevType,
Fstype: KataLocalDevType, Fstype: KataLocalDevType,
MountPoint: mounts[idx].Source, MountPoint: mounts[idx].Source,
Options: localDirOptions, Options: dir_options,
} }
localStorages = append(localStorages, localStorage) localStorages = append(localStorages, localStorage)
} }
} }
return localStorages return localStorages, nil
} }
// handleDeviceBlockVolume handles volume that is block device file // handleDeviceBlockVolume handles volume that is block device file

View File

@@ -205,7 +205,8 @@ func TestHandleEphemeralStorage(t *testing.T) {
func TestHandleLocalStorage(t *testing.T) { func TestHandleLocalStorage(t *testing.T) {
k := kataAgent{} k := kataAgent{}
var ociMounts []specs.Mount var ociMounts []specs.Mount
mountSource := "mountPoint" mountSource := "/tmp/mountPoint"
os.Mkdir(mountSource, 0755)
mount := specs.Mount{ mount := specs.Mount{
Type: KataLocalDevType, Type: KataLocalDevType,
@@ -216,7 +217,7 @@ func TestHandleLocalStorage(t *testing.T) {
rootfsSuffix := "rootfs" rootfsSuffix := "rootfs"
ociMounts = append(ociMounts, mount) ociMounts = append(ociMounts, mount)
localStorages := k.handleLocalStorage(ociMounts, sandboxID, rootfsSuffix) localStorages, _ := k.handleLocalStorage(ociMounts, sandboxID, rootfsSuffix)
assert.NotNil(t, localStorages) assert.NotNil(t, localStorages)
assert.Equal(t, len(localStorages), 1) assert.Equal(t, len(localStorages), 1)