[libvirt] [PATCH 0/6] qemu: add suport for "romfile", and associated cleanups

This patchset started out as cleanup to make it easier to add in support for doing PCI passthrough via the <interface> element (to be used to attach a host network device to a guest after performing some network-device-specific setup), but turned out to also make it much easier to add support for QEMU's "romfile" option, as requested in https://bugzilla.redhat.com/show_bug.cgi?id=781562 Patch 1 is trivial, and probably qualifies for pushing under the trivial rule, but it's just as easy to leave it in with the rest. Patches 2-4 reorganize some data definitions, and the code associated with them, with no functional change. Patch 5 expands support for "rombar" to network devices (as long as they attach to the guest PCI bus), and Patch 6 adds support for "romfile" to both generic PCI devices and network devices.

There is another identical call 4 lines up in the same function. --- src/conf/domain_conf.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e872396..471b0a2 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1807,7 +1807,6 @@ void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { VIR_FREE(info->addr.usb.port); } - VIR_FREE(info->alias); memset(&info->addr, 0, sizeof(info->addr)); info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; } -- 1.7.7.5

On 01/25/2012 09:58 AM, Laine Stump wrote:
There is another identical call 4 lines up in the same function. --- src/conf/domain_conf.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e872396..471b0a2 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1807,7 +1807,6 @@ void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { VIR_FREE(info->addr.usb.port); } - VIR_FREE(info->alias);
ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 01/25/2012 09:54 PM, Eric Blake wrote:
On 01/25/2012 09:58 AM, Laine Stump wrote:
There is another identical call 4 lines up in the same function. --- src/conf/domain_conf.c | 1 - 1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index e872396..471b0a2 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1807,7 +1807,6 @@ void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) { VIR_FREE(info->addr.usb.port); } - VIR_FREE(info->alias); ACK.
Thanks, pushed.

