[libvirt] [PATCH v5 8/9] qemu: Add quorum support in qemuBuildDriveDevStr
Peter Krempa
pkrempa at redhat.com
Tue May 12 15:38:14 UTC 2015
On Thu, Apr 23, 2015 at 14:41:20 +0200, Matthias Gatto wrote:
> Allow to libvirt to build the quorum string used by quemu.
>
> Add 2 static functions: qemuBuildQuorumStr and
> qemuBuildAndAppendDriveStrToVirBuffer.
> qemuBuildQuorumStr is made because a quorum can have another quorum
> as a child, so we may need to call qemuBuildQuorumStr recursively.
>
> qemuBuildQuorumFileSourceStr was basically made to share
> the code use to build the source between qemuBuildQuorumStr 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.
>
> But as explained in the cover letter and here:
> http://www.redhat.com/archives/libvir-list/2014-October/msg00529.html
> We miss some informations in _virStorageSource to have a complet
> quorum support in libvirt.
> Ideally I'd like to refactore virDomainDiskDefFormat to allow
> qemuBuildQuorumStr to call this function in a loop.
>
> Signed-off-by: Matthias Gatto <matthias.gatto at outscale.com>
> ---
> src/qemu/qemu_command.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 110 insertions(+)
>
...
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 6c40d3e..80cbb7d 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -3479,6 +3479,111 @@ qemuCheckDiskConfig(virDomainDiskDefPtr disk)
> return -1;
> }
>
> +static bool
> +qemuBuildQuorumFileSourceStr(virConnectPtr conn,
> + virStorageSourcePtr src,
> + virBuffer *opt,
> + const char *toAppend)
> +{
> + char *source = NULL;
> + int actualType = virStorageSourceGetActualType(src);
> +
> + if (qemuGetDriveSourceString(src, conn, &source) < 0)
> + goto error;
> +
> + if (source) {
> +
> + virBufferAsprintf(opt, ",%sfilename=", toAppend);
virBufferStrcat
> +
> + switch (actualType) {
> + case VIR_STORAGE_TYPE_DIR:
I'd forbid the DIR type altogether with quorums.
> + /* QEMU only supports magic FAT format for now */
> + if (src->format > 0 &&
> + src->format != VIR_STORAGE_FILE_FAT) {
> + virReportError(VIR_ERR_INTERNAL_ERROR,
> + _("unsupported disk driver type for '%s'"),
> + virStorageFileFormatTypeToString(src->format));
> + goto error;
> + }
> +
> + if (!src->readonly) {
> + virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> + _("cannot create virtual FAT disks in read-write mode"));
> + goto error;
> + }
> +
> + virBufferAddLit(opt, "fat:");
> +
> + break;
> +
> + default:
> + break;
> + }
> + virBufferAsprintf(opt, "%s", source);
virBufferAdd
> + }
> +
> + return true;
> + error:
> + return false;
Error can be returned right away since there is nothing to clean up.
> +}
> +
> +
> +static bool
> +qemuBuildQuorumStr(virConnectPtr conn,
> + virDomainDiskDefPtr disk,
> + virStorageSourcePtr src,
> + virBuffer *opt,
> + const char *toAppend)
> +{
> + char *tmp = NULL;
> + int ret;
> + virStorageSourcePtr backingStore;
> + size_t i;
> +
> + 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 childrens"));
'children' is the proper plural
> + 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 (qemuBuildQuorumFileSourceStr(conn, backingStore, opt, tmp) == false)
> + goto error;
> +
> + /* This operation avoid me to made another copy */
> + tmp[ret - sizeof("file")] = '\0';
> + if (backingStore->type == VIR_STORAGE_TYPE_QUORUM) {
> + if (!qemuBuildQuorumStr(conn, disk, backingStore, opt, tmp))
> + goto error;
This won't work if the quorum would be after an intermediate layer.
That's why this needs the internal backing chain tracking.
> + }
> + VIR_FREE(tmp);
> + }
> + return true;
> + error:
> + VIR_FREE(tmp);
> + return false;
> +}
> +
>
> /* Qemu 1.2 and later have a binary flag -enable-fips that must be
> * used for VNC auth to obey FIPS settings; but the flag only
> @@ -3952,6 +4057,11 @@ qemuBuildDriveStr(virConnectPtr conn,
> disk->blkdeviotune.size_iops_sec);
> }
>
> + if (actualType == VIR_STORAGE_TYPE_QUORUM) {
> + if (!qemuBuildQuorumStr(conn, disk, disk->src, &opt, ""))
> + goto error;
> + }
This is rather ugly. Since qemuBuildDriveStr skips the quorum storage
sources rather accidentally as they appear "empty" to the
virStorageSourceIsEmpty function. If you want/need to have a different
function you should make it explicit how the code is formatting the
source.
Additionally once the quorum disk won't be on top, sice you for example
created a snapshot on top of the quorum unified device, then this code
will terribly break since qemuBuildQuorumStr will never be called.
As I've explained in a previous patch, quorums will need libvirt to do
the houskeeping of the whole backing chain internally since it cannot be
recreated that easily.
Peter
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: Digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20150512/23569209/attachment-0001.sig>
More information about the libvir-list
mailing list