Skip to content

Commit

Permalink
Merge pull request #1742 from kevpar/getscsiuvmpath
Browse files Browse the repository at this point in the history
Remove dependence on GetScsiUvmPath function
  • Loading branch information
kevpar authored May 4, 2023
2 parents d446b24 + 1dd217b commit 4c7925c
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 59 deletions.
9 changes: 9 additions & 0 deletions cmd/gcstools/installdrivers.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ package main
import (
"context"
"fmt"
"io/fs"
"os"
"os/exec"
"path/filepath"
Expand All @@ -27,6 +28,14 @@ func install(ctx context.Context) error {
targetOverlayPath := args[0]
driver := args[1]

if _, err := os.Lstat(targetOverlayPath); err == nil {
// We assume the overlay path to be unique per set of drivers. Thus, if the path
// exists already, we have already installed these drivers, and can quit early.
return nil
} else if !errors.Is(err, fs.ErrNotExist) {
return fmt.Errorf("failed to stat overlay dir: %s: %w", targetOverlayPath, err)
}

// create an overlay mount from the driver's UVM path so we can write to the
// mount path in the UVM despite having mounted in the driver originally as
// readonly
Expand Down
14 changes: 7 additions & 7 deletions internal/devices/drivers.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,9 @@ func InstallDrivers(ctx context.Context, vm *uvm.UtilityVM, share string, gpuDri
return closer, execPnPInstallDriver(ctx, vm, uvmPath)
}

// no need to reinstall if the driver has already been added in LCOW, return early
if _, err := vm.GetScsiUvmPath(ctx, share); err != uvm.ErrNotAttached {
return nil, err
}

// first mount driver as scsi in standard mount location
uvmPathForShare := fmt.Sprintf(guestpath.LCOWGlobalMountPrefixFmt, vm.UVMMountCounter())
closer, err = vm.AddSCSI(ctx,
mount, err := vm.AddSCSI(ctx,
share,
uvmPathForShare,
true,
Expand All @@ -70,9 +65,14 @@ func InstallDrivers(ctx context.Context, vm *uvm.UtilityVM, share string, gpuDri
if err != nil {
return closer, fmt.Errorf("failed to add SCSI disk to utility VM for path %+v: %s", share, err)
}
closer = mount
uvmPathForShare = mount.UVMPath

// construct path that the drivers will be remounted as read/write in the UVM
driverGUID, err := guid.NewV4()

// 914aadc8-f700-4365-8016-ddad0a9d406d. Random GUID chosen for namespace.
ns := guid.GUID{Data1: 0x914aadc8, Data2: 0xf700, Data3: 0x4365, Data4: [8]byte{0x80, 0x16, 0xdd, 0xad, 0x0a, 0x9d, 0x40, 0x6d}}
driverGUID, err := guid.NewV5(ns, []byte(share))
if err != nil {
return closer, fmt.Errorf("failed to create a guid path for driver %+v: %s", share, err)
}
Expand Down
6 changes: 4 additions & 2 deletions internal/hcsoci/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ type createOptionsInternal struct {
actualOwner string // Owner for the container
actualNetworkNamespace string
ccgState *hcsschema.ContainerCredentialGuardState // Container Credential Guard information to be attached to HCS container document

windowsAdditionalMounts []hcsschema.MappedDirectory // Holds additional mounts based on added devices (such as SCSI). Only used for Windows v2 schema containers.
}

func validateContainerConfig(ctx context.Context, coi *createOptionsInternal) error {
Expand Down Expand Up @@ -173,7 +175,7 @@ func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.C
return nil, nil, fmt.Errorf("container config validation failed: %s", err)
}

r := resources.NewContainerResources(createOptions.ID)
r := resources.NewContainerResources(coi.ID)
defer func() {
if err != nil {
if !coi.DoNotReleaseResourcesOnFailure {
Expand All @@ -184,7 +186,7 @@ func CreateContainer(ctx context.Context, createOptions *CreateOptions) (_ cow.C

if coi.HostingSystem != nil {
if coi.Spec.Linux != nil {
r.SetContainerRootInUVM(fmt.Sprintf(lcowRootInUVM, createOptions.ID))
r.SetContainerRootInUVM(fmt.Sprintf(lcowRootInUVM, coi.ID))
} else {
n := coi.HostingSystem.ContainerCounter()
r.SetContainerRootInUVM(fmt.Sprintf(wcowRootInUVM, strconv.FormatUint(n, 16)))
Expand Down
17 changes: 4 additions & 13 deletions internal/hcsoci/hcsdoc_wcow.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,9 @@ func createMountsConfig(ctx context.Context, coi *createOptionsInternal) (*mount
}
mdv2.HostPath = src
} else if mount.Type == "virtual-disk" || mount.Type == "physical-disk" || mount.Type == "extensible-virtual-disk" {
mountPath := mount.Source
var err error
if mount.Type == "extensible-virtual-disk" {
_, mountPath, err = uvm.ParseExtensibleVirtualDiskPath(mount.Source)
if err != nil {
return nil, err
}
}
uvmPath, err := coi.HostingSystem.GetScsiUvmPath(ctx, mountPath)
if err != nil {
return nil, err
}
mdv2.HostPath = uvmPath
// For v2 schema containers, any disk mounts will be part of coi.additionalMounts.
// For v1 schema containers, we don't even get here, since there is no HostingSystem.
continue
} else if strings.HasPrefix(mount.Source, guestpath.SandboxMountPrefix) {
// Convert to the path in the guest that was asked for.
mdv2.HostPath = convertToWCOWSandboxMountPath(mount.Source)
Expand All @@ -97,6 +87,7 @@ func createMountsConfig(ctx context.Context, coi *createOptionsInternal) (*mount
config.mdsv2 = append(config.mdsv2, mdv2)
}
}
config.mdsv2 = append(config.mdsv2, coi.windowsAdditionalMounts...)
return &config, nil
}

Expand Down
66 changes: 42 additions & 24 deletions internal/hcsoci/resources_wcow.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/Microsoft/hcsshim/internal/cmd"
"github.com/Microsoft/hcsshim/internal/credentials"
"github.com/Microsoft/hcsshim/internal/guestpath"
hcsschema "github.com/Microsoft/hcsshim/internal/hcs/schema2"
"github.com/Microsoft/hcsshim/internal/layers"
"github.com/Microsoft/hcsshim/internal/log"
"github.com/Microsoft/hcsshim/internal/resources"
Expand Down Expand Up @@ -151,35 +152,52 @@ func setupMounts(ctx context.Context, coi *createOptionsInternal, r *resources.R
}
}
l := log.G(ctx).WithField("mount", fmt.Sprintf("%+v", mount))
if mount.Type == "physical-disk" {
l.Debug("hcsshim::allocateWindowsResources Hot-adding SCSI physical disk for OCI mount")
scsiMount, err := coi.HostingSystem.AddSCSIPhysicalDisk(ctx, mount.Source, uvmPath, readOnly, mount.Options)
if err != nil {
return errors.Wrapf(err, "adding SCSI physical disk mount %+v", mount)
}
r.Add(scsiMount)
} else if mount.Type == "virtual-disk" {
l.Debug("hcsshim::allocateWindowsResources Hot-adding SCSI virtual disk for OCI mount")
scsiMount, err := coi.HostingSystem.AddSCSI(
ctx,
mount.Source,
uvmPath,
readOnly,
false,
mount.Options,
uvm.VMAccessTypeIndividual,
if mount.Type == "physical-disk" || mount.Type == "virtual-disk" || mount.Type == "extensible-virtual-disk" {
var (
scsiMount *uvm.SCSIMount
err error
)
if err != nil {
return errors.Wrapf(err, "adding SCSI virtual disk mount %+v", mount)
switch mount.Type {
case "physical-disk":
l.Debug("hcsshim::allocateWindowsResources Hot-adding SCSI physical disk for OCI mount")
scsiMount, err = coi.HostingSystem.AddSCSIPhysicalDisk(
ctx,
mount.Source,
uvmPath,
readOnly,
mount.Options,
)
case "virtual-disk":
l.Debug("hcsshim::allocateWindowsResources Hot-adding SCSI virtual disk for OCI mount")
scsiMount, err = coi.HostingSystem.AddSCSI(
ctx,
mount.Source,
uvmPath,
readOnly,
false,
mount.Options,
uvm.VMAccessTypeIndividual,
)
case "extensible-virtual-disk":
l.Debug("hcsshim::allocateWindowsResource Hot-adding ExtensibleVirtualDisk")
scsiMount, err = coi.HostingSystem.AddSCSIExtensibleVirtualDisk(
ctx,
mount.Source,
uvmPath,
readOnly,
)
}
r.Add(scsiMount)
} else if mount.Type == "extensible-virtual-disk" {
l.Debug("hcsshim::allocateWindowsResource Hot-adding ExtensibleVirtualDisk")
scsiMount, err := coi.HostingSystem.AddSCSIExtensibleVirtualDisk(ctx, mount.Source, uvmPath, readOnly)
if err != nil {
return errors.Wrapf(err, "adding SCSI EVD mount failed %+v", mount)
return fmt.Errorf("adding SCSI mount %+v: %w", mount, err)
}
r.Add(scsiMount)
// Compute guest mounts now, and store them, so they can be added to the container doc later.
// We do this now because we have access to the guest path through the returned mount object.
coi.windowsAdditionalMounts = append(coi.windowsAdditionalMounts, hcsschema.MappedDirectory{
HostPath: scsiMount.UVMPath,
ContainerPath: mount.Destination,
ReadOnly: readOnly,
})
} else if strings.HasPrefix(mount.Source, guestpath.SandboxMountPrefix) {
// Mounts that map to a path in the UVM are specified with a 'sandbox://' prefix.
//
Expand Down
13 changes: 0 additions & 13 deletions internal/uvm/scsi.go
Original file line number Diff line number Diff line change
Expand Up @@ -519,19 +519,6 @@ func (uvm *UtilityVM) allocateSCSIMount(
return uvm.scsiLocations[controller][lun], false, nil
}

// GetScsiUvmPath returns the guest mounted path of a SCSI drive.
//
// If `hostPath` is not mounted returns `ErrNotAttached`.
func (uvm *UtilityVM) GetScsiUvmPath(ctx context.Context, hostPath string) (string, error) {
uvm.m.Lock()
defer uvm.m.Unlock()
sm, err := uvm.findSCSIAttachment(ctx, hostPath)
if err != nil {
return "", err
}
return sm.UVMPath, err
}

// ScratchEncryptionEnabled is a getter for `uvm.encryptScratch`.
//
// Returns true if the scratch disks should be encrypted, false otherwise.
Expand Down

0 comments on commit 4c7925c

Please sign in to comment.