On 02/21/2018 01:11 PM, Michal Privoznik wrote:
While we're not generating the command line just yet (look for
the next commits), we can generate the alias for pr-manager.
A domain can have up to one managed pr-manager (in which case
socket path is decided by libvirt and pr-helper is spawned by
libvirt too), but up to ndisks of unmanaged ones (one per disk
basically). In case of the former we can generate a simple alias
and be sure it'll not conflict. But in case of the latter to
avoid any conflicts let's generate alias that's based on
something unique - like disk target.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/libvirt_private.syms | 2 ++
src/qemu/qemu_domain.c | 80 +++++++++++++++++++++++++++++++++++++++++++++--
src/qemu/qemu_domain.h | 10 ++++++
src/util/virstoragefile.c | 15 +++++++++
src/util/virstoragefile.h | 2 ++
5 files changed, 106 insertions(+), 3 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d4bff0f0b..bb0183ea6 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2781,7 +2781,9 @@ virStorageNetHostTransportTypeToString;
virStorageNetProtocolTypeToString;
virStoragePRDefFormat;
virStoragePRDefFree;
+virStoragePRDefIsEnabled;
virStoragePRDefIsEqual;
+virStoragePRDefIsManaged;
virStoragePRDefParseNode;
virStorageSourceBackingStoreClear;
virStorageSourceClear;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index de8974d66..dffc4c30e 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -982,6 +982,18 @@ qemuDomainSecretInfoFree(qemuDomainSecretInfoPtr *secinfo)
}
+static void
+qemuDomainDiskPRDFree(qemuDomainDiskPRDPtr prd)
+{
+ if (!prd)
+ return;
+
+ VIR_FREE(prd->alias);
+ VIR_FREE(prd->path);
+ VIR_FREE(prd);
+}
+
+
static virClassPtr qemuDomainDiskPrivateClass;
static void qemuDomainDiskPrivateDispose(void *obj);
@@ -1062,6 +1074,7 @@ qemuDomainStorageSourcePrivateDispose(void *obj)
qemuDomainSecretInfoFree(&priv->secinfo);
qemuDomainSecretInfoFree(&priv->encinfo);
+ qemuDomainDiskPRDFree(priv->prd);
}
@@ -1473,9 +1486,6 @@ qemuDomainSecretStorageSourcePrepare(qemuDomainObjPrivatePtr priv,
if (!hasAuth && !hasEnc)
return 0;
- if (!(src->privateData = qemuDomainStorageSourcePrivateNew()))
- return -1;
-
How does the following not fail with the previous hunk removed? Oh, I
see, it's moved to qemuDomainPrepareDiskSource.... could be separated
out, but I see why it's here - so fine. Just eye opening ;-)
srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
if (hasAuth) {
@@ -11538,17 +11548,81 @@ qemuDomainCheckMigrationCapabilities(virQEMUDriverPtr driver,
}
+static int
+qemuDomainPrepareDiskPRD(qemuDomainObjPrivatePtr priv,
+ virDomainDiskDefPtr disk)
+{
+ qemuDomainStorageSourcePrivatePtr srcPriv;
+ virStoragePRDefPtr prd = disk->src->pr;
+ char *prAlias = NULL;
+ char *prPath = NULL;
+ int ret = -1;
+
+ if (!virStoragePRDefIsEnabled(prd))
+ return 0;
+
+ if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_PR_MANAGER_HELPER)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("reservations not supported with this QEMU
binary"));
+ goto cleanup;
+ }
+
+ if (!virStorageSourceIsLocalStorage(disk->src)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("reservations supported only for local storage"));
+ goto cleanup;
+ }
Ironically the above two could return -1 directly...
+
+ srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(disk->src);
+
+ if (virStoragePRDefIsManaged(prd)) {
+ /* Generate PR helper socket path & alias that are same
+ * for each disk in the domain. */
+
+ if (VIR_STRDUP(prAlias, "pr-helper0") < 0)
+ return -1;
+
+ if (virAsprintf(&prPath, "%s/pr-helper0.sock", priv->libDir)
< 0)
+ return -1;
Leaks prAlias
BTW: Whatever "managed" ends up being needs to be described somewhere
either prior to this or after this, but knowing how the connection
between libvirt and qemu's process is going to happen will be really
helpful... Something that I would think would be described in patch 1,
but again that's just me. This whole managed thing is really confusing
the way it's written. May make sense to you, but it doesn't make sense
to me, just saying.
+
+ } else {
+ if (virAsprintf(&prAlias, "pr-helper-%s", disk->dst) < 0)
+ return -1;
Or using the 'disk->info.alias' like other consumers.
+
+ if (VIR_STRDUP(prPath, prd->path) < 0)
+ return -1;
Leaks prAlias
I'm going to stop here - mainly because I'm confused about managed, but
hopefully a fresh look in the morning will help.
John
+ }
+
+ if (VIR_ALLOC(srcPriv->prd) < 0)
+ goto cleanup;
+ VIR_STEAL_PTR(srcPriv->prd->alias, prAlias);
+ VIR_STEAL_PTR(srcPriv->prd->path, prPath);
+
+ ret = 0;
+ cleanup:
+ VIR_FREE(prPath);
+ VIR_FREE(prAlias);
+ return ret;
+}
+
+
int
qemuDomainPrepareDiskSource(virDomainDiskDefPtr disk,
qemuDomainObjPrivatePtr priv,
virQEMUDriverConfigPtr cfg)
{
+ if (!(disk->src->privateData = qemuDomainStorageSourcePrivateNew()))
+ return -1;
+
if (qemuDomainPrepareDiskSourceTLS(disk->src, cfg) < 0)
return -1;
if (qemuDomainSecretDiskPrepare(priv, disk) < 0)
return -1;
+ if (qemuDomainPrepareDiskPRD(priv, disk) < 0)
+ return -1;
+
if (disk->src->type == VIR_STORAGE_TYPE_NETWORK &&
disk->src->protocol == VIR_STORAGE_NET_PROTOCOL_GLUSTER &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_GLUSTER_DEBUG_LEVEL)) {
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 6d3e6eb5e..b9258eb8e 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -373,6 +373,13 @@ struct _qemuDomainDiskPrivate {
bool removable; /* device media can be removed/changed */
};
+typedef struct _qemuDomainDiskPRD qemuDomainDiskPRD;
+typedef qemuDomainDiskPRD *qemuDomainDiskPRDPtr;
+struct _qemuDomainDiskPRD {
+ char *alias;
+ char *path; /* socket path. */
+};
+
# define QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src) \
((qemuDomainStorageSourcePrivatePtr) (src)->privateData)
@@ -386,6 +393,9 @@ struct _qemuDomainStorageSourcePrivate {
/* data required for decryption of encrypted storage source */
qemuDomainSecretInfoPtr encinfo;
+
+ /* data required for persistent reservations */
+ qemuDomainDiskPRDPtr prd;
};
virObjectPtr qemuDomainStorageSourcePrivateNew(void);
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 328f59788..a85fec330 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -2076,6 +2076,21 @@ virStoragePRDefIsEqual(virStoragePRDefPtr a,
return true;
}
+
+bool
+virStoragePRDefIsEnabled(virStoragePRDefPtr prd)
+{
+ return prd && prd->enabled == VIR_TRISTATE_BOOL_YES;
+}
+
+
+bool
+virStoragePRDefIsManaged(virStoragePRDefPtr prd)
+{
+ return prd && prd->managed == VIR_TRISTATE_BOOL_YES;> +}
+
+
virSecurityDeviceLabelDefPtr
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
const char *model)
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index e70c99076..cf931bbb1 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -385,6 +385,8 @@ void virStoragePRDefFormat(virBufferPtr buf,
virStoragePRDefPtr prd);
bool virStoragePRDefIsEqual(virStoragePRDefPtr a,
virStoragePRDefPtr b);
+bool virStoragePRDefIsEnabled(virStoragePRDefPtr prd);
+bool virStoragePRDefIsManaged(virStoragePRDefPtr prd);
virSecurityDeviceLabelDefPtr
virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,