avoid using QemuRecMutex inside coroutines, QemuMutex to lock outside
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
This commit is contained in:
		
							parent
							
								
									9e4a452f24
								
							
						
					
					
						commit
						751ed3661b
					
				
							
								
								
									
										211
									
								
								debian/patches/pve/0041-PVE-Backup-avoid-use-QemuRecMutex-inside-coroutines.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										211
									
								
								debian/patches/pve/0041-PVE-Backup-avoid-use-QemuRecMutex-inside-coroutines.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,211 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Dietmar Maurer <dietmar@proxmox.com> | ||||||
|  | Date: Fri, 17 Apr 2020 08:57:47 +0200 | ||||||
|  | Subject: [PATCH] PVE Backup: avoid use QemuRecMutex inside coroutines | ||||||
|  | 
 | ||||||
|  | ---
 | ||||||
|  |  pve-backup.c | 59 +++++++++++++++++++++++++++++++++------------------- | ||||||
|  |  1 file changed, 38 insertions(+), 21 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/pve-backup.c b/pve-backup.c
 | ||||||
|  | index 169f0c68d0..dddf430399 100644
 | ||||||
|  | --- a/pve-backup.c
 | ||||||
|  | +++ b/pve-backup.c
 | ||||||
|  | @@ -11,6 +11,23 @@
 | ||||||
|  |   | ||||||
|  |  /* PVE backup state and related function */ | ||||||
|  |   | ||||||
|  | +/*
 | ||||||
|  | + * Note: A resume from a qemu_coroutine_yield can happen in a different thread,
 | ||||||
|  | + * so you may not use normal mutexes within coroutines:
 | ||||||
|  | + *
 | ||||||
|  | + * ---bad-example---
 | ||||||
|  | + * qemu_rec_mutex_lock(lock)
 | ||||||
|  | + * ...
 | ||||||
|  | + * qemu_coroutine_yield() // wait for something
 | ||||||
|  | + * // we are now inside a different thread
 | ||||||
|  | + * qemu_rec_mutex_unlock(lock) // Crash - wrong thread!!
 | ||||||
|  | + * ---end-bad-example--
 | ||||||
|  | + *
 | ||||||
|  | + * ==> Always use CoMutext inside coroutines.
 | ||||||
|  | + * ==> Never acquire/release AioContext withing coroutines (because that use QemuRecMutex)
 | ||||||
|  | + *
 | ||||||
|  | + */
 | ||||||
|  | +
 | ||||||
