qemu/block/snapshot.c
<<
>>
Prefs
   1/*
   2 * Block layer snapshot related functions
   3 *
   4 * Copyright (c) 2003-2008 Fabrice Bellard
   5 *
   6 * Permission is hereby granted, free of charge, to any person obtaining a copy
   7 * of this software and associated documentation files (the "Software"), to deal
   8 * in the Software without restriction, including without limitation the rights
   9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 * copies of the Software, and to permit persons to whom the Software is
  11 * furnished to do so, subject to the following conditions:
  12 *
  13 * The above copyright notice and this permission notice shall be included in
  14 * all copies or substantial portions of the Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 * THE SOFTWARE.
  23 */
  24
  25#include "qemu/osdep.h"
  26#include "block/snapshot.h"
  27#include "block/block_int.h"
  28#include "qapi/error.h"
  29#include "qapi/qmp/qerror.h"
  30#include "qapi/qmp/qstring.h"
  31
  32QemuOptsList internal_snapshot_opts = {
  33    .name = "snapshot",
  34    .head = QTAILQ_HEAD_INITIALIZER(internal_snapshot_opts.head),
  35    .desc = {
  36        {
  37            .name = SNAPSHOT_OPT_ID,
  38            .type = QEMU_OPT_STRING,
  39            .help = "snapshot id"
  40        },{
  41            .name = SNAPSHOT_OPT_NAME,
  42            .type = QEMU_OPT_STRING,
  43            .help = "snapshot name"
  44        },{
  45            /* end of list */
  46        }
  47    },
  48};
  49
  50int bdrv_snapshot_find(BlockDriverState *bs, QEMUSnapshotInfo *sn_info,
  51                       const char *name)
  52{
  53    QEMUSnapshotInfo *sn_tab, *sn;
  54    int nb_sns, i, ret;
  55
  56    ret = -ENOENT;
  57    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
  58    if (nb_sns < 0) {
  59        return ret;
  60    }
  61    for (i = 0; i < nb_sns; i++) {
  62        sn = &sn_tab[i];
  63        if (!strcmp(sn->id_str, name) || !strcmp(sn->name, name)) {
  64            *sn_info = *sn;
  65            ret = 0;
  66            break;
  67        }
  68    }
  69    g_free(sn_tab);
  70    return ret;
  71}
  72
  73/**
  74 * Look up an internal snapshot by @id and @name.
  75 * @bs: block device to search
  76 * @id: unique snapshot ID, or NULL
  77 * @name: snapshot name, or NULL
  78 * @sn_info: location to store information on the snapshot found
  79 * @errp: location to store error, will be set only for exception
  80 *
  81 * This function will traverse snapshot list in @bs to search the matching
  82 * one, @id and @name are the matching condition:
  83 * If both @id and @name are specified, find the first one with id @id and
  84 * name @name.
  85 * If only @id is specified, find the first one with id @id.
  86 * If only @name is specified, find the first one with name @name.
  87 * if none is specified, abort().
  88 *
  89 * Returns: true when a snapshot is found and @sn_info will be filled, false
  90 * when error or not found. If all operation succeed but no matching one is
  91 * found, @errp will NOT be set.
  92 */
  93bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs,
  94                                       const char *id,
  95                                       const char *name,
  96                                       QEMUSnapshotInfo *sn_info,
  97                                       Error **errp)
  98{
  99    QEMUSnapshotInfo *sn_tab, *sn;
 100    int nb_sns, i;
 101    bool ret = false;
 102
 103    assert(id || name);
 104
 105    nb_sns = bdrv_snapshot_list(bs, &sn_tab);
 106    if (nb_sns < 0) {
 107        error_setg_errno(errp, -nb_sns, "Failed to get a snapshot list");
 108        return false;
 109    } else if (nb_sns == 0) {
 110        return false;
 111    }
 112
 113    if (id && name) {
 114        for (i = 0; i < nb_sns; i++) {
 115            sn = &sn_tab[i];
 116            if (!strcmp(sn->id_str, id) && !strcmp(sn->name, name)) {
 117                *sn_info = *sn;
 118                ret = true;
 119                break;
 120            }
 121        }
 122    } else if (id) {
 123        for (i = 0; i < nb_sns; i++) {
 124            sn = &sn_tab[i];
 125            if (!strcmp(sn->id_str, id)) {
 126                *sn_info = *sn;
 127                ret = true;
 128                break;
 129            }
 130        }
 131    } else if (name) {
 132        for (i = 0; i < nb_sns; i++) {
 133            sn = &sn_tab[i];
 134            if (!strcmp(sn->name, name)) {
 135                *sn_info = *sn;
 136                ret = true;
 137                break;
 138            }
 139        }
 140    }
 141
 142    g_free(sn_tab);
 143    return ret;
 144}
 145
 146int bdrv_can_snapshot(BlockDriverState *bs)
 147{
 148    BlockDriver *drv = bs->drv;
 149    if (!drv || !bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
 150        return 0;
 151    }
 152
 153    if (!drv->bdrv_snapshot_create) {
 154        if (bs->file != NULL) {
 155            return bdrv_can_snapshot(bs->file->bs);
 156        }
 157        return 0;
 158    }
 159
 160    return 1;
 161}
 162
 163int bdrv_snapshot_create(BlockDriverState *bs,
 164                         QEMUSnapshotInfo *sn_info)
 165{
 166    BlockDriver *drv = bs->drv;
 167    if (!drv) {
 168        return -ENOMEDIUM;
 169    }
 170    if (drv->bdrv_snapshot_create) {
 171        return drv->bdrv_snapshot_create(bs, sn_info);
 172    }
 173    if (bs->file) {
 174        return bdrv_snapshot_create(bs->file->bs, sn_info);
 175    }
 176    return -ENOTSUP;
 177}
 178
 179int bdrv_snapshot_goto(BlockDriverState *bs,
 180                       const char *snapshot_id,
 181                       Error **errp)
 182{
 183    BlockDriver *drv = bs->drv;
 184    int ret, open_ret;
 185
 186    if (!drv) {
 187        error_setg(errp, "Block driver is closed");
 188        return -ENOMEDIUM;
 189    }
 190
 191    if (!QLIST_EMPTY(&bs->dirty_bitmaps)) {
 192        error_setg(errp, "Device has active dirty bitmaps");
 193        return -EBUSY;
 194    }
 195
 196    if (drv->bdrv_snapshot_goto) {
 197        ret = drv->bdrv_snapshot_goto(bs, snapshot_id);
 198        if (ret < 0) {
 199            error_setg_errno(errp, -ret, "Failed to load snapshot");
 200        }
 201        return ret;
 202    }
 203
 204    if (bs->file) {
 205        BlockDriverState *file;
 206        QDict *options = qdict_clone_shallow(bs->options);
 207        QDict *file_options;
 208        Error *local_err = NULL;
 209
 210        file = bs->file->bs;
 211        /* Prevent it from getting deleted when detached from bs */
 212        bdrv_ref(file);
 213
 214        qdict_extract_subqdict(options, &file_options, "file.");
 215        QDECREF(file_options);
 216        qdict_put_str(options, "file", bdrv_get_node_name(file));
 217
 218        drv->bdrv_close(bs);
 219        bdrv_unref_child(bs, bs->file);
 220        bs->file = NULL;
 221
 222        ret = bdrv_snapshot_goto(file, snapshot_id, errp);
 223        open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err);
 224        QDECREF(options);
 225        if (open_ret < 0) {
 226            bdrv_unref(file);
 227            bs->drv = NULL;
 228            /* A bdrv_snapshot_goto() error takes precedence */
 229            error_propagate(errp, local_err);
 230            return ret < 0 ? ret : open_ret;
 231        }
 232
 233        assert(bs->file->bs == file);
 234        bdrv_unref(file);
 235        return ret;
 236    }
 237
 238    error_setg(errp, "Block driver does not support snapshots");
 239    return -ENOTSUP;
 240}
 241
 242/**
 243 * Delete an internal snapshot by @snapshot_id and @name.
 244 * @bs: block device used in the operation
 245 * @snapshot_id: unique snapshot ID, or NULL
 246 * @name: snapshot name, or NULL
 247 * @errp: location to store error
 248 *
 249 * If both @snapshot_id and @name are specified, delete the first one with
 250 * id @snapshot_id and name @name.
 251 * If only @snapshot_id is specified, delete the first one with id
 252 * @snapshot_id.
 253 * If only @name is specified, delete the first one with name @name.
 254 * if none is specified, return -EINVAL.
 255 *
 256 * Returns: 0 on success, -errno on failure. If @bs is not inserted, return
 257 * -ENOMEDIUM. If @snapshot_id and @name are both NULL, return -EINVAL. If @bs
 258 * does not support internal snapshot deletion, return -ENOTSUP. If @bs does
 259 * not support parameter @snapshot_id or @name, or one of them is not correctly
 260 * specified, return -EINVAL. If @bs can't find one matching @id and @name,
 261 * return -ENOENT. If @errp != NULL, it will always be filled with error
 262 * message on failure.
 263 */
 264int bdrv_snapshot_delete(BlockDriverState *bs,
 265                         const char *snapshot_id,
 266                         const char *name,
 267                         Error **errp)
 268{
 269    BlockDriver *drv = bs->drv;
 270    int ret;
 271
 272    if (!drv) {
 273        error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
 274        return -ENOMEDIUM;
 275    }
 276    if (!snapshot_id && !name) {
 277        error_setg(errp, "snapshot_id and name are both NULL");
 278        return -EINVAL;
 279    }
 280
 281    /* drain all pending i/o before deleting snapshot */
 282    bdrv_drained_begin(bs);
 283
 284    if (drv->bdrv_snapshot_delete) {
 285        ret = drv->bdrv_snapshot_delete(bs, snapshot_id, name, errp);
 286    } else if (bs->file) {
 287        ret = bdrv_snapshot_delete(bs->file->bs, snapshot_id, name, errp);
 288    } else {
 289        error_setg(errp, "Block format '%s' used by device '%s' "
 290                   "does not support internal snapshot deletion",
 291                   drv->format_name, bdrv_get_device_name(bs));
 292        ret = -ENOTSUP;
 293    }
 294
 295    bdrv_drained_end(bs);
 296    return ret;
 297}
 298
 299int bdrv_snapshot_delete_by_id_or_name(BlockDriverState *bs,
 300                                       const char *id_or_name,
 301                                       Error **errp)
 302{
 303    int ret;
 304    Error *local_err = NULL;
 305
 306    ret = bdrv_snapshot_delete(bs, id_or_name, NULL, &local_err);
 307    if (ret == -ENOENT || ret == -EINVAL) {
 308        error_free(local_err);
 309        local_err = NULL;
 310        ret = bdrv_snapshot_delete(bs, NULL, id_or_name, &local_err);
 311    }
 312
 313    if (ret < 0) {
 314        error_propagate(errp, local_err);
 315    }
 316    return ret;
 317}
 318
 319int bdrv_snapshot_list(BlockDriverState *bs,
 320                       QEMUSnapshotInfo **psn_info)
 321{
 322    BlockDriver *drv = bs->drv;
 323    if (!drv) {
 324        return -ENOMEDIUM;
 325    }
 326    if (drv->bdrv_snapshot_list) {
 327        return drv->bdrv_snapshot_list(bs, psn_info);
 328    }
 329    if (bs->file) {
 330        return bdrv_snapshot_list(bs->file->bs, psn_info);
 331    }
 332    return -ENOTSUP;
 333}
 334
 335/**
 336 * Temporarily load an internal snapshot by @snapshot_id and @name.
 337 * @bs: block device used in the operation
 338 * @snapshot_id: unique snapshot ID, or NULL
 339 * @name: snapshot name, or NULL
 340 * @errp: location to store error
 341 *
 342 * If both @snapshot_id and @name are specified, load the first one with
 343 * id @snapshot_id and name @name.
 344 * If only @snapshot_id is specified, load the first one with id
 345 * @snapshot_id.
 346 * If only @name is specified, load the first one with name @name.
 347 * if none is specified, return -EINVAL.
 348 *
 349 * Returns: 0 on success, -errno on fail. If @bs is not inserted, return
 350 * -ENOMEDIUM. If @bs is not readonly, return -EINVAL. If @bs did not support
 351 * internal snapshot, return -ENOTSUP. If qemu can't find a matching @id and
 352 * @name, return -ENOENT. If @errp != NULL, it will always be filled on
 353 * failure.
 354 */
 355int bdrv_snapshot_load_tmp(BlockDriverState *bs,
 356                           const char *snapshot_id,
 357                           const char *name,
 358                           Error **errp)
 359{
 360    BlockDriver *drv = bs->drv;
 361
 362    if (!drv) {
 363        error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
 364        return -ENOMEDIUM;
 365    }
 366    if (!snapshot_id && !name) {
 367        error_setg(errp, "snapshot_id and name are both NULL");
 368        return -EINVAL;
 369    }
 370    if (!bs->read_only) {
 371        error_setg(errp, "Device is not readonly");
 372        return -EINVAL;
 373    }
 374    if (drv->bdrv_snapshot_load_tmp) {
 375        return drv->bdrv_snapshot_load_tmp(bs, snapshot_id, name, errp);
 376    }
 377    error_setg(errp, "Block format '%s' used by device '%s' "
 378               "does not support temporarily loading internal snapshots",
 379               drv->format_name, bdrv_get_device_name(bs));
 380    return -ENOTSUP;
 381}
 382
 383int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
 384                                         const char *id_or_name,
 385                                         Error **errp)
 386{
 387    int ret;
 388    Error *local_err = NULL;
 389
 390    ret = bdrv_snapshot_load_tmp(bs, id_or_name, NULL, &local_err);
 391    if (ret == -ENOENT || ret == -EINVAL) {
 392        error_free(local_err);
 393        local_err = NULL;
 394        ret = bdrv_snapshot_load_tmp(bs, NULL, id_or_name, &local_err);
 395    }
 396
 397    error_propagate(errp, local_err);
 398
 399    return ret;
 400}
 401
 402
 403/* Group operations. All block drivers are involved.
 404 * These functions will properly handle dataplane (take aio_context_acquire
 405 * when appropriate for appropriate block drivers) */
 406
 407bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs)
 408{
 409    bool ok = true;
 410    BlockDriverState *bs;
 411    BdrvNextIterator it;
 412
 413    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
 414        AioContext *ctx = bdrv_get_aio_context(bs);
 415
 416        aio_context_acquire(ctx);
 417        if (bdrv_is_inserted(bs) && !bdrv_is_read_only(bs)) {
 418            ok = bdrv_can_snapshot(bs);
 419        }
 420        aio_context_release(ctx);
 421        if (!ok) {
 422            bdrv_next_cleanup(&it);
 423            goto fail;
 424        }
 425    }
 426
 427fail:
 428    *first_bad_bs = bs;
 429    return ok;
 430}
 431
 432int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs,
 433                             Error **err)
 434{
 435    int ret = 0;
 436    BlockDriverState *bs;
 437    BdrvNextIterator it;
 438    QEMUSnapshotInfo sn1, *snapshot = &sn1;
 439
 440    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
 441        AioContext *ctx = bdrv_get_aio_context(bs);
 442
 443        aio_context_acquire(ctx);
 444        if (bdrv_can_snapshot(bs) &&
 445                bdrv_snapshot_find(bs, snapshot, name) >= 0) {
 446            ret = bdrv_snapshot_delete_by_id_or_name(bs, name, err);
 447        }
 448        aio_context_release(ctx);
 449        if (ret < 0) {
 450            bdrv_next_cleanup(&it);
 451            goto fail;
 452        }
 453    }
 454
 455fail:
 456    *first_bad_bs = bs;
 457    return ret;
 458}
 459
 460
 461int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs,
 462                           Error **errp)
 463{
 464    int ret = 0;
 465    BlockDriverState *bs;
 466    BdrvNextIterator it;
 467
 468    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
 469        AioContext *ctx = bdrv_get_aio_context(bs);
 470
 471        aio_context_acquire(ctx);
 472        if (bdrv_can_snapshot(bs)) {
 473            ret = bdrv_snapshot_goto(bs, name, errp);
 474        }
 475        aio_context_release(ctx);
 476        if (ret < 0) {
 477            bdrv_next_cleanup(&it);
 478            goto fail;
 479        }
 480    }
 481
 482fail:
 483    *first_bad_bs = bs;
 484    return ret;
 485}
 486
 487int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs)
 488{
 489    QEMUSnapshotInfo sn;
 490    int err = 0;
 491    BlockDriverState *bs;
 492    BdrvNextIterator it;
 493
 494    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
 495        AioContext *ctx = bdrv_get_aio_context(bs);
 496
 497        aio_context_acquire(ctx);
 498        if (bdrv_can_snapshot(bs)) {
 499            err = bdrv_snapshot_find(bs, &sn, name);
 500        }
 501        aio_context_release(ctx);
 502        if (err < 0) {
 503            bdrv_next_cleanup(&it);
 504            goto fail;
 505        }
 506    }
 507
 508fail:
 509    *first_bad_bs = bs;
 510    return err;
 511}
 512
 513int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
 514                             BlockDriverState *vm_state_bs,
 515                             uint64_t vm_state_size,
 516                             BlockDriverState **first_bad_bs)
 517{
 518    int err = 0;
 519    BlockDriverState *bs;
 520    BdrvNextIterator it;
 521
 522    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
 523        AioContext *ctx = bdrv_get_aio_context(bs);
 524
 525        aio_context_acquire(ctx);
 526        if (bs == vm_state_bs) {
 527            sn->vm_state_size = vm_state_size;
 528            err = bdrv_snapshot_create(bs, sn);
 529        } else if (bdrv_can_snapshot(bs)) {
 530            sn->vm_state_size = 0;
 531            err = bdrv_snapshot_create(bs, sn);
 532        }
 533        aio_context_release(ctx);
 534        if (err < 0) {
 535            bdrv_next_cleanup(&it);
 536            goto fail;
 537        }
 538    }
 539
 540fail:
 541    *first_bad_bs = bs;
 542    return err;
 543}
 544
 545BlockDriverState *bdrv_all_find_vmstate_bs(void)
 546{
 547    BlockDriverState *bs;
 548    BdrvNextIterator it;
 549
 550    for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
 551        AioContext *ctx = bdrv_get_aio_context(bs);
 552        bool found;
 553
 554        aio_context_acquire(ctx);
 555        found = bdrv_can_snapshot(bs);
 556        aio_context_release(ctx);
 557
 558        if (found) {
 559            bdrv_next_cleanup(&it);
 560            break;
 561        }
 562    }
 563    return bs;
 564}
 565