@@ -157,6 +157,24 @@ def get_vif_devname(self, vif):
157157 return vif ['devname' ]
158158 return ("nic" + vif ['id' ])[:network_model .NIC_NAME_LEN ]
159159
160+ def get_vif_model (self , image_meta = None , vif_model = None ):
161+
162+ model = vif_model
163+
164+ # If the user has specified a 'vif_model' against the
165+ # image then honour that model
166+ if image_meta :
167+ model = osinfo .HardwareProperties (image_meta ).network_model
168+
169+ # If the virt type is KVM/QEMU/VZ(Parallels), then use virtio according
170+ # to the global config parameter
171+ if (model is None and CONF .libvirt .virt_type in
172+ ('kvm' , 'qemu' , 'parallels' ) and
173+ CONF .libvirt .use_virtio_for_bridges ):
174+ model = network_model .VIF_MODEL_VIRTIO
175+
176+ return model
177+
160178 def get_base_config (self , instance , mac , image_meta ,
161179 inst_type , virt_type , vnic_type ):
162180 # TODO(sahid): We should rewrite it. This method handles too
@@ -179,16 +197,9 @@ def get_base_config(self, instance, mac, image_meta,
179197
180198 rx_queue_size = CONF .libvirt .rx_queue_size
181199
182- # If the user has specified a 'vif_model' against the
183- # image then honour that model
184- if image_meta :
185- model = osinfo .HardwareProperties (image_meta ).network_model
186-
187- # If the virt type is KVM/QEMU/VZ(Parallels), then use virtio according
188- # to the global config parameter
189- if (model is None and virt_type in ('kvm' , 'qemu' , 'parallels' ) and
190- CONF .libvirt .use_virtio_for_bridges ):
191- model = network_model .VIF_MODEL_VIRTIO
200+ # if model has already been defined,
201+ # image_meta contents will override it
202+ model = self .get_vif_model (image_meta = image_meta , vif_model = model )
192203
193204 if not is_vif_model_valid_for_virt (virt_type , model ):
194205 raise exception .UnsupportedHardware (model = model , virt = virt_type )
@@ -244,10 +255,7 @@ def _get_virtio_mq_settings(self, image_meta, flavor):
244255 """
245256 driver = None
246257 vhost_queues = None
247- if not isinstance (image_meta , objects .ImageMeta ):
248- image_meta = objects .ImageMeta .from_dict (image_meta )
249- img_props = image_meta .properties
250- if img_props .get ('hw_vif_multiqueue_enabled' ):
258+ if self ._requests_multiqueue (image_meta ):
251259 driver = 'vhost'
252260 max_tap_queues = self ._get_max_tap_queues ()
253261 if max_tap_queues :
@@ -258,6 +266,19 @@ def _get_virtio_mq_settings(self, image_meta, flavor):
258266
259267 return (driver , vhost_queues )
260268
269+ def _requests_multiqueue (self , image_meta ):
270+ """Check if multiqueue property is set in the image metadata."""
271+
272+ if not isinstance (image_meta , objects .ImageMeta ):
273+ image_meta = objects .ImageMeta .from_dict (image_meta )
274+
275+ img_props = image_meta .properties
276+
277+ if img_props .get ('hw_vif_multiqueue_enabled' ):
278+ return True
279+
280+ return False
281+
261282 def _get_max_tap_queues (self ):
262283 # Note(sean-k-mooney): some linux distros have backported
263284 # changes for newer kernels which make the kernel version
@@ -641,7 +662,13 @@ def plug_tap(self, instance, vif):
641662 """Plug a VIF_TYPE_TAP virtual interface."""
642663 dev = self .get_vif_devname (vif )
643664 mac = vif ['details' ].get (network_model .VIF_DETAILS_TAP_MAC_ADDRESS )
644- nova .privsep .linux_net .create_tap_dev (dev , mac )
665+ image_meta = instance .image_meta
666+ vif_model = self .get_vif_model (image_meta = image_meta )
667+ # TODO(ganso): explore whether multiqueue works for other vif models
668+ # that go through this code path.
669+ multiqueue = (self ._requests_multiqueue (image_meta ) and
670+ vif_model == network_model .VIF_MODEL_VIRTIO )
671+ nova .privsep .linux_net .create_tap_dev (dev , mac , multiqueue = multiqueue )
645672 network = vif .get ('network' )
646673 mtu = network .get_meta ('mtu' ) if network else None
647674 nova .privsep .linux_net .set_device_mtu (dev , mtu )
0 commit comments