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