qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

backup.c (14754B)


      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 "qapi/error.h"
     24 #include "qapi/qmp/qerror.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 
     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 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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             ret = block_copy_reset_unallocated(s->bcs, offset, &count);
    273             if (ret < 0) {
    274                 return ret;
    275             }
    276 
    277             offset += count;
    278         }
    279         block_copy_set_skip_unallocated(s->bcs, false);
    280     }
    281 
    282     if (s->sync_mode == MIRROR_SYNC_MODE_NONE) {
    283         /*
    284          * All bits are set in bcs bitmap to allow any cluster to be copied.
    285          * This does not actually require them to be copied.
    286          */
    287         while (!job_is_cancelled(job)) {
    288             /*
    289              * Yield until the job is cancelled.  We just let our before_write
    290              * notify callback service CoW requests.
    291              */
    292             job_yield(job);
    293         }
    294     } else {
    295         return backup_loop(s);
    296     }
    297 
    298     return 0;
    299 }
    300 
    301 static void coroutine_fn backup_pause(Job *job)
    302 {
    303     BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
    304 
    305     if (s->bg_bcs_call && !block_copy_call_finished(s->bg_bcs_call)) {
    306         block_copy_call_cancel(s->bg_bcs_call);
    307         s->wait = true;
    308         qemu_coroutine_yield();
    309     }
    310 }
    311 
    312 static void backup_set_speed(BlockJob *job, int64_t speed)
    313 {
    314     BackupBlockJob *s = container_of(job, BackupBlockJob, common);
    315 
    316     /*
    317      * block_job_set_speed() is called first from block_job_create(), when we
    318      * don't yet have s->bcs.
    319      */
    320     if (s->bcs) {
    321         block_copy_set_speed(s->bcs, speed);
    322         if (s->bg_bcs_call) {
    323             block_copy_kick(s->bg_bcs_call);
    324         }
    325     }
    326 }
    327 
    328 static bool backup_cancel(Job *job, bool force)
    329 {
    330     BackupBlockJob *s = container_of(job, BackupBlockJob, common.job);
    331 
    332     bdrv_cancel_in_flight(s->target_bs);
    333     return true;
    334 }
    335 
    336 static const BlockJobDriver backup_job_driver = {
    337     .job_driver = {
    338         .instance_size          = sizeof(BackupBlockJob),
    339         .job_type               = JOB_TYPE_BACKUP,
    340         .free                   = block_job_free,
    341         .user_resume            = block_job_user_resume,
    342         .run                    = backup_run,
    343         .commit                 = backup_commit,
    344         .abort                  = backup_abort,
    345         .clean                  = backup_clean,
    346         .pause                  = backup_pause,
    347         .cancel                 = backup_cancel,
    348     },
    349     .set_speed = backup_set_speed,
    350 };
    351 
    352 BlockJob *backup_job_create(const char *job_id, BlockDriverState *bs,
    353                   BlockDriverState *target, int64_t speed,
    354                   MirrorSyncMode sync_mode, BdrvDirtyBitmap *sync_bitmap,
    355                   BitmapSyncMode bitmap_mode,
    356                   bool compress,
    357                   const char *filter_node_name,
    358                   BackupPerf *perf,
    359                   BlockdevOnError on_source_error,
    360                   BlockdevOnError on_target_error,
    361                   int creation_flags,
    362                   BlockCompletionFunc *cb, void *opaque,
    363                   JobTxn *txn, Error **errp)
    364 {
    365     int64_t len, target_len;
    366     BackupBlockJob *job = NULL;
    367     int64_t cluster_size;
    368     BlockDriverState *cbw = NULL;
    369     BlockCopyState *bcs = NULL;
    370 
    371     assert(bs);
    372     assert(target);
    373     GLOBAL_STATE_CODE();
    374 
    375     /* QMP interface protects us from these cases */
    376     assert(sync_mode != MIRROR_SYNC_MODE_INCREMENTAL);
    377     assert(sync_bitmap || sync_mode != MIRROR_SYNC_MODE_BITMAP);
    378 
    379     if (bs == target) {
    380         error_setg(errp, "Source and target cannot be the same");
    381         return NULL;
    382     }
    383 
    384     if (!bdrv_is_inserted(bs)) {
    385         error_setg(errp, "Device is not inserted: %s",
    386                    bdrv_get_device_name(bs));
    387         return NULL;
    388     }
    389 
    390     if (!bdrv_is_inserted(target)) {
    391         error_setg(errp, "Device is not inserted: %s",
    392                    bdrv_get_device_name(target));
    393         return NULL;
    394     }
    395 
    396     if (compress && !bdrv_supports_compressed_writes(target)) {
    397         error_setg(errp, "Compression is not supported for this drive %s",
    398                    bdrv_get_device_name(target));
    399         return NULL;
    400     }
    401 
    402     if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_BACKUP_SOURCE, errp)) {
    403         return NULL;
    404     }
    405 
    406     if (bdrv_op_is_blocked(target, BLOCK_OP_TYPE_BACKUP_TARGET, errp)) {
    407         return NULL;
    408     }
    409 
    410     if (perf->max_workers < 1 || perf->max_workers > INT_MAX) {
    411         error_setg(errp, "max-workers must be between 1 and %d", INT_MAX);
    412         return NULL;
    413     }
    414 
    415     if (perf->max_chunk < 0) {
    416         error_setg(errp, "max-chunk must be zero (which means no limit) or "
    417                    "positive");
    418         return NULL;
    419     }
    420 
    421     if (sync_bitmap) {
    422         /* If we need to write to this bitmap, check that we can: */
    423         if (bitmap_mode != BITMAP_SYNC_MODE_NEVER &&
    424             bdrv_dirty_bitmap_check(sync_bitmap, BDRV_BITMAP_DEFAULT, errp)) {
    425             return NULL;
    426         }
    427 
    428         /* Create a new bitmap, and freeze/disable this one. */
    429         if (bdrv_dirty_bitmap_create_successor(sync_bitmap, errp) < 0) {
    430             return NULL;
    431         }
    432     }
    433 
    434     len = bdrv_getlength(bs);
    435     if (len < 0) {
    436         error_setg_errno(errp, -len, "Unable to get length for '%s'",
    437                          bdrv_get_device_or_node_name(bs));
    438         goto error;
    439     }
    440 
    441     target_len = bdrv_getlength(target);
    442     if (target_len < 0) {
    443         error_setg_errno(errp, -target_len, "Unable to get length for '%s'",
    444                          bdrv_get_device_or_node_name(bs));
    445         goto error;
    446     }
    447 
    448     if (target_len != len) {
    449         error_setg(errp, "Source and target image have different sizes");
    450         goto error;
    451     }
    452 
    453     cbw = bdrv_cbw_append(bs, target, filter_node_name, &bcs, errp);
    454     if (!cbw) {
    455         goto error;
    456     }
    457 
    458     cluster_size = block_copy_cluster_size(bcs);
    459 
    460     if (perf->max_chunk && perf->max_chunk < cluster_size) {
    461         error_setg(errp, "Required max-chunk (%" PRIi64 ") is less than backup "
    462                    "cluster size (%" PRIi64 ")", perf->max_chunk, cluster_size);
    463         goto error;
    464     }
    465 
    466     /* job->len is fixed, so we can't allow resize */
    467     job = block_job_create(job_id, &backup_job_driver, txn, cbw,
    468                            0, BLK_PERM_ALL,
    469                            speed, creation_flags, cb, opaque, errp);
    470     if (!job) {
    471         goto error;
    472     }
    473 
    474     job->cbw = cbw;
    475     job->source_bs = bs;
    476     job->target_bs = target;
    477     job->on_source_error = on_source_error;
    478     job->on_target_error = on_target_error;
    479     job->sync_mode = sync_mode;
    480     job->sync_bitmap = sync_bitmap;
    481     job->bitmap_mode = bitmap_mode;
    482     job->bcs = bcs;
    483     job->cluster_size = cluster_size;
    484     job->len = len;
    485     job->perf = *perf;
    486 
    487     block_copy_set_copy_opts(bcs, perf->use_copy_range, compress);
    488     block_copy_set_progress_meter(bcs, &job->common.job.progress);
    489     block_copy_set_speed(bcs, speed);
    490 
    491     /* Required permissions are taken by copy-before-write filter target */
    492     block_job_add_bdrv(&job->common, "target", target, 0, BLK_PERM_ALL,
    493                        &error_abort);
    494 
    495     return &job->common;
    496 
    497  error:
    498     if (sync_bitmap) {
    499         bdrv_reclaim_dirty_bitmap(sync_bitmap, NULL);
    500     }
    501     if (cbw) {
    502         bdrv_cbw_drop(cbw);
    503     }
    504 
    505     return NULL;
    506 }