This patch adds the ability to configure non-contiguous boot orders on boot devices. This allows unplugging devices that have boot order specified without breaking migration. The new code now uses a slightly less memory efficient approach to store the boot order fields in a hashtable instead of a bitmap. --- src/conf/domain_conf.c | 66 ++++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 34 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index cc26f21..80a90e1 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2876,7 +2876,7 @@ cleanup: static int virDomainDeviceBootParseXML(xmlNodePtr node, int *bootIndex, - virBitmapPtr bootMap) + virHashTablePtr bootHash) { char *order; int boot; @@ -2895,18 +2895,19 @@ virDomainDeviceBootParseXML(xmlNodePtr node, goto cleanup; } - if (bootMap) { - bool set; - if (virBitmapGetBit(bootMap, boot - 1, &set) < 0) { - virReportError(VIR_ERR_INTERNAL_ERROR, "%s", - _("boot orders have to be contiguous and starting from 1")); + if (bootHash) { + if (virHashLookup(bootHash, order)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("boot order '%s' used for more than one device"), + order); goto cleanup; - } else if (set) { - virReportError(VIR_ERR_INTERNAL_ERROR, - _("boot order %d used for more than one device"), boot); + } + + if (virHashAddEntry(bootHash, order, (void *) 1) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Failed to add element to boot order hash")); goto cleanup; } - ignore_value(virBitmapSetBit(bootMap, boot - 1)); } *bootIndex = boot; @@ -2922,7 +2923,7 @@ cleanup: */ static int virDomainDeviceInfoParseXML(xmlNodePtr node, - virBitmapPtr bootMap, + virHashTablePtr bootHash, virDomainDeviceInfoPtr info, unsigned int flags) { @@ -2973,7 +2974,7 @@ virDomainDeviceInfoParseXML(xmlNodePtr node, } if (boot) { - if (virDomainDeviceBootParseXML(boot, &info->bootIndex, bootMap)) + if (virDomainDeviceBootParseXML(boot, &info->bootIndex, bootHash)) goto cleanup; } @@ -3945,7 +3946,7 @@ static virDomainDiskDefPtr virDomainDiskDefParseXML(virCapsPtr caps, xmlNodePtr node, xmlXPathContextPtr ctxt, - virBitmapPtr bootMap, + virHashTablePtr bootHash, virSecurityLabelDefPtr* vmSeclabels, int nvmSeclabels, unsigned int flags) @@ -4660,7 +4661,7 @@ virDomainDiskDefParseXML(virCapsPtr caps, } def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; } else { - if (virDomainDeviceInfoParseXML(node, bootMap, &def->info, + if (virDomainDeviceInfoParseXML(node, bootHash, &def->info, flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) < 0) goto error; } @@ -5318,7 +5319,7 @@ static virDomainNetDefPtr virDomainNetDefParseXML(virCapsPtr caps, xmlNodePtr node, xmlXPathContextPtr ctxt, - virBitmapPtr bootMap, + virHashTablePtr bootHash, unsigned int flags) { virDomainNetDefPtr def; @@ -5513,7 +5514,7 @@ virDomainNetDefParseXML(virCapsPtr caps, } def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI; } else { - if (virDomainDeviceInfoParseXML(node, bootMap, &def->info, + if (virDomainDeviceInfoParseXML(node, bootHash, &def->info, flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT | VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) < 0) goto error; @@ -7988,7 +7989,7 @@ error: static virDomainHostdevDefPtr virDomainHostdevDefParseXML(const xmlNodePtr node, xmlXPathContextPtr ctxt, - virBitmapPtr bootMap, + virHashTablePtr bootHash, unsigned int flags) { virDomainHostdevDefPtr def; @@ -8029,7 +8030,7 @@ virDomainHostdevDefParseXML(const xmlNodePtr node, } if (def->info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE) { - if (virDomainDeviceInfoParseXML(node, bootMap, def->info, + if (virDomainDeviceInfoParseXML(node, bootHash, def->info, flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT | VIR_DOMAIN_XML_INTERNAL_ALLOW_ROM) < 0) goto error; @@ -8063,7 +8064,7 @@ error: static virDomainRedirdevDefPtr virDomainRedirdevDefParseXML(const xmlNodePtr node, - virBitmapPtr bootMap, + virHashTablePtr bootHash, unsigned int flags) { xmlNodePtr cur; @@ -8113,7 +8114,7 @@ virDomainRedirdevDefParseXML(const xmlNodePtr node, def->source.chr.data.spicevmc = VIR_DOMAIN_CHR_SPICEVMC_USBREDIR; } - if (virDomainDeviceInfoParseXML(node, bootMap, &def->info, + if (virDomainDeviceInfoParseXML(node, bootHash, &def->info, flags | VIR_DOMAIN_XML_INTERNAL_ALLOW_BOOT) < 0) goto error; @@ -9098,8 +9099,7 @@ static char *virDomainDefDefaultEmulator(virDomainDefPtr def, static int virDomainDefParseBootXML(xmlXPathContextPtr ctxt, - virDomainDefPtr def, - unsigned long *bootCount) + virDomainDefPtr def) { xmlNodePtr *nodes = NULL; int i, n; @@ -9196,7 +9196,6 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt, def->os.bios.rt_set = true; } - *bootCount = deviceBoot; ret = 0; cleanup: @@ -9394,8 +9393,7 @@ virDomainDefParseXML(virCapsPtr caps, virDomainDefPtr def; unsigned long count; bool uuid_generated = false; - virBitmapPtr bootMap = NULL; - unsigned long bootMapSize = 0; + virHashTablePtr bootHash = NULL; xmlNodePtr cur; bool usb_none = false; bool usb_other = false; @@ -10289,10 +10287,10 @@ virDomainDefParseXML(virCapsPtr caps, } if (STREQ(def->os.type, "hvm")) { - if (virDomainDefParseBootXML(ctxt, def, &bootMapSize) < 0) + if (virDomainDefParseBootXML(ctxt, def) < 0) + goto error; + if (!(bootHash = virHashCreate(5, NULL))) goto error; - if (bootMapSize && !(bootMap = virBitmapNew(bootMapSize))) - goto no_memory; } def->emulator = virXPathString("string(./devices/emulator[1])", ctxt); @@ -10313,7 +10311,7 @@ virDomainDefParseXML(virCapsPtr caps, virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps, nodes[i], ctxt, - bootMap, + bootHash, def->seclabels, def->nseclabels, flags); @@ -10413,7 +10411,7 @@ virDomainDefParseXML(virCapsPtr caps, virDomainNetDefPtr net = virDomainNetDefParseXML(caps, nodes[i], ctxt, - bootMap, + bootHash, flags); if (!net) goto error; @@ -10796,7 +10794,7 @@ virDomainDefParseXML(virCapsPtr caps, for (i = 0 ; i < n ; i++) { virDomainHostdevDefPtr hostdev; - hostdev = virDomainHostdevDefParseXML(nodes[i], ctxt, bootMap, flags); + hostdev = virDomainHostdevDefParseXML(nodes[i], ctxt, bootHash, flags); if (!hostdev) goto error; @@ -10912,7 +10910,7 @@ virDomainDefParseXML(virCapsPtr caps, goto no_memory; for (i = 0 ; i < n ; i++) { virDomainRedirdevDefPtr redirdev = virDomainRedirdevDefParseXML(nodes[i], - bootMap, + bootHash, flags); if (!redirdev) goto error; @@ -11029,7 +11027,7 @@ virDomainDefParseXML(virCapsPtr caps, if (virDomainDefAddImplicitControllers(def) < 0) goto error; - virBitmapFree(bootMap); + virHashFree(bootHash); return def; @@ -11038,7 +11036,7 @@ no_memory: error: VIR_FREE(tmp); VIR_FREE(nodes); - virBitmapFree(bootMap); + virHashFree(bootHash); virDomainDefFree(def); return NULL; } -- 1.8.1.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list