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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list