Skip to content

Commit

Permalink
Merge pull request microsoft#2003 from katiewasnothere/kabaldau/assig…
Browse files Browse the repository at this point in the history
…ned_devices_return_multi

Allow mounting multiple dev nodes per assigned device
  • Loading branch information
katiewasnothere authored Feb 14, 2024
2 parents 474daff + 00844b8 commit 050205c
Showing 1 changed file with 22 additions and 12 deletions.
34 changes: 22 additions & 12 deletions guest/runtime/hcsv2/spec_devices.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const (
)

// addAssignedDevice goes through the assigned devices that have been enumerated
// on the spec and updates the spec so that the correct device files can be mounted
// on the spec and updates the spec so that the correct device nodes can be mounted
// into the resulting container by the runtime.
func addAssignedDevice(ctx context.Context, spec *oci.Spec) error {
for _, d := range spec.Windows.Devices {
Expand All @@ -38,21 +38,23 @@ func addAssignedDevice(ctx context.Context, spec *oci.Spec) error {
if err != nil {
return errors.Wrapf(err, "failed to find device pci path for device %v", d)
}
// find the device node that links to the pci path we just got
dev, err := devicePathFromPCIPath(fullPCIPath)
// find the device nodes that link to the pci path we just got
devs, err := devicePathsFromPCIPath(ctx, fullPCIPath)
if err != nil {
return errors.Wrapf(err, "failed to find dev node for device %v", d)
}
addLinuxDeviceToSpec(ctx, dev, spec, true)
for _, dev := range devs {
addLinuxDeviceToSpec(ctx, dev, spec, true)
}
}
}

return nil
}

// devicePathFromPCIPath takes a sysfs bus path to the pci device assigned into the guest
// and attempts to find the dev node in the guest that maps to it.
func devicePathFromPCIPath(pciPath string) (*devices.Device, error) {
// devicePathsFromPCIPath takes a sysfs bus path to the pci device assigned into the guest
// and attempts to find the dev nodes in the guest that map to it.
func devicePathsFromPCIPath(ctx context.Context, pciPath string) ([]*devices.Device, error) {
// get the full pci path to make sure that it's the final path
pciFullPath, err := filepath.EvalSymlinks(pciPath)
if err != nil {
Expand All @@ -65,7 +67,10 @@ func devicePathFromPCIPath(pciPath string) (*devices.Device, error) {
return nil, err
}

// find corresponding entry in sysfs
// some drivers create multiple dev nodes associated with the PCI device
out := []*devices.Device{}

// find corresponding entries in sysfs
for _, d := range hostDevices {
major := d.Rule.Major
minor := d.Rule.Minor
Expand All @@ -83,15 +88,20 @@ func devicePathFromPCIPath(pciPath string) (*devices.Device, error) {
syfsDevPath := fmt.Sprintf(sysfsDevPathFormat, deviceTypeString, major, minor)
sysfsFullPath, err := filepath.EvalSymlinks(syfsDevPath)
if err != nil {
return nil, err
// Some drivers will make dev nodes that do not have a matching block or
// char device -- skip those.
log.G(ctx).WithError(err).Debugf("failed to find sysfs path for device %s", d.Path)
continue
}
if strings.HasPrefix(sysfsFullPath, pciFullPath) {
// return early once we find the device
return d, nil
out = append(out, d)
}
}

return nil, errors.New("failed to find the device node from sysfs pci path")
if len(out) == 0 {
return nil, errors.New("failed to find the device nodes for sysfs pci path")
}
return out, nil
}

func addLinuxDeviceToSpec(ctx context.Context, hostDevice *devices.Device, spec *oci.Spec, addCgroupDevice bool) {
Expand Down

0 comments on commit 050205c

Please sign in to comment.