|  |  static struct PVEBackupState { | ||||||
|  |      struct { | ||||||
|  |          // Everithing accessed from qmp_backup_query command is protected using lock | ||||||
|  | @@ -30,12 +47,14 @@ static struct PVEBackupState {
 | ||||||
|  |      ProxmoxBackupHandle *pbs; | ||||||
|  |      GList *di_list; | ||||||
|  |      QemuRecMutex backup_mutex; | ||||||
|  | +    CoMutex dump_callback_mutex;
 | ||||||
|  |  } backup_state; | ||||||
|  |   | ||||||
|  |  static void pvebackup_init(void) | ||||||
|  |  { | ||||||
|  |      qemu_rec_mutex_init(&backup_state.stat.lock); | ||||||
|  |      qemu_rec_mutex_init(&backup_state.backup_mutex); | ||||||
|  | +    qemu_co_mutex_init(&backup_state.dump_callback_mutex);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  // initialize PVEBackupState at startup | ||||||
|  | @@ -114,16 +133,16 @@ pvebackup_co_dump_pbs_cb(
 | ||||||
|  |      Error *local_err = NULL; | ||||||
|  |      int pbs_res = -1; | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  | +    qemu_co_mutex_lock(&backup_state.dump_callback_mutex);
 | ||||||
|  |   | ||||||
|  |      // avoid deadlock if job is cancelled | ||||||
|  |      if (pvebackup_error_or_canceled()) { | ||||||
|  | -        qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | +        qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
 | ||||||
|  |          return -1; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      pbs_res = proxmox_backup_co_write_data(backup_state.pbs, di->dev_id, buf, start, size, &local_err); | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | +    qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
 | ||||||
|  |   | ||||||
|  |      if (pbs_res < 0) { | ||||||
|  |          pvebackup_propagate_error(local_err); | ||||||
|  | @@ -149,7 +168,6 @@ pvebackup_co_dump_vma_cb(
 | ||||||
|  |      const unsigned char *buf = pbuf; | ||||||
|  |      PVEBackupDevInfo *di = opaque; | ||||||
|  |   | ||||||
|  | -
 | ||||||
|  |      int ret = -1; | ||||||
|  |   | ||||||
|  |      assert(backup_state.vmaw); | ||||||
|  | @@ -167,16 +185,16 @@ pvebackup_co_dump_vma_cb(
 | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      while (remaining > 0) { | ||||||
|  | -        qemu_rec_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  | +        qemu_co_mutex_lock(&backup_state.dump_callback_mutex);
 | ||||||
|  |          // avoid deadlock if job is cancelled | ||||||
|  |          if (pvebackup_error_or_canceled()) { | ||||||
|  | -            qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | +            qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
 | ||||||
|  |              return -1; | ||||||
|  |          } | ||||||
|  |   | ||||||
|  |          size_t zero_bytes = 0; | ||||||
|  |          ret = vma_writer_write(backup_state.vmaw, di->dev_id, cluster_num, buf, &zero_bytes); | ||||||
|  | -        qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | +        qemu_co_mutex_unlock(&backup_state.dump_callback_mutex);
 | ||||||
|  |   | ||||||
|  |          ++cluster_num; | ||||||
|  |          if (buf) { | ||||||
|  | @@ -203,12 +221,11 @@ pvebackup_co_dump_vma_cb(
 | ||||||
|  |      return size; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +// assumes the caller holds backup_mutex
 | ||||||
|  |  static void coroutine_fn pvebackup_co_cleanup(void *unused) | ||||||
|  |  { | ||||||
|  |      assert(qemu_in_coroutine()); | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  | -
 | ||||||
|  |      qemu_rec_mutex_lock(&backup_state.stat.lock); | ||||||
|  |      backup_state.stat.end_time = time(NULL); | ||||||
|  |      qemu_rec_mutex_unlock(&backup_state.stat.lock); | ||||||
|  | @@ -239,9 +256,9 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
 | ||||||
|  |   | ||||||
|  |      g_list_free(backup_state.di_list); | ||||||
|  |      backup_state.di_list = NULL; | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +// assumes the caller holds backup_mutex
 | ||||||
|  |  static void coroutine_fn pvebackup_complete_stream(void *opaque) | ||||||
|  |  { | ||||||
|  |      PVEBackupDevInfo *di = opaque; | ||||||
|  | @@ -295,6 +312,8 @@ static void pvebackup_complete_cb(void *opaque, int ret)
 | ||||||
|  |   | ||||||
|  |  static void pvebackup_cancel(void) | ||||||
|  |  { | ||||||
|  | +    assert(!qemu_in_coroutine());
 | ||||||
|  | +
 | ||||||
|  |      Error *cancel_err = NULL; | ||||||
|  |      error_setg(&cancel_err, "backup canceled"); | ||||||
|  |      pvebackup_propagate_error(cancel_err); | ||||||
|  | @@ -348,6 +367,7 @@ void qmp_backup_cancel(Error **errp)
 | ||||||
|  |      pvebackup_cancel(); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +// assumes the caller holds backup_mutex
 | ||||||
|  |  static int coroutine_fn pvebackup_co_add_config( | ||||||
|  |      const char *file, | ||||||
|  |      const char *name, | ||||||
|  | @@ -431,9 +451,9 @@ static void pvebackup_run_next_job(void)
 | ||||||
|  |          } | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | -
 | ||||||
|  |      block_on_coroutine_fn(pvebackup_co_cleanup, NULL); // no more jobs, run cleanup | ||||||
|  | +
 | ||||||
|  | +    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static bool create_backup_jobs(void) { | ||||||
|  | @@ -520,6 +540,7 @@ typedef struct QmpBackupTask {
 | ||||||
|  |      UuidInfo *result; | ||||||
|  |  } QmpBackupTask; | ||||||
|  |   | ||||||
|  | +// assumes the caller holds backup_mutex
 | ||||||
|  |  static void coroutine_fn pvebackup_co_prepare(void *opaque) | ||||||
|  |  { | ||||||
|  |      assert(qemu_in_coroutine()); | ||||||
|  | @@ -543,11 +564,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
 | ||||||
|  |      const char *config_name = "qemu-server.conf"; | ||||||
|  |      const char *firewall_name = "qemu-server.fw"; | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  | -
 | ||||||
|  |      if (backup_state.di_list) { | ||||||
|  | -        qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | -        error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
 | ||||||
|  | +         error_set(task->errp, ERROR_CLASS_GENERIC_ERROR,
 | ||||||
|  |                    "previous backup not finished"); | ||||||
|  |          return; | ||||||
|  |      } | ||||||
|  | @@ -792,8 +810,6 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
 | ||||||
|  |   | ||||||
|  |      backup_state.di_list = di_list; | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | -
 | ||||||
|  |      uuid_info = g_malloc0(sizeof(*uuid_info)); | ||||||
|  |      uuid_info->UUID = uuid_str; | ||||||
|  |   | ||||||
|  | @@ -836,8 +852,6 @@ err:
 | ||||||
|  |          rmdir(backup_dir); | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | -
 | ||||||
|  |      task->result = NULL; | ||||||
|  |      return; | ||||||
|  |  } | ||||||
|  | @@ -881,13 +895,16 @@ UuidInfo *qmp_backup(
 | ||||||
|  |          .errp = errp, | ||||||
|  |      }; | ||||||
|  |   | ||||||
|  | +    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  | +
 | ||||||
|  |      block_on_coroutine_fn(pvebackup_co_prepare, &task); | ||||||
|  |   | ||||||
|  |      if (*errp == NULL) { | ||||||
|  | -        qemu_rec_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  |          create_backup_jobs(); | ||||||
|  |          qemu_rec_mutex_unlock(&backup_state.backup_mutex); | ||||||
|  |          pvebackup_run_next_job(); | ||||||
|  | +    } else {
 | ||||||
|  | +        qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      return task.result; | ||||||
| @ -1,403 +0,0 @@ | |||||||
| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |  | ||||||
| From: Stefan Reiter <s.reiter@proxmox.com> |  | ||||||
| Date: Thu, 16 Apr 2020 11:40:16 +0200 |  | ||||||
| Subject: [PATCH] PVE: Use non-recursive locks |  | ||||||
| 
 |  | ||||||
| Release the lock on qemu_coroutine_yield, so coroutines don't deadlock. |  | ||||||
| 
 |  | ||||||
| Signed-off-by: Stefan Reiter <s.reiter@proxmox.com> |  | ||||||
| ---
 |  | ||||||
|  pve-backup.c | 82 +++++++++++++++++++++++++++------------------------- |  | ||||||
|  vma-writer.c | 28 ++++++++++++++---- |  | ||||||
|  vma.h        |  1 + |  | ||||||
|  3 files changed, 66 insertions(+), 45 deletions(-) |  | ||||||
| 
 |  | ||||||
| diff --git a/pve-backup.c b/pve-backup.c
 |  | ||||||
| index 169f0c68d0..46a3d6f995 100644
 |  | ||||||
| --- a/pve-backup.c
 |  | ||||||
| +++ b/pve-backup.c
 |  | ||||||
| @@ -14,7 +14,7 @@
 |  | ||||||
|  static struct PVEBackupState { |  | ||||||
|      struct { |  | ||||||
|          // Everithing accessed from qmp_backup_query command is protected using lock |  | ||||||
| -        QemuRecMutex lock;
 |  | ||||||
| +        QemuMutex lock;
 |  | ||||||
|          Error *error; |  | ||||||
|          time_t start_time; |  | ||||||
|          time_t end_time; |  | ||||||
| @@ -29,13 +29,13 @@ static struct PVEBackupState {
 |  | ||||||
|      VmaWriter *vmaw; |  | ||||||
|      ProxmoxBackupHandle *pbs; |  | ||||||
|      GList *di_list; |  | ||||||
| -    QemuRecMutex backup_mutex;
 |  | ||||||
| +    QemuMutex backup_mutex;
 |  | ||||||
|  } backup_state; |  | ||||||
|   |  | ||||||
|  static void pvebackup_init(void) |  | ||||||
|  { |  | ||||||
| -    qemu_rec_mutex_init(&backup_state.stat.lock);
 |  | ||||||
| -    qemu_rec_mutex_init(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_init(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_init(&backup_state.backup_mutex);
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  // initialize PVEBackupState at startup |  | ||||||
| @@ -72,26 +72,26 @@ lookup_active_block_job(PVEBackupDevInfo *di)
 |  | ||||||
|   |  | ||||||
|  static void pvebackup_propagate_error(Error *err) |  | ||||||
|  { |  | ||||||
| -    qemu_rec_mutex_lock(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_lock(&backup_state.stat.lock);
 |  | ||||||
|      error_propagate(&backup_state.stat.error, err); |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static bool pvebackup_error_or_canceled(void) |  | ||||||
|  { |  | ||||||
| -    qemu_rec_mutex_lock(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_lock(&backup_state.stat.lock);
 |  | ||||||
|      bool error_or_canceled = !!backup_state.stat.error; |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
|   |  | ||||||
|      return error_or_canceled; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static void pvebackup_add_transfered_bytes(size_t transferred, size_t zero_bytes) |  | ||||||
|  { |  | ||||||
| -    qemu_rec_mutex_lock(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_lock(&backup_state.stat.lock);
 |  | ||||||
|      backup_state.stat.zero_bytes += zero_bytes; |  | ||||||
|      backup_state.stat.transferred += transferred; |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  // This may get called from multiple coroutines in multiple io-threads |  | ||||||
| @@ -114,16 +114,16 @@ pvebackup_co_dump_pbs_cb(
 |  | ||||||
|      Error *local_err = NULL; |  | ||||||
|      int pbs_res = -1; |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|      // avoid deadlock if job is cancelled |  | ||||||
|      if (pvebackup_error_or_canceled()) { |  | ||||||
| -        qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +        qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|          return -1; |  | ||||||
|      } |  | ||||||
|   |  | ||||||
|      pbs_res = proxmox_backup_co_write_data(backup_state.pbs, di->dev_id, buf, start, size, &local_err); |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|      if (pbs_res < 0) { |  | ||||||
|          pvebackup_propagate_error(local_err); |  | ||||||
| @@ -167,16 +167,16 @@ pvebackup_co_dump_vma_cb(
 |  | ||||||
|      } |  | ||||||
|   |  | ||||||
|      while (remaining > 0) { |  | ||||||
| -        qemu_rec_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
| +        qemu_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
|          // avoid deadlock if job is cancelled |  | ||||||
|          if (pvebackup_error_or_canceled()) { |  | ||||||
| -            qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +            qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|              return -1; |  | ||||||
|          } |  | ||||||
|   |  | ||||||
|          size_t zero_bytes = 0; |  | ||||||
|          ret = vma_writer_write(backup_state.vmaw, di->dev_id, cluster_num, buf, &zero_bytes); |  | ||||||
| -        qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +        qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|          ++cluster_num; |  | ||||||
|          if (buf) { |  | ||||||
| @@ -207,11 +207,11 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
 |  | ||||||
|  { |  | ||||||
|      assert(qemu_in_coroutine()); |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_lock(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_lock(&backup_state.stat.lock);
 |  | ||||||
|      backup_state.stat.end_time = time(NULL); |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
|   |  | ||||||
|      if (backup_state.vmaw) { |  | ||||||
|          Error *local_err = NULL; |  | ||||||
| @@ -239,7 +239,7 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
 |  | ||||||
|   |  | ||||||
|      g_list_free(backup_state.di_list); |  | ||||||
|      backup_state.di_list = NULL; |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|  } |  | ||||||
|   |  | ||||||
|  static void coroutine_fn pvebackup_complete_stream(void *opaque) |  | ||||||
| @@ -267,7 +267,7 @@ static void pvebackup_complete_cb(void *opaque, int ret)
 |  | ||||||
|   |  | ||||||
|      PVEBackupDevInfo *di = opaque; |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|      di->completed = true; |  | ||||||
|   |  | ||||||
| @@ -288,7 +288,7 @@ static void pvebackup_complete_cb(void *opaque, int ret)
 |  | ||||||
|   |  | ||||||
|      g_free(di); |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|      pvebackup_run_next_job(); |  | ||||||
|  } |  | ||||||
| @@ -299,7 +299,7 @@ static void pvebackup_cancel(void)
 |  | ||||||
|      error_setg(&cancel_err, "backup canceled"); |  | ||||||
|      pvebackup_propagate_error(cancel_err); |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|      if (backup_state.vmaw) { |  | ||||||
|          /* make sure vma writer does not block anymore */ |  | ||||||
| @@ -310,13 +310,13 @@ static void pvebackup_cancel(void)
 |  | ||||||
|          proxmox_backup_abort(backup_state.pbs, "backup canceled"); |  | ||||||
|      } |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|      for(;;) { |  | ||||||
|   |  | ||||||
|          BlockJob *next_job = NULL; |  | ||||||
|   |  | ||||||
| -        qemu_rec_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
| +        qemu_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|          GList *l = backup_state.di_list; |  | ||||||
|          while (l) { |  | ||||||
| @@ -330,7 +330,7 @@ static void pvebackup_cancel(void)
 |  | ||||||
|              } |  | ||||||
|          } |  | ||||||
|   |  | ||||||
| -        qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +        qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|          if (next_job) { |  | ||||||
|              AioContext *aio_context = next_job->job.aio_context; |  | ||||||
| @@ -403,7 +403,7 @@ static void pvebackup_run_next_job(void)
 |  | ||||||
|  { |  | ||||||
|      assert(!qemu_in_coroutine()); |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|      GList *l = backup_state.di_list; |  | ||||||
|      while (l) { |  | ||||||
| @@ -413,7 +413,7 @@ static void pvebackup_run_next_job(void)
 |  | ||||||
|          BlockJob *job = lookup_active_block_job(di); |  | ||||||
|   |  | ||||||
|          if (job) { |  | ||||||
| -            qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +            qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|              AioContext *aio_context = job->job.aio_context; |  | ||||||
|              aio_context_acquire(aio_context); |  | ||||||
| @@ -431,7 +431,7 @@ static void pvebackup_run_next_job(void)
 |  | ||||||
|          } |  | ||||||
|      } |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|      block_on_coroutine_fn(pvebackup_co_cleanup, NULL); // no more jobs, run cleanup |  | ||||||
|  } |  | ||||||
| @@ -543,10 +543,10 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
 |  | ||||||
|      const char *config_name = "qemu-server.conf"; |  | ||||||
|      const char *firewall_name = "qemu-server.fw"; |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|      if (backup_state.di_list) { |  | ||||||
| -        qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +        qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|          error_set(task->errp, ERROR_CLASS_GENERIC_ERROR, |  | ||||||
|                    "previous backup not finished"); |  | ||||||
|          return; |  | ||||||
| @@ -689,6 +689,8 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
 |  | ||||||
|              goto err; |  | ||||||
|          } |  | ||||||
|   |  | ||||||
| +	vma_writer_set_external_lock(vmaw, &backup_state.backup_mutex);
 |  | ||||||
| +
 |  | ||||||
|          /* register all devices for vma writer */ |  | ||||||
|          l = di_list; |  | ||||||
|          while (l) { |  | ||||||
| @@ -760,7 +762,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
 |  | ||||||
|      } |  | ||||||
|      /* initialize global backup_state now */ |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_lock(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_lock(&backup_state.stat.lock);
 |  | ||||||
|   |  | ||||||
|      if (backup_state.stat.error) { |  | ||||||
|          error_free(backup_state.stat.error); |  | ||||||
| @@ -783,7 +785,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
 |  | ||||||
|      backup_state.stat.transferred = 0; |  | ||||||
|      backup_state.stat.zero_bytes = 0; |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
|   |  | ||||||
|      backup_state.speed = (task->has_speed && task->speed > 0) ? task->speed : 0; |  | ||||||
|   |  | ||||||
| @@ -792,7 +794,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
 |  | ||||||
|   |  | ||||||
|      backup_state.di_list = di_list; |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|      uuid_info = g_malloc0(sizeof(*uuid_info)); |  | ||||||
|      uuid_info->UUID = uuid_str; |  | ||||||
| @@ -836,7 +838,7 @@ err:
 |  | ||||||
|          rmdir(backup_dir); |  | ||||||
|      } |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|   |  | ||||||
|      task->result = NULL; |  | ||||||
|      return; |  | ||||||
| @@ -884,9 +886,9 @@ UuidInfo *qmp_backup(
 |  | ||||||
|      block_on_coroutine_fn(pvebackup_co_prepare, &task); |  | ||||||
|   |  | ||||||
|      if (*errp == NULL) { |  | ||||||
| -        qemu_rec_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
| +        qemu_mutex_lock(&backup_state.backup_mutex);
 |  | ||||||
|          create_backup_jobs(); |  | ||||||
| -        qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
| +        qemu_mutex_unlock(&backup_state.backup_mutex);
 |  | ||||||
|          pvebackup_run_next_job(); |  | ||||||
|      } |  | ||||||
|   |  | ||||||
| @@ -897,11 +899,11 @@ BackupStatus *qmp_query_backup(Error **errp)
 |  | ||||||
|  { |  | ||||||
|      BackupStatus *info = g_malloc0(sizeof(*info)); |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_lock(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_lock(&backup_state.stat.lock);
 |  | ||||||
|   |  | ||||||
|      if (!backup_state.stat.start_time) { |  | ||||||
|          /* not started, return {} */ |  | ||||||
| -        qemu_rec_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
| +        qemu_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
|          return info; |  | ||||||
|      } |  | ||||||
|   |  | ||||||
| @@ -938,7 +940,7 @@ BackupStatus *qmp_query_backup(Error **errp)
 |  | ||||||
|      info->has_transferred = true; |  | ||||||
|      info->transferred = backup_state.stat.transferred; |  | ||||||
|   |  | ||||||
| -    qemu_rec_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
| +    qemu_mutex_unlock(&backup_state.stat.lock);
 |  | ||||||
|   |  | ||||||
|      return info; |  | ||||||
|  } |  | ||||||
| diff --git a/vma-writer.c b/vma-writer.c
 |  | ||||||
| index fe86b18a60..f3fa8e3b4c 100644
 |  | ||||||
| --- a/vma-writer.c
 |  | ||||||
| +++ b/vma-writer.c
 |  | ||||||
| @@ -68,8 +68,14 @@ struct VmaWriter {
 |  | ||||||
|      uint32_t config_names[VMA_MAX_CONFIGS]; /* offset into blob_buffer table */ |  | ||||||
|      uint32_t config_data[VMA_MAX_CONFIGS];  /* offset into blob_buffer table */ |  | ||||||
|      uint32_t config_count; |  | ||||||
| +
 |  | ||||||
| +    QemuMutex *external_lock;
 |  | ||||||
|  }; |  | ||||||
|   |  | ||||||
| +void vma_writer_set_external_lock(VmaWriter *vmaw, QemuMutex *lock) {
 |  | ||||||
| +    vmaw->external_lock = lock;
 |  | ||||||
| +}
 |  | ||||||
| +
 |  | ||||||
|  void vma_writer_set_error(VmaWriter *vmaw, const char *fmt, ...) |  | ||||||
|  { |  | ||||||
|      va_list ap; |  | ||||||
| @@ -199,13 +205,20 @@ int vma_writer_register_stream(VmaWriter *vmaw, const char *devname,
 |  | ||||||
|      return n; |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| -static void coroutine_fn yield_until_fd_writable(int fd)
 |  | ||||||
| +static void coroutine_fn yield_until_fd_writable(int fd, QemuMutex *external_lock)
 |  | ||||||
|  { |  | ||||||
|      assert(qemu_in_coroutine()); |  | ||||||
|      AioContext *ctx = qemu_get_current_aio_context(); |  | ||||||
|      aio_set_fd_handler(ctx, fd, false, NULL, (IOHandler *)qemu_coroutine_enter, |  | ||||||
|                         NULL, qemu_coroutine_self()); |  | ||||||
| +    if (external_lock) {
 |  | ||||||
| +	/* still protected from re-entering via flush_lock */
 |  | ||||||
| +	qemu_mutex_unlock(external_lock);
 |  | ||||||
| +    }
 |  | ||||||
|      qemu_coroutine_yield(); |  | ||||||
| +    if (!external_lock) {
 |  | ||||||
| +	qemu_mutex_lock(external_lock);
 |  | ||||||
| +    }
 |  | ||||||
|      aio_set_fd_handler(ctx, fd, false, NULL, NULL, NULL, NULL); |  | ||||||
|  } |  | ||||||
|   |  | ||||||
| @@ -227,11 +240,16 @@ vma_queue_write(VmaWriter *vmaw, const void *buf, size_t bytes)
 |  | ||||||
|   |  | ||||||
|      while (done < bytes) { |  | ||||||
|          if (vmaw->status < 0) { |  | ||||||
| -            DPRINTF("vma_queue_write detected canceled backup\n");
 |  | ||||||
| +            DPRINTF("vma_queue_write detected cancelled backup\n");
 |  | ||||||
| +            done = -1;
 |  | ||||||
| +            break;
 |  | ||||||
| +        }
 |  | ||||||
| +        yield_until_fd_writable(vmaw->fd, vmaw->external_lock);
 |  | ||||||
| +        if (vmaw->closed || vmaw->status < 0) {
 |  | ||||||
| +            DPRINTF("vma_queue_write backup cancelled after waiting for fd\n");
 |  | ||||||
|              done = -1; |  | ||||||
|              break; |  | ||||||
|          } |  | ||||||
| -        yield_until_fd_writable(vmaw->fd);
 |  | ||||||
|          ret = write(vmaw->fd, buf + done, bytes - done); |  | ||||||
|          if (ret > 0) { |  | ||||||
|              done += ret; |  | ||||||
| @@ -501,7 +519,7 @@ vma_writer_flush_output(VmaWriter *vmaw)
 |  | ||||||
|      int ret = vma_writer_flush(vmaw); |  | ||||||
|      qemu_co_mutex_unlock(&vmaw->flush_lock); |  | ||||||
|      if (ret < 0) { |  | ||||||
| -        vma_writer_set_error(vmaw, "vma_writer_flush_header failed");
 |  | ||||||
| +        vma_writer_set_error(vmaw, "vma_writer_flush_output failed");
 |  | ||||||
|      } |  | ||||||
|      return ret; |  | ||||||
|  } |  | ||||||
| @@ -570,7 +588,7 @@ static int vma_writer_get_buffer(VmaWriter *vmaw)
 |  | ||||||
|      while (vmaw->outbuf_count >= (VMA_BLOCKS_PER_EXTENT - 1)) { |  | ||||||
|          ret = vma_writer_flush(vmaw); |  | ||||||
|          if (ret < 0) { |  | ||||||
| -            vma_writer_set_error(vmaw, "vma_writer_get_buffer: flush failed");
 |  | ||||||
| +            vma_writer_set_error(vmaw, "vma_writer_get_header: flush failed");
 |  | ||||||
|              break; |  | ||||||
|          } |  | ||||||
|      } |  | ||||||
| diff --git a/vma.h b/vma.h
 |  | ||||||
| index c895c97f6d..ec6f09e83e 100644
 |  | ||||||
| --- a/vma.h
 |  | ||||||
| +++ b/vma.h
 |  | ||||||
| @@ -115,6 +115,7 @@ typedef struct VmaDeviceInfo {
 |  | ||||||
|  } VmaDeviceInfo; |  | ||||||
|   |  | ||||||
|  VmaWriter *vma_writer_create(const char *filename, uuid_t uuid, Error **errp); |  | ||||||
| +void vma_writer_set_external_lock(VmaWriter *vmaw, QemuMutex *lock);
 |  | ||||||
|  int vma_writer_close(VmaWriter *vmaw, Error **errp); |  | ||||||
|  void vma_writer_error_propagate(VmaWriter *vmaw, Error **errp); |  | ||||||
|  void vma_writer_destroy(VmaWriter *vmaw); |  | ||||||
							
								
								
									
										227
									
								
								debian/patches/pve/0042-PVE-Backup-use-QemuMutex-instead-of-QemuRecMutex.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										227
									
								
								debian/patches/pve/0042-PVE-Backup-use-QemuMutex-instead-of-QemuRecMutex.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,227 @@ | |||||||
|  | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: Dietmar Maurer <dietmar@proxmox.com> | ||||||
|  | Date: Fri, 17 Apr 2020 08:57:48 +0200 | ||||||
|  | Subject: [PATCH] PVE Backup: use QemuMutex instead of QemuRecMutex | ||||||
|  | 
 | ||||||
|  | We acquire/release all mutexes outside coroutines now, so we can now | ||||||
|  | correctly use a normal mutex. | ||||||
|  | ---
 | ||||||
|  |  pve-backup.c | 58 ++++++++++++++++++++++++++-------------------------- | ||||||
|  |  1 file changed, 29 insertions(+), 29 deletions(-) | ||||||
|  | 
 | ||||||
|  | diff --git a/pve-backup.c b/pve-backup.c
 | ||||||
|  | index dddf430399..bb917ee972 100644
 | ||||||
|  | --- a/pve-backup.c
 | ||||||
|  | +++ b/pve-backup.c
 | ||||||
|  | @@ -31,7 +31,7 @@
 | ||||||
|  |  static struct PVEBackupState { | ||||||
|  |      struct { | ||||||
|  |          // Everithing accessed from qmp_backup_query command is protected using lock | ||||||
|  | -        QemuRecMutex lock;
 | ||||||
|  | +        QemuMutex lock;
 | ||||||
|  |          Error *error; | ||||||
|  |          time_t start_time; | ||||||
|  |          time_t end_time; | ||||||
|  | @@ -46,14 +46,14 @@ static struct PVEBackupState {
 | ||||||
|  |      VmaWriter *vmaw; | ||||||
|  |      ProxmoxBackupHandle *pbs; | ||||||
|  |      GList *di_list; | ||||||
|  | -    QemuRecMutex backup_mutex;
 | ||||||
|  | +    QemuMutex backup_mutex;
 | ||||||
|  |      CoMutex dump_callback_mutex; | ||||||
|  |  } backup_state; | ||||||
|  |   | ||||||
|  |  static void pvebackup_init(void) | ||||||
|  |  { | ||||||
|  | -    qemu_rec_mutex_init(&backup_state.stat.lock);
 | ||||||
|  | -    qemu_rec_mutex_init(&backup_state.backup_mutex);
 | ||||||
|  | +    qemu_mutex_init(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_init(&backup_state.backup_mutex);
 | ||||||
|  |      qemu_co_mutex_init(&backup_state.dump_callback_mutex); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | @@ -91,26 +91,26 @@ lookup_active_block_job(PVEBackupDevInfo *di)
 | ||||||
|  |   | ||||||
|  |  static void pvebackup_propagate_error(Error *err) | ||||||
|  |  { | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_lock(&backup_state.stat.lock);
 | ||||||
|  |      error_propagate(&backup_state.stat.error, err); | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static bool pvebackup_error_or_canceled(void) | ||||||
|  |  { | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_lock(&backup_state.stat.lock);
 | ||||||
|  |      bool error_or_canceled = !!backup_state.stat.error; | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  |   | ||||||
|  |      return error_or_canceled; | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static void pvebackup_add_transfered_bytes(size_t transferred, size_t zero_bytes) | ||||||
|  |  { | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_lock(&backup_state.stat.lock);
 | ||||||
|  |      backup_state.stat.zero_bytes += zero_bytes; | ||||||
|  |      backup_state.stat.transferred += transferred; | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  // This may get called from multiple coroutines in multiple io-threads | ||||||
|  | @@ -226,9 +226,9 @@ static void coroutine_fn pvebackup_co_cleanup(void *unused)
 | ||||||
|  |  { | ||||||
|  |      assert(qemu_in_coroutine()); | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_lock(&backup_state.stat.lock);
 | ||||||
|  |      backup_state.stat.end_time = time(NULL); | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  |   | ||||||
|  |      if (backup_state.vmaw) { | ||||||
|  |          Error *local_err = NULL; | ||||||
|  | @@ -284,7 +284,7 @@ static void pvebackup_complete_cb(void *opaque, int ret)
 | ||||||
|  |   | ||||||
|  |      PVEBackupDevInfo *di = opaque; | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  | +    qemu_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  |   | ||||||
|  |      di->completed = true; | ||||||
|  |   | ||||||
|  | @@ -305,7 +305,7 @@ static void pvebackup_complete_cb(void *opaque, int ret)
 | ||||||
|  |   | ||||||
|  |      g_free(di); | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | +    qemu_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  |   | ||||||
|  |      pvebackup_run_next_job(); | ||||||
|  |  } | ||||||
|  | @@ -318,7 +318,7 @@ static void pvebackup_cancel(void)
 | ||||||
|  |      error_setg(&cancel_err, "backup canceled"); | ||||||
|  |      pvebackup_propagate_error(cancel_err); | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  | +    qemu_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  |   | ||||||
|  |      if (backup_state.vmaw) { | ||||||
|  |          /* make sure vma writer does not block anymore */ | ||||||
|  | @@ -329,13 +329,13 @@ static void pvebackup_cancel(void)
 | ||||||
|  |          proxmox_backup_abort(backup_state.pbs, "backup canceled"); | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | +    qemu_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  |   | ||||||
|  |      for(;;) { | ||||||
|  |   | ||||||
|  |          BlockJob *next_job = NULL; | ||||||
|  |   | ||||||
|  | -        qemu_rec_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  | +        qemu_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  |   | ||||||
|  |          GList *l = backup_state.di_list; | ||||||
|  |          while (l) { | ||||||
|  | @@ -349,7 +349,7 @@ static void pvebackup_cancel(void)
 | ||||||
|  |              } | ||||||
|  |          } | ||||||
|  |   | ||||||
|  | -        qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | +        qemu_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  |   | ||||||
|  |          if (next_job) { | ||||||
|  |              AioContext *aio_context = next_job->job.aio_context; | ||||||
|  | @@ -423,7 +423,7 @@ static void pvebackup_run_next_job(void)
 | ||||||
|  |  { | ||||||
|  |      assert(!qemu_in_coroutine()); | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  | +    qemu_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  |   | ||||||
|  |      GList *l = backup_state.di_list; | ||||||
|  |      while (l) { | ||||||
|  | @@ -433,7 +433,7 @@ static void pvebackup_run_next_job(void)
 | ||||||
|  |          BlockJob *job = lookup_active_block_job(di); | ||||||
|  |   | ||||||
|  |          if (job) { | ||||||
|  | -            qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | +            qemu_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  |   | ||||||
|  |              AioContext *aio_context = job->job.aio_context; | ||||||
|  |              aio_context_acquire(aio_context); | ||||||
|  | @@ -453,7 +453,7 @@ static void pvebackup_run_next_job(void)
 | ||||||
|  |   | ||||||
|  |      block_on_coroutine_fn(pvebackup_co_cleanup, NULL); // no more jobs, run cleanup | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | +    qemu_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  |  } | ||||||
|  |   | ||||||
|  |  static bool create_backup_jobs(void) { | ||||||
|  | @@ -778,7 +778,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
 | ||||||
|  |      } | ||||||
|  |      /* initialize global backup_state now */ | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_lock(&backup_state.stat.lock);
 | ||||||
|  |   | ||||||
|  |      if (backup_state.stat.error) { | ||||||
|  |          error_free(backup_state.stat.error); | ||||||
|  | @@ -801,7 +801,7 @@ static void coroutine_fn pvebackup_co_prepare(void *opaque)
 | ||||||
|  |      backup_state.stat.transferred = 0; | ||||||
|  |      backup_state.stat.zero_bytes = 0; | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  |   | ||||||
|  |      backup_state.speed = (task->has_speed && task->speed > 0) ? task->speed : 0; | ||||||
|  |   | ||||||
|  | @@ -895,16 +895,16 @@ UuidInfo *qmp_backup(
 | ||||||
|  |          .errp = errp, | ||||||
|  |      }; | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  | +    qemu_mutex_lock(&backup_state.backup_mutex);
 | ||||||
|  |   | ||||||
|  |      block_on_coroutine_fn(pvebackup_co_prepare, &task); | ||||||
|  |   | ||||||
|  |      if (*errp == NULL) { | ||||||
|  |          create_backup_jobs(); | ||||||
|  | -        qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | +        qemu_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  |          pvebackup_run_next_job(); | ||||||
|  |      } else { | ||||||
|  | -        qemu_rec_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  | +        qemu_mutex_unlock(&backup_state.backup_mutex);
 | ||||||
|  |      } | ||||||
|  |   | ||||||
|  |      return task.result; | ||||||
|  | @@ -914,11 +914,11 @@ BackupStatus *qmp_query_backup(Error **errp)
 | ||||||
|  |  { | ||||||
|  |      BackupStatus *info = g_malloc0(sizeof(*info)); | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_lock(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_lock(&backup_state.stat.lock);
 | ||||||
|  |   | ||||||
|  |      if (!backup_state.stat.start_time) { | ||||||
|  |          /* not started, return {} */ | ||||||
|  | -        qemu_rec_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  | +        qemu_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  |          return info; | ||||||
|  |      } | ||||||
|  |   | ||||||
|  | @@ -955,7 +955,7 @@ BackupStatus *qmp_query_backup(Error **errp)
 | ||||||
|  |      info->has_transferred = true; | ||||||
|  |      info->transferred = backup_state.stat.transferred; | ||||||
|  |   | ||||||
|  | -    qemu_rec_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  | +    qemu_mutex_unlock(&backup_state.stat.lock);
 | ||||||
|  |   | ||||||
|  |      return info; | ||||||
|  |  } | ||||||
							
								
								
									
										3
									
								
								debian/patches/series
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								debian/patches/series
									
									
									
									
										vendored
									
									
								
							| @ -38,4 +38,5 @@ pve/0037-mirror-switch-to-bdrv_dirty_bitmap_merge_internal.patch | |||||||
| pve/0038-iotests-add-test-for-bitmap-mirror.patch | pve/0038-iotests-add-test-for-bitmap-mirror.patch | ||||||
| pve/0039-mirror-move-some-checks-to-qmp.patch | pve/0039-mirror-move-some-checks-to-qmp.patch | ||||||
| pve/0040-PVE-savevm-async-set-up-migration-state.patch | pve/0040-PVE-savevm-async-set-up-migration-state.patch | ||||||
| pve/0041-PVE-Use-non-recursive-locks.patch | pve/0041-PVE-Backup-avoid-use-QemuRecMutex-inside-coroutines.patch | ||||||
|  | pve/0042-PVE-Backup-use-QemuMutex-instead-of-QemuRecMutex.patch | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Thomas Lamprecht
						Thomas Lamprecht