Documentation
¶
Index ¶
- Variables
- func GetDeviceSysfsPath(pciAddress string) string
- func GetIOMMUGroupDevices(iommuGroup int) ([]string, error)
- func ValidateDeviceName(name string) bool
- func ValidatePCIAddress(addr string) bool
- type AvailableDevice
- type CreateDeviceRequest
- type Device
- type DeviceType
- type InstanceLivenessChecker
- type Manager
- type VFIOBinder
- func (v *VFIOBinder) BindToVFIO(pciAddress string) error
- func (v *VFIOBinder) CheckIOMMUGroupSafe(pciAddress string, allowedDevices []string) error
- func (v *VFIOBinder) GetVFIOGroupPath(pciAddress string) (string, error)
- func (v *VFIOBinder) IsDeviceBoundToVFIO(pciAddress string) bool
- func (v *VFIOBinder) IsVFIOAvailable() bool
- func (v *VFIOBinder) UnbindFromVFIO(pciAddress string) error
Constants ¶
This section is empty.
Variables ¶
var ( // ErrNotFound is returned when a device is not found ErrNotFound = errors.New("device not found") // ErrInUse is returned when a device is currently attached to an instance ErrInUse = errors.New("device is in use") // ErrNotBound is returned when a VFIO operation requires the device to be bound ErrNotBound = errors.New("device is not bound to VFIO") // ErrAlreadyBound is returned when trying to bind a device that's already bound to VFIO ErrAlreadyBound = errors.New("device is already bound to VFIO") // ErrAlreadyExists is returned when trying to register a device that already exists ErrAlreadyExists = errors.New("device already exists") // ErrInvalidName is returned when the device name doesn't match the required pattern ErrInvalidName = errors.New("device name must match pattern ^[a-zA-Z0-9][a-zA-Z0-9_.-]+$") // ErrNameExists is returned when a device with the same name already exists ErrNameExists = errors.New("device name already exists") // ErrInvalidPCIAddress is returned when the PCI address format is invalid ErrInvalidPCIAddress = errors.New("invalid PCI address format") // ErrDeviceNotFound is returned when the PCI device doesn't exist on the host ErrDeviceNotFound = errors.New("PCI device not found on host") // ErrVFIONotAvailable is returned when VFIO modules are not loaded ErrVFIONotAvailable = errors.New("VFIO is not available (modules not loaded)") // ErrIOMMUGroupConflict is returned when not all devices in IOMMU group can be passed through ErrIOMMUGroupConflict = errors.New("IOMMU group contains other devices that must also be passed through") )
var DeviceNamePattern = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_.-]+$`)
DeviceNamePattern is the regex pattern for valid device names Must start with alphanumeric, followed by alphanumeric, underscore, dot, or dash
Functions ¶
func GetDeviceSysfsPath ¶
GetDeviceSysfsPath returns the sysfs path for a PCI device (used by cloud-hypervisor)
func GetIOMMUGroupDevices ¶
GetIOMMUGroupDevices returns all PCI devices in the same IOMMU group
func ValidateDeviceName ¶
ValidateDeviceName validates that a device name matches the required pattern
func ValidatePCIAddress ¶
ValidatePCIAddress validates that a string is a valid PCI address format
Types ¶
type AvailableDevice ¶
type AvailableDevice struct {
PCIAddress string `json:"pci_address"`
VendorID string `json:"vendor_id"`
DeviceID string `json:"device_id"`
VendorName string `json:"vendor_name"`
DeviceName string `json:"device_name"`
IOMMUGroup int `json:"iommu_group"`
CurrentDriver *string `json:"current_driver"` // nil if no driver bound
}
AvailableDevice represents a PCI device discovered on the host
func DiscoverAvailableDevices ¶
func DiscoverAvailableDevices() ([]AvailableDevice, error)
DiscoverAvailableDevices scans sysfs for PCI devices that can be used for passthrough It filters for devices that are likely candidates (GPUs, network cards, etc.)
func GetDeviceInfo ¶
func GetDeviceInfo(pciAddress string) (*AvailableDevice, error)
GetDeviceInfo reads information about a specific PCI device
type CreateDeviceRequest ¶
type CreateDeviceRequest struct {
Name string `json:"name,omitempty"` // optional: globally unique name (auto-generated if not provided)
PCIAddress string `json:"pci_address"` // required: PCI address (e.g., "0000:a2:00.0")
}
CreateDeviceRequest is the request to register a new device
type Device ¶
type Device struct {
Id string `json:"id"` // cuid2 identifier
Name string `json:"name"` // user-provided globally unique name
Type DeviceType `json:"type"` // gpu or pci
PCIAddress string `json:"pci_address"` // e.g., "0000:a2:00.0"
VendorID string `json:"vendor_id"` // e.g., "10de"
DeviceID string `json:"device_id"` // e.g., "27b8"
IOMMUGroup int `json:"iommu_group"` // IOMMU group number
BoundToVFIO bool `json:"bound_to_vfio"` // whether device is bound to vfio-pci
AttachedTo *string `json:"attached_to"` // instance ID if attached, nil otherwise
CreatedAt time.Time `json:"created_at"`
}
Device represents a registered PCI device for passthrough
type DeviceType ¶
type DeviceType string
DeviceType represents the type of PCI device
const ( DeviceTypeGPU DeviceType = "gpu" DeviceTypeGeneric DeviceType = "pci" )
func DetermineDeviceType ¶
func DetermineDeviceType(device *AvailableDevice) DeviceType
DetermineDeviceType determines the DeviceType based on device properties
type InstanceLivenessChecker ¶
type InstanceLivenessChecker interface {
// IsInstanceRunning returns true if the instance exists and is in a running state
// (i.e., has an active VMM process). Returns false if the instance doesn't exist
// or is stopped/standby/unknown.
IsInstanceRunning(ctx context.Context, instanceID string) bool
// GetInstanceDevices returns the list of device IDs attached to an instance.
// Returns nil if the instance doesn't exist.
GetInstanceDevices(ctx context.Context, instanceID string) []string
// ListAllInstanceDevices returns a map of instanceID -> []deviceIDs for all instances.
ListAllInstanceDevices(ctx context.Context) map[string][]string
// DetectSuspiciousVMMProcesses finds cloud-hypervisor processes that don't match
// known instances and logs warnings. Returns the count of suspicious processes found.
DetectSuspiciousVMMProcesses(ctx context.Context) int
}
InstanceLivenessChecker provides a way to check if an instance is running. This interface allows devices to query instance state without a circular dependency.
type Manager ¶
type Manager interface {
// ListDevices returns all registered devices
ListDevices(ctx context.Context) ([]Device, error)
// ListAvailableDevices discovers passthrough-capable devices on the host
ListAvailableDevices(ctx context.Context) ([]AvailableDevice, error)
// CreateDevice registers a new device for passthrough
CreateDevice(ctx context.Context, req CreateDeviceRequest) (*Device, error)
// GetDevice returns a device by ID or name
GetDevice(ctx context.Context, idOrName string) (*Device, error)
// DeleteDevice unregisters a device
DeleteDevice(ctx context.Context, id string) error
// BindToVFIO binds a device to vfio-pci driver
BindToVFIO(ctx context.Context, id string) error
// UnbindFromVFIO unbinds a device from vfio-pci driver
UnbindFromVFIO(ctx context.Context, id string) error
// MarkAttached marks a device as attached to an instance
MarkAttached(ctx context.Context, deviceID, instanceID string) error
// MarkDetached marks a device as detached from an instance
MarkDetached(ctx context.Context, deviceID string) error
// ReconcileDevices cleans up stale device state on startup.
// It detects devices with AttachedTo referencing non-existent instances
// and clears the orphaned attachment state.
ReconcileDevices(ctx context.Context) error
// SetLivenessChecker sets the instance liveness checker after construction.
// This allows breaking the circular dependency between device and instance managers.
SetLivenessChecker(checker InstanceLivenessChecker)
}
Manager provides device management operations
func NewManager ¶
NewManager creates a new device manager. Use SetLivenessChecker after construction to enable accurate orphan detection.
type VFIOBinder ¶
type VFIOBinder struct{}
VFIOBinder handles binding and unbinding devices to/from VFIO
func (*VFIOBinder) BindToVFIO ¶
func (v *VFIOBinder) BindToVFIO(pciAddress string) error
BindToVFIO binds a PCI device to the vfio-pci driver This requires: 1. Stopping any processes using the device (e.g., nvidia-persistenced for NVIDIA GPUs) 2. Unbinding the device from its current driver (if any) 3. Binding it to vfio-pci
func (*VFIOBinder) CheckIOMMUGroupSafe ¶
func (v *VFIOBinder) CheckIOMMUGroupSafe(pciAddress string, allowedDevices []string) error
CheckIOMMUGroupSafe checks if all devices in the IOMMU group are safe to pass through Returns an error if there are other devices in the group that aren't being passed through
func (*VFIOBinder) GetVFIOGroupPath ¶
func (v *VFIOBinder) GetVFIOGroupPath(pciAddress string) (string, error)
GetVFIOGroupPath returns the path to the VFIO group device for a PCI device
func (*VFIOBinder) IsDeviceBoundToVFIO ¶
func (v *VFIOBinder) IsDeviceBoundToVFIO(pciAddress string) bool
IsDeviceBoundToVFIO checks if a device is currently bound to vfio-pci
func (*VFIOBinder) IsVFIOAvailable ¶
func (v *VFIOBinder) IsVFIOAvailable() bool
IsVFIOAvailable checks if VFIO is available on the system
func (*VFIOBinder) UnbindFromVFIO ¶
func (v *VFIOBinder) UnbindFromVFIO(pciAddress string) error
UnbindFromVFIO unbinds a device from vfio-pci and restores the original driver