xref: /openbmc/qemu/block/backup.c (revision 72cb4806fdb0c5d7efca181dedfd46bed2acc9e7)
1  /*
2   * QEMU backup
3   *
4   * Copyright (C) 2013 Proxmox Server Solutions
5   * Copyright (c) 2019 Virtuozzo International GmbH.
6   *
7   * Authors:
8   *  Dietmar Maurer (dietmar@proxmox.com)
9   *
10   * This work is licensed under the terms of the GNU GPL, version 2 or later.
11   * See the COPYING file in the top-level directory.
12   *
13   */
14  
15  #include "qemu/osdep.h"
16  
17  #include "trace.h"
18  #include "block/block.h"
19  #include "block/block_int.h"
20  #include "block/blockjob_int.h"
21  #include "block/block_backup.h"
22  #include "block/block-copy.h"
23  #include "block/dirty-bitmap.h"
24  #include "qapi/error.h"
25  #include "qemu/cutils.h"
26  #include "sysemu/block-backend.h"
27  #include "qemu/bitmap.h"
28  #include "qemu/error-report.h"
29  
30  #include "block/copy-before-write.h"
31  
32  typedef struct BackupBlockJob {
33      BlockJob common;
34      BlockDriverState *cbw;
35      BlockDriverState *source_bs;
36      BlockDriverState *target_bs;
37  
38      BdrvDirtyBitmap *sync_bitmap;
39  
40      MirrorSyncMode sync_mode;
41      BitmapSyncMode bitmap_mode;
42      BlockdevOnError on_source_error;
43      BlockdevOnError on_target_error;
44      uint64_t len;
45      int64_t cluster_size;
46      BackupPerf perf;
47  
48      BlockCopyState *bcs;
49  
50      bool wait;
51      BlockCopyCallState *bg_bcs_call;
52  } BackupBlockJob;
53  
54  static const BlockJobDriver backup_job_driver;
55  
backup_cleanup_sync_bitmap(BackupBlockJob * job,int ret)56  static void backup_cleanup_sync_bitmap(BackupBlockJob *job, int ret)
57  {
58      BdrvDirtyBitmap *bm;
59      bool sync = (((ret == 0) || (job->bitmap_mode == BITMAP_SYNC_MODE_ALWAYS)) \
60                   && (job->bitmap_mode != BITMAP_SYNC_MODE_NEVER));
61  
62      if (sync) {
63          /*
64           * We succeeded, or we always intended to sync the bitmap.
65           * Delete this bitmap and install the child.
66           */
67          bm = bdrv_dirty_bitmap_abdicate(job->sync_bitmap, NULL);
68      } else {
69          /*
70           * We failed, or we never intended to sync the bitmap anyway.
71           * Merge the successor back into the parent, keeping all data.
72           */
73          bm = bdrv_reclaim_dirty_bitmap(job->sync_bitmap, NULL);
74      }
75  
76      assert(bm);
77  
78      if (ret < 0 && job->bitmap_mode == BITMAP_SYNC_MODE_ALWAYS) {
79          /* If we failed and synced, merge in the bits we didn't copy: */
80          bdrv_dirty_bitmap_merge_internal(bm, block_copy_dirty_bitmap(job->bcs),
81                                           NULL, true);
82      }
83  }
84  
backup_commit(Job * job)85  static void backup_commit(Job *job)
86  {
87      BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
88      if (s->sync_bitmap) {
89          backup_cleanup_sync_bitmap(s, 0);
90      }
91  }
92  
backup_abort(Job * job)93  static void backup_abort(Job *job)
94  {
95      BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
96      if (s->sync_bitmap) {
97          backup_cleanup_sync_bitmap(s, -1);
98      }
99  }
100  
backup_clean(Job * job)101  static void backup_clean(Job *job)
102  {
103      BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
104      block_job_remove_all_bdrv(&s->common);
105      bdrv_cbw_drop(s->cbw);
106  }
107  
backup_do_checkpoint(BlockJob * job,Error ** errp)108  void backup_do_checkpoint(BlockJob *job, Error **errp)
109  {
110      BackupBlockJob *backup_job = container_of(job, BackupBlockJob, common);
111  
112      assert(block_job_driver(job) == &backup_job_driver);
113  
114      if (backup_job->sync_mode != MIRROR_SYNC_MODE_NONE) {
115          error_setg(errp, "The backup job only supports block checkpoint in"
116                     " sync=none mode");
117          return;
118      }
119  
120      bdrv_set_dirty_bitmap(block_copy_dirty_bitmap(backup_job->bcs), 0,
121                            backup_job->len);
122  }
123  
backup_error_action(BackupBlockJob * job,bool read,int error)124  static BlockErrorAction backup_error_action(BackupBlockJob *job,
125                                              bool read, int error)
126  {
127      if (read) {
128          return block_job_error_action(&job->common, job->on_source_error,
129                                        true, error);
130      } else {
131          return block_job_error_action(&job->common, job->on_target_error,
132                                        false, error);
133      }
134  }
135  
backup_block_copy_callback(void * opaque)136  static void coroutine_fn backup_block_copy_callback(void *opaque)
137  {
138      BackupBlockJob *s = opaque;
139  
140      if (s->wait) {
141          s->wait = false;
142          aio_co_wake(s->common.job.co);
143      } else {
144          job_enter(&s->common.job);
145      }
146  }
147  
backup_loop(BackupBlockJob * job)148  static int coroutine_fn backup_loop(BackupBlockJob *job)
149  {
150      BlockCopyCallState *s = NULL;
151      int ret = 0;
152      bool error_is_read;
153      BlockErrorAction act;
154  
155      while (true) { /* retry loop */
156          job->bg_bcs_call = s = block_copy_async(job->bcs, 0,
157                  QEMU_ALIGN_UP(job->len, job->cluster_size),
158                  job->perf.max_workers, job->perf.max_chunk,
159                  backup_block_copy_callback, job);
160  
161          while (!block_copy_call_finished(s) &&
162                 !job_is_cancelled(&job->common.job))
163          {
164              job_yield(&job->common.job);
165          }
166  
167          if (!block_copy_call_finished(s)) {
168              assert(job_is_cancelled(&job->common.job));
169              /*
170               * Note that we can't use job_yield() here, as it doesn't work for
171               * cancelled job.
172               */
173              block_copy_call_cancel(s);
174              job->wait = true;
175              qemu_coroutine_yield();
176              assert(block_copy_call_finished(s));
177              ret = 0;
178              goto out;
179          }
180  
181          if (job_is_cancelled(&job->common.job) ||
182              block_copy_call_succeeded(s))
183          {
184              ret = 0;
185              goto out;
186          }
187  
188          if (block_copy_call_cancelled(s)) {
189              /*
190               * Job is not cancelled but only block-copy call. This is possible
191               * after job pause. Now the pause is finished, start new block-copy
192               * iteration.
193               */
194              block_copy_call_free(s);
195              continue;
196          }
197  
198          /* The only remaining case is failed block-copy call. */
199          assert(block_copy_call_failed(s));
200  
201          ret = block_copy_call_status(s, &error_is_read);
202          act = backup_error_action(job, error_is_read, -ret);
203          switch (act) {
204          case BLOCK_ERROR_ACTION_REPORT:
205              goto out;
206          case BLOCK_ERROR_ACTION_STOP:
207              /*
208               * Go to pause prior to starting new block-copy call on the next
209               * iteration.
210               */
211              job_pause_point(&job->common.job);
212              break;
213          case BLOCK_ERROR_ACTION_IGNORE:
214              /* Proceed to new block-copy call to retry. */
215              break;
216          default:
217              abort();
218          }
219  
220          block_copy_call_free(s);
221      }
222  
223  out:
224      block_copy_call_free(s);
225      job->bg_bcs_call = NULL;
226      return ret;
227  }
228  
backup_init_bcs_bitmap(BackupBlockJob * job)229  static void backup_init_bcs_bitmap(BackupBlockJob *job)
230  {
231      uint64_t estimate;
232      BdrvDirtyBitmap *bcs_bitmap = block_copy_dirty_bitmap(job->bcs);
233  
234      if (job->sync_mode == MIRROR_SYNC_MODE_BITMAP) {
235          bdrv_clear_dirty_bitmap(bcs_bitmap, NULL);
236          bdrv_dirty_bitmap_merge_internal(bcs_bitmap, job->sync_bitmap, NULL,
237                                           true);
238      } else if (job->sync_mode == MIRROR_SYNC_MODE_TOP) {
239          /*
240           * We can't hog the coroutine to initialize this thoroughly.
241           * Set a flag and resume work when we are able to yield safely.
242           */
243          block_copy_set_skip_unallocated(job->bcs, true);
244      }
245  
246      estimate = bdrv_get_dirty_count(bcs_bitmap);
247      job_progress_set_remaining(&job->common.job, estimate);
248  }
249  
backup_run(Job * job,Error ** errp)250  static int coroutine_fn backup_run(Job *job, Error **errp)
251  {
252      BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
253      int ret;
254  
255      backup_init_bcs_bitmap(s);
256  
257      if (s->sync_mode == MIRROR_SYNC_MODE_TOP) {
258          int64_t offset = 0;
259          int64_t count;
260  
261          for (offset = 0; offset < s->len; ) {
262              if (job_is_cancelled(job)) {
263                  return -ECANCELED;
264              }
265  
266              job_pause_point(job);
267  
268              if (job_is_cancelled(job)) {
269                  return -ECANCELED;
270              }
271  
272              /* rdlock protects the subsequent call to bdrv_is_allocated() */
273              bdrv_graph_co_rdlock();
274              ret = block_copy_reset_unallocated(s->bcs, offset, &count);
275              bdrv_graph_co_rdunlock();
276              if (ret < 0) {
277                  return ret;
278              }
279  
280              offset += count;
281          }
282          block_copy_set_skip_unallocated(s->bcs, false);
283      }
284  
285      if (s->sync_mode == MIRROR_SYNC_MODE_NONE) {
286          /*
287           * All bits are set in bcs bitmap to allow any cluster to be copied.
288           * This does not actually require them to be copied.
289           */
290          while (!job_is_cancelled(job)) {
291              /*
292               * Yield until the job is cancelled.  We just let our before_write
293               * notify callback service CoW requests.
294               */
295              job_yield(job);
296          }
297      } else {
298          return backup_loop(s);
299      }
300  
301      return 0;
302  }
303  
backup_pause(Job * job)304  static void coroutine_fn backup_pause(Job *job)
305  {
306      BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
307  
308      if (s->bg_bcs_call && !block_copy_call_finished(s->bg_bcs_call)) {
309          block_copy_call_cancel(s->bg_bcs_call);
310          s->wait = true;
311          qemu_coroutine_yield();
312      }
313  }
314  
backup_set_speed(BlockJob * job,int64_t speed)315  static void backup_set_speed(BlockJob *job, int64_t speed)
316  {
317      BackupBlockJob *s = container_of(job, BackupBlockJob, common);
318  
319      /*
320       * block_job_set_speed() is called first from block_job_create(), when we
321       * don't yet have s->bcs.
322       */
323      if (s->bcs) {
324          block_copy_set_speed(s->bcs, speed);
325          if (s->bg_bcs_call) {
326              block_copy_kick(s->bg_bcs_call);
327          }
328      }
329  }
330  
backup_cancel(Job * job,bool force)331  static bool backup_cancel(Job *job, bool force)
332  {
333      BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
334  
335      bdrv_cancel_in_flight(s->target_bs);
336      return true;
337  }
338  
339  static const BlockJobDriver backup_job_driver = {
340      .job_driver = {
341          .instance_size          = sizeof(BackupBlockJob),
342          .job_type               = JOB_TYPE_BACKUP,
343          .free                   = block_job_free,
344          .user_resume            = block_job_user_resume,
345          .run                    = backup_run,
346          .commit                 = backup_commit,
347          .abort                  = backup_abort,
348          .clean                  = backup_clean,
349          .pause                  = backup_pause,
350          .cancel                 = backup_cancel,
351      },
352      .set_speed = backup_set_speed,
353  };
354  
backup_job_create(const char * job_id,BlockDriverState * bs,BlockDriverState * target,int64_t speed,MirrorSyncMode sync_mode,BdrvDirtyBitmap * sync_bitmap,BitmapSyncMode bitmap_mode,bool compress,bool discard_source,const char * filter_node_name,BackupPerf * perf,BlockdevOnError on_source_error,BlockdevOnError on_target_error,int creation_flags,BlockCompletionFunc * cb,void * opaque,JobTxn * txn,Error ** errp)355  BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
356                    BlockDriverState *target, int64_t speed,
357                    MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
358                    BitmapSyncMode bitmap_mode,
359                    bool compress, bool discard_source,
360                    const char *filter_node_name,
361                    BackupPerf *perf,
362                    BlockdevOnError on_source_error,
363                    BlockdevOnError on_target_error,
364                    int creation_flags,
365                    BlockCompletionFunc *cb, void *opaque,
366                    JobTxn *txn, Error **errp)
367  {
368      int64_t len, target_len;
369      BackupBlockJob *job = NULL;
370      int64_t cluster_size;
371      BlockDriverState *cbw = NULL;
372      BlockCopyState *bcs = NULL;
373  
374      assert(bs);
375      assert(target);
376      GLOBAL_STATE_CODE();
377  
378      /* QMP interface protects us from these cases */
379      assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
380      assert(sync_bitmap || sync_mode != MIRROR_SYNC_MODE_BITMAP);
381  
382      if (bs == target) {
383          error_setg(errp, "Source and target cannot be the same");
384          return NULL;
385      }
386  
387      bdrv_graph_rdlock_main_loop();
388      if (!bdrv_is_inserted(bs)) {
389          error_setg(errp, "Device is not inserted: %s",
390                     bdrv_get_device_name(bs));
391          goto error_rdlock;
392      }
393  
394      if (!bdrv_is_inserted(target)) {
395          error_setg(errp, "Device is not inserted: %s",
396                     bdrv_get_device_name(target));
397          goto error_rdlock;
398      }
399  
400      if (compress && !bdrv_supports_compressed_writes(target)) {
401          error_setg(errp, "Compression is not supported for this drive %s",
402                     bdrv_get_device_name(target));
403          goto error_rdlock;
404      }
405  
406      if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {
407          goto error_rdlock;
408      }
409  
410      if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
411          goto error_rdlock;
412      }
413      bdrv_graph_rdunlock_main_loop();
414  
415      if (perf->max_workers < 1 || perf->max_workers > INT_MAX) {
416          error_setg(errp, "max-workers must be between 1 and %d", INT_MAX);
417          return NULL;
418      }
419  
420      if (perf->max_chunk < 0) {
421          error_setg(errp, "max-chunk must be zero (which means no limit) or "
422                     "positive");
423          return NULL;
424      }
425  
426      if (sync_bitmap) {
427          /* If we need to write to this bitmap, check that we can: */
428          if (bitmap_mode != BITMAP_SYNC_MODE_NEVER &&
429              bdrv_dirty_bitmap_check(sync_bitmap, BDRV_BITMAP_DEFAULT, errp)) {
430              return NULL;
431          }
432  
433          /* Create a new bitmap, and freeze/disable this one. */
434          if (bdrv_dirty_bitmap_create_successor(sync_bitmap, errp) < 0) {
435              return NULL;
436          }
437      }
438  
439      len = bdrv_getlength(bs);
440      if (len < 0) {
441          GRAPH_RDLOCK_GUARD_MAINLOOP();
442          error_setg_errno(errp, -len, "Unable to get length for '%s'",
443                           bdrv_get_device_or_node_name(bs));
444          goto error;
445      }
446  
447      target_len = bdrv_getlength(target);
448      if (target_len < 0) {
449          GRAPH_RDLOCK_GUARD_MAINLOOP();
450          error_setg_errno(errp, -target_len, "Unable to get length for '%s'",
451                           bdrv_get_device_or_node_name(bs));
452          goto error;
453      }
454  
455      if (target_len != len) {
456          error_setg(errp, "Source and target image have different sizes");
457          goto error;
458      }
459  
460      cbw = bdrv_cbw_append(bs, target, filter_node_name, discard_source,
461                            perf->min_cluster_size, &bcs, errp);
462      if (!cbw) {
463          goto error;
464      }
465  
466      cluster_size = block_copy_cluster_size(bcs);
467  
468      if (perf->max_chunk && perf->max_chunk < cluster_size) {
469          error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup "
470                     "cluster size (%" PRIi64 ")", perf->max_chunk, cluster_size);
471          goto error;
472      }
473  
474      /* job->len is fixed, so we can't allow resize */
475      job = block_job_create(job_id, &backup_job_driver, txn, cbw,
476                             0, BLK_PERM_ALL,
477                             speed, creation_flags, cb, opaque, errp);
478      if (!job) {
479          goto error;
480      }
481  
482      job->cbw = cbw;
483      job->source_bs = bs;
484      job->target_bs = target;
485      job->on_source_error = on_source_error;
486      job->on_target_error = on_target_error;
487      job->sync_mode = sync_mode;
488      job->sync_bitmap = sync_bitmap;
489      job->bitmap_mode = bitmap_mode;
490      job->bcs = bcs;
491      job->cluster_size = cluster_size;
492      job->len = len;
493      job->perf = *perf;
494  
495      block_copy_set_copy_opts(bcs, perf->use_copy_range, compress);
496      block_copy_set_progress_meter(bcs, &job->common.job.progress);
497      block_copy_set_speed(bcs, speed);
498  
499      /* Required permissions are taken by copy-before-write filter target */
500      bdrv_graph_wrlock();
501      block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
502                         &error_abort);
503      bdrv_graph_wrunlock();
504  
505      return &job->common;
506  
507   error:
508      if (sync_bitmap) {
509          bdrv_reclaim_dirty_bitmap(sync_bitmap, NULL);
510      }
511      if (cbw) {
512          bdrv_cbw_drop(cbw);
513      }
514  
515      return NULL;
516  
517  error_rdlock:
518      bdrv_graph_rdunlock_main_loop();
519      return NULL;
520  }
521