[libvirt] [PATCH v7 08/13] domain_conf: Read and Write quorum config

Matthias Gatto matthias.gatto at outscale.com
Thu Dec 3 14:35:18 UTC 2015


Add the capabiltty to libvirt to parse and format the quorum syntax
as described here:
http://www.redhat.com/archives/libvir-list/2014-May/msg00533.html

We need a different unique index for each backing store
to manipulate individually each child of a quorum.

If a disk have 2 childs A and B, the index will be 1 for A and 2 for B,
but if A have 2 childs C and D, so A will have the index 1, C and D: 2 and 3
and B will be 4.

Here is a representation of our disk tree and they indexs:

         C[2]
        /
    A[1]
   /    \D[3]
HDA
   \
    B[4]

Signed-off-by: Matthias Gatto <matthias.gatto at outscale.com>
---
 src/conf/domain_conf.c | 157 +++++++++++++++++++++++++++++++++----------------
 1 file changed, 106 insertions(+), 51 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index e2a1870..5178e57 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -6306,17 +6306,45 @@ virDomainDiskSourceParse(xmlNodePtr node,
 
 
 static int
+virDomainDiskThresholdParse(virStorageSourcePtr src,
+                            xmlXPathContextPtr ctxt)
+{
+    char *threshold = virXPathString("string(./@threshold)", ctxt);
+    int ret;
+
+    if (!threshold)
+        return 0;
+    ret = virStrToLong_ul(threshold, NULL, 10, &src->threshold);
+    if (ret < 0 || src->threshold < 2) {
+        virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                       _("threshold must be a decimal number greater than 2 "
+                         "and less than the number of children"));
+        VIR_FREE(threshold);
+        return -1;
+    }
+    VIR_FREE(threshold);
+    return 0;
+}
+
+#define VIR_DOMAIN_DISK_BACKING_STORE_PARSE_RECALL 1
+
+static int
 virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt,
-                               virStorageSourcePtr src)
+                               virStorageSourcePtr src,
+                               size_t pos)
 {
     virStorageSourcePtr backingStore = NULL;
     xmlNodePtr save_ctxt = ctxt->node;
     xmlNodePtr source;
     char *type = NULL;
     char *format = NULL;
+    char *path;
     int ret = -1;
 
-    if (!(ctxt->node = virXPathNode("./backingStore[*]", ctxt))) {
+    if (virAsprintf(&path, "./backingStore[%lu][*]", pos + 1) < 0)
+        return -1;
+
+    if (!(ctxt->node = virXPathNode(path, ctxt))) {
         ret = 0;
         goto cleanup;
     }
@@ -6350,29 +6378,35 @@ virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt,
         goto cleanup;
     }
 
-    if (!(source = virXPathNode("./source", ctxt))) {
-        virReportError(VIR_ERR_XML_ERROR, "%s",
-                       _("missing disk backing store source"));
+    source = virXPathNode("./source", ctxt);
+
+    if (source && virDomainDiskSourceParse(source, ctxt, backingStore) < 0)
         goto cleanup;
-    }
 
-    if (virDomainDiskSourceParse(source, ctxt, backingStore) < 0 ||
-        virDomainDiskBackingStoreParse(ctxt, backingStore) < 0)
+    if (virDomainDiskBackingStoreParse(ctxt, backingStore, 0) < 0)
         goto cleanup;
 
-    if (virStorageSourceSetBackingStore(src, backingStore, 0) < 0)
+    if (virDomainDiskThresholdParse(backingStore, ctxt) < 0)
         goto cleanup;
-    ret = 0;
+
+    if (virStorageSourceSetBackingStore(src, backingStore, pos) < 0)
+        goto cleanup;
+
+    ret = VIR_DOMAIN_DISK_BACKING_STORE_PARSE_RECALL;
 
  cleanup:
     if (ret < 0)
         virStorageSourceFree(backingStore);
+    VIR_FREE(path);
     VIR_FREE(type);
     VIR_FREE(format);
     ctxt->node = save_ctxt;
-    return ret;
+    if (ret != VIR_DOMAIN_DISK_BACKING_STORE_PARSE_RECALL)
+        return ret;
+    return virDomainDiskBackingStoreParse(ctxt, src, pos + 1);
 }
 
+#undef VIR_DOMAIN_DISK_BACKING_STORE_PARSE_RECALL
 
 #define VENDOR_LEN  8
 #define PRODUCT_LEN 16
@@ -6902,12 +6936,16 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
         def->device = VIR_DOMAIN_DISK_DEVICE_DISK;
     }
 
+    if (virDomainDiskThresholdParse(def->src, ctxt) < 0)
+        goto error;
+
     /* Only CDROM and Floppy devices are allowed missing source path
      * to indicate no media present. LUN is for raw access CD-ROMs
      * that are not attached to a physical device presently */
     if (virStorageSourceIsEmpty(def->src) &&
         (def->device == VIR_DOMAIN_DISK_DEVICE_DISK ||
-         (flags & VIR_DOMAIN_DEF_PARSE_DISK_SOURCE))) {
+         (flags & VIR_DOMAIN_DEF_PARSE_DISK_SOURCE)) &&
+        !(virStorageSourceIsRAID(def->src))) {
         virReportError(VIR_ERR_NO_SOURCE,
                        target ? "%s" : NULL, target);
         goto error;
@@ -7250,10 +7288,8 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
         }
     }
 
