From fb3b2d9eaf8317cec62e52a99f17946610b8cdca Mon Sep 17 00:00:00 2001 From: Kevin_Zheng Date: Tue, 15 Nov 2016 14:13:58 +0800 Subject: [PATCH] Don't apply multi-queue to SRIOV ports The multi-queue feature was added: https://blueprints.launchpad.net/nova/+spec/libvirt-virtio-net-multiqueue and it is controlled using image metadata: hw_vif_mutliqueue_enabled=true|false when users want to launch an instance with a SRIOV port and several normal ports with multi-queue feature, ERROR can take place due to wrong driver name for SRIOV interface. Details could be found in bug description. Change-Id: I52c51ff17f43133154f6ea8aa4107f1673f82dde Closes-bug: #1641814 --- nova/tests/unit/virt/libvirt/test_vif.py | 22 ++++++++++++-- nova/virt/libvirt/vif.py | 37 ++++++++++++++---------- 2 files changed, 41 insertions(+), 18 deletions(-) diff --git a/nova/tests/unit/virt/libvirt/test_vif.py b/nova/tests/unit/virt/libvirt/test_vif.py index 88a22fc6e2..342a5a7af3 100644 --- a/nova/tests/unit/virt/libvirt/test_vif.py +++ b/nova/tests/unit/virt/libvirt/test_vif.py @@ -619,7 +619,7 @@ class LibvirtVifTestCase(test.NoDBTestCase): is_public=True, vcpu_weight=None, id=2, disabled=False, rxtx_factor=1.0) conf = d.get_base_config(None, 'ca:fe:de:ad:be:ef', image_meta, - flavor, 'kvm') + flavor, 'kvm', 'normal') self.assertEqual(4, conf.vhost_queues) self.assertEqual('vhost', conf.driver_name) @@ -734,10 +734,28 @@ class LibvirtVifTestCase(test.NoDBTestCase): image_meta = {'properties': {'os_name': 'fedora22'}} image_meta = objects.ImageMeta.from_dict(image_meta) d.get_base_config(None, 'ca:fe:de:ad:be:ef', image_meta, - None, 'kvm') + None, 'kvm', 'normal') mock_set.assert_called_once_with(mock.ANY, 'ca:fe:de:ad:be:ef', 'virtio', None, None) + @mock.patch.object(vif.designer, 'set_vif_guest_frontend_config') + def test_model_sriov_multi_queue_not_set(self, mock_set): + self.flags(use_virtio_for_bridges=True, + virt_type='kvm', + group='libvirt') + self.useFixture(fixtures.MonkeyPatch( + 'nova.virt.osinfo.libosinfo', + fakelibosinfo)) + d = vif.LibvirtGenericVIFDriver() + image_meta = {'properties': {'os_name': 'fedora22'}} + image_meta = objects.ImageMeta.from_dict(image_meta) + conf = d.get_base_config(None, 'ca:fe:de:ad:be:ef', image_meta, + None, 'kvm', 'direct') + mock_set.assert_called_once_with(mock.ANY, 'ca:fe:de:ad:be:ef', + 'virtio', None, None) + self.assertIsNone(conf.vhost_queues) + self.assertIsNone(conf.driver_name) + def _test_model_qemu(self, *vif_objs, **kw): libvirt_version = kw.get('libvirt_version') self.flags(use_virtio_for_bridges=True, diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py index eb340a1955..154a7de22e 100644 --- a/nova/virt/libvirt/vif.py +++ b/nova/virt/libvirt/vif.py @@ -98,7 +98,7 @@ class LibvirtGenericVIFDriver(object): return prefix + devname[3:] def get_base_config(self, instance, mac, image_meta, - inst_type, virt_type): + inst_type, virt_type, vnic_type): conf = vconfig.LibvirtConfigGuestInterface() # Default to letting libvirt / the hypervisor choose the model model = None @@ -128,7 +128,8 @@ class LibvirtGenericVIFDriver(object): raise exception.UnsupportedHardware(model=model, virt=virt_type) if (virt_type in ('kvm', 'parallels') and - model == network_model.VIF_MODEL_VIRTIO): + model == network_model.VIF_MODEL_VIRTIO and + vnic_type not in network_model.VNIC_TYPES_SRIOV): vhost_drv, vhost_queues = self._get_virtio_mq_settings(image_meta, inst_type) driver = vhost_drv or driver @@ -219,7 +220,7 @@ class LibvirtGenericVIFDriver(object): inst_type, virt_type, host): """Get VIF configurations for bridge type.""" conf = self.get_base_config(instance, vif['address'], image_meta, - inst_type, virt_type) + inst_type, virt_type, vif['vnic_type']) designer.set_vif_host_backend_bridge_config( conf, self.get_bridge_name(vif), @@ -250,7 +251,8 @@ class LibvirtGenericVIFDriver(object): vif['address'], image_meta, inst_type, - virt_type) + virt_type, + vif['vnic_type']) dev = self.get_vif_devname(vif) designer.set_vif_host_backend_ethernet_config(conf, dev) @@ -275,7 +277,7 @@ class LibvirtGenericVIFDriver(object): def get_config_802qbg(self, instance, vif, image_meta, inst_type, virt_type, host): conf = self.get_base_config(instance, vif['address'], image_meta, - inst_type, virt_type) + inst_type, virt_type, vif['vnic_type']) params = vif["qbg_params"] designer.set_vif_host_backend_802qbg_config( @@ -292,7 +294,7 @@ class LibvirtGenericVIFDriver(object): def get_config_802qbh(self, instance, vif, image_meta, inst_type, virt_type, host): conf = self.get_base_config(instance, vif['address'], image_meta, - inst_type, virt_type) + inst_type, virt_type, vif['vnic_type']) profile = vif["profile"] vif_details = vif["details"] @@ -311,7 +313,7 @@ class LibvirtGenericVIFDriver(object): def get_config_hw_veb(self, instance, vif, image_meta, inst_type, virt_type, host): conf = self.get_base_config(instance, vif['address'], image_meta, - inst_type, virt_type) + inst_type, virt_type, vif['vnic_type']) profile = vif["profile"] vif_details = vif["details"] @@ -334,7 +336,7 @@ class LibvirtGenericVIFDriver(object): def get_config_macvtap(self, instance, vif, image_meta, inst_type, virt_type, host): conf = self.get_base_config(instance, vif['address'], image_meta, - inst_type, virt_type) + inst_type, virt_type, vif['vnic_type']) vif_details = vif['details'] macvtap_src = vif_details.get(network_model.VIF_DETAILS_MACVTAP_SOURCE) @@ -365,7 +367,7 @@ class LibvirtGenericVIFDriver(object): def get_config_iovisor(self, instance, vif, image_meta, inst_type, virt_type, host): conf = self.get_base_config(instance, vif['address'], image_meta, - inst_type, virt_type) + inst_type, virt_type, vif['vnic_type']) dev = self.get_vif_devname(vif) designer.set_vif_host_backend_ethernet_config(conf, dev) @@ -377,7 +379,7 @@ class LibvirtGenericVIFDriver(object): def get_config_midonet(self, instance, vif, image_meta, inst_type, virt_type, host): conf = self.get_base_config(instance, vif['address'], image_meta, - inst_type, virt_type) + inst_type, virt_type, vif['vnic_type']) dev = self.get_vif_devname(vif) designer.set_vif_host_backend_ethernet_config(conf, dev) @@ -387,7 +389,7 @@ class LibvirtGenericVIFDriver(object): def get_config_tap(self, instance, vif, image_meta, inst_type, virt_type, host): conf = self.get_base_config(instance, vif['address'], image_meta, - inst_type, virt_type) + inst_type, virt_type, vif['vnic_type']) dev = self.get_vif_devname(vif) designer.set_vif_host_backend_ethernet_config(conf, dev) @@ -407,7 +409,7 @@ class LibvirtGenericVIFDriver(object): def get_config_vhostuser(self, instance, vif, image_meta, inst_type, virt_type, host): conf = self.get_base_config(instance, vif['address'], image_meta, - inst_type, virt_type) + inst_type, virt_type, vif['vnic_type']) mode, sock_path = self._get_vhostuser_settings(vif) designer.set_vif_host_backend_vhostuser_config(conf, mode, sock_path) # (vladikr) Not setting up driver and queues for vhostuser @@ -426,7 +428,7 @@ class LibvirtGenericVIFDriver(object): def get_config_vrouter(self, instance, vif, image_meta, inst_type, virt_type, host): conf = self.get_base_config(instance, vif['address'], image_meta, - inst_type, virt_type) + inst_type, virt_type, vif['vnic_type']) dev = self.get_vif_devname(vif) designer.set_vif_host_backend_ethernet_config(conf, dev) @@ -474,7 +476,7 @@ class LibvirtGenericVIFDriver(object): func(vif.port_profile, conf) def _get_config_os_vif(self, instance, vif, image_meta, inst_type, - virt_type, host): + virt_type, host, vnic_type): """Get the domain config for a VIF :param instance: nova.objects.Instance @@ -483,13 +485,14 @@ class LibvirtGenericVIFDriver(object): :param inst_type: nova.objects.Flavor :param virt_type: virtualization type :param host: nova.virt.libvirt.host.Host + :param vnic_type: vnic type :returns: nova.virt.libvirt.config.LibvirtConfigGuestInterface """ # Do the config that's common to all vif types conf = self.get_base_config(instance, vif.address, image_meta, - inst_type, virt_type) + inst_type, virt_type, vnic_type) # Do the VIF type specific config viffunc = "_set_config_" + vif.obj_name() @@ -507,6 +510,7 @@ class LibvirtGenericVIFDriver(object): def get_config(self, instance, vif, image_meta, inst_type, virt_type, host): vif_type = vif['type'] + vnic_type = vif['vnic_type'] LOG.debug('vif_type=%(vif_type)s instance=%(instance)s ' 'vif=%(vif)s virt_type=%(virt_type)s', @@ -522,7 +526,8 @@ class LibvirtGenericVIFDriver(object): vif_obj = os_vif_util.nova_to_osvif_vif(vif) if vif_obj is not None: return self._get_config_os_vif(instance, vif_obj, image_meta, - inst_type, virt_type, host) + inst_type, virt_type, host, + vnic_type) # Legacy non-os-vif codepath vif_slug = self._normalize_vif_type(vif_type)