12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 |
- 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}
- }
|