kata devices

const (
    driver9pType        = "9p"
    driverVirtioFSType  = "virtio-fs"
    driverBlkType       = "blk"
    driverBlkCCWType    = "blk-ccw"
    driverMmioBlkType   = "mmioblk"
    driverSCSIType      = "scsi"
    driverNvdimmType    = "nvdimm"
    driverEphemeralType = "ephemeral"
    driverLocalType     = "local"
    vmRootfs            = "/"
)
Access to devices on the host
If you need to directly expose some host devices to a container, you can use the devices parameter in the host_config param in Client.create_container as shown below:

cli.create_container(
    'busybox', 'true', host_config=cli.create_host_config(devices=[
        '/dev/sda:/dev/xvda:rwm'
    ])
)
Each string is a single mapping using the following format: <path_on_host>:<path_in_container>:<cgroup_permissions> The above example allows the container to have read-write access to the host's /dev/sda via a node named /dev/xvda inside the container.

As a more verbose alternative, each host device definition can be specified as a dictionary with the following keys:

{
    'PathOnHost': '/dev/sda1',
    'PathInContainer': '/dev/xvda',
    'CgroupPermissions': 'rwm'
}
// Stores a mapping of device names (in host / outer container naming)
// to the device and resources slots in a container spec
type devIndexEntry struct {
        idx         int
func makeDevIndex(spec *pb.Spec) devIndex {
        devIdx := make(devIndex)

        if spec == nil || spec.Linux == nil || spec.Linux.Devices == nil {
                return devIdx
        }

        for i, d := range spec.Linux.Devices {
                rIdx := make([]int, 0)

                if spec.Linux.Resources != nil && spec.Linux.Resources.Devices != nil {
                        for j, r := range spec.Linux.Resources.Devices {
                                if r.Type == d.Type && r.Major == d.Major && r.Minor == d.Minor {
                                        rIdx = append(rIdx, j)
                                }
                        }
                }

                devIdx[d.Path] = devIndexEntry{
                        idx:         i,
                        resourceIdx: rIdx,
                }
        }

        return devIdx
}
func (a *agentGRPC) CreateContainer(ctx context.Context, req *pb.CreateContainerRequest) (resp *gpb.Empty, err error) {
        if err := a.createContainerChecks(req); err != nil {
                return emptyResp, err
        }

        // re-scan PCI bus
        // looking for hidden devices
        if err = rescanPciBus(); err != nil {
                agentLog.WithError(err).Warn("Could not rescan PCI bus")
        }

        // Some devices need some extra processing (the ones invoked with
        // --device for instance), and that's what this call is doing. It
        // updates the devices listed in the OCI spec, so that they actually
        // match real devices inside the VM. This step is necessary since we
        // cannot predict everything from the caller.
        if err = addDevices(ctx, req.Devices, req.OCI, a.sandbox); err != nil {
                return emptyResp, err
        }
func addDevices(ctx context.Context, devices []*pb.Device, spec *pb.Spec, s *sandbox) error {
        devIdx := makeDevIndex(spec)

        for _, device := range devices {
                if device == nil {
                        continue
                }

                err := addDevice(ctx, device, spec, s, devIdx)
                if err != nil {
                        return err
                }

        }

        return nil
}
func addDevice(ctx context.Context, device *pb.Device, spec *pb.Spec, s *sandbox, devIdx devIndex) error {
        if device == nil {
                return grpcStatus.Error(codes.InvalidArgument, "invalid device")
        }

        if spec == nil {
                return grpcStatus.Error(codes.InvalidArgument, "invalid spec")
        }

        // log before validation to help with debugging gRPC protocol
        // version differences.
        agentLog.WithFields(logrus.Fields{
                "device-id":             device.Id,
                "device-type":           device.Type,
                "device-vm-path":        device.VmPath,
                "device-container-path": device.ContainerPath,
                "device-options":        device.Options,
        }).Debug()

        if device.Type == "" {
                return grpcStatus.Errorf(codes.InvalidArgument,
                        "invalid type for device %v", device)
        }

        if device.Id == "" && device.VmPath == "" {
                return grpcStatus.Errorf(codes.InvalidArgument,
                        "invalid ID and VM path for device %v", device)
        }

        if device.ContainerPath == "" {
                return grpcStatus.Errorf(codes.InvalidArgument,
                        "invalid container path for device %v", device)
        }

        devHandler, ok := deviceHandlerList[device.Type]
        if !ok {
                return grpcStatus.Errorf(codes.InvalidArgument,
                        "Unknown device type %q", device.Type)
        }

        return devHandler(ctx, *device, spec, s, devIdx)
}
type deviceHandler func(ctx context.Context, device pb.Device, spec *pb.Spec, s *sandbox, devIdx devIndex) error

var deviceHandlerList = map[string]deviceHandler{
        driverMmioBlkType: virtioMmioBlkDeviceHandler,
        driverBlkType:     virtioBlkDeviceHandler,
        driverBlkCCWType:  virtioBlkCCWDeviceHandler,
        driverSCSIType:    virtioSCSIDeviceHandler,
        driverNvdimmType:  nvdimmDeviceHandler,
}
原文地址:https://www.cnblogs.com/dream397/p/14023460.html