X-Git-Url: https://git.proxmox.com/?p=pve-qemu.git;a=blobdiff_plain;f=debian%2Fpatches%2Fpve%2F0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch;fp=debian%2Fpatches%2Fpve%2F0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch;h=0000000000000000000000000000000000000000;hp=f3bfb157de08f0b25c3dc264e43f8d9df3efb1ca;hb=5b15e2ecaf054107200a49c7d2509053fb91c9fe;hpb=2775b2e3788bfed64345046ce6a669bcdf28eb43 diff --git a/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch b/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch deleted file mode 100644 index f3bfb15..0000000 --- a/debian/patches/pve/0057-PVE-Backup-ensure-jobs-in-di_list-are-referenced.patch +++ /dev/null @@ -1,76 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fabian Ebner -Date: Wed, 25 May 2022 13:59:38 +0200 -Subject: [PATCH] PVE-Backup: ensure jobs in di_list are referenced - -Ensures that qmp_backup_cancel doesn't pick a job that's already been -freed. With unlucky timings it seems possible that: -1. job_exit -> job_completed -> job_finalize_single starts -2. pvebackup_co_complete_stream gets spawned in completion callback -3. job finalize_single finishes -> job's refcount hits zero -> job is - freed -4. qmp_backup_cancel comes in and locks backup_state.backup_mutex - before pvebackup_co_complete_stream can remove the job from the - di_list -5. qmp_backup_cancel will pick a job that's already been freed - -Signed-off-by: Fabian Ebner -Signed-off-by: Wolfgang Bumiller ---- - pve-backup.c | 25 ++++++++++++++++++++----- - 1 file changed, 20 insertions(+), 5 deletions(-) - -diff --git a/pve-backup.c b/pve-backup.c -index 5bed6f4014..0c34428713 100644 ---- a/pve-backup.c -+++ b/pve-backup.c -@@ -316,6 +316,14 @@ static void coroutine_fn pvebackup_co_complete_stream(void *opaque) - } - } - -+ if (di->job) { -+ AioContext *ctx = di->job->job.aio_context; -+ aio_context_acquire(ctx); -+ job_unref(&di->job->job); -+ di->job = NULL; -+ aio_context_release(ctx); -+ } -+ - // remove self from job list - backup_state.di_list = g_list_remove(backup_state.di_list, di); - -@@ -491,9 +499,12 @@ static void create_backup_jobs_bh(void *opaque) { - bitmap_mode, false, NULL, &perf, BLOCKDEV_ON_ERROR_REPORT, BLOCKDEV_ON_ERROR_REPORT, - JOB_DEFAULT, pvebackup_complete_cb, di, backup_state.txn, &local_err); - -- aio_context_release(aio_context); -- - di->job = job; -+ if (job) { -+ job_ref(&job->job); -+ } -+ -+ aio_context_release(aio_context); - - if (!job || local_err) { - error_setg(errp, "backup_job_create failed: %s", -@@ -521,12 +532,16 @@ static void create_backup_jobs_bh(void *opaque) { - di->target = NULL; - } - -- if (!canceled && di->job) { -+ if (di->job) { - AioContext *ctx = di->job->job.aio_context; - aio_context_acquire(ctx); -- job_cancel_sync(&di->job->job, true); -+ if (!canceled) { -+ job_cancel_sync(&di->job->job, true); -+ canceled = true; -+ } -+ job_unref(&di->job->job); -+ di->job = NULL; - aio_context_release(ctx); -- canceled = true; - } - } - }