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
Signed-off-by: Matthias Gatto
---
src/conf/domain_conf.c | 165 +++--
1 file changed, 120 insertions(+), 45 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 1add21f..9164cf3 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5469,20 +5469,58 @@ virDomainDiskSourceParse(xmlNodePtr node,
}
+static bool
+virDomainDiskThresholdParse(virStorageSourcePtr src,
+xmlNodePtr node)
+{
+char *threshold = virXMLPropString(node, "threshold");
+int ret;
+
+if (!threshold) {
+virReportError(VIR_ERR_XML_ERROR,
+ "%s", _("missing threshold in quorum"));
+return false;
+}
+ret = virStrToLong_ul(threshold, NULL, 10, &src->threshold);
+if (ret < 0 || src->threshold < 2) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unexpected threshold %s"),
+ "threshold must be a decimal number superior to 2 "
+ "and inferior to the number of children");
+VIR_FREE(threshold);
+return false;
+}
+VIR_FREE(threshold);
+return true;
+}
+
+
static int
virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt,
- virStorageSourcePtr src)
+ virStorageSourcePtr src,
+ xmlNodePtr node,
+ size_t pos)
{
virStorageSourcePtr backingStore = NULL;
xmlNodePtr save_ctxt = ctxt->node;
-xmlNodePtr source;
+xmlNodePtr source = NULL;
+xmlNodePtr cur = NULL;
char *type = NULL;
char *format = NULL;
int ret = -1;
+size_t i = 0;
-if (!(ctxt->node = virXPathNode("./backingStore[*]", ctxt))) {
-ret = 0;
-goto cleanup;
+if (src->type == VIR_STORAGE_TYPE_QUORUM) {
+if (!node) {
+ret = 0;
+goto cleanup;
+}
+ctxt->node = node;
+} else {
+if (!(ctxt->node = virXPathNode("./backingStore[*]", ctxt))) {
+ret = 0;
+goto cleanup;
+}
}
if (VIR_ALLOC(backingStore) < 0)
@@ -5514,6 +5552,22 @@ virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt,
goto cleanup;
}
+if (backingStore->type == VIR_STORAGE_TYPE_QUORUM) {
+if (!virDomainDiskThresholdParse(backingStore, node))
+goto cleanup;
+
+for (cur = node->children, i = 0; cur != NULL; cur = cur->next) {
+if (xmlStrEqual(cur->name, BAD_CAST "backingStore")) {
+if (virStorageSourcePushBackingStore(backingStore) == false)
+goto cleanup;
+if ((virDomainDiskBackingStoreParse(ctxt, backingStore, cur,
i) < 0))
+goto cleanup;
+++i;
+}
+}
+goto exit;
+}
+
if (!(source = virXPathNode("./source", ctxt))) {
virReportError(VIR_ERR_XML_ERROR, "%s",
_("missing disk backing store source"));
@@ -5521,10 +5575,11 @@ virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt,
}
if (virDomainDiskSourceParse(source, ctxt, backingStore) < 0 ||
-virDomainDiskBackingStoreParse(ctxt, backingStore) < 0)
+virDomainDiskBackingStoreParse(ctxt, backingStore, NULL, 0) < 0)
goto cleanup;
-virStorageSourceSetBackingStore(src, backingStore, 0);
+ exit:
+virStorageSourceSetBackingStore(src, backingStore, pos);
ret = 0;
cleanup:
@@ -5536,7 +5591,6 @@ virDomainDiskBackingStoreParse(xmlXPathContextPtr ctxt,
return ret;
}
-
#define VENDOR_LEN 8
#define PRODUCT_LEN 16
@@ -6030,6 +6084,12 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
}
} else if (xmlStrEqual(cur->name, BAD_CAST "boot")) {
/* boot is parsed as part of virDomainDeviceInfoParseXML */
+} else if (xmlStrEqual(cur->name, BAD_CAST "backingStore")) {
+if (virStorageSourcePushBackingStore(def->src) == false)
+goto error;
+if (virDomainDiskBackingStoreParse(ctxt, def->src, cur,
+ def->src->nBackingStores -
1) < 0)
+goto error;
}
}
cur = cur->next;
@@ -6053,12 +6113,19 @@ virDomainDiskDefParseXML(virDomainXMLOptionPtr xmlopt,
def->device = VIR_DOMAIN_DISK_DEVICE_DISK;
}
+if (def->src->type == VIR_STORAGE_TYPE_QUORUM &&
+!virDomainDiskThresholdParse(def->src, node))
+goto error;
+
+snapshot = virXMLPropString(node, "snapshot");
+
/* Only CDROM and Floppy devices are allowed missing source path
* to indicate no media present. LUN is for raw