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 | 31 ++++++++++++++++++++++++++++--- src/qemu/qemu_command.h | 1 + src/qemu/qemu_hotplug.c | 4 ++-- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 4d00fd9..183ab97 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -5978,6 +5978,7 @@ qemuOpenPCIConfig(virDomainHostdevDefPtr dev) char * qemuBuildPCIHostdevDevStr(virDomainDefPtr def, virDomainHostdevDefPtr dev, + int bootIndex, /* used iff dev->info->bootIndex == 0 */ const char *configfd, virQEMUCapsPtr qemuCaps) { @@ -6020,7 +6021,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) @@ -9166,7 +9169,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", @@ -10154,6 +10158,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; } } @@ -10871,6 +10885,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); @@ -10886,7 +10910,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; diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h index bebdd27..c773b8f 100644 --- a/src/qemu/qemu_command.h +++ b/src/qemu/qemu_command.h @@ -180,6 +180,7 @@ char *qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev, /* Current, best practice */ char *qemuBuildPCIHostdevDevStr(virDomainDefPtr def, virDomainHostdevDefPtr dev, + int bootIndex, const char *configfd, virQEMUCapsPtr qemuCaps); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 8804d3d..872ebcd 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1321,8 +1321,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); -- 2.4.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list