From c7ace4b4bc74c4824c7d1b84b7ea94e0499f9d24 Mon Sep 17 00:00:00 2001 From: Ace-Tang Date: Tue, 11 Dec 2018 13:57:42 +0800 Subject: [PATCH 1/2] qemu: throw error when fail to get addr from bridges Return error soon when addDeviceToBridge() can not get empty address from bridges, or the error will thrown by qemu, this is not obvious. Fixes: #1005 Signed-off-by: Ace-Tang --- virtcontainers/qemu.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index 7ee216433f..3625206a4c 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) From 502fdab75ef4f8b039434e189039293a2c779417 Mon Sep 17 00:00:00 2001 From: Ace-Tang Date: Mon, 11 Mar 2019 22:09:06 +0800 Subject: [PATCH 2/2] test: add test for addDeviceToBridge add test for addDeviceToBridge in three case 1. addDeviceToBridge successful 2. fail cause no more available bridge slot 3. fail cause state.bridge == 0 Signed-off-by: Ace-Tang --- virtcontainers/qemu.go | 2 +- virtcontainers/qemu_test.go | 39 +++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/virtcontainers/qemu.go b/virtcontainers/qemu.go index 3625206a4c..374b60740f 100644 --- a/virtcontainers/qemu.go +++ b/virtcontainers/qemu.go @@ -768,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) +}