File libvirt-conf-Allow-for-non-contiguous-device-boot-orders.patch of Package libvirt

From 7df17386ea4f00600ca7a1873b707675b3e628cf Mon Sep 17 00:00:00 2001
Message-Id: <7df17386ea4f00600ca7a1873b707675b3e628cf.1373271642.git.jdenemar@redhat.com>
From: Peter Krempa <pkrempa@redhat.com>
Date: Thu, 13 Jun 2013 11:12:25 +0200
Subject: [PATCH] conf: Allow for non-contiguous device boot orders

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

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.
(cherry picked from commit 039a3283fcde23572cd93e9e09cfbfb508e5d44b)

Conflicts:
	src/conf/domain_conf.c - domain def callback stuff not backported (context)
                           - cc244e24 not backported (missing argument)
---
 src/conf/domain_conf.c | 65 ++++++++++++++++++++++++--------------------------
 1 file changed, 31 insertions(+), 34 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ba722fe..4234541 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2529,7 +2529,7 @@ cleanup:
 static int
 virDomainDeviceBootParseXML(xmlNodePtr node,
                             int *bootIndex,
-                            virBitmapPtr bootMap)
+                            virHashTablePtr bootHash)
 {
     char *order;
     int boot;
@@ -2548,18 +2548,16 @@ 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"));
-            goto cleanup;
-        } else if (set) {
-            virReportError(VIR_ERR_INTERNAL_ERROR,
-                           _("boot order %d used for more than one device"), boot);
+    if (bootHash) {
+        if (virHashLookup(bootHash, order)) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("boot order '%s' used for more than one device"),
+                           order);
             goto cleanup;
         }
-        ignore_value(virBitmapSetBit(bootMap, boot - 1));
+
+        if (virHashAddEntry(bootHash, order, (void *) 1) < 0)
+            goto cleanup;
     }
 
     *bootIndex = boot;
@@ -2575,7 +2573,7 @@ cleanup:
  */
 static int
 virDomainDeviceInfoParseXML(xmlNodePtr node,
-                            virBitmapPtr bootMap,
+                            virHashTablePtr bootHash,
                             virDomainDeviceInfoPtr info,
                             unsigned int flags)
 {
@@ -2626,7 +2624,7 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
     }
 
     if (boot) {
-        if (virDomainDeviceBootParseXML(boot, &info->bootIndex, bootMap))
+        if (virDomainDeviceBootParseXML(boot, &info->bootIndex, bootHash))
             goto cleanup;
     }
 
@@ -3536,7 +3534,7 @@ static virDomainDiskDefPtr
 virDomainDiskDefParseXML(virCapsPtr caps,
                          xmlNodePtr node,
                          xmlXPathContextPtr ctxt,
-                         virBitmapPtr bootMap,
+                         virHashTablePtr bootHash,
                          virSecurityLabelDefPtr* vmSeclabels,
                          int nvmSeclabels,
                          unsigned int flags)
@@ -4179,7 +4177,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;
     }
@@ -4816,7 +4814,7 @@ static virDomainNetDefPtr
 virDomainNetDefParseXML(virCapsPtr caps,
                         xmlNodePtr node,
                         xmlXPathContextPtr ctxt,
-                        virBitmapPtr bootMap,
+                        virHashTablePtr bootHash,
                         unsigned int flags)
 {
     virDomainNetDefPtr def;
@@ -5010,7 +5008,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;
@@ -7337,7 +7335,7 @@ error:
 static virDomainHostdevDefPtr
 virDomainHostdevDefParseXML(const xmlNodePtr node,
                             xmlXPathContextPtr ctxt,
-                            virBitmapPtr bootMap,
+                            virHashTablePtr bootHash,
                             unsigned int flags)
 {
     virDomainHostdevDefPtr def;
@@ -7355,7 +7353,7 @@ virDomainHostdevDefParseXML(const xmlNodePtr node,
         goto error;
 
     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;
@@ -7389,6 +7387,7 @@ error:
 
 static virDomainRedirdevDefPtr
 virDomainRedirdevDefParseXML(const xmlNodePtr node,
+                             virHashTablePtr bootHash,
                              unsigned int flags)
 {
     xmlNodePtr cur;
@@ -7443,7 +7442,7 @@ virDomainRedirdevDefParseXML(const xmlNodePtr node,
         def->source.chr.data.spicevmc = VIR_DOMAIN_CHR_SPICEVMC_USBREDIR;
     }
 
-    if (virDomainDeviceInfoParseXML(node, NULL, &def->info, flags) < 0)
+    if (virDomainDeviceInfoParseXML(node, bootHash, &def->info, flags) < 0)
         goto error;
 
     if (def->bus == VIR_DOMAIN_REDIRDEV_BUS_USB &&
@@ -7788,7 +7787,7 @@ virDomainDeviceDefPtr virDomainDeviceDefParse(virCapsPtr caps,
             goto error;
     } else if (xmlStrEqual(node->name, BAD_CAST "redirdev")) {
         dev->type = VIR_DOMAIN_DEVICE_REDIRDEV;
-        if (!(dev->data.redirdev = virDomainRedirdevDefParseXML(node, flags)))
+        if (!(dev->data.redirdev = virDomainRedirdevDefParseXML(node, NULL, flags)))
             goto error;
     } else {
         virReportError(VIR_ERR_XML_ERROR,
@@ -8361,8 +8360,7 @@ static char *virDomainDefDefaultEmulator(virDomainDefPtr def,
 
 static int
 virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
-                         virDomainDefPtr def,
-                         unsigned long *bootCount)
+                         virDomainDefPtr def)
 {
     xmlNodePtr *nodes = NULL;
     int i, n;
@@ -8458,7 +8456,6 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
         def->os.bios.rt_set = true;
     }
 
-    *bootCount = deviceBoot;
     ret = 0;
 
 cleanup:
@@ -8654,8 +8651,7 @@ static virDomainDefPtr 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;
@@ -9507,10 +9503,10 @@ static virDomainDefPtr 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);
@@ -9531,7 +9527,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
         virDomainDiskDefPtr disk = virDomainDiskDefParseXML(caps,
                                                             nodes[i],
                                                             ctxt,
-                                                            bootMap,
+                                                            bootHash,
                                                             def->seclabels,
                                                             def->nseclabels,
                                                             flags);
@@ -9631,7 +9627,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
         virDomainNetDefPtr net = virDomainNetDefParseXML(caps,
                                                          nodes[i],
                                                          ctxt,
-                                                         bootMap,
+                                                         bootHash,
                                                          flags);
         if (!net)
             goto error;
@@ -10014,7 +10010,7 @@ static virDomainDefPtr 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;
 
@@ -10115,6 +10111,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
         goto no_memory;
     for (i = 0 ; i < n ; i++) {
         virDomainRedirdevDefPtr redirdev = virDomainRedirdevDefParseXML(nodes[i],
+                                                                        bootHash,
                                                                         flags);
         if (!redirdev)
             goto error;
@@ -10236,7 +10233,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
     if (virDomainDefAddImplicitControllers(def) < 0)
         goto error;
 
-    virBitmapFree(bootMap);
+    virHashFree(bootHash);
 
     return def;
 
@@ -10247,7 +10244,7 @@ no_memory:
  error:
     VIR_FREE(tmp);
     VIR_FREE(nodes);
-    virBitmapFree(bootMap);
+    virHashFree(bootHash);
     virDomainDefFree(def);
     return NULL;
 }
-- 
1.8.2.1

openSUSE Build Service is sponsored by