When <interface> is expanded to allow passthrough with extra dev-dependent network interface info, the host-side address of the device will need to be added to virDomainNetDef. It will be much simpler if this is done with a common typedefed struct rather than inlining the same struct stuff. --- src/conf/domain_conf.h | 34 +++++++++++++++++++++------------- 1 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 3b522a9..dd2abf8 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -92,6 +92,26 @@ struct _virDomainDevicePCIAddress { int multi; /* enum virDomainDeviceAddressPciMulti */ }; +typedef struct _virDomainDeviceSubsysUSBAddress virDomainDeviceSubsysUSBAddress; +typedef virDomainDeviceSubsysUSBAddress *virDomainDeviceSubsysUSBAddressPtr; +struct _virDomainDeviceSubsysUSBAddress { + unsigned bus; + unsigned device; + + unsigned vendor; + unsigned product; +}; + +typedef struct _virDomainDeviceSubsysAddress virDomainDeviceSubsysAddress; +typedef virDomainDeviceSubsysAddress *virDomainDeviceSubsysAddressPtr; +struct _virDomainDeviceSubsysAddress { + int type; /* enum virDomainHostdevBusType */ + union { + virDomainDeviceSubsysUSBAddress usb; + virDomainDevicePCIAddress pci; /* host address */ + } u; +}; + typedef struct _virDomainDeviceDriveAddress virDomainDeviceDriveAddress; typedef virDomainDeviceDriveAddress *virDomainDeviceDriveAddressPtr; struct _virDomainDeviceDriveAddress { @@ -1088,19 +1108,7 @@ struct _virDomainHostdevDef { int mode; /* enum virDomainHostdevMode */ unsigned int managed : 1; union { - struct { - int type; /* enum virDomainHostdevBusType */ - union { - struct { - unsigned bus; - unsigned device; - - unsigned vendor; - unsigned product; - } usb; - virDomainDevicePCIAddress pci; /* host address */ - } u; - } subsys; + virDomainDeviceSubsysAddress subsys; /* USB or PCI */ struct { /* TBD: struct capabilities see: * https://www.redhat.com/archives/libvir-list/2008-July/msg00429.html -- 1.7.7.5

On 01/25/2012 09:58 AM, Laine Stump wrote:
When <interface> is expanded to allow passthrough with extra dev-dependent network interface info, the host-side address of the device will need to be added to virDomainNetDef. It will be much simpler if this is done with a common typedefed struct rather than inlining the same struct stuff. --- src/conf/domain_conf.h | 34 +++++++++++++++++++++------------- 1 files changed, 21 insertions(+), 13 deletions(-)
ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

To help consolidate the commonality between virDomainHostdevDef and virDomainInterface into as few members as possible (and because I think it makes sense), this patch moves the rombar and bootIndex members into the "info" member that is common to both (and to all the other structs that use them). It's a bit problematic that this gives rombar and bootIndex to many device types that don't use them, but this is already the case for the master and mastertype members of virDomainDeviceInfo, and is properly commented as such in the definition. Note that this opens the door to supporting rombar for other devices that are attached to the guest PCI bus - virtio-blk-pci, virtio-net-pci, various other network adapters - which which have that capability in qemu, but previously had no support in libvirt. --- src/conf/domain_conf.c | 26 +++++++++++++------------- src/conf/domain_conf.h | 24 ++++++++++++------------ src/qemu/qemu_command.c | 16 ++++++++-------- src/qemu/qemu_driver.c | 4 ++-- 4 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 471b0a2..8a35e6e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3021,7 +3021,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, (xmlStrEqual(cur->name, BAD_CAST "serial"))) { serial = (char *)xmlNodeGetContent(cur); } else if (xmlStrEqual(cur->name, BAD_CAST "boot")) { - if (virDomainDeviceBootParseXML(cur, &def->bootIndex, + if (virDomainDeviceBootParseXML(cur, &def->info.bootIndex, bootMap)) goto error; } @@ -3790,7 +3790,7 @@ virDomainNetDefParseXML(virCapsPtr caps, /* Legacy back-compat. Don't add any more attributes here */ devaddr = virXMLPropString(cur, "devaddr"); } else if (xmlStrEqual(cur->name, BAD_CAST "boot")) { - if (virDomainDeviceBootParseXML(cur, &def->bootIndex, + if (virDomainDeviceBootParseXML(cur, &def->info.bootIndex, bootMap)) goto error; } else if ((actual == NULL) && @@ -6229,7 +6229,7 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, } else if (xmlStrEqual(cur->name, BAD_CAST "alias")) { /* alias is parsed as part of virDomainDeviceInfoParseXML */ } else if (xmlStrEqual(cur->name, BAD_CAST "boot")) { - if (virDomainDeviceBootParseXML(cur, &def->bootIndex, + if (virDomainDeviceBootParseXML(cur, &def->info.bootIndex, bootMap)) goto error; } else if (xmlStrEqual(cur->name, BAD_CAST "rom")) { @@ -6239,7 +6239,7 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, "%s", _("missing rom bar attribute")); goto error; } - if ((def->rombar = virDomainPciRombarModeTypeFromString(rombar)) <= 0) { + if ((def->info.rombar = virDomainPciRombarModeTypeFromString(rombar)) <= 0) { virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("unknown rom bar value '%s'"), rombar); VIR_FREE(rombar); @@ -10088,8 +10088,8 @@ virDomainDiskDefFormat(virBufferPtr buf, virBufferAddLit(buf, " </iotune>\n"); } - if (def->bootIndex) - virBufferAsprintf(buf, " <boot order='%d'/>\n", def->bootIndex); + if (def->info.bootIndex) + virBufferAsprintf(buf, " <boot order='%d'/>\n", def->info.bootIndex); if (def->readonly) virBufferAddLit(buf, " <readonly/>\n"); if (def->shared) @@ -10453,8 +10453,8 @@ virDomainNetDefFormat(virBufferPtr buf, return -1; virBufferAdjustIndent(buf, -6); } - if (def->bootIndex) - virBufferAsprintf(buf, " <boot order='%d'/>\n", def->bootIndex); + if (def->info.bootIndex) + virBufferAsprintf(buf, " <boot order='%d'/>\n", def->info.bootIndex); if (def->tune.sndbuf_specified) { virBufferAddLit(buf, " <tune>\n"); @@ -11304,19 +11304,19 @@ virDomainHostdevDefFormat(virBufferPtr buf, virBufferAddLit(buf, " </source>\n"); - if (def->bootIndex) - virBufferAsprintf(buf, " <boot order='%d'/>\n", def->bootIndex); + if (def->info.bootIndex) + virBufferAsprintf(buf, " <boot order='%d'/>\n", def->info.bootIndex); if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) return -1; - if (def->rombar) { + if (def->info.rombar) { const char *rombar - = virDomainPciRombarModeTypeToString(def->rombar); + = virDomainPciRombarModeTypeToString(def->info.rombar); if (!rombar) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _("unexpected rom bar value %d"), - def->rombar); + def->info.rombar); return -1; } virBufferAsprintf(buf, " <rom bar='%s'/>\n", rombar); diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index dd2abf8..8fab383 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -82,6 +82,14 @@ enum virDomainDeviceAddressPciMulti { VIR_DOMAIN_DEVICE_ADDRESS_PCI_MULTI_LAST }; +enum virDomainPciRombarMode { + VIR_DOMAIN_PCI_ROMBAR_DEFAULT = 0, + VIR_DOMAIN_PCI_ROMBAR_ON, + VIR_DOMAIN_PCI_ROMBAR_OFF, + + VIR_DOMAIN_PCI_ROMBAR_LAST +}; + typedef struct _virDomainDevicePCIAddress virDomainDevicePCIAddress; typedef virDomainDevicePCIAddress *virDomainDevicePCIAddressPtr; struct _virDomainDevicePCIAddress { @@ -179,6 +187,10 @@ struct _virDomainDeviceInfo { union { virDomainDeviceUSBMaster usb; } master; + /* rombar is only used for pci hostdev devices, and bootIndex only + * for disk, network interface, and hostdev devices */ + int rombar; /* enum virDomainPciRombarMode */ + int bootIndex; }; enum virDomainSeclabelType { @@ -409,7 +421,6 @@ struct _virDomainDiskDef { int cachemode; int error_policy; /* enum virDomainDiskErrorPolicy */ int rerror_policy; /* enum virDomainDiskErrorPolicy */ - int bootIndex; int iomode; int ioeventfd; int event_idx; @@ -655,7 +666,6 @@ struct _virDomainNetDef { } tune; char *script; char *ifname; - int bootIndex; virDomainDeviceInfo info; char *filter; virNWFilterHashTablePtr filterparams; @@ -1094,14 +1104,6 @@ enum virDomainHostdevSubsysType { VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST }; -enum virDomainPciRombarMode { - VIR_DOMAIN_PCI_ROMBAR_DEFAULT = 0, - VIR_DOMAIN_PCI_ROMBAR_ON, - VIR_DOMAIN_PCI_ROMBAR_OFF, - - VIR_DOMAIN_PCI_ROMBAR_LAST -}; - typedef struct _virDomainHostdevDef virDomainHostdevDef; typedef virDomainHostdevDef *virDomainHostdevDefPtr; struct _virDomainHostdevDef { @@ -1116,9 +1118,7 @@ struct _virDomainHostdevDef { int dummy; } caps; } source; - int bootIndex; virDomainDeviceInfo info; /* Guest address */ - int rombar; /* enum virDomainPciRombarMode */ virDomainHostdevOrigStates origstates; }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index aaccf62..fd170bf 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -2849,19 +2849,19 @@ qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, const char *configfd, virBufferAsprintf(&buf, ",id=%s", dev->info.alias); if (configfd && *configfd) virBufferAsprintf(&buf, ",configfd=%s", configfd); - if (dev->bootIndex) - virBufferAsprintf(&buf, ",bootindex=%d", dev->bootIndex); + if (dev->info.bootIndex) + virBufferAsprintf(&buf, ",bootindex=%d", dev->info.bootIndex); if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) goto error; - if (dev->rombar) { + if (dev->info.rombar) { if (!qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_ROMBAR)) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("rombar not supported in this QEMU binary")); goto error; } - switch (dev->rombar) { + switch (dev->info.rombar) { case VIR_DOMAIN_PCI_ROMBAR_OFF: virBufferAddLit(&buf, ",rombar=0"); break; @@ -4419,8 +4419,8 @@ qemuBuildCommandLine(virConnectPtr conn, if (!emitBootindex) bootindex = 0; - else if (disk->bootIndex) - bootindex = disk->bootIndex; + else if (disk->info.bootIndex) + bootindex = disk->info.bootIndex; if (withDeviceArg) { if (disk->bus == VIR_DOMAIN_DISK_BUS_FDC) { @@ -4614,7 +4614,7 @@ qemuBuildCommandLine(virConnectPtr conn, bootNet = 0; if (!bootindex) - bootindex = net->bootIndex; + bootindex = net->info.bootIndex; /* VLANs are not used with -netdev, so don't record them */ if (qemuCapsGet(qemuCaps, QEMU_CAPS_NETDEV) && @@ -5547,7 +5547,7 @@ qemuBuildCommandLine(virConnectPtr conn, virDomainHostdevDefPtr hostdev = def->hostdevs[i]; char *devstr; - if (hostdev->bootIndex) { + if (hostdev->info.bootIndex) { if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index c81289a..729c621 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4518,7 +4518,7 @@ static char *qemuDomainXMLToNative(virConnectPtr conn, */ for (i = 0 ; i < def->nnets ; i++) { virDomainNetDefPtr net = def->nets[i]; - int bootIndex = net->bootIndex; + int bootIndex = net->info.bootIndex; if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) { int actualType = virDomainNetGetActualType(net); const char *brname; @@ -4576,7 +4576,7 @@ static char *qemuDomainXMLToNative(virConnectPtr conn, net->data.ethernet.dev = brname; net->data.ethernet.ipaddr = ipaddr; } - net->bootIndex = bootIndex; + net->info.bootIndex = bootIndex; } for (i = 0 ; i < def->ngraphics ; i++) { if (def->graphics[i]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && -- 1.7.7.5

On 01/25/2012 09:58 AM, Laine Stump wrote:
To help consolidate the commonality between virDomainHostdevDef and virDomainInterface into as few members as possible (and because I think it makes sense), this patch moves the rombar and bootIndex members into the "info" member that is common to both (and to all the other structs that use them).
It's a bit problematic that this gives rombar and bootIndex to many device types that don't use them, but this is already the case for the master and mastertype members of virDomainDeviceInfo, and is properly commented as such in the definition.
Note that this opens the door to supporting rombar for other devices that are attached to the guest PCI bus - virtio-blk-pci, virtio-net-pci, various other network adapters - which which have that capability in qemu, but previously had no support in libvirt.
Looks like a reasonable move; the code itself is fine once we accept the need for the refactoring. ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 01/25/2012 09:57 PM, Eric Blake wrote:
On 01/25/2012 09:58 AM, Laine Stump wrote:
To help consolidate the commonality between virDomainHostdevDef and virDomainInterface into as few members as possible (and because I think it makes sense), this patch moves the rombar and bootIndex members into the "info" member that is common to both (and to all the other structs that use them).
It's a bit problematic that this gives rombar and bootIndex to many device types that don't use them, but this is already the case for the master and mastertype members of virDomainDeviceInfo, and is properly commented as such in the definition.
Note that this opens the door to supporting rombar for other devices that are attached to the guest PCI bus - virtio-blk-pci, virtio-net-pci, various other network adapters - which which have that capability in qemu, but previously had no support in libvirt. Looks like a reasonable move; the code itself is fine once we accept the need for the refactoring. ACK.
Thanks! I pushed this with a slightly different summary: conf: put all guest-related HostdevDef data in one object. I'm deferring patch 2/6 for now though, as even the small changes in v1 of that patch aren't necessary for the rest of this series, but are essential for another series I'm working on now to support intelligent PCI passthrough of network interface devices (via <interface> rather than <hostdev>); in anticipation that I may want to change it a bit still, I'll repost that patch with this new series.

Since these two items are now in the virDomainDeviceInfo struct, it makes sense to parse/format them in the functions written to parse/format that structure. Not all types of devices allow them, so two internal flags are added to indicate when it is appropriate to do so. I was lucky - only one test case needed to be re-ordered! --- src/conf/domain_conf.c | 224 +++++++++++--------- tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml | 2 +- 2 files changed, 123 insertions(+), 103 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 8a35e6e..9723d95 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -67,6 +67,8 @@ typedef enum { VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET = (1<<17), /* dump/parse original states of host PCI device */ VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES = (1<<18), + VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM = (1<<19), + VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT = (1<<20), } virDomainXMLInternalFlags; VIR_ENUM_IMPL(virDomainTaint, VIR_DOMAIN_TAINT_LAST, @@ -1908,6 +1910,9 @@ virDomainDeviceInfoFormat(virBufferPtr buf, virDomainDeviceInfoPtr info, unsigned int flags) { + if ((flags & VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) && info->bootIndex) + virBufferAsprintf(buf, " <boot order='%d'/>\n", info->bootIndex); + if (info->alias && !(flags & VIR_DOMAIN_XML_INACTIVE)) { virBufferAsprintf(buf, " <alias name='%s'/>\n", info->alias); @@ -1918,6 +1923,18 @@ virDomainDeviceInfoFormat(virBufferPtr buf, info->master.usb.startport); } + if ((flags & VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) && info->rombar) { + const char *rombar + = virDomainPciRombarModeTypeToString(info->rombar); + if (!rombar) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected rom bar value %d"), + info->rombar); + return -1; + } + virBufferAsprintf(buf, " <rom bar='%s'/>\n", rombar); + } + if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) return 0; @@ -2266,11 +2283,56 @@ cleanup: return ret; } +static int +virDomainDeviceBootParseXML(xmlNodePtr node, + int *bootIndex, + virBitmapPtr bootMap) +{ + char *order; + int boot; + int ret = -1; + + order = virXMLPropString(node, "order"); + if (!order) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("missing boot order attribute")); + goto cleanup; + } else if (virStrToLong_i(order, NULL, 10, &boot) < 0 || + boot <= 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("incorrect boot order '%s', expecting positive integer"), + order); + goto cleanup; + } + + if (bootMap) { + bool set; + if (virBitmapGetBit(bootMap, boot - 1, &set) < 0) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("boot orders have to be contiguous and starting from 1")); + goto cleanup; + } else if (set) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("boot order %d used for more than one device"), boot); + goto cleanup; + } + ignore_value(virBitmapSetBit(bootMap, boot - 1)); + } + + *bootIndex = boot; + ret = 0; + +cleanup: + VIR_FREE(order); + return ret; +} + /* Parse the XML definition for a device address * @param node XML nodeset to parse for device address definition */ static int virDomainDeviceInfoParseXML(xmlNodePtr node, + virBitmapPtr bootMap, virDomainDeviceInfoPtr info, unsigned int flags) { @@ -2278,6 +2340,8 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, xmlNodePtr address = NULL; xmlNodePtr master = NULL; xmlNodePtr alias = NULL; + xmlNodePtr boot = NULL; + xmlNodePtr rom = NULL; char *type = NULL; int ret = -1; @@ -2296,6 +2360,14 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, } else if (master == NULL && xmlStrEqual(cur->name, BAD_CAST "master")) { master = cur; + } else if (boot == NULL && bootMap && + (flags & VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) && + xmlStrEqual(cur->name, BAD_CAST "boot")) { + boot = cur; + } else if (rom == NULL && + (flags & VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) && + xmlStrEqual(cur->name, BAD_CAST "rom")) { + rom = cur; } } cur = cur->next; @@ -2310,6 +2382,27 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, goto cleanup; } + if (boot) { + if (virDomainDeviceBootParseXML(boot, &info->bootIndex, bootMap)) + goto cleanup; + } + + if (rom) { + char *rombar = virXMLPropString(rom, "bar"); + if (!rombar) { + virDomainReportError(VIR_ERR_XML_ERROR, + "%s", _("missing rom bar attribute")); + goto cleanup; + } + if ((info->rombar = virDomainPciRombarModeTypeFromString(rombar)) <= 0) { + virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("unknown rom bar value '%s'"), rombar); + VIR_FREE(rombar); + goto cleanup; + } + VIR_FREE(rombar); + } + if (!address) return 0; @@ -2376,50 +2469,6 @@ cleanup: } static int -virDomainDeviceBootParseXML(xmlNodePtr node, - int *bootIndex, - virBitmapPtr bootMap) -{ - char *order; - int boot; - int ret = -1; - - order = virXMLPropString(node, "order"); - if (!order) { - virDomainReportError(VIR_ERR_INTERNAL_ERROR, - "%s", _("missing boot order attribute")); - goto cleanup; - } else if (virStrToLong_i(order, NULL, 10, &boot) < 0 || - boot <= 0) { - virDomainReportError(VIR_ERR_INTERNAL_ERROR, - _("incorrect boot order '%s', expecting positive integer"), - order); - goto cleanup; - } - - if (bootMap) { - bool set; - if (virBitmapGetBit(bootMap, boot - 1, &set) < 0) { - virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("boot orders have to be contiguous and starting from 1")); - goto cleanup; - } else if (set) { - virDomainReportError(VIR_ERR_INTERNAL_ERROR, - _("boot order %d used for more than one device"), boot); - goto cleanup; - } - ignore_value(virBitmapSetBit(bootMap, boot - 1)); - } - - *bootIndex = boot; - ret = 0; - -cleanup: - VIR_FREE(order); - return ret; -} - -static int virDomainParseLegacyDeviceAddress(char *devaddr, virDomainDevicePCIAddressPtr pci) { @@ -3021,9 +3070,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, (xmlStrEqual(cur->name, BAD_CAST "serial"))) { serial = (char *)xmlNodeGetContent(cur); } else if (xmlStrEqual(cur->name, BAD_CAST "boot")) { - if (virDomainDeviceBootParseXML(cur, &def->info.bootIndex, - bootMap)) - goto error; + /* boot is parsed as part of virDomainDeviceInfoParseXML */ } } cur = cur->next; @@ -3229,7 +3276,8 @@ virDomainDiskDefParseXML(virCapsPtr caps, } def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; } else { - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, bootMap, &def->info, + flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) < 0) goto error; } @@ -3389,7 +3437,7 @@ virDomainControllerDefParseXML(xmlNodePtr node, def->model = -1; } - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; switch (def->type) { @@ -3555,7 +3603,7 @@ virDomainFSDefParseXML(xmlNodePtr node, def->dst = target; target = NULL; - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; cleanup: @@ -3790,9 +3838,7 @@ virDomainNetDefParseXML(virCapsPtr caps, /* Legacy back-compat. Don't add any more attributes here */ devaddr = virXMLPropString(cur, "devaddr"); } else if (xmlStrEqual(cur->name, BAD_CAST "boot")) { - if (virDomainDeviceBootParseXML(cur, &def->info.bootIndex, - bootMap)) - goto error; + /* boot is parsed as part of virDomainDeviceInfoParseXML */ } else if ((actual == NULL) && (flags & VIR_DOMAIN_XML_INTERNAL_ACTUAL_NET) && (def->type == VIR_DOMAIN_NET_TYPE_NETWORK) && @@ -3828,7 +3874,8 @@ virDomainNetDefParseXML(virCapsPtr caps, } def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; } else { - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, bootMap, &def->info, + flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) < 0) goto error; } @@ -4579,7 +4626,7 @@ virDomainChrDefParseXML(virCapsPtr caps, } } - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; cleanup: @@ -4700,7 +4747,7 @@ virDomainSmartcardDefParseXML(xmlNodePtr node, goto error; } - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_CCID) { @@ -4796,7 +4843,7 @@ virDomainInputDefParseXML(const char *ostype, } } - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; if (def->bus == VIR_DOMAIN_INPUT_BUS_USB && @@ -4846,7 +4893,7 @@ virDomainHubDefParseXML(xmlNodePtr node, unsigned int flags) goto error; } - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; cleanup: @@ -5596,7 +5643,7 @@ virDomainSoundDefParseXML(const xmlNodePtr node, goto error; } - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; cleanup: @@ -5650,7 +5697,7 @@ virDomainWatchdogDefParseXML(const xmlNodePtr node, } } - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; cleanup: @@ -5690,7 +5737,7 @@ virDomainMemballoonDefParseXML(const xmlNodePtr node, goto error; } - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; cleanup: @@ -5939,7 +5986,7 @@ virDomainVideoDefParseXML(const xmlNodePtr node, def->heads = 1; } - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; VIR_FREE(type); @@ -6229,23 +6276,9 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, } else if (xmlStrEqual(cur->name, BAD_CAST "alias")) { /* alias is parsed as part of virDomainDeviceInfoParseXML */ } else if (xmlStrEqual(cur->name, BAD_CAST "boot")) { - if (virDomainDeviceBootParseXML(cur, &def->info.bootIndex, - bootMap)) - goto error; + /* boot is parsed as part of virDomainDeviceInfoParseXML */ } else if (xmlStrEqual(cur->name, BAD_CAST "rom")) { - char *rombar = virXMLPropString(cur, "bar"); - if (!rombar) { - virDomainReportError(VIR_ERR_XML_ERROR, - "%s", _("missing rom bar attribute")); - goto error; - } - if ((def->info.rombar = virDomainPciRombarModeTypeFromString(rombar)) <= 0) { - virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, - _("unknown rom bar value '%s'"), rombar); - VIR_FREE(rombar); - goto error; - } - VIR_FREE(rombar); + /* rombar is parsed as part of virDomainDeviceInfoParseXML */ } else { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _("unknown node %s"), cur->name); @@ -6255,7 +6288,9 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, } if (def->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, bootMap, &def->info, + flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT + | VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) < 0) goto error; } @@ -6339,7 +6374,7 @@ virDomainRedirdevDefParseXML(const xmlNodePtr node, def->source.chr.data.spicevmc = VIR_DOMAIN_CHR_SPICEVMC_USBREDIR; } - if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0) + if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0) goto error; if (def->bus == VIR_DOMAIN_REDIRDEV_BUS_USB && @@ -10088,8 +10123,6 @@ virDomainDiskDefFormat(virBufferPtr buf, virBufferAddLit(buf, " </iotune>\n"); } - if (def->info.bootIndex) - virBufferAsprintf(buf, " <boot order='%d'/>\n", def->info.bootIndex); if (def->readonly) virBufferAddLit(buf, " <readonly/>\n"); if (def->shared) @@ -10104,7 +10137,8 @@ virDomainDiskDefFormat(virBufferPtr buf, virBufferAdjustIndent(buf, -6); } - if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) + if (virDomainDeviceInfoFormat(buf, &def->info, + flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) < 0) return -1; virBufferAddLit(buf, " </disk>\n"); @@ -10453,8 +10487,6 @@ virDomainNetDefFormat(virBufferPtr buf, return -1; virBufferAdjustIndent(buf, -6); } - if (def->info.bootIndex) - virBufferAsprintf(buf, " <boot order='%d'/>\n", def->info.bootIndex); if (def->tune.sndbuf_specified) { virBufferAddLit(buf, " <tune>\n"); @@ -10472,7 +10504,8 @@ virDomainNetDefFormat(virBufferPtr buf, return -1; virBufferAdjustIndent(buf, -6); - if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) + if (virDomainDeviceInfoFormat(buf, &def->info, + flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) < 0) return -1; virBufferAddLit(buf, " </interface>\n"); @@ -11304,24 +11337,11 @@ virDomainHostdevDefFormat(virBufferPtr buf, virBufferAddLit(buf, " </source>\n"); - if (def->info.bootIndex) - virBufferAsprintf(buf, " <boot order='%d'/>\n", def->info.bootIndex); - - if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0) + if (virDomainDeviceInfoFormat(buf, &def->info, + flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT + | VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) < 0) return -1; - if (def->info.rombar) { - const char *rombar - = virDomainPciRombarModeTypeToString(def->info.rombar); - if (!rombar) { - virDomainReportError(VIR_ERR_INTERNAL_ERROR, - _("unexpected rom bar value %d"), - def->info.rombar); - return -1; - } - virBufferAsprintf(buf, " <rom bar='%s'/>\n", rombar); - } - virBufferAddLit(buf, " </hostdev>\n"); return 0; diff --git a/tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml b/tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml index 0022c92..68741fe 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml @@ -21,8 +21,8 @@ <disk type='file' device='cdrom'> <source file='/root/boot.iso'/> <target dev='hdc' bus='ide'/> - <boot order='1'/> <readonly/> + <boot order='1'/> <address type='drive' controller='0' bus='1' unit='0'/> </disk> <disk type='network' device='disk'> -- 1.7.7.5

On 01/25/2012 09:58 AM, Laine Stump wrote:
Since these two items are now in the virDomainDeviceInfo struct, it makes sense to parse/format them in the functions written to parse/format that structure. Not all types of devices allow them, so two internal flags are added to indicate when it is appropriate to do so.
I was lucky - only one test case needed to be re-ordered! --- src/conf/domain_conf.c | 224 +++++++++++--------- tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml | 2 +- 2 files changed, 123 insertions(+), 103 deletions(-)
ACK. Nice use of internal flags to share logic while still keeping the overall parsing and output the same. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 01/25/2012 10:02 PM, Eric Blake wrote:
On 01/25/2012 09:58 AM, Laine Stump wrote:
Since these two items are now in the virDomainDeviceInfo struct, it makes sense to parse/format them in the functions written to parse/format that structure. Not all types of devices allow them, so two internal flags are added to indicate when it is appropriate to do so.
I was lucky - only one test case needed to be re-ordered! --- src/conf/domain_conf.c | 224 +++++++++++--------- tests/qemuxml2argvdata/qemuxml2argv-boot-order.xml | 2 +- 2 files changed, 123 insertions(+), 103 deletions(-) ACK. Nice use of internal flags to share logic while still keeping the overall parsing and output the same.
Thanks. I pushed this now.

When support for the rombar option was added, it was only added for PCI passthrough devices, configured with <hostdev>. The same option is available for any network device that is attached to the guest's PCI bus. This patch allows setting rombar for any PCI network device type. After adding cases to test this to qemuxml2argv-hostdev-pci-rombar.*, I decided to rename those files (to qemuxml2argv-pci-rom.*) to more accurately reflect the additional tests, and also noticed that up to now we've only been performing a domainschematest for that case, so I added the "pci-rom" test to both qemuxml2argv and qemuxml2xml (and in the process found some bugs whose fixes I squashed into previous commits of this series). --- docs/formatdomain.html.in | 27 ++++++++++ docs/schemas/domaincommon.rng | 25 ++++++--- src/conf/domain_conf.c | 6 ++- src/qemu/qemu_command.c | 54 +++++++++++++------- .../qemuxml2argv-hostdev-pci-rombar.args | 5 -- tests/qemuxml2argvdata/qemuxml2argv-pci-rom.args | 12 ++++ ...dev-pci-rombar.xml => qemuxml2argv-pci-rom.xml} | 18 +++++++ tests/qemuxml2argvtest.c | 3 + tests/qemuxml2xmltest.c | 1 + 9 files changed, 116 insertions(+), 35 deletions(-) delete mode 100644 tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-rombar.args create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-pci-rom.args rename tests/qemuxml2argvdata/{qemuxml2argv-hostdev-pci-rombar.xml => qemuxml2argv-pci-rom.xml} (57%) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index dfb010d..85cdbea 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1951,6 +1951,7 @@ <mac address='00:16:3e:5d:c7:9e'/> <script path='vif-bridge'/> <boot order='1'/> + <rom bar='off'/> </interface> </devices> ...</pre> @@ -2479,6 +2480,32 @@ qemu-kvm -net nic,model=? /dev/null <span class="since">Since 0.8.8</span> </p> + <h5><a name="elementsNICSROM">Interface ROM BIOS configuration</a></h5> + +<pre> + ... + <devices> + <interface type='network'> + <source network='default'/> + <target dev='vnet1'/> + <b><rom bar='off'/></b> + </interface> + </devices> + ...</pre> + + <p> + For hypervisors which support this, you can change how a PCI Network + device's ROM is presented to the guest. The <code>bar</code> + attribute can be set to "on" or "off", and determines whether + or not the device's ROM will be visible in the guest's memory + map. (In PCI documentation, the "rombar" setting controls the + presence of the Base Address Register for the ROM). If no rom + bar is specified, the qemu default will be used (older + versions of qemu used a default of "off", while newer qemus + have a default of "on"). <span class="since">Since + 0.9.10 (QEMU and KVM only)</span> + </p> + <h5><a name="elementQoS">Quality of service</a></h5> <pre> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 4fa968d..6bef645 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -1490,6 +1490,9 @@ <ref name="deviceBoot"/> </optional> <optional> + <ref name="rom"/> + </optional> + <optional> <ref name="bandwidth"/> </optional> </interleave> @@ -2347,15 +2350,7 @@ <ref name="address"/> </optional> <optional> - <element name="rom"> - <attribute name="bar"> - <choice> - <value>on</value> - <value>off</value> - </choice> - </attribute> - <empty/> - </element> + <ref name="rom"/> </optional> </element> </define> @@ -2815,6 +2810,18 @@ </element> </define> + <define name="rom"> + <element name="rom"> + <attribute name="bar"> + <choice> + <value>on</value> + <value>off</value> + </choice> + </attribute> + <empty/> + </element> + </define> + <define name="usbmaster"> <element name="master"> <attribute name="startport"> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 9723d95..0799c5e 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -3875,7 +3875,8 @@ virDomainNetDefParseXML(virCapsPtr caps, def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; } else { if (virDomainDeviceInfoParseXML(node, bootMap, &def->info, - flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) < 0) + flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT + | VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) < 0) goto error; } @@ -10505,7 +10506,8 @@ virDomainNetDefFormat(virBufferPtr buf, virBufferAdjustIndent(buf, -6); if (virDomainDeviceInfoFormat(buf, &def->info, - flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) < 0) + flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT + | VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) < 0) return -1; virBufferAddLit(buf, " </interface>\n"); diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index fd170bf..3fcd4b1 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1515,6 +1515,37 @@ qemuBuildDeviceAddressStr(virBufferPtr buf, } static int +qemuBuildRomStr(virBufferPtr buf, + virDomainDeviceInfoPtr info, + virBitmapPtr qemuCaps) +{ + if (info->rombar) { + if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, + "%s", _("rombar is supported only for PCI devices")); + return -1; + } + if (!qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_ROMBAR)) { + qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, + "%s", _("rombar not supported in this QEMU binary")); + return -1; + } + + switch (info->rombar) { + case VIR_DOMAIN_PCI_ROMBAR_OFF: + virBufferAddLit(buf, ",rombar=0"); + break; + case VIR_DOMAIN_PCI_ROMBAR_ON: + virBufferAddLit(buf, ",rombar=1"); + break; + default: + break; + } + } + return 0; +} + +static int qemuBuildIoEventFdStr(virBufferPtr buf, enum virDomainIoEventFd use, virBitmapPtr qemuCaps) @@ -2502,6 +2533,8 @@ qemuBuildNicDevStr(virDomainNetDefPtr net, net->mac[4], net->mac[5]); if (qemuBuildDeviceAddressStr(&buf, &net->info, qemuCaps) < 0) goto error; + if (qemuBuildRomStr(&buf, &net->info, qemuCaps) < 0) + goto error; if (bootindex && qemuCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX)) virBufferAsprintf(&buf, ",bootindex=%d", bootindex); @@ -2853,25 +2886,8 @@ qemuBuildPCIHostdevDevStr(virDomainHostdevDefPtr dev, const char *configfd, virBufferAsprintf(&buf, ",bootindex=%d", dev->info.bootIndex); if (qemuBuildDeviceAddressStr(&buf, &dev->info, qemuCaps) < 0) goto error; - - if (dev->info.rombar) { - if (!qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_ROMBAR)) { - qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, - "%s", _("rombar not supported in this QEMU binary")); - goto error; - } - - switch (dev->info.rombar) { - case VIR_DOMAIN_PCI_ROMBAR_OFF: - virBufferAddLit(&buf, ",rombar=0"); - break; - case VIR_DOMAIN_PCI_ROMBAR_ON: - virBufferAddLit(&buf, ",rombar=1"); - break; - default: - break; - } - } + if (qemuBuildRomStr(&buf, &dev->info, qemuCaps) < 0) + goto error; if (virBufferError(&buf)) { virReportOOMError(); diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-rombar.args b/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-rombar.args deleted file mode 100644 index 1a8b14e..0000000 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-rombar.args +++ /dev/null @@ -1,5 +0,0 @@ -LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ -pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \ -unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \ -/dev/HostVG/QEMUGuest2 -usb -device pci-assign,host=06:12.5,id=hostdev0,\ -bus=pci.0,addr=0x3,rombar=0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.args b/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.args new file mode 100644 index 0000000..11e0f0f --- /dev/null +++ b/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.args @@ -0,0 +1,12 @@ +LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \ +pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \ +unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda \ +/dev/HostVG/QEMUGuest2 \ +-device virtio-net-pci,vlan=0,id=net0,mac=52:54:00:24:a5:9f,bus=pci.0,addr=0x3,rombar=1 \ +-net user,vlan=0,name=hostnet0 \ +-device virtio-net-pci,vlan=1,id=net1,mac=52:54:00:24:a5:9e,bus=pci.0,addr=0x4,\ +romfile=/etc/fake/bootrom.bin -net user,vlan=1,name=hostnet1 \ +-usb -device pci-assign,host=06:12.5,id=hostdev0,bus=pci.0,addr=0x5,rombar=0 \ +-device pci-assign,host=06:12.6,id=hostdev1,bus=pci.0,addr=0x6,rombar=1,\ +romfile=/etc/fake/bootrom.bin \ +-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x7 diff --git a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-rombar.xml b/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml similarity index 57% rename from tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-rombar.xml rename to tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml index bf17cc4..731a69d 100644 --- a/tests/qemuxml2argvdata/qemuxml2argv-hostdev-pci-rombar.xml +++ b/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml @@ -17,13 +17,31 @@ <disk type='block' device='disk'> <source dev='/dev/HostVG/QEMUGuest2'/> <target dev='hda' bus='ide'/> + <address type='drive' controller='0' bus='0' unit='0'/> </disk> + <controller type='ide' index='0'/> + <interface type='user'> + <mac address='52:54:00:24:a5:9f'/> + <model type='virtio'/> + <rom bar='on'/> + </interface> + <interface type='user'> + <mac address='52:54:00:24:a5:9e'/> + <model type='virtio'/> + <rom file='/etc/fake/bootrom.bin'/> + </interface> <hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x06' slot='0x12' function='0x5'/> </source> <rom bar='off'/> </hostdev> + <hostdev mode='subsystem' type='pci' managed='yes'> + <source> + <address domain='0x0000' bus='0x06' slot='0x12' function='0x6'/> + </source> + <rom bar='on' file='/etc/fake/bootrom.bin'/> + </hostdev> <memballoon model='virtio'/> </devices> </domain> diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c index d40b37e..3fabb66 100644 --- a/tests/qemuxml2argvtest.c +++ b/tests/qemuxml2argvtest.c @@ -660,6 +660,9 @@ mymain(void) DO_TEST("hostdev-pci-address", false, QEMU_CAPS_PCIDEVICE); DO_TEST("hostdev-pci-address-device", false, QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG); + DO_TEST("pci-rom", false, + QEMU_CAPS_PCIDEVICE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG, + QEMU_CAPS_PCI_ROMBAR); DO_TEST_FULL("restore-v1", "stdio", 7, false, false, QEMU_CAPS_MIGRATE_KVM_STDIO); diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c index df317fd..3b6e6ea 100644 --- a/tests/qemuxml2xmltest.c +++ b/tests/qemuxml2xmltest.c @@ -181,6 +181,7 @@ mymain(void) DO_TEST("hostdev-usb-address"); DO_TEST("hostdev-pci-address"); + DO_TEST("pci-rom"); DO_TEST("encrypted-disk"); DO_TEST("memtune"); -- 1.7.7.5

On 01/25/2012 09:58 AM, Laine Stump wrote:
When support for the rombar option was added, it was only added for PCI passthrough devices, configured with <hostdev>. The same option is available for any network device that is attached to the guest's PCI bus. This patch allows setting rombar for any PCI network device type.
After adding cases to test this to qemuxml2argv-hostdev-pci-rombar.*, I decided to rename those files (to qemuxml2argv-pci-rom.*) to more accurately reflect the additional tests, and also noticed that up to now we've only been performing a domainschematest for that case, so I added the "pci-rom" test to both qemuxml2argv and qemuxml2xml (and in the process found some bugs whose fixes I squashed into previous commits of this series). --- docs/formatdomain.html.in | 27 ++++++++++ docs/schemas/domaincommon.rng | 25 ++++++--- src/conf/domain_conf.c | 6 ++- src/qemu/qemu_command.c | 54 +++++++++++++------- .../qemuxml2argv-hostdev-pci-rombar.args | 5 -- tests/qemuxml2argvdata/qemuxml2argv-pci-rom.args | 12 ++++ ...dev-pci-rombar.xml => qemuxml2argv-pci-rom.xml} | 18 +++++++ tests/qemuxml2argvtest.c | 3 + tests/qemuxml2xmltest.c | 1 +
docs, rng, and tests all in one go! I'm impressed :) I didn't see anything fishy in here, so ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 01/25/2012 08:08 PM, Eric Blake wrote:
On 01/25/2012 09:58 AM, Laine Stump wrote:
When support for the rombar option was added, it was only added for PCI passthrough devices, configured with <hostdev>. The same option is available for any network device that is attached to the guest's PCI bus. This patch allows setting rombar for any PCI network device type.
After adding cases to test this to qemuxml2argv-hostdev-pci-rombar.*, I decided to rename those files (to qemuxml2argv-pci-rom.*) to more accurately reflect the additional tests, and also noticed that up to now we've only been performing a domainschematest for that case, so I added the "pci-rom" test to both qemuxml2argv and qemuxml2xml (and in the process found some bugs whose fixes I squashed into previous commits of this series). --- docs/formatdomain.html.in | 27 ++++++++++ docs/schemas/domaincommon.rng | 25 ++++++--- src/conf/domain_conf.c | 6 ++- src/qemu/qemu_command.c | 54 +++++++++++++------- .../qemuxml2argv-hostdev-pci-rombar.args | 5 -- tests/qemuxml2argvdata/qemuxml2argv-pci-rom.args | 12 ++++ ...dev-pci-rombar.xml => qemuxml2argv-pci-rom.xml} | 18 +++++++ tests/qemuxml2argvtest.c | 3 + tests/qemuxml2xmltest.c | 1 +
docs, rng, and tests all in one go! I'm impressed :)
I didn't see anything fishy in here, so ACK.
Actually,
+ <define name="rom"> + <element name="rom"> + <attribute name="bar"> + <choice> + <value>on</value> + <value>off</value> + </choice> + </attribute> + <empty/> + </element> + </define> +
+-device pci-assign,host=06:12.6,id=hostdev1,bus=pci.0,addr=0x6,rombar=1,\ +romfile=/etc/fake/bootrom.bin \
+ <interface type='user'> + <mac address='52:54:00:24:a5:9e'/> + <model type='virtio'/> + <rom file='/etc/fake/bootrom.bin'/> + </interface>
You don't add rom file='' until patch 6/6, and the RNG schema doesn't look like it supports file yet. </me installs the series to see if this passes 'make check'...> 153) qemuxml2argvdata/qemuxml2argv-pci-rom.xml ... FAILED xmllint --relaxng /home/remote/eblake/libvirt/tests/../docs/schemas/domain.rng --noout /home/remote/eblake/libvirt/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml Relax-NG validity error : Extra element devices in interleave /home/remote/eblake/libvirt/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml:15: element devices: Relax-NG validity error : Element domain failed to validate content /home/remote/eblake/libvirt/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml fails to validate It looks like you didn't quite rebase this for 'git bisect' purposes. Would you mind rebasing one more time to move the <rom file=> stuff into 6/6 where the rng support was added? Since it is just motion between the two patches, and the end result is the same, no need to post a v2. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

On 01/25/2012 10:18 PM, Eric Blake wrote:
On 01/25/2012 08:08 PM, Eric Blake wrote:
On 01/25/2012 09:58 AM, Laine Stump wrote:
When support for the rombar option was added, it was only added for PCI passthrough devices, configured with<hostdev>. The same option is available for any network device that is attached to the guest's PCI bus. This patch allows setting rombar for any PCI network device type.
After adding cases to test this to qemuxml2argv-hostdev-pci-rombar.*, I decided to rename those files (to qemuxml2argv-pci-rom.*) to more accurately reflect the additional tests, and also noticed that up to now we've only been performing a domainschematest for that case, so I added the "pci-rom" test to both qemuxml2argv and qemuxml2xml (and in the process found some bugs whose fixes I squashed into previous commits of this series). --- docs/formatdomain.html.in | 27 ++++++++++ docs/schemas/domaincommon.rng | 25 ++++++--- src/conf/domain_conf.c | 6 ++- src/qemu/qemu_command.c | 54 +++++++++++++------- .../qemuxml2argv-hostdev-pci-rombar.args | 5 -- tests/qemuxml2argvdata/qemuxml2argv-pci-rom.args | 12 ++++ ...dev-pci-rombar.xml => qemuxml2argv-pci-rom.xml} | 18 +++++++ tests/qemuxml2argvtest.c | 3 + tests/qemuxml2xmltest.c | 1 + docs, rng, and tests all in one go! I'm impressed :)
I didn't see anything fishy in here, so ACK. Actually,
+<define name="rom"> +<element name="rom"> +<attribute name="bar"> +<choice> +<value>on</value> +<value>off</value> +</choice> +</attribute> +<empty/> +</element> +</define> + +-device pci-assign,host=06:12.6,id=hostdev1,bus=pci.0,addr=0x6,rombar=1,\ +romfile=/etc/fake/bootrom.bin \ +<interface type='user'> +<mac address='52:54:00:24:a5:9e'/> +<model type='virtio'/> +<rom file='/etc/fake/bootrom.bin'/> +</interface> You don't add rom file='' until patch 6/6, and the RNG schema doesn't look like it supports file yet.
</me installs the series to see if this passes 'make check'...>
153) qemuxml2argvdata/qemuxml2argv-pci-rom.xml ... FAILED xmllint --relaxng /home/remote/eblake/libvirt/tests/../docs/schemas/domain.rng --noout /home/remote/eblake/libvirt/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml Relax-NG validity error : Extra element devices in interleave /home/remote/eblake/libvirt/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml:15: element devices: Relax-NG validity error : Element domain failed to validate content /home/remote/eblake/libvirt/tests/qemuxml2argvdata/qemuxml2argv-pci-rom.xml fails to validate
It looks like you didn't quite rebase this for 'git bisect' purposes. Would you mind rebasing one more time to move the<rom file=> stuff into 6/6 where the rng support was added? Since it is just motion between the two patches, and the end result is the same, no need to post a v2.
Thanks for catching that! I forgot to mention it in the "pushed" message for 5/6, but I did make that change and verify make check passes at each stage of the patch series before pushing 5/6. I've push 6/6 now too.

This patch addresses: https://bugzilla.redhat.com/show_bug.cgi?id=781562 Along with the "rombar" option that controls whether or not a boot rom is made visible to the guest, qemu also has a "romfile" option that allows specifying a binary file to present as the ROM BIOS of any emulated or passthrough PCI device. This patch adds support for specifying romfile to both passthrough PCI devices, and emulated network devices that attach to the guest's PCI bus (just about everything other than ne2k_isa). One example of the usefulness of this option is described in the bugzilla report: 82576 sriov network adapters don't provide a ROM BIOS for the cards virtual functions (VF), but an image of such a ROM is available, and with this ROM visible to the guest, it can PXE boot. In libvirt's xml, the new option is configured like this: <hostdev> ... <rom file='/etc/fake/boot.bin'/> ... </hostdev (similarly for <interface>). --- docs/formatdomain.html.in | 22 ++++++++++++++++------ docs/schemas/domaincommon.rng | 19 +++++++++++++------ src/conf/domain_conf.c | 37 ++++++++++++++++++++++--------------- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 8 +++++--- 5 files changed, 57 insertions(+), 30 deletions(-) diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index 85cdbea..afd3d22 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -1737,7 +1737,7 @@ <address bus='0x06' slot='0x02' function='0x0'/> </source> <boot order='1'/> - <rom bar='off'/> + <rom bar='on' file='/etc/fake/boot.bin'/> </hostdev> </devices> ...</pre> @@ -1779,7 +1779,7 @@ <span class="since">Since 0.8.8</span></dd> <dt><code>rom</code></dt> <dd>The <code>rom</code> element is used to change how a PCI - device's ROM is presented to the guest. The <code>bar</code> + device's ROM is presented to the guest. The optional <code>bar</code> attribute can be set to "on" or "off", and determines whether or not the device's ROM will be visible in the guest's memory map. (In PCI documentation, the "rombar" setting controls the @@ -1787,7 +1787,13 @@ bar is specified, the qemu default will be used (older versions of qemu used a default of "off", while newer qemus have a default of "on"). <span class="since">Since - 0.9.7</span> + 0.9.7 (QEMU and KVM only)</span>. The optional + <code>file</code> attribute is used to point to a binary file + to be presented to the guest as the device's ROM BIOS. This + can be useful, for example, to provide a PXE boot ROM for a + virtual function of an sr-iov capable ethernet device (which + has no boot ROMs for the VFs). + <span class="since">Since 0.9.10 (QEMU and KVM only)</span>. </dd> <dt><code>address</code></dt> <dd>The <code>address</code> element for USB devices has a @@ -2488,7 +2494,7 @@ qemu-kvm -net nic,model=? /dev/null <interface type='network'> <source network='default'/> <target dev='vnet1'/> - <b><rom bar='off'/></b> + <b><rom bar='on' file='/etc/fake/boot.bin'/></b> </interface> </devices> ...</pre> @@ -2502,8 +2508,12 @@ qemu-kvm -net nic,model=? /dev/null presence of the Base Address Register for the ROM). If no rom bar is specified, the qemu default will be used (older versions of qemu used a default of "off", while newer qemus - have a default of "on"). <span class="since">Since - 0.9.10 (QEMU and KVM only)</span> + have a default of "on"). + The optional <code>file</code> attribute is used to point to a + binary file to be presented to the guest as the device's ROM + BIOS. This can be useful to provide an alternative boot ROM for a + network device. + <span class="since">Since 0.9.10 (QEMU and KVM only)</span>. </p> <h5><a name="elementQoS">Quality of service</a></h5> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng index 6bef645..5eea745 100644 --- a/docs/schemas/domaincommon.rng +++ b/docs/schemas/domaincommon.rng @@ -2812,12 +2812,19 @@ <define name="rom"> <element name="rom"> - <attribute name="bar"> - <choice> - <value>on</value> - <value>off</value> - </choice> - </attribute> + <optional> + <attribute name="bar"> + <choice> + <value>on</value> + <value>off</value> + </choice> + </attribute> + </optional> + <optional> + <attribute name="file"> + <ref name="absFilePath"/> + </attribute> + </optional> <empty/> </element> </define> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 0799c5e..683417b 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -1811,6 +1811,7 @@ void virDomainDeviceInfoClear(virDomainDeviceInfoPtr info) } memset(&info->addr, 0, sizeof(info->addr)); info->type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE; + VIR_FREE(info->romfile); } @@ -1923,16 +1924,25 @@ virDomainDeviceInfoFormat(virBufferPtr buf, info->master.usb.startport); } - if ((flags & VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) && info->rombar) { - const char *rombar - = virDomainPciRombarModeTypeToString(info->rombar); - if (!rombar) { - virDomainReportError(VIR_ERR_INTERNAL_ERROR, - _("unexpected rom bar value %d"), - info->rombar); - return -1; + if ((flags & VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) && + (info->rombar || info->romfile)) { + + virBufferAddLit(buf, " <rom"); + if (info->rombar) { + + const char *rombar = virDomainPciRombarModeTypeToString(info->rombar); + + if (!rombar) { + virDomainReportError(VIR_ERR_INTERNAL_ERROR, + _("unexpected rom bar value %d"), + info->rombar); + return -1; + } + virBufferAsprintf(buf, " bar='%s'", rombar); } - virBufferAsprintf(buf, " <rom bar='%s'/>\n", rombar); + if (info->romfile) + virBufferAsprintf(buf, " file='%s'", info->romfile); + virBufferAddLit(buf, "/>\n"); } if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) @@ -2389,18 +2399,15 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, if (rom) { char *rombar = virXMLPropString(rom, "bar"); - if (!rombar) { - virDomainReportError(VIR_ERR_XML_ERROR, - "%s", _("missing rom bar attribute")); - goto cleanup; - } - if ((info->rombar = virDomainPciRombarModeTypeFromString(rombar)) <= 0) { + if (rombar && + ((info->rombar = virDomainPciRombarModeTypeFromString(rombar)) <= 0)) { virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("unknown rom bar value '%s'"), rombar); VIR_FREE(rombar); goto cleanup; } VIR_FREE(rombar); + info->romfile = virXMLPropString(rom, "file"); } if (!address) diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 8fab383..7f33df2 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -190,6 +190,7 @@ struct _virDomainDeviceInfo { /* rombar is only used for pci hostdev devices, and bootIndex only * for disk, network interface, and hostdev devices */ int rombar; /* enum virDomainPciRombarMode */ + char *romfile; int bootIndex; }; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 3fcd4b1..e4b0431 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1519,15 +1519,15 @@ qemuBuildRomStr(virBufferPtr buf, virDomainDeviceInfoPtr info, virBitmapPtr qemuCaps) { - if (info->rombar) { + if (info->rombar || info->romfile) { if (info->type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, - "%s", _("rombar is supported only for PCI devices")); + "%s", _("rombar and romfile are supported only for PCI devices")); return -1; } if (!qemuCapsGet(qemuCaps, QEMU_CAPS_PCI_ROMBAR)) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, - "%s", _("rombar not supported in this QEMU binary")); + "%s", _("rombar and romfile not supported in this QEMU binary")); return -1; } @@ -1541,6 +1541,8 @@ qemuBuildRomStr(virBufferPtr buf, default: break; } + if (info->romfile) + virBufferAsprintf(buf, ",romfile=%s", info->romfile); } return 0; } -- 1.7.7.5

s/suport/support in the subject actually, that makes the subject a bit long; how about just: s/suport for // On 01/25/2012 09:58 AM, Laine Stump wrote:
This patch addresses: https://bugzilla.redhat.com/show_bug.cgi?id=781562
Always fun to finally get to the real driver of the series.
Along with the "rombar" option that controls whether or not a boot rom is made visible to the guest, qemu also has a "romfile" option that allows specifying a binary file to present as the ROM BIOS of any emulated or passthrough PCI device. This patch adds support for specifying romfile to both passthrough PCI devices, and emulated network devices that attach to the guest's PCI bus (just about everything other than ne2k_isa).
One example of the usefulness of this option is described in the bugzilla report: 82576 sriov network adapters don't provide a ROM BIOS for the cards virtual functions (VF), but an image of such a ROM is available, and with this ROM visible to the guest, it can PXE boot.
In libvirt's xml, the new option is configured like this:
<hostdev> ... <rom file='/etc/fake/boot.bin'/> ... </hostdev
(similarly for <interface>). --- docs/formatdomain.html.in | 22 ++++++++++++++++------ docs/schemas/domaincommon.rng | 19 +++++++++++++------ src/conf/domain_conf.c | 37 ++++++++++++++++++++++--------------- src/conf/domain_conf.h | 1 + src/qemu/qemu_command.c | 8 +++++--- 5 files changed, 57 insertions(+), 30 deletions(-)
See my amended review of 5/6 about moving the specific tests for this new XML into this patch. Beyond those nits, ACK. -- Eric Blake eblake@redhat.com +1-919-301-3266 Libvirt virtualization library http://libvirt.org

When <interface> is expanded to allow passthrough with extra dev-dependent network interface info, the host-side address of the device will need to be added to virDomainNetDef. It will be much simpler if this is done with a common typedefed struct rather than inlining the same struct stuff. In the end, the virDomainHostdevDef really has two kinds of data - data about the device as it exists on the host side (source), and data about the device that is presented to the guest. All of the guest-related data is already in the virDomainDeviceInfo info member of the HostdevDef; this patch moves everything host-related into a new virDomainDeviceSourceInfo source struct. Much of this data was already in a union called source - that union was moved into the newly define struct and made an anonymous union, so that all references to its data can remain unchanged. That left only the following items which needed to have "source." added to the beginning of their references: origstates - this contains the original state of the device on the host, prior to attaching it to the guest. mode - "capabilities" or "subsystem". Only subsystem is ever used. managed - whether or not the device is managed (i.e. if it should be re-attached to the host after detaching from guest). (note that I changed this from a 1-bit bitfield to a bool while rearranging) The entire virDomainHostdevDef now contains two structs and nothing else. This will make it much easier to transplant PCI passthrough functionality into virDomainNetDef (for example). --- Change from V1: almost all of the patch! V1 of this patch just moved the subsys data into its own struct. Although this isn't directly related to adding romfile support (the declared purpose of the patch series), this patch first so well with PATCH 1/6 that it makes sense to push them together. NB: in my local tree I re-ordered 1/6 and 2/6 while re-basing, so this patch is now 1/6 and the other (which relocated with no conflicts) is 2/6. src/conf/domain_conf.c | 42 ++++++++-------- src/conf/domain_conf.h | 102 +++++++++++++++++++++---------------- src/qemu/qemu_cgroup.c | 2 +- src/qemu/qemu_command.c | 16 +++--- src/qemu/qemu_hostdev.c | 26 +++++----- src/qemu/qemu_hotplug.c | 12 ++-- src/security/security_apparmor.c | 2 +- src/security/security_dac.c | 4 +- src/security/security_selinux.c | 4 +- src/util/pci.c | 4 +- src/util/pci.h | 4 +- src/vbox/vbox_tmpl.c | 10 ++-- src/xen/xend_internal.c | 6 +- src/xenxs/xen_sxpr.c | 12 ++-- src/xenxs/xen_xm.c | 6 +- 15 files changed, 133 insertions(+), 119 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 8a35e6e..bb803d0 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -6146,7 +6146,7 @@ virDomainHostdevSubsysPciDefParseXML(const xmlNodePtr node, def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; } else if ((flags & VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES) && xmlStrEqual(cur->name, BAD_CAST "origstates")) { - virDomainHostdevOrigStatesPtr states = &def->origstates; + virDomainHostdevOrigStatesPtr states = &def->source.origstates; if (virDomainHostdevSubsysPciOrigStatesDefParseXML(cur, states) < 0) goto out; } else { @@ -6181,13 +6181,13 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, mode = virXMLPropString(node, "mode"); if (mode) { - if ((def->mode=virDomainHostdevModeTypeFromString(mode)) < 0) { + if ((def->source.mode=virDomainHostdevModeTypeFromString(mode)) < 0) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, _("unknown hostdev mode '%s'"), mode); goto error; } } else { - def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; + def->source.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; } type = virXMLPropString(node, "type"); @@ -6206,7 +6206,7 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, managed = virXMLPropString(node, "managed"); if (managed != NULL) { if (STREQ(managed, "yes")) - def->managed = 1; + def->source.managed = true; VIR_FREE(managed); } @@ -6214,12 +6214,12 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, while (cur != NULL) { if (cur->type == XML_ELEMENT_NODE) { if (xmlStrEqual(cur->name, BAD_CAST "source")) { - if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + if (def->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { if (virDomainHostdevSubsysUsbDefParseXML(cur, def) < 0) goto error; } - if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + if (def->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { if (virDomainHostdevSubsysPciDefParseXML(cur, def, flags) < 0) goto error; @@ -6259,7 +6259,7 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, goto error; } - if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { + if (def->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { switch (def->source.subsys.type) { case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI: if (def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE && @@ -8739,15 +8739,15 @@ static bool virDomainHostdevDefCheckABIStability(virDomainHostdevDefPtr src, { bool identical = false; - if (src->mode != dst->mode) { + if (src->source.mode != dst->source.mode) { virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target host device mode %s does not match source %s"), - virDomainHostdevModeTypeToString(dst->mode), - virDomainHostdevModeTypeToString(src->mode)); + virDomainHostdevModeTypeToString(dst->source.mode), + virDomainHostdevModeTypeToString(src->source.mode)); goto cleanup; } - if (src->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { + if (src->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { if (src->source.subsys.type != dst->source.subsys.type) { virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("Target host device subsystem %s does not match source %s"), @@ -11244,12 +11244,12 @@ virDomainHostdevDefFormat(virBufferPtr buf, virDomainHostdevDefPtr def, unsigned int flags) { - const char *mode = virDomainHostdevModeTypeToString(def->mode); + const char *mode = virDomainHostdevModeTypeToString(def->source.mode); const char *type; - if (!mode || def->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { + if (!mode || def->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { virDomainReportError(VIR_ERR_INTERNAL_ERROR, - _("unexpected hostdev mode %d"), def->mode); + _("unexpected hostdev mode %d"), def->source.mode); return -1; } @@ -11264,7 +11264,7 @@ virDomainHostdevDefFormat(virBufferPtr buf, } virBufferAsprintf(buf, " <hostdev mode='%s' type='%s' managed='%s'>\n", - mode, type, def->managed ? "yes" : "no"); + mode, type, def->source.managed ? "yes" : "no"); virBufferAddLit(buf, " <source>\n"); if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { @@ -11288,15 +11288,15 @@ virDomainHostdevDefFormat(virBufferPtr buf, def->source.subsys.u.pci.function); if ((flags & VIR_DOMAIN_XML_INTERNAL_PCI_ORIG_STATES) && - (def->origstates.states.pci.unbind_from_stub || - def->origstates.states.pci.remove_slot || - def->origstates.states.pci.reprobe)) { + (def->source.origstates.states.pci.unbind_from_stub || + def->source.origstates.states.pci.remove_slot || + def->source.origstates.states.pci.reprobe)) { virBufferAddLit(buf, " <origstates>\n"); - if (def->origstates.states.pci.unbind_from_stub) + if (def->source.origstates.states.pci.unbind_from_stub) virBufferAddLit(buf, " <unbind/>\n"); - if (def->origstates.states.pci.remove_slot) + if (def->source.origstates.states.pci.remove_slot) virBufferAddLit(buf, " <removeslot/>\n"); - if (def->origstates.states.pci.reprobe) + if (def->source.origstates.states.pci.reprobe) virBufferAddLit(buf, " <reprobe/>\n"); virBufferAddLit(buf, " </origstates>\n"); } diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index a2fffd1..2b66469 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -100,6 +100,16 @@ struct _virDomainDevicePCIAddress { int multi; /* enum virDomainDeviceAddressPciMulti */ }; +typedef struct _virDomainDeviceSubsysUSBAddress virDomainDeviceSubsysUSBAddress; +typedef virDomainDeviceSubsysUSBAddress *virDomainDeviceSubsysUSBAddressPtr; +struct _virDomainDeviceSubsysUSBAddress { + unsigned bus; + unsigned device; + + unsigned vendor; + unsigned product; +}; + typedef struct _virDomainDeviceDriveAddress virDomainDeviceDriveAddress; typedef virDomainDeviceDriveAddress *virDomainDeviceDriveAddressPtr; struct _virDomainDeviceDriveAddress { @@ -217,6 +227,54 @@ struct _virDomainHostdevOrigStates { } states; }; +enum virDomainHostdevSubsysType { + VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB, + VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI, + + VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST +}; + +typedef struct _virDomainDeviceSubsysAddress virDomainDeviceSubsysAddress; +typedef virDomainDeviceSubsysAddress *virDomainDeviceSubsysAddressPtr; +struct _virDomainDeviceSubsysAddress { + int type; /* enum virDomainHostdevSubsysType */ + union { + virDomainDeviceSubsysUSBAddress usb; + virDomainDevicePCIAddress pci; /* host address */ + } u; +}; + +enum virDomainHostdevMode { + VIR_DOMAIN_HOSTDEV_MODE_SUBSYS, + VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES, + + VIR_DOMAIN_HOSTDEV_MODE_LAST, +}; + +typedef struct _virDomainDeviceSourceInfo virDomainDeviceSourceInfo; +typedef virDomainDeviceSourceInfo *virDomainDeviceSourceInfoPtr; +struct _virDomainDeviceSourceInfo { + int mode; /* enum virDomainHostdevMode */ + bool managed; + union { + virDomainDeviceSubsysAddress subsys; /* USB or PCI */ + struct { + /* TBD: struct capabilities see: + * https://www.redhat.com/archives/libvir-list/2008-July/msg00429.html + */ + int dummy; + } caps; + }; + virDomainHostdevOrigStates origstates; +}; + +typedef struct _virDomainHostdevDef virDomainHostdevDef; +typedef virDomainHostdevDef *virDomainHostdevDefPtr; +struct _virDomainHostdevDef { + virDomainDeviceSourceInfo source; /* host address info */ + virDomainDeviceInfo info; /* guest address info */ +}; + typedef struct _virDomainLeaseDef virDomainLeaseDef; typedef virDomainLeaseDef *virDomainLeaseDefPtr; struct _virDomainLeaseDef { @@ -1070,50 +1128,6 @@ struct _virDomainGraphicsDef { virDomainGraphicsListenDefPtr listens; }; -enum virDomainHostdevMode { - VIR_DOMAIN_HOSTDEV_MODE_SUBSYS, - VIR_DOMAIN_HOSTDEV_MODE_CAPABILITIES, - - VIR_DOMAIN_HOSTDEV_MODE_LAST, -}; - -enum virDomainHostdevSubsysType { - VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB, - VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI, - - VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_LAST -}; - -typedef struct _virDomainHostdevDef virDomainHostdevDef; -typedef virDomainHostdevDef *virDomainHostdevDefPtr; -struct _virDomainHostdevDef { - int mode; /* enum virDomainHostdevMode */ - unsigned int managed : 1; - union { - struct { - int type; /* enum virDomainHostdevBusType */ - union { - struct { - unsigned bus; - unsigned device; - - unsigned vendor; - unsigned product; - } usb; - virDomainDevicePCIAddress pci; /* host address */ - } u; - } subsys; - struct { - /* TBD: struct capabilities see: - * https://www.redhat.com/archives/libvir-list/2008-July/msg00429.html - */ - int dummy; - } caps; - } source; - virDomainDeviceInfo info; /* Guest address */ - virDomainHostdevOrigStates origstates; -}; - enum virDomainRedirdevBus { VIR_DOMAIN_REDIRDEV_BUS_USB, diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 2d970d6..e384df2 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -282,7 +282,7 @@ int qemuSetupCgroup(struct qemud_driver *driver, virDomainHostdevDefPtr hostdev = vm->def->hostdevs[i]; usbDevice *usb; - if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + if (hostdev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) continue; if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) continue; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index fd170bf..54ccce1 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -1385,7 +1385,7 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs) for (i = 0; i < def->nhostdevs ; i++) { if (def->hostdevs[i]->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) continue; - if (def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + if (def->hostdevs[i]->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || def->hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; @@ -5548,7 +5548,7 @@ qemuBuildCommandLine(virConnectPtr conn, char *devstr; if (hostdev->info.bootIndex) { - if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + if (hostdev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("booting from assigned devices is only" @@ -5563,7 +5563,7 @@ qemuBuildCommandLine(virConnectPtr conn, } /* USB */ - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + if (hostdev->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { @@ -5582,7 +5582,7 @@ qemuBuildCommandLine(virConnectPtr conn, } /* PCI */ - if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + if (hostdev->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { if (qemuCapsGet(qemuCaps, QEMU_CAPS_DEVICE)) { char *configfd_name = NULL; @@ -6538,8 +6538,8 @@ qemuParseCommandLinePCI(const char *val) goto cleanup; } - def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; - def->managed = 1; + def->source.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; + def->source.managed = true; def->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI; def->source.subsys.u.pci.bus = bus; def->source.subsys.u.pci.slot = slot; @@ -6604,8 +6604,8 @@ qemuParseCommandLineUSB(const char *val) goto cleanup; } - def->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; - def->managed = 0; + def->source.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; + def->source.managed = false; def->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB; if (*end == '.') { def->source.subsys.u.usb.bus = first; diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c index b3cad8e..99fd4bc 100644 --- a/src/qemu/qemu_hostdev.c +++ b/src/qemu/qemu_hostdev.c @@ -43,7 +43,7 @@ qemuGetPciHostDeviceList(virDomainHostdevDefPtr *hostdevs, int nhostdevs) virDomainHostdevDefPtr hostdev = hostdevs[i]; pciDevice *dev; - if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + if (hostdev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) continue; if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; @@ -63,7 +63,7 @@ qemuGetPciHostDeviceList(virDomainHostdevDefPtr *hostdevs, int nhostdevs) return NULL; } - pciDeviceSetManaged(dev, hostdev->managed); + pciDeviceSetManaged(dev, hostdev->source.managed); } return list; @@ -85,7 +85,7 @@ qemuGetActivePciHostDeviceList(struct qemud_driver *driver, pciDevice *dev; pciDevice *activeDev; - if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + if (hostdev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) continue; if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; @@ -126,7 +126,7 @@ int qemuUpdateActivePciHostdevs(struct qemud_driver *driver, pciDevice *dev = NULL; hostdev = def->hostdevs[i]; - if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + if (hostdev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) continue; if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; @@ -139,13 +139,13 @@ int qemuUpdateActivePciHostdevs(struct qemud_driver *driver, if (!dev) return -1; - pciDeviceSetManaged(dev, hostdev->managed); + pciDeviceSetManaged(dev, hostdev->source.managed); pciDeviceSetUsedBy(dev, def->name); /* Setup the original states for the PCI device */ - pciDeviceSetUnbindFromStub(dev, hostdev->origstates.states.pci.unbind_from_stub); - pciDeviceSetRemoveSlot(dev, hostdev->origstates.states.pci.remove_slot); - pciDeviceSetReprobe(dev, hostdev->origstates.states.pci.reprobe); + pciDeviceSetUnbindFromStub(dev, hostdev->source.origstates.states.pci.unbind_from_stub); + pciDeviceSetRemoveSlot(dev, hostdev->source.origstates.states.pci.remove_slot); + pciDeviceSetReprobe(dev, hostdev->source.origstates.states.pci.reprobe); if (pciDeviceListAdd(driver->activePciHostdevs, dev) < 0) { pciFreeDevice(dev); @@ -258,7 +258,7 @@ int qemuPrepareHostdevPCIDevices(struct qemud_driver *driver, pciDevice *pcidev; virDomainHostdevDefPtr hostdev = hostdevs[i]; - if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + if (hostdev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) continue; if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; @@ -273,11 +273,11 @@ int qemuPrepareHostdevPCIDevices(struct qemud_driver *driver, * loop 2. */ if ((pcidev = pciDeviceListFind(pcidevs, dev))) { - hostdev->origstates.states.pci.unbind_from_stub = + hostdev->source.origstates.states.pci.unbind_from_stub = pciDeviceGetUnbindFromStub(pcidev); - hostdev->origstates.states.pci.remove_slot = + hostdev->source.origstates.states.pci.remove_slot = pciDeviceGetRemoveSlot(pcidev); - hostdev->origstates.states.pci.reprobe = + hostdev->source.origstates.states.pci.reprobe = pciDeviceGetReprobe(pcidev); } @@ -346,7 +346,7 @@ qemuPrepareHostdevUSBDevices(struct qemud_driver *driver, for (i = 0 ; i < nhostdevs ; i++) { virDomainHostdevDefPtr hostdev = hostdevs[i]; - if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + if (hostdev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) continue; if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) continue; diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index 4b60839..9eb4ee1 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -1089,10 +1089,10 @@ int qemuDomainAttachHostDevice(struct qemud_driver *driver, virDomainObjPtr vm, virDomainHostdevDefPtr hostdev) { - if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { + if (hostdev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("hostdev mode '%s' not supported"), - virDomainHostdevModeTypeToString(hostdev->mode)); + virDomainHostdevModeTypeToString(hostdev->source.mode)); return -1; } @@ -1970,7 +1970,7 @@ qemuDomainDetachHostPciDevice(struct qemud_driver *driver, pciDevice *activePci; for (i = 0 ; i < vm->def->nhostdevs ; i++) { - if (vm->def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + if (vm->def->hostdevs[i]->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || vm->def->hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) continue; @@ -2078,7 +2078,7 @@ qemuDomainDetachHostUsbDevice(struct qemud_driver *driver, int i, ret; for (i = 0 ; i < vm->def->nhostdevs ; i++) { - if (vm->def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + if (vm->def->hostdevs[i]->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || vm->def->hostdevs[i]->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) continue; @@ -2170,10 +2170,10 @@ int qemuDomainDetachHostDevice(struct qemud_driver *driver, virDomainHostdevDefPtr detach = NULL; int ret; - if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { + if (hostdev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, _("hostdev mode '%s' not supported"), - virDomainHostdevModeTypeToString(hostdev->mode)); + virDomainHostdevModeTypeToString(hostdev->source.mode)); return -1; } diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c index 8f8b200..4a76920 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -698,7 +698,7 @@ AppArmorSetSecurityHostdevLabel(virSecurityManagerPtr mgr, if (secdef->norelabel) return 0; - if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + if (dev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) return 0; if (profile_loaded(secdef->imagelabel) < 0) diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 2fb4a14..fbee0ff 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -283,7 +283,7 @@ virSecurityDACSetSecurityHostdevLabel(virSecurityManagerPtr mgr, if (!priv->dynamicOwnership) return 0; - if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + if (dev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) return 0; switch (dev->source.subsys.type) { @@ -354,7 +354,7 @@ virSecurityDACRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr, if (!priv->dynamicOwnership) return 0; - if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + if (dev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) return 0; switch (dev->source.subsys.type) { diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c index c2dceca..252bde5 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -710,7 +710,7 @@ SELinuxSetSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, if (secdef->norelabel) return 0; - if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + if (dev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) return 0; switch (dev->source.subsys.type) { @@ -779,7 +779,7 @@ SELinuxRestoreSecurityHostdevLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED, if (secdef->norelabel) return 0; - if (dev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) + if (dev->source.mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) return 0; switch (dev->source.subsys.type) { diff --git a/src/util/pci.c b/src/util/pci.c index 633dcd8..c413669 100644 --- a/src/util/pci.c +++ b/src/util/pci.c @@ -1428,12 +1428,12 @@ pciDeviceGetName(pciDevice *dev) return dev->name; } -void pciDeviceSetManaged(pciDevice *dev, unsigned managed) +void pciDeviceSetManaged(pciDevice *dev, bool managed) { dev->managed = !!managed; } -unsigned pciDeviceGetManaged(pciDevice *dev) +bool pciDeviceGetManaged(pciDevice *dev) { return dev->managed; } diff --git a/src/util/pci.h b/src/util/pci.h index 25b5b66..2183b06 100644 --- a/src/util/pci.h +++ b/src/util/pci.h @@ -50,8 +50,8 @@ int pciResetDevice (pciDevice *dev, pciDeviceList *activeDevs, pciDeviceList *inactiveDevs); void pciDeviceSetManaged(pciDevice *dev, - unsigned managed); -unsigned pciDeviceGetManaged(pciDevice *dev); + bool managed); +bool pciDeviceGetManaged(pciDevice *dev); void pciDeviceSetUsedBy(pciDevice *dev, const char *used_by); const char *pciDeviceGetUsedBy(pciDevice *dev); diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c index d720432..22136f7 100644 --- a/src/vbox/vbox_tmpl.c +++ b/src/vbox/vbox_tmpl.c @@ -3345,7 +3345,7 @@ sharedFoldersCleanup: unsigned productId = 0; char *endptr = NULL; - def->hostdevs[USBFilterCount]->mode = + def->hostdevs[USBFilterCount]->source.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; def->hostdevs[USBFilterCount]->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB; @@ -4874,7 +4874,7 @@ vboxAttachUSB(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine) * usual */ for (i = 0; i < def->nhostdevs; i++) { - if (def->hostdevs[i]->mode == + if (def->hostdevs[i]->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { if (def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { @@ -4900,7 +4900,7 @@ vboxAttachUSB(virDomainDefPtr def, vboxGlobalData *data, IMachine *machine) USBController->vtbl->SetEnabledEhci(USBController, 1); for (i = 0; i < def->nhostdevs; i++) { - if (def->hostdevs[i]->mode == + if (def->hostdevs[i]->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { if (def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { @@ -5483,7 +5483,7 @@ static int vboxDomainAttachDeviceImpl(virDomainPtr dom, #endif /* VBOX_API_VERSION >= 3001 */ } else if (dev->type == VIR_DOMAIN_DEVICE_NET) { } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { - if (dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { + if (dev->data.hostdev->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { if (dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { } } @@ -5669,7 +5669,7 @@ static int vboxDomainDetachDevice(virDomainPtr dom, const char *xml) { #endif /* VBOX_API_VERSION >= 3001 */ } else if (dev->type == VIR_DOMAIN_DEVICE_NET) { } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { - if (dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { + if (dev->data.hostdev->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) { if (dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_USB) { } } diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c index 1d8e035..e0aff1e 100644 --- a/src/xen/xend_internal.c +++ b/src/xen/xend_internal.c @@ -2722,7 +2722,7 @@ xenDaemonAttachDeviceFlags(virDomainPtr domain, const char *xml, break; case VIR_DOMAIN_DEVICE_HOSTDEV: - if (dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + if (dev->data.hostdev->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { if (xenFormatSxprOnePCI(dev->data.hostdev, &buf, 0) < 0) goto cleanup; @@ -2972,7 +2972,7 @@ xenDaemonDetachDeviceFlags(virDomainPtr domain, const char *xml, goto cleanup; if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV) { - if (dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + if (dev->data.hostdev->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { if (xenFormatSxprOnePCI(dev->data.hostdev, &buf, 1) < 0) goto cleanup; @@ -3969,7 +3969,7 @@ virDomainXMLDevID(virDomainPtr domain, if (tmp == NULL) return -1; } else if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV && - dev->data.hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + dev->data.hostdev->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && dev->data.hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { char *bdf; virDomainHostdevDefPtr def = dev->data.hostdev; diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c index 04ba5aa..5101915 100644 --- a/src/xenxs/xen_sxpr.c +++ b/src/xenxs/xen_sxpr.c @@ -1016,8 +1016,8 @@ xenParseSxprPCI(virDomainDefPtr def, if (VIR_ALLOC(dev) < 0) goto no_memory; - dev->mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; - dev->managed = 0; + dev->source.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS; + dev->source.managed = false; dev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI; dev->source.subsys.u.pci.domain = domainID; dev->source.subsys.u.pci.bus = busID; @@ -1909,7 +1909,7 @@ xenFormatSxprOnePCI(virDomainHostdevDefPtr def, virBufferPtr buf, int detach) { - if (def->managed) { + if (def->source.managed) { XENXS_ERROR(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("managed PCI devices not supported with XenD")); return -1; @@ -1934,7 +1934,7 @@ xenFormatSxprAllPCI(virDomainDefPtr def, int i; for (i = 0 ; i < def->nhostdevs ; i++) - if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + if (def->hostdevs[i]->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) hasPCI = 1; @@ -1957,9 +1957,9 @@ xenFormatSxprAllPCI(virDomainDefPtr def, virBufferAddLit(buf, "(device (pci "); for (i = 0 ; i < def->nhostdevs ; i++) { - if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + if (def->hostdevs[i]->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { - if (def->hostdevs[i]->managed) { + if (def->hostdevs[i]->source.managed) { XENXS_ERROR(VIR_ERR_CONFIG_UNSUPPORTED, "%s", _("managed PCI devices not supported with XenD")); return -1; diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c index 0aa04f3..d2dbb51 100644 --- a/src/xenxs/xen_xm.c +++ b/src/xenxs/xen_xm.c @@ -818,7 +818,7 @@ xenParseXM(virConfPtr conf, int xendConfigVersion, if (VIR_ALLOC(hostdev) < 0) goto no_memory; - hostdev->managed = 0; + hostdev->source.managed = false; hostdev->source.subsys.type = VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI; hostdev->source.subsys.u.pci.domain = domainID; hostdev->source.subsys.u.pci.bus = busID; @@ -1379,7 +1379,7 @@ xenFormatXMPCI(virConfPtr conf, int i; for (i = 0 ; i < def->nhostdevs ; i++) - if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + if (def->hostdevs[i]->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) hasPCI = 1; @@ -1395,7 +1395,7 @@ xenFormatXMPCI(virConfPtr conf, pciVal->list = NULL; for (i = 0 ; i < def->nhostdevs ; i++) { - if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + if (def->hostdevs[i]->source.mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && def->hostdevs[i]->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) { virConfValuePtr val, tmp; char *buf; -- 1.7.7.5
participants (2)
-
Eric Blake
-
Laine Stump