diff --git a/gns3server/compute/qemu/qemu_vm.py b/gns3server/compute/qemu/qemu_vm.py index fd9e9360..30c4d061 100644 --- a/gns3server/compute/qemu/qemu_vm.py +++ b/gns3server/compute/qemu/qemu_vm.py @@ -1454,7 +1454,13 @@ class QemuVM(BaseNode): network_options.extend(["-device", "i82801b11-bridge,id=dmi_pci_bridge{bridge_id}".format(bridge_id=bridge_id)]) network_options.extend(["-device", "pci-bridge,id=pci-bridge{bridge_id},bus=dmi_pci_bridge{bridge_id},chassis_nr=0x1,addr=0x{bridge_id},shpc=off".format(bridge_id=bridge_id)]) + if bridge_id > 1: + qemu_version = yield from self.manager.get_qemu_version(self.qemu_path) + if qemu_version and parse_version(qemu_version) < parse_version("2.4.0"): + raise QemuError("You need to Qemu 2.4 or later in order to support large number of adapters") + pci_device_id = 4 + bridge_id # Bridge consume PCI ports + for adapter_number, adapter in enumerate(self._ethernet_adapters): mac = int_to_macaddress(macaddress_to_int(self._mac_address) + adapter_number) diff --git a/tests/compute/qemu/test_qemu_vm.py b/tests/compute/qemu/test_qemu_vm.py index 91e40d9c..854f47e4 100644 --- a/tests/compute/qemu/test_qemu_vm.py +++ b/tests/compute/qemu/test_qemu_vm.py @@ -611,6 +611,9 @@ def test_build_command_large_number_of_adapters(vm, loop, fake_qemu_binary, port additionnal interfaces """ + # It's supported only with Qemu 2.4 and later + vm.manager.get_qemu_version = AsyncioMagicMock(return_value="2.4.0") + vm.adapters = 100 vm.mac_address = "00:00:ab:0e:0f:09" mac_0 = vm._mac_address @@ -626,8 +629,6 @@ def test_build_command_large_number_of_adapters(vm, loop, fake_qemu_binary, port assert "pci-bridge,id=pci-bridge2,bus=dmi_pci_bridge2,chassis_nr=0x1,addr=0x2,shpc=off" in cmd assert "i82801b11-bridge,id=dmi_pci_bridge1" in cmd - print(cmd) - mac_29 = int_to_macaddress(macaddress_to_int(vm._mac_address) + 29) assert "e1000,mac={},bus=pci-bridge1,addr=0x04".format(mac_29) in cmd mac_30 = int_to_macaddress(macaddress_to_int(vm._mac_address) + 30) @@ -635,8 +636,18 @@ def test_build_command_large_number_of_adapters(vm, loop, fake_qemu_binary, port mac_74 = int_to_macaddress(macaddress_to_int(vm._mac_address) + 74) assert "e1000,mac={},bus=pci-bridge2,addr=0x11".format(mac_74) in cmd + # Qemu < 2.4 doesn't support large number of adapters + vm.manager.get_qemu_version = AsyncioMagicMock(return_value="2.0.0") + with pytest.raises(QemuError): + with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()) as process: + cmd = loop.run_until_complete(asyncio.async(vm._build_command())) + vm.adapters = 5 + with asyncio_patch("asyncio.create_subprocess_exec", return_value=MagicMock()) as process: + cmd = loop.run_until_complete(asyncio.async(vm._build_command())) # Windows accept this kind of mistake + + @pytest.mark.skipif(sys.platform.startswith("win"), reason="Not supported on Windows") def test_build_command_with_invalid_options(vm, loop, fake_qemu_binary):