This patch introduces virDomainJobWait, which waits for the specified
domain job to finish. The caller specifies the desired job type to wait
for. For now, only dump jobs are supported.
This functionality is needed so that the process that started the dump
job can pick it up and continue waiting for it in case it restarted.
Signed-off-by: Thanos Makatos <thanos.makatos(a)nutanix.com>
---
include/libvirt/libvirt-domain.h | 54 ++++++++++++++++++--------------
src/driver-hypervisor.h | 4 +++
src/libvirt-domain.c | 22 ++++++++++++-
src/libvirt_public.syms | 1 +
src/qemu/qemu_driver.c | 28 +++++++++++++++++
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 14 ++++++++-
src/remote_protocol-structs | 5 +++
8 files changed, 104 insertions(+), 25 deletions(-)
diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 30cce85b29..7ca77f2e41 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -1681,6 +1681,7 @@ int virDomainCoreDumpWithFormat (virDomainPtr
domain,
unsigned int dumpformat,
unsigned int flags);
+
/*
* Screenshot of current domain console
*/
@@ -3130,6 +3131,36 @@ typedef enum {
int virDomainBlockJobAbort(virDomainPtr dom, const char *disk,
unsigned int flags);
+/**
+ * virDomainJobOperation:
+ *
+ * Since: 3.3.0
+ */
+typedef enum {
+ VIR_DOMAIN_JOB_OPERATION_UNKNOWN = 0, /* (Since: 3.3.0) */
+ VIR_DOMAIN_JOB_OPERATION_START = 1, /* (Since: 3.3.0) */
+ VIR_DOMAIN_JOB_OPERATION_SAVE = 2, /* (Since: 3.3.0) */
+ VIR_DOMAIN_JOB_OPERATION_RESTORE = 3, /* (Since: 3.3.0) */
+ VIR_DOMAIN_JOB_OPERATION_MIGRATION_IN = 4, /* (Since: 3.3.0) */
+ VIR_DOMAIN_JOB_OPERATION_MIGRATION_OUT = 5, /* (Since: 3.3.0) */
+ VIR_DOMAIN_JOB_OPERATION_SNAPSHOT = 6, /* (Since: 3.3.0) */
+ VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_REVERT = 7, /* (Since: 3.3.0) */
+ VIR_DOMAIN_JOB_OPERATION_DUMP = 8, /* (Since: 3.3.0) */
+ VIR_DOMAIN_JOB_OPERATION_BACKUP = 9, /* (Since: 6.0.0) */
+ VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_DELETE = 10, /* (Since: 9.0.0) */
+
+# ifdef VIR_ENUM_SENTINELS
+ VIR_DOMAIN_JOB_OPERATION_LAST /* (Since: 3.3.0) */
+# endif
+} virDomainJobOperation;
+
+/*
+ * Wait for job to finish
+ *
+ * Since 10.1.0
+ */
+int virDomainJobWait (virDomainPtr domain, int op);
+
/**
* virDomainBlockJobInfoFlags:
*
@@ -4185,29 +4216,6 @@ typedef enum {
int virDomainAbortJobFlags(virDomainPtr dom,
unsigned int flags);
-/**
- * virDomainJobOperation:
- *
- * Since: 3.3.0
- */
-typedef enum {
- VIR_DOMAIN_JOB_OPERATION_UNKNOWN = 0, /* (Since: 3.3.0) */
- VIR_DOMAIN_JOB_OPERATION_START = 1, /* (Since: 3.3.0) */
- VIR_DOMAIN_JOB_OPERATION_SAVE = 2, /* (Since: 3.3.0) */
- VIR_DOMAIN_JOB_OPERATION_RESTORE = 3, /* (Since: 3.3.0) */
- VIR_DOMAIN_JOB_OPERATION_MIGRATION_IN = 4, /* (Since: 3.3.0) */
- VIR_DOMAIN_JOB_OPERATION_MIGRATION_OUT = 5, /* (Since: 3.3.0) */
- VIR_DOMAIN_JOB_OPERATION_SNAPSHOT = 6, /* (Since: 3.3.0) */
- VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_REVERT = 7, /* (Since: 3.3.0) */
- VIR_DOMAIN_JOB_OPERATION_DUMP = 8, /* (Since: 3.3.0) */
- VIR_DOMAIN_JOB_OPERATION_BACKUP = 9, /* (Since: 6.0.0) */
- VIR_DOMAIN_JOB_OPERATION_SNAPSHOT_DELETE = 10, /* (Since: 9.0.0) */
-
-# ifdef VIR_ENUM_SENTINELS
- VIR_DOMAIN_JOB_OPERATION_LAST /* (Since: 3.3.0) */
-# endif
-} virDomainJobOperation;
-
/**
* VIR_DOMAIN_JOB_OPERATION:
*
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index 5219344b72..717a5d511f 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -750,6 +750,9 @@ typedef int
(*virDrvDomainAbortJobFlags)(virDomainPtr domain,
unsigned int flags);
+typedef int
+(*virDrvDomainJobWait)(virDomainPtr domain, int op);
+
typedef int
(*virDrvDomainMigrateGetMaxDowntime)(virDomainPtr domain,
unsigned long long *downtime,
@@ -1602,6 +1605,7 @@ struct _virHypervisorDriver {
virDrvDomainGetJobStats domainGetJobStats;
virDrvDomainAbortJob domainAbortJob;
virDrvDomainAbortJobFlags domainAbortJobFlags;
+ virDrvDomainJobWait domainJobWait;
virDrvDomainMigrateGetMaxDowntime domainMigrateGetMaxDowntime;
virDrvDomainMigrateSetMaxDowntime domainMigrateSetMaxDowntime;
virDrvDomainMigrateGetCompressionCache domainMigrateGetCompressionCache;
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 83abad251e..846d711f1b 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -1527,7 +1527,6 @@ virDomainCoreDumpWithFormat(virDomainPtr domain, const char *to,
return -1;
}
-
/**
* virDomainScreenshot:
* @domain: a domain object
@@ -10660,6 +10659,27 @@ virDomainBlockJobAbort(virDomainPtr dom, const char *disk,
return -1;
}
+/**
+ * virDomainJobWait:
+ * @domain: a domain object
+ * @op: the job type to wait for
+ *
+ * Waits for the specified pending domain job to complete.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ *
+ * Since: 10.1.0
+ */
+int
+virDomainJobWait(virDomainPtr domain, int op)
+{
+ if (domain->conn->driver->domainJobWait) {
+ return domain->conn->driver->domainJobWait(domain, op);
+ }
+ virReportError(VIR_ERR_NO_SUPPORT, "%s",
+ _("does not support waiting for domain job to complete"));
+ return -1;
+}
/**
* virDomainGetBlockJobInfo:
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 0304b8f824..0bb679efd0 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -941,6 +941,7 @@ LIBVIRT_9.7.0 {
LIBVIRT_10.1.0 {
global:
virNodeDeviceUpdate;
+ virDomainJobWait;
} LIBVIRT_9.7.0;
# .... define new API here using predicted next version number ....
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 448e6b1591..8f6a6c4306 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -3286,6 +3286,33 @@ qemuDomainCoreDump(virDomainPtr dom,
flags);
}
+static int
+qemuDomainJobWait(virDomainPtr dom, int op)
+{
+ virDomainObj *vm;
+ int ret = -1;
+
+ if (!(vm = qemuDomainObjFromDomain(dom)))
+ return -1;
+
+ if (virDomainJobWaitEnsureACL(dom->conn, vm->def) < 0)
+ goto cleanup;
+
+ if (virDomainObjCheckActive(vm) < 0)
+ goto cleanup;
+
+ if ((virDomainJobOperation)op == VIR_DOMAIN_JOB_OPERATION_DUMP &&
+ vm->job->asyncJob == VIR_ASYNC_JOB_DUMP)
+ ret = qemuDomainObjWait(vm);
+ else
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ _("job mismatch, want=%d have=%d"), op,
vm->job->asyncJob);
+
+cleanup:
+ virDomainObjEndAPI(&vm);
+ return ret;
+}
+
static char *
qemuDomainScreenshot(virDomainPtr dom,
@@ -20060,6 +20087,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
.domainGetJobStats = qemuDomainGetJobStats, /* 1.0.3 */
.domainAbortJob = qemuDomainAbortJob, /* 0.7.7 */
.domainAbortJobFlags = qemuDomainAbortJobFlags, /* 8.5.0 */
+ .domainJobWait = qemuDomainJobWait, /* 10.1.0 */
.domainMigrateGetMaxDowntime = qemuDomainMigrateGetMaxDowntime, /* 3.7.0 */
.domainMigrateSetMaxDowntime = qemuDomainMigrateSetMaxDowntime, /* 0.8.0 */
.domainMigrateGetCompressionCache = qemuDomainMigrateGetCompressionCache, /* 1.0.3
*/
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index f156475bd2..42577c4a0d 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -7721,6 +7721,7 @@ static virHypervisorDriver hypervisor_driver = {
.domainGetJobStats = remoteDomainGetJobStats, /* 1.0.3 */
.domainAbortJob = remoteDomainAbortJob, /* 0.7.7 */
.domainAbortJobFlags = remoteDomainAbortJobFlags, /* 8.5.0 */
+ .domainJobWait = remoteDomainJobWait, /* 10.1.0 */
.domainMigrateGetMaxDowntime = remoteDomainMigrateGetMaxDowntime, /* 3.7.0 */
.domainMigrateSetMaxDowntime = remoteDomainMigrateSetMaxDowntime, /* 0.8.0 */
.domainMigrateGetCompressionCache = remoteDomainMigrateGetCompressionCache, /* 1.0.3
*/
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 71ae0cf6c1..482f249f46 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -1406,6 +1406,11 @@ struct remote_domain_block_job_abort_args {
unsigned int flags;
};
+struct remote_domain_job_wait_args {
+ remote_nonnull_domain dom;
+ int op;
+};
+
struct remote_domain_get_block_job_info_args {
remote_nonnull_domain dom;
remote_nonnull_string path;
@@ -7037,5 +7042,12 @@ enum remote_procedure {
* @acl:
node_device:save:!VIR_NODE_DEVICE_UPDATE_AFFECT_CONFIG|VIR_NODE_DEVICE_UPDATE_AFFECT_LIVE
* @acl: node_device:save:VIR_NODE_DEVICE_UPDATE_AFFECT_CONFIG
*/
- REMOTE_PROC_NODE_DEVICE_UPDATE = 447
+ REMOTE_PROC_NODE_DEVICE_UPDATE = 447,
+
+ /**
+ * @generate: both
+ * @acl: domain:read
+ */
+ REMOTE_PROC_DOMAIN_JOB_WAIT = 448
+
};
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index ee2ec3e6fa..78a5fd45b9 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -979,6 +979,10 @@ struct remote_domain_block_job_abort_args {
remote_nonnull_string path;
u_int flags;
};
+struct remote_domain_job_wait_args {
+ remote_nonnull_domain dom;
+ int op;
+};
struct remote_domain_get_block_job_info_args {
remote_nonnull_domain dom;
remote_nonnull_string path;
@@ -3749,4 +3753,5 @@ enum remote_procedure {
REMOTE_PROC_NETWORK_GET_METADATA = 445,
REMOTE_PROC_NETWORK_EVENT_CALLBACK_METADATA_CHANGE = 446,
REMOTE_PROC_NODE_DEVICE_UPDATE = 447,
+ REMOTE_PROC_DOMAIN_CORE_DUMP_WAIT = 448
};
--
2.30.2