diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index 402381ef1e..808227e913 100644 --- a/virtcontainers/qemu.go +++ b/virtcontainers/qemu.go @@ -8,6 +8,7 @@ package virtcontainers import ( "context" "encoding/json" + "errors" "fmt" "io/ioutil" "math" @@ -755,6 +756,10 @@ func (q *qemu) addDeviceToBridge(ID string) (string, types.PCIBridge, error) { var err error var addr uint32 + if len(q.state.Bridges) == 0 { + return "", types.PCIBridge{}, errors.New("failed to get available address from bridges") + } + // looking for an empty address in the bridges for _, b := range q.state.Bridges { addr, err = b.AddDevice(ID) @@ -763,7 +768,7 @@ func (q *qemu) addDeviceToBridge(ID string) (string, types.PCIBridge, error) { } } - return "", types.PCIBridge{}, err + return "", types.PCIBridge{}, fmt.Errorf("no more bridge slots available") } func (q *qemu) removeDeviceFromBridge(ID string) error { diff --git a/virtcontainers/qemu_test.go b/virtcontainers/qemu_test.go index 067a9dfca9..a2d7e4ac73 100644 --- a/virtcontainers/qemu_test.go +++ b/virtcontainers/qemu_test.go @@ -7,6 +7,7 @@ package virtcontainers import ( "context" + "errors" "fmt" "io/ioutil" "os" @@ -443,3 +444,41 @@ func TestQemuGrpc(t *testing.T) { assert.True(q.id == q2.id) } + +func TestQemuAddDeviceToBridge(t *testing.T) { + assert := assert.New(t) + + config := newQemuConfig() + config.DefaultBridges = defaultBridges + + // addDeviceToBridge successfully + config.HypervisorMachineType = QemuPC + q := &qemu{ + config: config, + arch: newQemuArch(config), + } + + q.state.Bridges = q.arch.bridges(q.config.DefaultBridges) + // get pciBridgeMaxCapacity value from virtcontainers/types/pci.go + const pciBridgeMaxCapacity = 30 + for i := uint32(1); i <= pciBridgeMaxCapacity; i++ { + _, _, err := q.addDeviceToBridge(fmt.Sprintf("qemu-bridge-%d", i)) + assert.Nil(err) + } + + // fail to add device to bridge cause no more available bridge slot + _, _, err := q.addDeviceToBridge("qemu-bridge-31") + exceptErr := errors.New("no more bridge slots available") + assert.Equal(exceptErr, err) + + // addDeviceToBridge fails cause q.state.Bridges == 0 + config.HypervisorMachineType = QemuPCLite + q = &qemu{ + config: config, + arch: newQemuArch(config), + } + q.state.Bridges = q.arch.bridges(q.config.DefaultBridges) + _, _, err = q.addDeviceToBridge("qemu-bridge") + exceptErr = errors.New("failed to get available address from bridges") + assert.Equal(exceptErr, err) +}