Allow libvirt to build the quorum string used by quemu.
Add 2 static functions: qemuBuildRAIDStr and
qemuBuildRAIDFileSourceStr.
qemuBuildRAIDStr is made because a quorum can have another quorum
as a child, so we may need to call qemuBuildRAIDStr recursively.
qemuBuildRAIDFileSourceStr was basically made to share
the code use to build the source between qemuBuildRAIDStr and
qemuBuildDriveStr, but there is some difference betwin the syntax
use by libvirt to declare a disk and the one qemu need to build a quorum:
a quorum need a syntaxe like:
"domaine_name.children.X.file.filename=filename"
where libvirt don't use "file.filename=" but directly "file=".
Therfore I use this function only for quorum.
Signed-off-by: Matthias Gatto <matthias.gatto(a)outscale.com>
---
src/qemu/qemu_command.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 50cf8cc..4ca0011 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3612,6 +3612,93 @@ qemuCheckDiskConfig(virDomainDiskDefPtr disk)
return -1;
}
+static bool
+qemuBuildRAIDFileSourceStr(virConnectPtr conn,
+ virStorageSourcePtr src,
+ virBuffer *opt,
+ const char *toAppend)
+{
+ char *source = NULL;
+ int actualType = virStorageSourceGetActualType(src);
+
+ if (qemuGetDriveSourceString(src, conn, &source) < 0)
+ return false;
+
+ if (source) {
+ virBufferStrcat(opt, ",", toAppend, "filename=", NULL);
+
+ if (actualType == VIR_STORAGE_TYPE_DIR) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unsupported disk driver type for '%s'"),
+ virStorageFileFormatTypeToString(src->format));
+ return false;
+ }
+ virBufferAdd(opt, source, -1);
+ }
+
+ return true;
+}
+
+
+static bool
+qemuBuildRAIDStr(virConnectPtr conn,
+ virDomainDiskDefPtr disk,
+ virStorageSourcePtr src,
+ virBuffer *opt,
+ const char *toAppend)
+{
+ char *tmp = NULL;
+ int ret;
+ virStorageSourcePtr backingStore;
+ size_t i;
+
+ if (virStorageSourceGetActualType(src) == VIR_STORAGE_TYPE_QUORUM) {
+ if (!src->threshold) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("threshold missing in the quorum
configuration"));
+ return false;
+ }
+ if (src->nBackingStores < 2) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("a quorum must have at last 2 children"));
+ return false;
+ }
+ if (src->threshold > src->nBackingStores) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("threshold must not exceed the number of
children"));
+ return false;
+ }
+ virBufferAsprintf(opt, ",%svote-threshold=%lu",
+ toAppend, src->threshold);
+ }
+
+ for (i = 0; i < src->nBackingStores; ++i) {
+ backingStore = virStorageSourceGetBackingStore(src, i);
+ ret = virAsprintf(&tmp, "%schildren.%lu.file.", toAppend, i);
+ if (ret < 0)
+ return false;
+
+ virBufferAsprintf(opt, ",%schildren.%lu.driver=%s",
+ toAppend, i,
+ virStorageFileFormatTypeToString(backingStore->format));
+
+ if (qemuBuildRAIDFileSourceStr(conn, backingStore, opt, tmp) == false)
+ goto error;
+
+ /* This operation avoid us to made another copy */
+ tmp[ret - sizeof("file")] = '\0';
+ if (virStorageSourceIsRAID(backingStore)) {
+ if (!qemuBuildRAIDStr(conn, disk, backingStore, opt, tmp))
+ goto error;
+ }
+ VIR_FREE(tmp);
+ }
+ return true;
+ error:
+ VIR_FREE(tmp);
+ return false;
+}
+
/* Check whether the device address is using either 'ccw' or default s390
* address format and whether that's "legal" for the current qemu and/or
@@ -3781,6 +3868,7 @@ qemuBuildDriveStr(virConnectPtr conn,
goto error;
if (source &&
+ !virStorageSourceIsRAID(disk->src) &&
!((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
@@ -4132,6 +4220,11 @@ qemuBuildDriveStr(virConnectPtr conn,
disk->blkdeviotune.size_iops_sec);
}
+ if (virStorageSourceIsRAID(disk->src)) {
+ if (!qemuBuildRAIDStr(conn, disk, disk->src, &opt, ""))
+ goto error;
+ }
+
if (virBufferCheckError(&opt) < 0)
goto error;
--
2.6.1