dedf5747cc
Signed-off-by: Evan Lezar <elezar@nvidia.com>
49 lines
1.7 KiB
Go
49 lines
1.7 KiB
Go
package daemon // import "github.com/docker/docker/daemon"
|
|
|
|
import (
|
|
"github.com/docker/docker/api/types/container"
|
|
"github.com/docker/docker/pkg/capabilities"
|
|
specs "github.com/opencontainers/runtime-spec/specs-go"
|
|
)
|
|
|
|
var deviceDrivers = map[string]*deviceDriver{}
|
|
|
|
type deviceDriver struct {
|
|
capset capabilities.Set
|
|
updateSpec func(*specs.Spec, *deviceInstance) error
|
|
}
|
|
|
|
type deviceInstance struct {
|
|
req container.DeviceRequest
|
|
selectedCaps []string
|
|
}
|
|
|
|
func registerDeviceDriver(name string, d *deviceDriver) {
|
|
deviceDrivers[name] = d
|
|
}
|
|
|
|
func (daemon *Daemon) handleDevice(req container.DeviceRequest, spec *specs.Spec) error {
|
|
if req.Driver == "" {
|
|
for _, dd := range deviceDrivers {
|
|
if selected := dd.capset.Match(req.Capabilities); selected != nil {
|
|
return dd.updateSpec(spec, &deviceInstance{req: req, selectedCaps: selected})
|
|
}
|
|
}
|
|
} else if dd := deviceDrivers[req.Driver]; dd != nil {
|
|
// We add a special case for the CDI driver here as the cdi driver does
|
|
// not distinguish between capabilities.
|
|
// Furthermore, the "OR" and "AND" matching logic for the capability
|
|
// sets requires that a dummy capability be specified when constructing a
|
|
// DeviceRequest.
|
|
// This workaround can be removed once these device driver are
|
|
// refactored to be plugins, with each driver implementing its own
|
|
// matching logic, for example.
|
|
if req.Driver == "cdi" {
|
|
return dd.updateSpec(spec, &deviceInstance{req: req})
|
|
}
|
|
if selected := dd.capset.Match(req.Capabilities); selected != nil {
|
|
return dd.updateSpec(spec, &deviceInstance{req: req, selectedCaps: selected})
|
|
}
|
|
}
|
|
return incompatibleDeviceRequest{req.Driver, req.Capabilities}
|
|
}
|