From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Fabian Ebner Date: Wed, 25 May 2022 13:59:37 +0200 Subject: [PATCH] PVE-Backup: create jobs: correctly cancel in error scenario The first call to job_cancel_sync() will cancel and free all jobs in the transaction, so ensure that it's called only once and get rid of the job_unref() that would operate on freed memory. It's also necessary to NULL backup_state.pbs in the error scenario, because a subsequent backup_cancel QMP call (as happens in PVE when the backup QMP command fails) would try to call proxmox_backup_abort() and run into a segfault. Signed-off-by: Fiona Ebner Signed-off-by: Wolfgang Bumiller [FE: adapt for new job lock mechanism replacing AioContext locks] Signed-off-by: Fiona Ebner --- pve-backup.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pve-backup.c b/pve-backup.c index 809ff6d134..221e45ed0e 100644 --- a/pve-backup.c +++ b/pve-backup.c @@ -505,6 +505,11 @@ static void create_backup_jobs_bh(void *opaque) { } if (*errp) { + /* + * It's enough to cancel one job in the transaction, the rest will + * follow automatically. + */ + bool canceled = false; l = backup_state.di_list; while (l) { PVEBackupDevInfo *di = (PVEBackupDevInfo *)l->data; @@ -515,11 +520,11 @@ static void create_backup_jobs_bh(void *opaque) { di->target = NULL; } - if (di->job) { + if (!canceled && di->job) { WITH_JOB_LOCK_GUARD() { job_cancel_sync_locked(&di->job->job, true); - job_unref_locked(&di->job->job); } + canceled = true; } } } @@ -945,6 +950,7 @@ err: if (pbs) { proxmox_backup_disconnect(pbs); + backup_state.pbs = NULL; } if (backup_dir) {