-    if (!(flags & VIR_DOMAIN_DEF_PARSE_DISK_SOURCE)) {
-        if (virDomainDiskBackingStoreParse(ctxt, def->src) < 0)
-            goto error;
-    }
+    if (virDomainDiskBackingStoreParse(ctxt, def->src, 0) < 0)
+        goto error;
 
  cleanup:
     VIR_FREE(bus);
@@ -18591,12 +18627,14 @@ virDomainDiskSourceFormat(virBufferPtr buf,
 
 static int
 virDomainDiskBackingStoreFormat(virBufferPtr buf,
-                                virStorageSourcePtr backingStore,
-                                const char *backingStoreRaw,
-                                unsigned int idx)
+                                virStorageSourcePtr src,
+                                unsigned int *idx)
 {
+    const char *backingStoreRaw = src->backingStoreRaw;
+    virStorageSourcePtr backingStore = virStorageSourceGetBackingStore(src, 0);
     const char *type;
     const char *format;
+    size_t i;
 
     if (!backingStore) {
         if (!backingStoreRaw)
@@ -18604,37 +18642,48 @@ virDomainDiskBackingStoreFormat(virBufferPtr buf,
         return 0;
     }
 
-    if (!backingStore->type ||
-        !(type = virStorageTypeToString(backingStore->type))) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("unexpected disk backing store type %d"),
-                       backingStore->type);
-        return -1;
-    }
+    for (i = 0; i < src->nBackingStores; ++i) {
+        backingStore = virStorageSourceGetBackingStore(src, i);
 
-    if (backingStore->format <= 0 ||
-        !(format = virStorageFileFormatTypeToString(backingStore->format))) {
-        virReportError(VIR_ERR_INTERNAL_ERROR,
-                       _("unexpected disk backing store format %d"),
-                       backingStore->format);
-        return -1;
-    }
+        if (!backingStore) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("expected disk backing store"));
+            return -1;
+        }
 
-    virBufferAsprintf(buf, "<backingStore type='%s' index='%u'>\n",
-                      type, idx);
-    virBufferAdjustIndent(buf, 2);
+        if (!backingStore->type ||
+            !(type = virStorageTypeToString(backingStore->type))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("unexpected disk backing store type %d"),
+                           backingStore->type);
+            return -1;
+        }
 
-    virBufferAsprintf(buf, "<format type='%s'/>\n", format);
-    /* We currently don't output seclabels for backing chain element */
-    if (virDomainDiskSourceFormatInternal(buf, backingStore, 0, 0, true) < 0 ||
-        virDomainDiskBackingStoreFormat(buf,
-                                        virStorageSourceGetBackingStore(backingStore, 0),
-                                        backingStore->backingStoreRaw,
-                                        idx + 1) < 0)
-        return -1;
+        if (backingStore->format <= 0 ||
+            !(format = virStorageFileFormatTypeToString(backingStore->format))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR,
+                           _("unexpected disk backing store format %d"),
+                           backingStore->format);
+            return -1;
+        }
 
-    virBufferAdjustIndent(buf, -2);
-    virBufferAddLit(buf, "</backingStore>\n");
+        *idx += 1;
+        virBufferAsprintf(buf, "<backingStore type='%s' index='%u'",
+                          type, *idx);
+        if (backingStore->threshold)
+            virBufferAsprintf(buf, " threshold='%lu'", backingStore->threshold);
+        virBufferAddLit(buf, ">\n");
+        virBufferAdjustIndent(buf, 2);
+
+        virBufferAsprintf(buf, "<format type='%s'/>\n", format);
+        /* We currently don't output seclabels for backing chain element */
+        if (virDomainDiskSourceFormatInternal(buf, backingStore, 0, 0, true) < 0 ||
+            virDomainDiskBackingStoreFormat(buf, backingStore, idx) < 0)
+            return -1;
+
+        virBufferAdjustIndent(buf, -2);
+        virBufferAddLit(buf, "</backingStore>\n");
+    }
     return 0;
 }
 
@@ -18704,6 +18753,10 @@ virDomainDiskDefFormat(virBufferPtr buf,
           def->src->readonly))
         virBufferAsprintf(buf, " snapshot='%s'",
                           virDomainSnapshotLocationTypeToString(def->snapshot));
+    if (def->src->threshold) {
+        virBufferAsprintf(buf, " threshold='%lu'",
+                          def->src->threshold);
+    }
     virBufferAddLit(buf, ">\n");
     virBufferAdjustIndent(buf, 2);
 
@@ -18748,11 +18801,13 @@ virDomainDiskDefFormat(virBufferPtr buf,
 
     /* Don't format backingStore to inactive XMLs until the code for
      * persistent storage of backing chains is ready. */
-    if (!(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE) &&
-        virDomainDiskBackingStoreFormat(buf,
-                                        virStorageSourceGetBackingStore(def->src, 0),
-                                        def->src->backingStoreRaw, 1) < 0)
-        return -1;
+    if (!(flags & VIR_DOMAIN_DEF_FORMAT_INACTIVE) ||
+        virStorageSourceIsRAID(def->src)) {
+        unsigned int idx = 0;
+
+        if (virDomainDiskBackingStoreFormat(buf, def->src, &idx) < 0)
+            return -1;
+    }
 
     virBufferEscapeString(buf, "<backenddomain name='%s'/>\n", def->domain_name);
 
-- 
2.6.2




More information about the libvir-list mailing list