|
|
acda74 |
From 11dd7c99fa96364962f81d4efae0ed220c7a7190 Mon Sep 17 00:00:00 2001
|
|
|
acda74 |
Message-Id: <11dd7c99fa96364962f81d4efae0ed220c7a7190@dist-git>
|
|
|
acda74 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
acda74 |
Date: Fri, 10 Feb 2023 17:16:43 +0100
|
|
|
acda74 |
Subject: [PATCH] qemu: blockjob: Handle 'pending' blockjob state only when we
|
|
|
acda74 |
need it
|
|
|
acda74 |
|
|
|
acda74 |
The 'pending' state needs to be handled by the blockjob code only when
|
|
|
acda74 |
the snapshot code requests a block-commit without auto-finalization.
|
|
|
acda74 |
|
|
|
acda74 |
If we always handle it we fail to properly remove the blockjob data for
|
|
|
acda74 |
the 'blockdev-create' job as that also transitions trhough 'pending' but
|
|
|
acda74 |
we'd never update it once it reaches 'concluded' as the code already
|
|
|
acda74 |
thinks that the job has finished and is no longer watching it.
|
|
|
acda74 |
|
|
|
acda74 |
Introduce a 'processPending' property into block job data and set it
|
|
|
acda74 |
only when we know that we need to process 'pending'.
|
|
|
acda74 |
|
|
|
acda74 |
Fixes: 90d9bc9d74a5157167548b26c00b1a016655e295
|
|
|
acda74 |
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=2168769
|
|
|
acda74 |
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
|
|
|
acda74 |
Reviewed-by: Pavel Hrdina <phrdina@redhat.com>
|
|
|
acda74 |
(cherry picked from commit c433c2434c0459df98ed3355ef615e341acd9009)
|
|
|
acda74 |
---
|
|
|
acda74 |
src/qemu/qemu_block.c | 1 +
|
|
|
acda74 |
src/qemu/qemu_blockjob.c | 19 ++++++++++---------
|
|
|
acda74 |
src/qemu/qemu_blockjob.h | 4 ++++
|
|
|
acda74 |
3 files changed, 15 insertions(+), 9 deletions(-)
|
|
|
acda74 |
|
|
|
acda74 |
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
|
|
|
acda74 |
index c218262691..d8ca50d618 100644
|
|
|
acda74 |
--- a/src/qemu/qemu_block.c
|
|
|
acda74 |
+++ b/src/qemu/qemu_block.c
|
|
|
acda74 |
@@ -3374,6 +3374,7 @@ qemuBlockCommit(virDomainObj *vm,
|
|
|
acda74 |
if (!(job = qemuBlockJobDiskNewCommit(vm, disk, top_parent, topSource,
|
|
|
acda74 |
baseSource,
|
|
|
acda74 |
flags & VIR_DOMAIN_BLOCK_COMMIT_DELETE,
|
|
|
acda74 |
+ autofinalize,
|
|
|
acda74 |
flags)))
|
|
|
acda74 |
goto cleanup;
|
|
|
acda74 |
|
|
|
acda74 |
diff --git a/src/qemu/qemu_blockjob.c b/src/qemu/qemu_blockjob.c
|
|
|
acda74 |
index cb2d05d71d..a20cf1db62 100644
|
|
|
acda74 |
--- a/src/qemu/qemu_blockjob.c
|
|
|
acda74 |
+++ b/src/qemu/qemu_blockjob.c
|
|
|
acda74 |
@@ -274,6 +274,7 @@ qemuBlockJobDiskNewCommit(virDomainObj *vm,
|
|
|
acda74 |
virStorageSource *top,
|
|
|
acda74 |
virStorageSource *base,
|
|
|
acda74 |
bool delete_imgs,
|
|
|
acda74 |
+ virTristateBool autofinalize,
|
|
|
acda74 |
unsigned int jobflags)
|
|
|
acda74 |
{
|
|
|
acda74 |
g_autoptr(qemuBlockJobData) job = NULL;
|
|
|
acda74 |
@@ -290,6 +291,7 @@ qemuBlockJobDiskNewCommit(virDomainObj *vm,
|
|
|
acda74 |
job->data.commit.top = top;
|
|
|
acda74 |
job->data.commit.base = base;
|
|
|
acda74 |
job->data.commit.deleteCommittedImages = delete_imgs;
|
|
|
acda74 |
+ job->processPending = autofinalize == VIR_TRISTATE_BOOL_NO;
|
|
|
acda74 |
job->jobflags = jobflags;
|
|
|
acda74 |
|
|
|
acda74 |
if (qemuBlockJobRegister(job, vm, disk, true) < 0)
|
|
|
acda74 |
@@ -532,8 +534,6 @@ qemuBlockJobRefreshJobs(virDomainObj *vm)
|
|
|
acda74 |
if (job->state == QEMU_BLOCKJOB_STATE_NEW ||
|
|
|
acda74 |
job->state == QEMU_BLOCKJOB_STATE_RUNNING)
|
|
|
acda74 |
job->newstate = newstate;
|
|
|
acda74 |
- } else if (newstate == QEMU_BLOCKJOB_STATE_PENDING) {
|
|
|
acda74 |
- job->newstate = newstate;
|
|
|
acda74 |
}
|
|
|
acda74 |
/* don't update the job otherwise */
|
|
|
acda74 |
}
|
|
|
acda74 |
@@ -1568,13 +1568,14 @@ qemuBlockJobEventProcess(virQEMUDriver *driver,
|
|
|
acda74 |
|
|
|
acda74 |
case QEMU_BLOCKJOB_STATE_PENDING:
|
|
|
acda74 |
/* Similarly as for 'ready' state we should handle it only when
|
|
|
acda74 |
- * previous state was 'new' or 'running' as there are other cases
|
|
|
acda74 |
- * when it can be emitted by QEMU. Currently we need this only when
|
|
|
acda74 |
- * deleting non-active external snapshots. */
|
|
|
acda74 |
- if (job->state == QEMU_BLOCKJOB_STATE_NEW ||
|
|
|
acda74 |
- job->state == QEMU_BLOCKJOB_STATE_RUNNING) {
|
|
|
acda74 |
- job->state = job->newstate;
|
|
|
acda74 |
- qemuDomainSaveStatus(vm);
|
|
|
acda74 |
+ * previous state was 'new' or 'running' and only if the blockjob code
|
|
|
acda74 |
+ * is handling finalization of the job explicitly. */
|
|
|
acda74 |
+ if (job->processPending) {
|
|
|
acda74 |
+ if (job->state == QEMU_BLOCKJOB_STATE_NEW ||
|
|
|
acda74 |
+ job->state == QEMU_BLOCKJOB_STATE_RUNNING) {
|
|
|
acda74 |
+ job->state = job->newstate;
|
|
|
acda74 |
+ qemuDomainSaveStatus(vm);
|
|
|
acda74 |
+ }
|
|
|
acda74 |
}
|
|
|
acda74 |
job->newstate = -1;
|
|
|
acda74 |
break;
|
|
|
acda74 |
diff --git a/src/qemu/qemu_blockjob.h b/src/qemu/qemu_blockjob.h
|
|
|
acda74 |
index e9b283da20..f1ac43b4c7 100644
|
|
|
acda74 |
--- a/src/qemu/qemu_blockjob.h
|
|
|
acda74 |
+++ b/src/qemu/qemu_blockjob.h
|
|
|
acda74 |
@@ -138,6 +138,9 @@ struct _qemuBlockJobData {
|
|
|
acda74 |
|
|
|
acda74 |
int brokentype; /* the previous type of a broken blockjob qemuBlockJobType */
|
|
|
acda74 |
|
|
|
acda74 |
+ bool processPending; /* process the 'pending' state of the job, if the job
|
|
|
acda74 |
+ should not be auto-finalized */
|
|
|
acda74 |
+
|
|
|
acda74 |
bool invalidData; /* the job data (except name) is not valid */
|
|
|
acda74 |
bool reconnected; /* internal field for tracking whether job is live after reconnect to qemu */
|
|
|
acda74 |
};
|
|
|
acda74 |
@@ -175,6 +178,7 @@ qemuBlockJobDiskNewCommit(virDomainObj *vm,
|
|
|
acda74 |
virStorageSource *top,
|
|
|
acda74 |
virStorageSource *base,
|
|
|
acda74 |
bool delete_imgs,
|
|
|
acda74 |
+ virTristateBool autofinalize,
|
|
|
acda74 |
unsigned int jobflags);
|
|
|
acda74 |
|
|
|
acda74 |
qemuBlockJobData *
|
|
|
acda74 |
--
|
|
|
acda74 |
2.39.1
|
|
|
acda74 |
|