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