diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 05268b8d12c8f31ca01e278a1349b43b198fa462..a0cff12df538f05f5446575c59e46e9a25408825 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -114,6 +114,7 @@ VIR_ENUM_IMPL(qemuDomainAsyncJob, "dump", "snapshot", "start", + "backup", ); VIR_ENUM_IMPL(qemuDomainNamespace, @@ -210,6 +211,7 @@ qemuDomainAsyncJobPhaseToString(qemuDomainAsyncJob job, case QEMU_ASYNC_JOB_SNAPSHOT: case QEMU_ASYNC_JOB_START: case QEMU_ASYNC_JOB_NONE: + case QEMU_ASYNC_JOB_BACKUP: G_GNUC_FALLTHROUGH; case QEMU_ASYNC_JOB_LAST: break; @@ -235,6 +237,7 @@ qemuDomainAsyncJobPhaseFromString(qemuDomainAsyncJob job, case QEMU_ASYNC_JOB_SNAPSHOT: case QEMU_ASYNC_JOB_START: case QEMU_ASYNC_JOB_NONE: + case QEMU_ASYNC_JOB_BACKUP: G_GNUC_FALLTHROUGH; case QEMU_ASYNC_JOB_LAST: break; diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index a7ee6a9c6ed5a84b8fb723f7352a0cf8eb0198b0..7c752abc8037c6bcd9c236a4e8099a21009a2a8b 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -104,6 +104,7 @@ typedef enum { QEMU_ASYNC_JOB_DUMP, QEMU_ASYNC_JOB_SNAPSHOT, QEMU_ASYNC_JOB_START, + QEMU_ASYNC_JOB_BACKUP, QEMU_ASYNC_JOB_LAST } qemuDomainAsyncJob; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index e3872d5c3bccdd40fc6764d77e93c2784a35a5d2..02126bc0496521d8b582c9b756d6ff08a32201e3 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -14041,6 +14041,10 @@ static int qemuDomainAbortJob(virDomainPtr dom) ret = qemuDomainAbortJobMigration(vm); break; + case QEMU_ASYNC_JOB_BACKUP: + /* TODO: to be implemented later */ + break; + case QEMU_ASYNC_JOB_LAST: default: virReportEnumRangeError(qemuDomainAsyncJob, priv->job.asyncJob); diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 73acf7790e1dfb43c899b33f939052a8e3ceeb1e..f9e89e67a332472a7a1ec91990ac30bf073c9191 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -1444,6 +1444,8 @@ qemuMigrationJobName(virDomainObjPtr vm) return _("snapshot job"); case QEMU_ASYNC_JOB_START: return _("start job"); + case QEMU_ASYNC_JOB_BACKUP: + return _("backup job"); case QEMU_ASYNC_JOB_LAST: default: return _("job"); diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 31877d65765914e3796de6e61b0518a21798b58e..4b844b4b7c650962ea94b67073065737cc125f70 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -89,6 +89,7 @@ #include "virresctrl.h" #include "virvsock.h" #include "viridentity.h" +#include "virthreadjob.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -3575,6 +3576,7 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver, qemuDomainObjPrivatePtr priv = vm->privateData; virDomainState state; int reason; + unsigned long long now; state = virDomainObjGetState(vm, &reason); @@ -3624,6 +3626,29 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver, /* Already handled in VIR_DOMAIN_PAUSED_STARTING_UP check. */ break; + case QEMU_ASYNC_JOB_BACKUP: + ignore_value(virTimeMillisNow(&now)); + + /* Restore the config of the async job which is not persisted */ + priv->jobs_queued++; + priv->job.asyncJob = QEMU_ASYNC_JOB_BACKUP; + priv->job.asyncOwnerAPI = virThreadJobGet(); + priv->job.asyncStarted = now; + + qemuDomainObjSetAsyncJobMask(vm, (QEMU_JOB_DEFAULT_MASK | + JOB_MASK(QEMU_JOB_SUSPEND) | + JOB_MASK(QEMU_JOB_MODIFY))); + + /* We reset the job parameters for backup so that the job will look + * active. This is possible because we are able to recover the state + * of blockjobs and also the backup job allows all sub-job types */ + priv->job.current = g_new0(qemuDomainJobInfo, 1); + priv->job.current->operation = VIR_DOMAIN_JOB_OPERATION_BACKUP; + priv->job.current->statsType = QEMU_DOMAIN_JOB_STATS_TYPE_BACKUP; + priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE; + priv->job.current->started = now; + break; + case QEMU_ASYNC_JOB_NONE: case QEMU_ASYNC_JOB_LAST: break;