From 2b163ca3018467289b642bed0c099cb4a49d1e97 Mon Sep 17 00:00:00 2001 From: Jiri Denemark Date: Tue, 10 May 2022 15:20:25 +0200 Subject: [PATCH] qemu: Refactor qemuDomainObjSetJobPhase We will want to update migration phase without affecting job ownership. Either in the thread that already owns the job or from an event handler which only changes the phase (of a job no-one owns) without assuming it. Let's move the ownership change to a new qemuDomainObjStartJobPhase helper and let qemuDomainObjSetJobPhase set the phase without touching ownership. Signed-off-by: Jiri Denemark Reviewed-by: Peter Krempa Reviewed-by: Pavel Hrdina --- src/qemu/qemu_domainjob.c | 48 ++++++++++++++++++++++++++++++++++----- src/qemu/qemu_domainjob.h | 3 +++ src/qemu/qemu_migration.c | 2 +- 3 files changed, 46 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_domainjob.c b/src/qemu/qemu_domainjob.c index e76eb7f2cf..1f6d976558 100644 --- a/src/qemu/qemu_domainjob.c +++ b/src/qemu/qemu_domainjob.c @@ -717,6 +717,10 @@ qemuDomainJobDataToParams(virDomainJobData *jobData, } +/* + * Sets the job phase without changing the job owner. The owner is supposed to + * be 0 or the current thread, a warning is issued otherwise. + */ void qemuDomainObjSetJobPhase(virDomainObj *obj, int phase) @@ -731,19 +735,51 @@ qemuDomainObjSetJobPhase(virDomainObj *obj, virDomainAsyncJobTypeToString(priv->job.asyncJob), qemuDomainAsyncJobPhaseToString(priv->job.asyncJob, phase)); - if (priv->job.asyncOwner == 0) { - priv->job.asyncOwnerAPI = g_strdup(virThreadJobGet()); - } else if (me != priv->job.asyncOwner) { - VIR_WARN("'%s' async job is owned by thread %llu", + if (priv->job.asyncOwner != 0 && + priv->job.asyncOwner != me) { + VIR_WARN("'%s' async job is owned by thread %llu, API '%s'", virDomainAsyncJobTypeToString(priv->job.asyncJob), - priv->job.asyncOwner); + priv->job.asyncOwner, + NULLSTR(priv->job.asyncOwnerAPI)); } priv->job.phase = phase; - priv->job.asyncOwner = me; qemuDomainSaveStatus(obj); } + +/* + * Changes the job owner and sets the job phase. The current owner is supposed + * to be 0 or the current thread, a warning is issued otherwise. + */ +void +qemuDomainObjStartJobPhase(virDomainObj *obj, + int phase) +{ + qemuDomainObjPrivate *priv = obj->privateData; + unsigned long long me = virThreadSelfID(); + + if (!priv->job.asyncJob) + return; + + VIR_DEBUG("Starting phase '%s' of '%s' job", + qemuDomainAsyncJobPhaseToString(priv->job.asyncJob, phase), + virDomainAsyncJobTypeToString(priv->job.asyncJob)); + + if (priv->job.asyncOwner == 0) { + priv->job.asyncOwnerAPI = g_strdup(virThreadJobGet()); + } else if (me != priv->job.asyncOwner) { + VIR_WARN("'%s' async job is owned by thread %llu, API '%s'", + virDomainAsyncJobTypeToString(priv->job.asyncJob), + priv->job.asyncOwner, + NULLSTR(priv->job.asyncOwnerAPI)); + } + + priv->job.asyncOwner = me; + qemuDomainObjSetJobPhase(obj, phase); +} + + void qemuDomainObjSetAsyncJobMask(virDomainObj *obj, unsigned long long allowedJobs) diff --git a/src/qemu/qemu_domainjob.h b/src/qemu/qemu_domainjob.h index 707d4e91ed..e8021a7f04 100644 --- a/src/qemu/qemu_domainjob.h +++ b/src/qemu/qemu_domainjob.h @@ -156,6 +156,9 @@ void qemuDomainObjEndAsyncJob(virDomainObj *obj); void qemuDomainObjAbortAsyncJob(virDomainObj *obj); void qemuDomainObjSetJobPhase(virDomainObj *obj, int phase); +void +qemuDomainObjStartJobPhase(virDomainObj *obj, + int phase); void qemuDomainObjSetAsyncJobMask(virDomainObj *obj, unsigned long long allowedJobs); int qemuDomainObjPreserveJob(virDomainObj *obj, diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c index 9cc2c07c79..8940c266bb 100644 --- a/src/qemu/qemu_migration.c +++ b/src/qemu/qemu_migration.c @@ -165,7 +165,7 @@ qemuMigrationJobSetPhase(virDomainObj *vm, if (qemuMigrationCheckPhase(vm, phase) < 0) return -1; - qemuDomainObjSetJobPhase(vm, phase); + qemuDomainObjStartJobPhase(vm, phase); return 0; }