]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: add bootindex option to hostdev network interface commandline
authorLaine Stump <laine@laine.org>
Mon, 30 Nov 2015 22:40:44 +0000 (17:40 -0500)
committerLaine Stump <laine@laine.org>
Tue, 15 Dec 2015 15:57:27 +0000 (10:57 -0500)
when appropriate, of course. If the config for a domain specifies boot
order with <boot dev='blah'/> elements, e.g.:

     <os>
       ...
       <boot dev='hd'/>
       <boot dev='network'/>
     </os>

Then the first disk device in the config will have ",bootindex=1"
appended to its qemu commandline -device options, and the first (and
*only* the first) network interface device will get ",bootindex=2".

However, if the first network interface device is a "hostdev" device
(an SRIOV Virtual Function (VF) being assigned to the domain with
vfio), then the bootindex option will *not* be appended. This happens
because the bootindex=n option corresponding to the order of "<boot
dev='network'/>" is added to the -device for the first network device
when network device commandline args are constructed, but if it's a
hostdev network device, its commandline arg is instead constructed in
the loop for hostdevs.

This patch fixes that omission by noticing (in bootHostdevNet) if the
first network device was a hostdev, and if so passing on the proper
bootindex to the commandline generator for hostdev devices - the
result is that ",bootindex=2" will be properly appended to the first
"network" device in the config even if it is really a hostdev
(including if it is assigned from a libvirt network pool). (note that
this is only the case if there is no <bootmenu enabled='yes'/> element
in the config ("-boot menu-on" in qemu) , since the two are mutually
exclusive - when the bootmenu is enabled, the individual per-device
bootindex options can't be used by qemu, and we revert to using "-boot
order=xyz" instead).

If a greater level of control over boot order is desired (e.g., more
than one network device should be tried, or a network device other
than the first one encountered in the config), then <boot
dev='network'/> in the <os> element should not be used; instead, the
individual device elements in the config should be given a "<boot
order='n'/>

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1278421

src/qemu/qemu_command.c
src/qemu/qemu_command.h
src/qemu/qemu_hotplug.c

index d2f37e408babca97ad14d8d31ddb45d9b6263083..1f612b41d04a0875c4b30748930a8113b6922a0d 100644 (file)
@@ -6084,6 +6084,7 @@ qemuOpenPCIConfig(virDomainHostdevDefPtr dev)
 char *
 qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
                           virDomainHostdevDefPtr dev,
+                          int bootIndex, /* used iff dev->info->bootIndex == 0 */
                           const char *configfd,
                           virQEMUCapsPtr qemuCaps)
 {
@@ -6126,7 +6127,9 @@ qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
                       pcisrc->addr.function);
     virBufferAsprintf(&buf, ",id=%s", dev->info->alias);
     if (dev->info->bootIndex)
-        virBufferAsprintf(&buf, ",bootindex=%d", dev->info->bootIndex);
+        bootIndex = dev->info->bootIndex;
+    if (bootIndex)
+        virBufferAsprintf(&buf, ",bootindex=%d", bootIndex);
     if (qemuBuildDeviceAddressStr(&buf, def, dev->info, qemuCaps) < 0)
         goto error;
     if (qemuBuildRomStr(&buf, dev->info, qemuCaps) < 0)
@@ -9291,7 +9294,8 @@ qemuBuildCommandLine(virConnectPtr conn,
     char *boot_order_str = NULL, *boot_opts_str = NULL;
     virBuffer fdc_opts = VIR_BUFFER_INITIALIZER;
     char *fdc_opts_str = NULL;
-    int bootCD = 0, bootFloppy = 0, bootDisk = 0;
+    int bootCD = 0, bootFloppy = 0, bootDisk = 0, bootHostdevNet = 0;
+
 
     VIR_DEBUG("conn=%p driver=%p def=%p mon=%p json=%d "
               "qemuCaps=%p migrateURI=%s snapshot=%p vmop=%d",
@@ -10279,6 +10283,16 @@ qemuBuildCommandLine(virConnectPtr conn,
                 goto error;
 
             last_good_net = i;
+            /* if this interface is a type='hostdev' interface and we
+             * haven't yet added a "bootindex" parameter to an
+             * emulated network device, save the bootindex - hostdev
+             * interface commandlines will be built later on when we
+             * cycle through all the hostdevs, and we'll use it then.
+             */
+            if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_HOSTDEV &&
+                bootHostdevNet == 0) {
+                bootHostdevNet = bootNet;
+            }
             bootNet = 0;
         }
     }
@@ -11005,6 +11019,16 @@ qemuBuildCommandLine(virConnectPtr conn,
 
             if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) {
                 char *configfd_name = NULL;
+                int bootIndex = hostdev->info->bootIndex;
+
+                /* bootNet will be non-0 if boot order was set and no other
+                 * net devices were encountered
+                 */
+                if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
+                    bootIndex == 0) {
+                    bootIndex = bootHostdevNet;
+                    bootHostdevNet = 0;
+                }
                 if ((backend != VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) &&
                     virQEMUCapsGet(qemuCaps, QEMU_CAPS_PCI_CONFIGFD)) {
                     int configfd = qemuOpenPCIConfig(hostdev);
@@ -11020,7 +11044,8 @@ qemuBuildCommandLine(virConnectPtr conn,
                     }
                 }
                 virCommandAddArg(cmd, "-device");
-                devstr = qemuBuildPCIHostdevDevStr(def, hostdev, configfd_name, qemuCaps);
+                devstr = qemuBuildPCIHostdevDevStr(def, hostdev, bootIndex,
+                                                   configfd_name, qemuCaps);
                 VIR_FREE(configfd_name);
                 if (!devstr)
                     goto error;
index f0d6900b46755e4e20d90470b764d951ea001215..a96e57d70a2d8362643b22799f8f0678d0d886fe 100644 (file)
@@ -180,6 +180,7 @@ char *qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev,
 /* Current, best practice */
 char *qemuBuildPCIHostdevDevStr(virDomainDefPtr def,
                                 virDomainHostdevDefPtr dev,
+                                int bootIndex,
                                 const char *configfd,
                                 virQEMUCapsPtr qemuCaps);
 
index a88c2f2de78fcc5d64187e96d6f1097a9a235fb5..d2395fe025a0068f90546b1773454f15218eb93e 100644 (file)
@@ -1327,8 +1327,8 @@ qemuDomainAttachHostPCIDevice(virQEMUDriverPtr driver,
             goto error;
         }
 
-        if (!(devstr = qemuBuildPCIHostdevDevStr(vm->def, hostdev, configfd_name,
-                                                 priv->qemuCaps)))
+        if (!(devstr = qemuBuildPCIHostdevDevStr(vm->def, hostdev, 0,
+                                                 configfd_name, priv->qemuCaps)))
             goto error;
 
         qemuDomainObjEnterMonitor(driver, vm);