diff --git a/hcsoci/create.go b/hcsoci/create.go index 70ae8cbba1..e425316298 100644 --- a/hcsoci/create.go +++ b/hcsoci/create.go @@ -118,10 +118,10 @@ func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.C }() if coi.HostingSystem != nil { - n := coi.HostingSystem.ContainerCounter() if coi.Spec.Linux != nil { r.SetContainerRootInUVM(fmt.Sprintf(lcowRootInUVM, createOptions.ID)) } else { + n := coi.HostingSystem.ContainerCounter() r.SetContainerRootInUVM(fmt.Sprintf(wcowRootInUVM, strconv.FormatUint(n, 16))) } } diff --git a/layers/layers.go b/layers/layers.go index 187ca7df62..fb5429bcc0 100644 --- a/layers/layers.go +++ b/layers/layers.go @@ -143,9 +143,13 @@ func MountContainerLayers(ctx context.Context, layerFolders []string, guestRoot } } - hostPath := filepath.Join(layerFolders[len(layerFolders)-1], "sandbox.vhdx") containerScratchPathInUVM := ospath.Join(uvm.OS(), guestRoot) + hostPath, err := getScratchVHDPath(layerFolders) + if err != nil { + return "", fmt.Errorf("failed to get scratch VHD path in layer folders: %s", err) + } log.G(ctx).WithField("hostPath", hostPath).Debug("mounting scratch VHD") + scsiMount, err := uvm.AddSCSI(ctx, hostPath, containerScratchPathInUVM, false, uvmpkg.VMAccessTypeIndividual) if err != nil { return "", fmt.Errorf("failed to add SCSI scratch VHD: %s", err) @@ -284,7 +288,10 @@ func UnmountContainerLayers(ctx context.Context, layerFolders []string, containe // Unload the SCSI scratch path if (op & UnmountOperationSCSI) == UnmountOperationSCSI { - hostScratchFile := filepath.Join(layerFolders[len(layerFolders)-1], "sandbox.vhdx") + hostScratchFile, err := getScratchVHDPath(layerFolders) + if err != nil { + return fmt.Errorf("failed to get scratch VHD path in layer folders: %s", err) + } if err := uvm.RemoveSCSI(ctx, hostScratchFile); err != nil { log.G(ctx).WithError(err).Warn("failed to remove scratch") if retError == nil { @@ -353,3 +360,18 @@ func containerRootfsPath(uvm *uvm.UtilityVM, rootPath string) string { } return ospath.Join(uvm.OS(), rootPath, uvmpkg.RootfsPath) } + +func getScratchVHDPath(layerFolders []string) (string, error) { + hostPath := filepath.Join(layerFolders[len(layerFolders)-1], "sandbox.vhdx") + // For LCOW, we can reuse another container's scratch space (usually the sandbox container's). + // + // When sharing a scratch space, the `hostPath` will be a symlink to the sandbox.vhdx location to use. + // When not sharing a scratch space, `hostPath` will be the path to the sandbox.vhdx to use. + // + // Evaluate the symlink here (if there is one). + hostPath, err := filepath.EvalSymlinks(hostPath) + if err != nil { + return "", fmt.Errorf("failed to eval symlinks: %s", err) + } + return hostPath, nil +} diff --git a/uvm/create_wcow.go b/uvm/create_wcow.go index 6c2b1bf395..d9956b1342 100644 --- a/uvm/create_wcow.go +++ b/uvm/create_wcow.go @@ -16,6 +16,7 @@ import ( hcsschema "github.com/Microsoft/hcsshim/internal/schema2" "github.com/Microsoft/hcsshim/internal/schemaversion" "github.com/Microsoft/hcsshim/internal/uvmfolder" + "github.com/Microsoft/hcsshim/internal/wclayer" "github.com/Microsoft/hcsshim/internal/wcow" "github.com/pkg/errors" "go.opencensus.io/trace" @@ -110,6 +111,11 @@ func CreateWCOW(ctx context.Context, opts *OptionsWCOW) (_ *UtilityVM, err error if err := wcow.CreateUVMScratch(ctx, uvmFolder, scratchFolder, uvm.id); err != nil { return nil, fmt.Errorf("failed to create scratch: %s", err) } + } else { + // Sandbox.vhdx exists, just need to grant vm access to it. + if err := wclayer.GrantVmAccess(ctx, uvm.id, scratchPath); err != nil { + return nil, errors.Wrap(err, "failed to grant vm access to scratch") + } } processorTopology, err := hostProcessorInfo(ctx)