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 | 87 +++++++++++++++++++++++++++++++++++++++++++++--
src/qemu/qemu_domain.h | 10 ++++++
src/util/virstoragefile.c | 15 ++++++++
src/util/virstoragefile.h | 2 ++
5 files changed, 113 insertions(+), 3 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 9c32d6240..777de47ae 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2784,7 +2784,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 d8fd54493..c17e40dc8 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;
-
srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(src);
if (hasAuth) {
@@ -11802,17 +11812,88 @@ 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"));
+ return ret;
+ }
+
+ if (!virStorageSourceIsLocalStorage(disk->src)) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("reservations supported only for local storage"));
+ return ret;
+ }
+
+ srcPriv = QEMU_DOMAIN_STORAGE_SOURCE_PRIVATE(disk->src);
+
+ /* Managed PR means there's one pr-manager object per domain
+ * and the pr-helper process is spawned and managed by
+ * libvirt.
+ * If PR is unmanaged there's one pr-manager object per disk
+ * (in general each disk can have its own pr-manager) and
+ * it's user's responsibility to start the pr-helper process.
+ */
+ 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 ret;
+
+ if (virAsprintf(&prPath, "%s/pr-helper0.sock", priv->libDir)
< 0)
+ goto cleanup;
+
+ } else {
+ if (virAsprintf(&prAlias, "pr-helper-%s", disk->info.alias) <
0)
+ return ret;
+
+ if (VIR_STRDUP(prPath, prd->path) < 0)
+ goto cleanup;
+ }
+
+ 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 e481dcd6d..6bcbddf32 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -2057,6 +2057,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 a6fcf36d6..88bfb9d2f 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -386,6 +386,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,
--
2.16.1