mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-09-13 21:09:31 +00:00
@@ -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)?;
|
||||||
|
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
Reference in New Issue
Block a user