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