Skip to content
This repository has been archived by the owner on May 12, 2021. It is now read-only.

Commit

Permalink
virtcontainers: fix hotplug pci devices execeed max capacity bug
Browse files Browse the repository at this point in the history
add rollback operations when hotplug block/net devices execeed pciBridgeMaxCapacity

Fixes: #1941

Signed-off-by: jiangpengfei <[email protected]>
  • Loading branch information
flyflypeng authored and Eric Ernst committed Aug 29, 2019
1 parent f43e18b commit e1be326
Showing 1 changed file with 36 additions and 8 deletions.
44 changes: 36 additions & 8 deletions virtcontainers/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -968,9 +968,7 @@ func (q *qemu) removeDeviceFromBridge(ID string) error {
return err
}

func (q *qemu) hotplugAddBlockDevice(drive *config.BlockDrive, op operation, devID string) error {
var err error

func (q *qemu) hotplugAddBlockDevice(drive *config.BlockDrive, op operation, devID string) (err error) {
if q.config.BlockDeviceDriver == config.Nvdimm {
var blocksize int64
file, err := os.Open(drive.File)
Expand Down Expand Up @@ -998,13 +996,25 @@ func (q *qemu) hotplugAddBlockDevice(drive *config.BlockDrive, op operation, dev
return err
}

defer func() {
if err != nil {
q.qmpMonitorCh.qmp.ExecuteBlockdevDel(q.qmpMonitorCh.ctx, drive.ID)
}
}()

if q.config.BlockDeviceDriver == config.VirtioBlock {
driver := "virtio-blk-pci"
addr, bridge, err := q.addDeviceToBridge(drive.ID)
if err != nil {
return err
}

defer func() {
if err != nil {
q.removeDeviceFromBridge(drive.ID)
}
}()

// PCI address is in the format bridge-addr/device-addr eg. "03/02"
drive.PCIAddr = fmt.Sprintf("%02x", bridge.Addr) + "/" + addr

Expand Down Expand Up @@ -1060,8 +1070,8 @@ func (q *qemu) hotplugBlockDevice(drive *config.BlockDrive, op operation) error
return err
}

func (q *qemu) hotplugVFIODevice(device *config.VFIODev, op operation) error {
err := q.qmpSetup()
func (q *qemu) hotplugVFIODevice(device *config.VFIODev, op operation) (err error) {
err = q.qmpSetup()
if err != nil {
return err
}
Expand All @@ -1088,6 +1098,12 @@ func (q *qemu) hotplugVFIODevice(device *config.VFIODev, op operation) error {
return err
}

defer func() {
if err != nil {
q.removeDeviceFromBridge(devID)
}
}()

switch device.Type {
case config.VFIODeviceNormalType:
return q.qmpMonitorCh.qmp.ExecutePCIVFIODeviceAdd(q.qmpMonitorCh.ctx, devID, device.BDF, addr, bridge.ID, romFile)
Expand Down Expand Up @@ -1134,8 +1150,8 @@ func (q *qemu) hotAddNetDevice(name, hardAddr string, VMFds, VhostFds []*os.File
return q.qmpMonitorCh.qmp.ExecuteNetdevAddByFds(q.qmpMonitorCh.ctx, "tap", name, VMFdNames, VhostFdNames)
}

func (q *qemu) hotplugNetDevice(endpoint Endpoint, op operation) error {
err := q.qmpSetup()
func (q *qemu) hotplugNetDevice(endpoint Endpoint, op operation) (err error) {
err = q.qmpSetup()
if err != nil {
return err
}
Expand All @@ -1154,15 +1170,27 @@ func (q *qemu) hotplugNetDevice(endpoint Endpoint, op operation) error {

devID := "virtio-" + tap.ID
if op == addDevice {

if err = q.hotAddNetDevice(tap.Name, endpoint.HardwareAddr(), tap.VMFds, tap.VhostFds); err != nil {
return err
}

defer func() {
if err != nil {
q.qmpMonitorCh.qmp.ExecuteNetdevDel(q.qmpMonitorCh.ctx, tap.Name)
}
}()

addr, bridge, err := q.addDeviceToBridge(tap.ID)
if err != nil {
return err
}

defer func() {
if err != nil {
q.removeDeviceFromBridge(tap.ID)
}
}()

pciAddr := fmt.Sprintf("%02x/%s", bridge.Addr, addr)
endpoint.SetPciAddr(pciAddr)

Expand Down

0 comments on commit e1be326

Please sign in to comment.