mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-24 14:32:33 +00:00
Merge pull request #8597 from amshinde/vfio-hotplug-support
Implement hotplug support for physical endpoints
This commit is contained in:
commit
d0dc67bb96
@ -94,4 +94,5 @@ type DeviceManager interface {
|
||||
GetDeviceByID(string) Device
|
||||
GetAllDevices() []Device
|
||||
LoadDevices([]config.DeviceState)
|
||||
FindDevice(*config.DeviceInfo) Device
|
||||
}
|
||||
|
@ -22,13 +22,12 @@ import (
|
||||
|
||||
// bind/unbind paths to aid in SRIOV VF bring-up/restore
|
||||
const (
|
||||
pciDriverUnbindPath = "/sys/bus/pci/devices/%s/driver/unbind"
|
||||
pciDriverBindPath = "/sys/bus/pci/drivers/%s/bind"
|
||||
vfioNewIDPath = "/sys/bus/pci/drivers/vfio-pci/new_id"
|
||||
vfioRemoveIDPath = "/sys/bus/pci/drivers/vfio-pci/remove_id"
|
||||
iommuGroupPath = "/sys/bus/pci/devices/%s/iommu_group"
|
||||
vfioDevPath = "/dev/vfio/%s"
|
||||
vfioAPSysfsDir = "/sys/devices/vfio_ap"
|
||||
pciDriverUnbindPath = "/sys/bus/pci/devices/%s/driver/unbind"
|
||||
pciDriverOverridePath = "/sys/bus/pci/devices/%s/driver_override"
|
||||
driversProbePath = "/sys/bus/pci/drivers_probe"
|
||||
iommuGroupPath = "/sys/bus/pci/devices/%s/iommu_group"
|
||||
vfioDevPath = "/dev/vfio/%s"
|
||||
vfioAPSysfsDir = "/sys/devices/vfio_ap"
|
||||
)
|
||||
|
||||
// VFIODevice is a vfio device meant to be passed to the hypervisor
|
||||
@ -269,42 +268,8 @@ func GetBDF(deviceSysStr string) string {
|
||||
return tokens[1]
|
||||
}
|
||||
|
||||
// BindDevicetoVFIO binds the device to vfio driver after unbinding from host.
|
||||
// Will be called by a network interface or a generic pcie device.
|
||||
func BindDevicetoVFIO(bdf, hostDriver, vendorDeviceID string) (string, error) {
|
||||
|
||||
// Unbind from the host driver
|
||||
unbindDriverPath := fmt.Sprintf(pciDriverUnbindPath, bdf)
|
||||
deviceLogger().WithFields(logrus.Fields{
|
||||
"device-bdf": bdf,
|
||||
"driver-path": unbindDriverPath,
|
||||
}).Info("Unbinding device from driver")
|
||||
|
||||
if err := utils.WriteToFile(unbindDriverPath, []byte(bdf)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Add device id to vfio driver.
|
||||
deviceLogger().WithFields(logrus.Fields{
|
||||
"vendor-device-id": vendorDeviceID,
|
||||
"vfio-new-id-path": vfioNewIDPath,
|
||||
}).Info("Writing vendor-device-id to vfio new-id path")
|
||||
|
||||
if err := utils.WriteToFile(vfioNewIDPath, []byte(vendorDeviceID)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Bind to vfio-pci driver.
|
||||
bindDriverPath := fmt.Sprintf(pciDriverBindPath, "vfio-pci")
|
||||
|
||||
api.DeviceLogger().WithFields(logrus.Fields{
|
||||
"device-bdf": bdf,
|
||||
"driver-path": bindDriverPath,
|
||||
}).Info("Binding device to vfio driver")
|
||||
|
||||
// Device may be already bound at this time because of earlier write to new_id, ignore error
|
||||
utils.WriteToFile(bindDriverPath, []byte(bdf))
|
||||
|
||||
func GetVFIODevPath(bdf string) (string, error) {
|
||||
// Determine the iommu group that the device belongs to.
|
||||
groupPath, err := os.Readlink(fmt.Sprintf(iommuGroupPath, bdf))
|
||||
if err != nil {
|
||||
return "", err
|
||||
@ -313,11 +278,66 @@ func BindDevicetoVFIO(bdf, hostDriver, vendorDeviceID string) (string, error) {
|
||||
return fmt.Sprintf(vfioDevPath, filepath.Base(groupPath)), nil
|
||||
}
|
||||
|
||||
// BindDevicetoHost binds the device to the host driver after unbinding from vfio-pci.
|
||||
func BindDevicetoHost(bdf, hostDriver, vendorDeviceID string) error {
|
||||
// Unbind from vfio-pci driver
|
||||
// BindDevicetoVFIO binds the device to vfio driver after unbinding from host
|
||||
// driver if present.
|
||||
// Will be called by a network interface or a generic pcie device.
|
||||
func BindDevicetoVFIO(bdf, hostDriver string) (string, error) {
|
||||
|
||||
overrideDriverPath := fmt.Sprintf(pciDriverOverridePath, bdf)
|
||||
deviceLogger().WithFields(logrus.Fields{
|
||||
"device-bdf": bdf,
|
||||
"driver-override-path": overrideDriverPath,
|
||||
}).Info("Write vfio-pci to driver_override")
|
||||
|
||||
// Write vfio-pci to driver_override file to allow the device to bind to vfio-pci
|
||||
// Reference: https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-bus-platform
|
||||
if err := utils.WriteToFile(overrideDriverPath, []byte("vfio-pci")); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
unbindDriverPath := fmt.Sprintf(pciDriverUnbindPath, bdf)
|
||||
deviceLogger().WithFields(logrus.Fields{
|
||||
"device-bdf": bdf,
|
||||
"driver-path": unbindDriverPath,
|
||||
}).Info("Unbinding device from driver")
|
||||
|
||||
// Unbind device from the host driver. In some cases, a driver may not be bound
|
||||
// to the device, in which case this step may fail. Hence ignore error for this step.
|
||||
utils.WriteToFile(unbindDriverPath, []byte(bdf))
|
||||
|
||||
deviceLogger().WithFields(logrus.Fields{
|
||||
"device-bdf": bdf,
|
||||
"drivers-probe-path": driversProbePath,
|
||||
}).Info("Writing bdf to drivers-probe-path")
|
||||
|
||||
// Invoke drivers_probe so that the driver matching driver_override, in our case
|
||||
// the vfio-pci driver will probe the device.
|
||||
if err := utils.WriteToFile(driversProbePath, []byte(bdf)); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return GetVFIODevPath(bdf)
|
||||
}
|
||||
|
||||
// BindDevicetoHost unbinds the device from vfio-pci driver and binds it to the
|
||||
// previously bound driver.
|
||||
func BindDevicetoHost(bdf, hostDriver string) error {
|
||||
overrideDriverPath := fmt.Sprintf(pciDriverOverridePath, bdf)
|
||||
api.DeviceLogger().WithFields(logrus.Fields{
|
||||
"device-bdf": bdf,
|
||||
"driver-override-path": overrideDriverPath,
|
||||
}).Infof("Write %s to driver_override", hostDriver)
|
||||
|
||||
// write previously bound host driver to driver_override to allow the
|
||||
// device to bind to it. This could be empty which means the device will not be
|
||||
// bound to any driver later on.
|
||||
if err := utils.WriteToFile(overrideDriverPath, []byte(hostDriver)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Unbind device from vfio-pci driver.
|
||||
unbindDriverPath := fmt.Sprintf(pciDriverUnbindPath, bdf)
|
||||
deviceLogger().WithFields(logrus.Fields{
|
||||
"device-bdf": bdf,
|
||||
"driver-path": unbindDriverPath,
|
||||
}).Info("Unbinding device from driver")
|
||||
@ -326,17 +346,12 @@ func BindDevicetoHost(bdf, hostDriver, vendorDeviceID string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// To prevent new VFs from binding to VFIO-PCI, remove_id
|
||||
if err := utils.WriteToFile(vfioRemoveIDPath, []byte(vendorDeviceID)); err != nil {
|
||||
return err
|
||||
}
|
||||
deviceLogger().WithFields(logrus.Fields{
|
||||
"device-bdf": bdf,
|
||||
"drivers-probe-path": driversProbePath,
|
||||
}).Info("Writing bdf to drivers-probe-path")
|
||||
|
||||
// Bind back to host driver
|
||||
bindDriverPath := fmt.Sprintf(pciDriverBindPath, hostDriver)
|
||||
api.DeviceLogger().WithFields(logrus.Fields{
|
||||
"device-bdf": bdf,
|
||||
"driver-path": bindDriverPath,
|
||||
}).Info("Binding back device to host driver")
|
||||
|
||||
return utils.WriteToFile(bindDriverPath, []byte(bdf))
|
||||
// Invoke drivers_probe so that the driver matching driver_override, in this case
|
||||
// the previous host driver will probe the device.
|
||||
return utils.WriteToFile(driversProbePath, []byte(bdf))
|
||||
}
|
||||
|
@ -82,7 +82,7 @@ func NewDeviceManager(blockDriver string, vhostUserStoreEnabled bool, vhostUserS
|
||||
return dm
|
||||
}
|
||||
|
||||
func (dm *deviceManager) findDevice(devInfo *config.DeviceInfo) api.Device {
|
||||
func (dm *deviceManager) FindDevice(devInfo *config.DeviceInfo) api.Device {
|
||||
// For devices with a major of -1, we use the host path to find existing instances.
|
||||
if devInfo.Major == -1 {
|
||||
for _, dev := range dm.devices {
|
||||
@ -121,7 +121,7 @@ func (dm *deviceManager) createDevice(devInfo config.DeviceInfo) (dev api.Device
|
||||
}
|
||||
}()
|
||||
|
||||
if existingDev := dm.findDevice(&devInfo); existingDev != nil {
|
||||
if existingDev := dm.FindDevice(&devInfo); existingDev != nil {
|
||||
return existingDev, nil
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@ type Endpoint interface {
|
||||
SetPciPath(vcTypes.PciPath)
|
||||
Attach(context.Context, *Sandbox) error
|
||||
Detach(ctx context.Context, netNsCreated bool, netNsPath string) error
|
||||
HotAttach(ctx context.Context, h Hypervisor) error
|
||||
HotDetach(ctx context.Context, h Hypervisor, netNsCreated bool, netNsPath string) error
|
||||
HotAttach(context.Context, *Sandbox) error
|
||||
HotDetach(ctx context.Context, s *Sandbox, netNsCreated bool, netNsPath string) error
|
||||
|
||||
save() persistapi.NetworkEndpoint
|
||||
load(persistapi.NetworkEndpoint)
|
||||
|
@ -125,10 +125,11 @@ func (endpoint *IPVlanEndpoint) Detach(ctx context.Context, netNsCreated bool, n
|
||||
})
|
||||
}
|
||||
|
||||
func (endpoint *IPVlanEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
|
||||
func (endpoint *IPVlanEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
|
||||
span, ctx := ipvlanTrace(ctx, "HotAttach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
h := s.hypervisor
|
||||
if err := xConnectVMNetwork(ctx, endpoint, h); err != nil {
|
||||
networkLogger().WithError(err).Error("Error bridging ipvlan ep")
|
||||
return err
|
||||
@ -142,7 +143,7 @@ func (endpoint *IPVlanEndpoint) HotAttach(ctx context.Context, h Hypervisor) err
|
||||
return nil
|
||||
}
|
||||
|
||||
func (endpoint *IPVlanEndpoint) HotDetach(ctx context.Context, h Hypervisor, netNsCreated bool, netNsPath string) error {
|
||||
func (endpoint *IPVlanEndpoint) HotDetach(ctx context.Context, s *Sandbox, netNsCreated bool, netNsPath string) error {
|
||||
if !netNsCreated {
|
||||
return nil
|
||||
}
|
||||
@ -156,6 +157,7 @@ func (endpoint *IPVlanEndpoint) HotDetach(ctx context.Context, h Hypervisor, net
|
||||
networkLogger().WithError(err).Warn("Error un-bridging ipvlan ep")
|
||||
}
|
||||
|
||||
h := s.hypervisor
|
||||
if _, err := h.HotplugRemoveDevice(ctx, endpoint, NetDev); err != nil {
|
||||
networkLogger().WithError(err).Error("Error detach ipvlan ep")
|
||||
return err
|
||||
|
@ -122,10 +122,11 @@ func (endpoint *MacvlanEndpoint) Detach(ctx context.Context, netNsCreated bool,
|
||||
})
|
||||
}
|
||||
|
||||
func (endpoint *MacvlanEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
|
||||
func (endpoint *MacvlanEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
|
||||
span, ctx := macvlanTrace(ctx, "HotAttach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
h := s.hypervisor
|
||||
if err := xConnectVMNetwork(ctx, endpoint, h); err != nil {
|
||||
networkLogger().WithError(err).Error("Error bridging macvlan ep")
|
||||
return err
|
||||
@ -139,7 +140,7 @@ func (endpoint *MacvlanEndpoint) HotAttach(ctx context.Context, h Hypervisor) er
|
||||
return nil
|
||||
}
|
||||
|
||||
func (endpoint *MacvlanEndpoint) HotDetach(ctx context.Context, h Hypervisor, netNsCreated bool, netNsPath string) error {
|
||||
func (endpoint *MacvlanEndpoint) HotDetach(ctx context.Context, s *Sandbox, netNsCreated bool, netNsPath string) error {
|
||||
if !netNsCreated {
|
||||
return nil
|
||||
}
|
||||
@ -153,6 +154,7 @@ func (endpoint *MacvlanEndpoint) HotDetach(ctx context.Context, h Hypervisor, ne
|
||||
networkLogger().WithError(err).Warn("Error un-bridging macvlan ep")
|
||||
}
|
||||
|
||||
h := s.hypervisor
|
||||
if _, err := h.HotplugRemoveDevice(ctx, endpoint, NetDev); err != nil {
|
||||
networkLogger().WithError(err).Error("Error detach macvlan ep")
|
||||
return err
|
||||
|
@ -93,12 +93,12 @@ func (endpoint *MacvtapEndpoint) Detach(ctx context.Context, netNsCreated bool,
|
||||
}
|
||||
|
||||
// HotAttach for macvtap endpoint not supported yet
|
||||
func (endpoint *MacvtapEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
|
||||
func (endpoint *MacvtapEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
|
||||
return fmt.Errorf("MacvtapEndpoint does not support Hot attach")
|
||||
}
|
||||
|
||||
// HotDetach for macvtap endpoint not supported yet
|
||||
func (endpoint *MacvtapEndpoint) HotDetach(ctx context.Context, h Hypervisor, netNsCreated bool, netNsPath string) error {
|
||||
func (endpoint *MacvtapEndpoint) HotDetach(ctx context.Context, s *Sandbox, netNsCreated bool, netNsPath string) error {
|
||||
return fmt.Errorf("MacvtapEndpoint does not support Hot detach")
|
||||
}
|
||||
|
||||
|
@ -202,7 +202,7 @@ func (n *LinuxNetwork) addSingleEndpoint(ctx context.Context, s *Sandbox, netInf
|
||||
|
||||
networkLogger().WithField("endpoint-type", endpoint.Type()).WithField("hotplug", hotplug).Info("Attaching endpoint")
|
||||
if hotplug {
|
||||
if err := endpoint.HotAttach(ctx, s.hypervisor); err != nil {
|
||||
if err := endpoint.HotAttach(ctx, s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
@ -265,7 +265,7 @@ func (n *LinuxNetwork) removeSingleEndpoint(ctx context.Context, s *Sandbox, end
|
||||
// if required.
|
||||
networkLogger().WithField("endpoint-type", endpoint.Type()).Info("Detaching endpoint")
|
||||
if hotplug && s != nil {
|
||||
if err := endpoint.HotDetach(ctx, s.hypervisor, n.netNSCreated, n.netNSPath); err != nil {
|
||||
if err := endpoint.HotDetach(ctx, s, n.netNSCreated, n.netNSPath); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
|
@ -123,13 +123,65 @@ func (endpoint *PhysicalEndpoint) Detach(ctx context.Context, netNsCreated bool,
|
||||
}
|
||||
|
||||
// HotAttach for physical endpoint not supported yet
|
||||
func (endpoint *PhysicalEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
|
||||
return fmt.Errorf("PhysicalEndpoint does not support Hot attach")
|
||||
func (endpoint *PhysicalEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
|
||||
span, ctx := physicalTrace(ctx, "HotAttach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
// Unbind physical interface from host driver and bind to vfio
|
||||
// so that it can be passed to the hypervisor.
|
||||
vfioPath, err := bindNICToVFIO(endpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := resCtrl.DeviceToCgroupDeviceRule(vfioPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d := config.DeviceInfo{
|
||||
ContainerPath: vfioPath,
|
||||
DevType: string(c.Type),
|
||||
Major: c.Major,
|
||||
Minor: c.Minor,
|
||||
ColdPlug: false,
|
||||
}
|
||||
|
||||
_, err = s.AddDevice(ctx, d)
|
||||
return err
|
||||
}
|
||||
|
||||
// HotDetach for physical endpoint not supported yet
|
||||
func (endpoint *PhysicalEndpoint) HotDetach(ctx context.Context, h Hypervisor, netNsCreated bool, netNsPath string) error {
|
||||
return fmt.Errorf("PhysicalEndpoint does not support Hot detach")
|
||||
func (endpoint *PhysicalEndpoint) HotDetach(ctx context.Context, s *Sandbox, netNsCreated bool, netNsPath string) error {
|
||||
span, _ := physicalTrace(ctx, "HotDetach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
var vfioPath string
|
||||
var err error
|
||||
|
||||
if vfioPath, err = drivers.GetVFIODevPath(endpoint.BDF); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
c, err := resCtrl.DeviceToCgroupDeviceRule(vfioPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d := config.DeviceInfo{
|
||||
ContainerPath: vfioPath,
|
||||
DevType: string(c.Type),
|
||||
Major: c.Major,
|
||||
Minor: c.Minor,
|
||||
ColdPlug: false,
|
||||
}
|
||||
|
||||
device := s.devManager.FindDevice(&d)
|
||||
s.devManager.RemoveDevice(device.DeviceID())
|
||||
|
||||
// We do not need to enter the network namespace to bind back the
|
||||
// physical interface to host driver.
|
||||
return bindNICToHost(endpoint)
|
||||
}
|
||||
|
||||
// isPhysicalIface checks if an interface is a physical device.
|
||||
@ -218,11 +270,11 @@ func createPhysicalEndpoint(netInfo NetworkInfo) (*PhysicalEndpoint, error) {
|
||||
}
|
||||
|
||||
func bindNICToVFIO(endpoint *PhysicalEndpoint) (string, error) {
|
||||
return drivers.BindDevicetoVFIO(endpoint.BDF, endpoint.Driver, endpoint.VendorDeviceID)
|
||||
return drivers.BindDevicetoVFIO(endpoint.BDF, endpoint.Driver)
|
||||
}
|
||||
|
||||
func bindNICToHost(endpoint *PhysicalEndpoint) error {
|
||||
return drivers.BindDevicetoHost(endpoint.BDF, endpoint.Driver, endpoint.VendorDeviceID)
|
||||
return drivers.BindDevicetoHost(endpoint.BDF, endpoint.Driver)
|
||||
}
|
||||
|
||||
func (endpoint *PhysicalEndpoint) save() persistapi.NetworkEndpoint {
|
||||
|
@ -27,9 +27,11 @@ func TestPhysicalEndpoint_HotAttach(t *testing.T) {
|
||||
HardAddr: net.HardwareAddr{0x02, 0x00, 0xca, 0xfe, 0x00, 0x04}.String(),
|
||||
}
|
||||
|
||||
h := &mockHypervisor{}
|
||||
s := &Sandbox{
|
||||
hypervisor: &mockHypervisor{},
|
||||
}
|
||||
|
||||
err := v.HotAttach(context.Background(), h)
|
||||
err := v.HotAttach(context.Background(), s)
|
||||
assert.Error(err)
|
||||
}
|
||||
|
||||
@ -40,9 +42,11 @@ func TestPhysicalEndpoint_HotDetach(t *testing.T) {
|
||||
HardAddr: net.HardwareAddr{0x02, 0x00, 0xca, 0xfe, 0x00, 0x04}.String(),
|
||||
}
|
||||
|
||||
h := &mockHypervisor{}
|
||||
s := &Sandbox{
|
||||
hypervisor: &mockHypervisor{},
|
||||
}
|
||||
|
||||
err := v.HotDetach(context.Background(), h, true, "")
|
||||
err := v.HotDetach(context.Background(), s, true, "")
|
||||
assert.Error(err)
|
||||
}
|
||||
|
||||
|
@ -92,12 +92,13 @@ func (endpoint *TapEndpoint) Detach(ctx context.Context, netNsCreated bool, netN
|
||||
}
|
||||
|
||||
// HotAttach for the tap endpoint uses hot plug device
|
||||
func (endpoint *TapEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
|
||||
func (endpoint *TapEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
|
||||
networkLogger().Info("Hot attaching tap endpoint")
|
||||
|
||||
span, ctx := tapTrace(ctx, "HotAttach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
h := s.hypervisor
|
||||
if err := tapNetwork(endpoint, h.HypervisorConfig().NumVCPUs(), h.HypervisorConfig().DisableVhostNet); err != nil {
|
||||
networkLogger().WithError(err).Error("Error bridging tap ep")
|
||||
return err
|
||||
@ -111,7 +112,7 @@ func (endpoint *TapEndpoint) HotAttach(ctx context.Context, h Hypervisor) error
|
||||
}
|
||||
|
||||
// HotDetach for the tap endpoint uses hot pull device
|
||||
func (endpoint *TapEndpoint) HotDetach(ctx context.Context, h Hypervisor, netNsCreated bool, netNsPath string) error {
|
||||
func (endpoint *TapEndpoint) HotDetach(ctx context.Context, s *Sandbox, netNsCreated bool, netNsPath string) error {
|
||||
networkLogger().Info("Hot detaching tap endpoint")
|
||||
|
||||
span, ctx := tapTrace(ctx, "HotDetach", endpoint)
|
||||
@ -123,6 +124,7 @@ func (endpoint *TapEndpoint) HotDetach(ctx context.Context, h Hypervisor, netNsC
|
||||
networkLogger().WithError(err).Warn("Error un-bridging tap ep")
|
||||
}
|
||||
|
||||
h := s.hypervisor
|
||||
if _, err := h.HotplugRemoveDevice(ctx, endpoint, NetDev); err != nil {
|
||||
networkLogger().WithError(err).Error("Error detach tap ep")
|
||||
return err
|
||||
|
@ -103,12 +103,13 @@ func (endpoint *TuntapEndpoint) Detach(ctx context.Context, netNsCreated bool, n
|
||||
}
|
||||
|
||||
// HotAttach for the tun/tap endpoint uses hot plug device
|
||||
func (endpoint *TuntapEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
|
||||
func (endpoint *TuntapEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
|
||||
networkLogger().Info("Hot attaching tun/tap endpoint")
|
||||
|
||||
span, ctx := tuntapTrace(ctx, "HotAttach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
h := s.hypervisor
|
||||
if err := tuntapNetwork(endpoint, h.HypervisorConfig().NumVCPUs(), h.HypervisorConfig().DisableVhostNet); err != nil {
|
||||
networkLogger().WithError(err).Error("Error bridging tun/tap ep")
|
||||
return err
|
||||
@ -122,7 +123,7 @@ func (endpoint *TuntapEndpoint) HotAttach(ctx context.Context, h Hypervisor) err
|
||||
}
|
||||
|
||||
// HotDetach for the tun/tap endpoint uses hot pull device
|
||||
func (endpoint *TuntapEndpoint) HotDetach(ctx context.Context, h Hypervisor, netNsCreated bool, netNsPath string) error {
|
||||
func (endpoint *TuntapEndpoint) HotDetach(ctx context.Context, s *Sandbox, netNsCreated bool, netNsPath string) error {
|
||||
networkLogger().Info("Hot detaching tun/tap endpoint")
|
||||
|
||||
span, ctx := tuntapTrace(ctx, "HotDetach", endpoint)
|
||||
@ -134,6 +135,7 @@ func (endpoint *TuntapEndpoint) HotDetach(ctx context.Context, h Hypervisor, net
|
||||
networkLogger().WithError(err).Warn("Error un-bridging tun/tap ep")
|
||||
}
|
||||
|
||||
h := s.hypervisor
|
||||
if _, err := h.HotplugRemoveDevice(ctx, endpoint, NetDev); err != nil {
|
||||
networkLogger().WithError(err).Error("Error detach tun/tap ep")
|
||||
return err
|
||||
|
@ -126,10 +126,11 @@ func (endpoint *VethEndpoint) Detach(ctx context.Context, netNsCreated bool, net
|
||||
}
|
||||
|
||||
// HotAttach for the veth endpoint uses hot plug device
|
||||
func (endpoint *VethEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
|
||||
func (endpoint *VethEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
|
||||
span, ctx := vethTrace(ctx, "HotAttach", endpoint)
|
||||
defer span.End()
|
||||
|
||||
h := s.hypervisor
|
||||
if err := xConnectVMNetwork(ctx, endpoint, h); err != nil {
|
||||
networkLogger().WithError(err).Error("Error bridging virtual ep")
|
||||
return err
|
||||
@ -143,7 +144,7 @@ func (endpoint *VethEndpoint) HotAttach(ctx context.Context, h Hypervisor) error
|
||||
}
|
||||
|
||||
// HotDetach for the veth endpoint uses hot pull device
|
||||
func (endpoint *VethEndpoint) HotDetach(ctx context.Context, h Hypervisor, netNsCreated bool, netNsPath string) error {
|
||||
func (endpoint *VethEndpoint) HotDetach(ctx context.Context, s *Sandbox, netNsCreated bool, netNsPath string) error {
|
||||
if !netNsCreated {
|
||||
return nil
|
||||
}
|
||||
@ -157,6 +158,7 @@ func (endpoint *VethEndpoint) HotDetach(ctx context.Context, h Hypervisor, netNs
|
||||
networkLogger().WithError(err).Warn("Error un-bridging virtual ep")
|
||||
}
|
||||
|
||||
h := s.hypervisor
|
||||
if _, err := h.HotplugRemoveDevice(ctx, endpoint, NetDev); err != nil {
|
||||
networkLogger().WithError(err).Error("Error detach virtual ep")
|
||||
return err
|
||||
|
@ -107,12 +107,12 @@ func (endpoint *VhostUserEndpoint) Detach(ctx context.Context, netNsCreated bool
|
||||
}
|
||||
|
||||
// HotAttach for vhostuser endpoint not supported yet
|
||||
func (endpoint *VhostUserEndpoint) HotAttach(ctx context.Context, h Hypervisor) error {
|
||||
func (endpoint *VhostUserEndpoint) HotAttach(ctx context.Context, s *Sandbox) error {
|
||||
return fmt.Errorf("VhostUserEndpoint does not support Hot attach")
|
||||
}
|
||||
|
||||
// HotDetach for vhostuser endpoint not supported yet
|
||||
func (endpoint *VhostUserEndpoint) HotDetach(ctx context.Context, h Hypervisor, netNsCreated bool, netNsPath string) error {
|
||||
func (endpoint *VhostUserEndpoint) HotDetach(ctx context.Context, s *Sandbox, netNsCreated bool, netNsPath string) error {
|
||||
return fmt.Errorf("VhostUserEndpoint does not support Hot detach")
|
||||
}
|
||||
|
||||
|
@ -97,9 +97,11 @@ func TestVhostUserEndpoint_HotAttach(t *testing.T) {
|
||||
EndpointType: VhostUserEndpointType,
|
||||
}
|
||||
|
||||
h := &mockHypervisor{}
|
||||
s := &Sandbox{
|
||||
hypervisor: &mockHypervisor{},
|
||||
}
|
||||
|
||||
err := v.HotAttach(context.Background(), h)
|
||||
err := v.HotAttach(context.Background(), s)
|
||||
assert.Error(err)
|
||||
}
|
||||
|
||||
@ -111,9 +113,11 @@ func TestVhostUserEndpoint_HotDetach(t *testing.T) {
|
||||
EndpointType: VhostUserEndpointType,
|
||||
}
|
||||
|
||||
h := &mockHypervisor{}
|
||||
s := &Sandbox{
|
||||
hypervisor: &mockHypervisor{},
|
||||
}
|
||||
|
||||
err := v.HotDetach(context.Background(), h, true, "")
|
||||
err := v.HotDetach(context.Background(), s, true, "")
|
||||
assert.Error(err)
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user