diff --git a/internal/oci/uvm.go b/internal/oci/uvm.go index 9b8c6933aa..00a10e7081 100644 --- a/internal/oci/uvm.go +++ b/internal/oci/uvm.go @@ -138,6 +138,7 @@ const ( annotationStorageQoSIopsMaximum = "io.microsoft.virtualmachine.storageqos.iopsmaximum" annotationFullyPhysicallyBacked = "io.microsoft.virtualmachine.fullyphysicallybacked" annotationDisableCompartmentNamespace = "io.microsoft.virtualmachine.disablecompartmentnamespace" + annotationVSMBNoDirectMap = "io.microsoft.virtualmachine.wcow.virtualSMB.nodirectmap" // A boolean annotation to control whether to use an external bridge or the // HCS-GCS bridge. Default value is true which means external bridge will be used // by default. @@ -490,6 +491,7 @@ func SpecToUVMCreateOpts(ctx context.Context, s *specs.Spec, id, owner string) ( wopts.DisableCompartmentNamespace = parseAnnotationsBool(ctx, s.Annotations, annotationDisableCompartmentNamespace, wopts.DisableCompartmentNamespace) wopts.CPUGroupID = parseAnnotationsString(s.Annotations, annotationCPUGroupID, wopts.CPUGroupID) wopts.NetworkConfigProxy = parseAnnotationsString(s.Annotations, annotationNetworkConfigProxy, wopts.NetworkConfigProxy) + wopts.NoDirectMap = parseAnnotationsBool(ctx, s.Annotations, annotationVSMBNoDirectMap, wopts.NoDirectMap) handleAnnotationFullyPhysicallyBacked(ctx, s.Annotations, wopts) if err := handleCloneAnnotations(ctx, s.Annotations, wopts); err != nil { return nil, err diff --git a/internal/uvm/create.go b/internal/uvm/create.go index 73355e2c06..2ec528f0d3 100644 --- a/internal/uvm/create.go +++ b/internal/uvm/create.go @@ -373,6 +373,11 @@ func (uvm *UtilityVM) DevicesPhysicallyBacked() bool { return uvm.devicesPhysicallyBacked } +// VSMBNoDirectMap returns if VSMB devices should be mounted with `NoDirectMap` set to true +func (uvm *UtilityVM) VSMBNoDirectMap() bool { + return uvm.vsmbNoDirectMap +} + // Closes the external GCS connection if it is being used and also closes the // listener for GCS connection. func (uvm *UtilityVM) CloseGCSConnection() (err error) { diff --git a/internal/uvm/create_wcow.go b/internal/uvm/create_wcow.go index 3fc84edaca..04eb1dd9d1 100644 --- a/internal/uvm/create_wcow.go +++ b/internal/uvm/create_wcow.go @@ -46,6 +46,9 @@ type OptionsWCOW struct { // which holds all the information about the template from // which this clone should be created. TemplateConfig *UVMTemplateConfig + + // NoDirectMap specifies that no direct mapping should be used for any VSMBs added to the UVM + NoDirectMap bool } // NewDefaultOptionsWCOW creates the default options for a bootable version of @@ -225,6 +228,7 @@ func CreateWCOW(ctx context.Context, opts *OptionsWCOW) (_ *UtilityVM, err error vpciDevices: make(map[string]*VPCIDevice), physicallyBacked: !opts.AllowOvercommit, devicesPhysicallyBacked: opts.FullyPhysicallyBacked, + vsmbNoDirectMap: opts.NoDirectMap, createOpts: *opts, } diff --git a/internal/uvm/types.go b/internal/uvm/types.go index 91e44aa24d..24b632865c 100644 --- a/internal/uvm/types.go +++ b/internal/uvm/types.go @@ -74,9 +74,10 @@ type UtilityVM struct { // unrestricted mappings of directories. `vsmbFileShares` tracks shares that // are restricted to some subset of files in the directory. This is used as // part of a temporary fix to allow WCOW single-file mapping to function. - vsmbDirShares map[string]*VSMBShare - vsmbFileShares map[string]*VSMBShare - vsmbCounter uint64 // Counter to generate a unique share name for each VSMB share. + vsmbDirShares map[string]*VSMBShare + vsmbFileShares map[string]*VSMBShare + vsmbCounter uint64 // Counter to generate a unique share name for each VSMB share. + vsmbNoDirectMap bool // indicates if VSMB devices should be added with the `NoDirectMap` option // VPMEM devices that are mapped into a Linux UVM. These are used for read-only layers, or for // booting from VHD. diff --git a/internal/uvm/vsmb.go b/internal/uvm/vsmb.go index f01009774e..f81dfe8a01 100644 --- a/internal/uvm/vsmb.go +++ b/internal/uvm/vsmb.go @@ -50,7 +50,7 @@ func (vsmb *VSMBShare) Release(ctx context.Context) error { // returns the default VSMB options for a readonly share. func (uvm *UtilityVM) DefaultVSMBOptions(readOnly bool) *hcsschema.VirtualSmbShareOptions { opts := &hcsschema.VirtualSmbShareOptions{ - NoDirectmap: uvm.DevicesPhysicallyBacked(), + NoDirectmap: uvm.DevicesPhysicallyBacked() || uvm.VSMBNoDirectMap(), } if readOnly { opts.ShareRead = true diff --git a/test/cri-containerd/runpodsandbox_test.go b/test/cri-containerd/runpodsandbox_test.go index 9758b194ae..b106fc6b47 100644 --- a/test/cri-containerd/runpodsandbox_test.go +++ b/test/cri-containerd/runpodsandbox_test.go @@ -197,6 +197,18 @@ func Test_RunPodSandbox_FullyPhysicallyBacked_WCOW_Hypervisor(t *testing.T) { runPodSandboxTest(t, request) } +func Test_RunPodSandbox_VSMBNoDirectMap_WCOW_Hypervisor(t *testing.T) { + requireFeatures(t, featureWCOWHypervisor) + + pullRequiredImages(t, []string{imageWindowsNanoserver}) + + request := getRunPodSandboxRequest(t, wcowHypervisorRuntimeHandler) + request.Config.Annotations = map[string]string{ + "io.microsoft.virtualmachine.wcow.virtualSMB.nodirectmap": "true", + } + runPodSandboxTest(t, request) +} + func Test_RunPodSandbox_PhysicalMemory_LCOW(t *testing.T) { requireFeatures(t, featureLCOW)