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