diff --git a/src/runtime/pkg/katautils/create.go b/src/runtime/pkg/katautils/create.go index 3c3bf05c8d..bcc7d8ce7f 100644 --- a/src/runtime/pkg/katautils/create.go +++ b/src/runtime/pkg/katautils/create.go @@ -129,7 +129,7 @@ func CreateSandbox(ctx context.Context, vci vc.VC, ociSpec specs.Spec, runtimeCo } if !rootFs.Mounted && len(sandboxConfig.Containers) == 1 { - if rootFs.Source != "" { + if rootFs.Source != "" && !vc.HasOptionPrefix(rootFs.Options, vc.VirtualVolumePrefix) { realPath, err := ResolvePath(rootFs.Source) if err != nil { return nil, vc.Process{}, err diff --git a/src/runtime/virtcontainers/fs_share_linux.go b/src/runtime/virtcontainers/fs_share_linux.go index 347e63ebfb..06c21c3afa 100644 --- a/src/runtime/virtcontainers/fs_share_linux.go +++ b/src/runtime/virtcontainers/fs_share_linux.go @@ -27,6 +27,7 @@ import ( "github.com/kata-containers/kata-containers/src/runtime/pkg/katautils/katatrace" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/agent/protocols/grpc" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/pkg/annotations" + "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/types" "github.com/kata-containers/kata-containers/src/runtime/virtcontainers/utils" ) @@ -443,6 +444,77 @@ func (f *FilesystemShare) shareRootFilesystemWithNydus(ctx context.Context, c *C }, nil } +// handleVirtualVolume processes each `extraoption` in rootFs.Options, +// creating storage, and then aggregates all storages into an array. +func handleVirtualVolume(c *Container) ([]*grpc.Storage, string, error) { + var volumes []*grpc.Storage + var volumeType string + + for _, o := range c.rootFs.Options { + if strings.HasPrefix(o, VirtualVolumePrefix) { + virtVolume, err := types.ParseKataVirtualVolume(strings.TrimPrefix(o, VirtualVolumePrefix)) + if err != nil { + return nil, "", err + } + + volumeType = virtVolume.VolumeType + var vol *grpc.Storage + if virtVolume.VolumeType == types.KataVirtualVolumeImageRawBlockType || virtVolume.VolumeType == types.KataVirtualVolumeLayerRawBlockType { + for i, d := range c.devices { + if d.ContainerPath == virtVolume.Source { + vol, err = handleVirtualVolumeStorageObject(c, d.ID, virtVolume) + if err != nil { + return nil, "", err + } + c.devices[i].ContainerPath = vol.MountPoint + vol.Fstype = virtVolume.FSType + vol.Options = append(vol.Options, virtVolume.Options...) + break + } + } + } + if vol != nil { + volumes = append(volumes, vol) + } + } + } + + return volumes, volumeType, nil +} + +func (f *FilesystemShare) shareRootFilesystemWithVirtualVolume(ctx context.Context, c *Container) (*SharedFile, error) { + kataGuestDir := filepath.Join(defaultKataGuestVirtualVolumedir, "containers") + guestPath := filepath.Join("/run/kata-containers/", c.id, c.rootfsSuffix) + rootFsStorages, volumeType, err := handleVirtualVolume(c) + if err != nil { + return nil, err + } + + if volumeType == types.KataVirtualVolumeImageRawBlockType || volumeType == types.KataVirtualVolumeLayerRawBlockType { + rootfs := &grpc.Storage{} + rootfs.MountPoint = guestPath + overlayDirDriverOption := "io.katacontainers.volume.overlayfs.create_directory" + rootfs.Source = typeOverlayFS + rootfs.Fstype = typeOverlayFS + rootfs.Driver = kataOverlayDevType + for _, v := range rootFsStorages { + rootfs.Options = append(rootfs.Options, fmt.Sprintf("%s=%s", lowerDir, v.MountPoint)) + } + rootfsUpperDir := filepath.Join(kataGuestDir, c.id, "fs") + rootfsWorkDir := filepath.Join(kataGuestDir, c.id, "work") + rootfs.DriverOptions = append(rootfs.DriverOptions, fmt.Sprintf("%s=%s", overlayDirDriverOption, rootfsUpperDir)) + rootfs.DriverOptions = append(rootfs.DriverOptions, fmt.Sprintf("%s=%s", overlayDirDriverOption, rootfsWorkDir)) + rootfs.Options = append(rootfs.Options, fmt.Sprintf("%s=%s", upperDir, rootfsUpperDir)) + rootfs.Options = append(rootfs.Options, fmt.Sprintf("%s=%s", workDir, rootfsWorkDir)) + rootFsStorages = append(rootFsStorages, rootfs) + f.Logger().Infof("verity rootfs info: %#v\n", rootfs) + } + return &SharedFile{ + containerStorages: rootFsStorages, + guestPath: guestPath, + }, nil +} + // func (c *Container) shareRootfs(ctx context.Context) (*grpc.Storage, string, error) { func (f *FilesystemShare) ShareRootFilesystem(ctx context.Context, c *Container) (*SharedFile, error) { rootfsGuestPath := filepath.Join(kataGuestSharedDir(), c.id, c.rootfsSuffix) @@ -456,6 +528,10 @@ func (f *FilesystemShare) ShareRootFilesystem(ctx context.Context, c *Container) }, nil } + if HasOptionPrefix(c.rootFs.Options, VirtualVolumePrefix) { + return f.shareRootFilesystemWithVirtualVolume(ctx, c) + } + if c.rootFs.Type == NydusRootFSType { return f.shareRootFilesystemWithNydus(ctx, c) } diff --git a/src/runtime/virtcontainers/kata_agent.go b/src/runtime/virtcontainers/kata_agent.go index cbd76b1b45..21b99d3579 100644 --- a/src/runtime/virtcontainers/kata_agent.go +++ b/src/runtime/virtcontainers/kata_agent.go @@ -1202,6 +1202,10 @@ func (k *kataAgent) appendDevices(deviceList []*grpc.Device, c *Container) []*gr return nil } + if strings.HasPrefix(dev.ContainerPath, defaultKataGuestVirtualVolumedir) { + continue + } + switch device.DeviceType() { case config.DeviceBlock: kataDevice = k.appendBlockDevice(dev, device, c)