xref: /openbmc/qemu/block/snapshot.c (revision 2b75ef01caf74be5af964f97e37f07ff9034fe0b)
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 
32 QemuOptsList 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 
50 int 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  */
93 bool 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 
146 int 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 
163 int 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 
179 int bdrv_snapshot_goto(BlockDriverState *bs,
180                        const char *snapshot_id)
181 {
182     BlockDriver *drv = bs->drv;
183     int ret, open_ret;
184     int64_t len;
185 
186     if (!drv) {
187         return -ENOMEDIUM;
188     }
189 
190     len = bdrv_getlength(bs);
191     if (len < 0) {
192         return len;
193     }
194     /* We should set all bits in all enabled dirty bitmaps, because dirty
195      * bitmaps reflect active state of disk and snapshot switch operation
196      * actually dirties active state.
197      * TODO: It may make sense not to set all bits but analyze block status of
198      * current state and destination snapshot and do not set bits corresponding
199      * to both-zero or both-unallocated areas. */
200     bdrv_set_dirty(bs, 0, len);
201 
202     if (drv->bdrv_snapshot_goto) {
203         return drv->bdrv_snapshot_goto(bs, snapshot_id);
204     }
205 
206     if (bs->file) {
207         BlockDriverState *file;
208         QDict *options = qdict_clone_shallow(bs->options);
209         QDict *file_options;
210 
211         file = bs->file->bs;
212         /* Prevent it from getting deleted when detached from bs */
213         bdrv_ref(file);
214 
215         qdict_extract_subqdict(options, &file_options, "file.");
216         QDECREF(file_options);
217         qdict_put_str(options, "file", bdrv_get_node_name(file));
218 
219         drv->bdrv_close(bs);
220         bdrv_unref_child(bs, bs->file);
221         bs->file = NULL;
222 
223         ret = bdrv_snapshot_goto(file, snapshot_id);
224         open_ret = drv->bdrv_open(bs, options, bs->open_flags, NULL);
225         QDECREF(options);
226         if (open_ret < 0) {
227             bdrv_unref(file);
228             bs->drv = NULL;
229             return open_ret;
230         }
231 
232         assert(bs->file->bs == file);
233         bdrv_unref(file);
234         return ret;
235     }
236 
237     return -ENOTSUP;
238 }
239 
240 /**
241  * Delete an internal snapshot by @snapshot_id and @name.
242  * @bs: block device used in the operation
243  * @snapshot_id: unique snapshot ID, or NULL
244  * @name: snapshot name, or NULL
245  * @errp: location to store error
246  *
247  * If both @snapshot_id and @name are specified, delete the first one with
248  * id @snapshot_id and name @name.
249  * If only @snapshot_id is specified, delete the first one with id
250  * @snapshot_id.
251  * If only @name is specified, delete the first one with name @name.
252  * if none is specified, return -EINVAL.
253  *
254  * Returns: 0 on success, -errno on failure. If @bs is not inserted, return
255  * -ENOMEDIUM. If @snapshot_id and @name are both NULL, return -EINVAL. If @bs
256  * does not support internal snapshot deletion, return -ENOTSUP. If @bs does
257  * not support parameter @snapshot_id or @name, or one of them is not correctly
258  * specified, return -EINVAL. If @bs can't find one matching @id and @name,
259  * return -ENOENT. If @errp != NULL, it will always be filled with error
260  * message on failure.
261  */
262 int bdrv_snapshot_delete(BlockDriverState *bs,
263                          const char *snapshot_id,
264                          const char *name,
265                          Error **errp)
266 {
267     BlockDriver *drv = bs->drv;
268     int ret;
269 
270     if (!drv) {
271         error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
272         return -ENOMEDIUM;
273     }
274     if (!snapshot_id && !name) {
275         error_setg(errp, "snapshot_id and name are both NULL");
276         return -EINVAL;
277     }
278 
279     /* drain all pending i/o before deleting snapshot */
280     bdrv_drained_begin(bs);
281 
282     if (drv->bdrv_snapshot_delete) {
283         ret = drv->bdrv_snapshot_delete(bs, snapshot_id, name, errp);
284     } else if (bs->file) {
285         ret = bdrv_snapshot_delete(bs->file->bs, snapshot_id, name, errp);
286     } else {
287         error_setg(errp, "Block format '%s' used by device '%s' "
288                    "does not support internal snapshot deletion",
289                    drv->format_name, bdrv_get_device_name(bs));
290         ret = -ENOTSUP;
291     }
292 
293     bdrv_drained_end(bs);
294     return ret;
295 }
296 
297 int bdrv_snapshot_delete_by_id_or_name(BlockDriverState *bs,
298                                        const char *id_or_name,
299                                        Error **errp)
300 {
301     int ret;
302     Error *local_err = NULL;
303 
304     ret = bdrv_snapshot_delete(bs, id_or_name, NULL, &local_err);
305     if (ret == -ENOENT || ret == -EINVAL) {
306         error_free(local_err);
307         local_err = NULL;
308         ret = bdrv_snapshot_delete(bs, NULL, id_or_name, &local_err);
309     }
310 
311     if (ret < 0) {
312         error_propagate(errp, local_err);
313     }
314     return ret;
315 }
316 
317 int bdrv_snapshot_list(BlockDriverState *bs,
318                        QEMUSnapshotInfo **psn_info)
319 {
320     BlockDriver *drv = bs->drv;
321     if (!drv) {
322         return -ENOMEDIUM;
323     }
324     if (drv->bdrv_snapshot_list) {
325         return drv->bdrv_snapshot_list(bs, psn_info);
326     }
327     if (bs->file) {
328         return bdrv_snapshot_list(bs->file->bs, psn_info);
329     }
330     return -ENOTSUP;
331 }
332 
333 /**
334  * Temporarily load an internal snapshot by @snapshot_id and @name.
335  * @bs: block device used in the operation
336  * @snapshot_id: unique snapshot ID, or NULL
337  * @name: snapshot name, or NULL
338  * @errp: location to store error
339  *
340  * If both @snapshot_id and @name are specified, load the first one with
341  * id @snapshot_id and name @name.
342  * If only @snapshot_id is specified, load the first one with id
343  * @snapshot_id.
344  * If only @name is specified, load the first one with name @name.
345  * if none is specified, return -EINVAL.
346  *
347  * Returns: 0 on success, -errno on fail. If @bs is not inserted, return
348  * -ENOMEDIUM. If @bs is not readonly, return -EINVAL. If @bs did not support
349  * internal snapshot, return -ENOTSUP. If qemu can't find a matching @id and
350  * @name, return -ENOENT. If @errp != NULL, it will always be filled on
351  * failure.
352  */
353 int bdrv_snapshot_load_tmp(BlockDriverState *bs,
354                            const char *snapshot_id,
355                            const char *name,
356                            Error **errp)
357 {
358     BlockDriver *drv = bs->drv;
359 
360     if (!drv) {
361         error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
362         return -ENOMEDIUM;
363     }
364     if (!snapshot_id && !name) {
365         error_setg(errp, "snapshot_id and name are both NULL");
366         return -EINVAL;
367     }
368     if (!bs->read_only) {
369         error_setg(errp, "Device is not readonly");
370         return -EINVAL;
371     }
372     if (drv->bdrv_snapshot_load_tmp) {
373         return drv->bdrv_snapshot_load_tmp(bs, snapshot_id, name, errp);
374     }
375     error_setg(errp, "Block format '%s' used by device '%s' "
376                "does not support temporarily loading internal snapshots",
377                drv->format_name, bdrv_get_device_name(bs));
378     return -ENOTSUP;
379 }
380 
381 int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
382                                          const char *id_or_name,
383                                          Error **errp)
384 {
385     int ret;
386     Error *local_err = NULL;
387 
388     ret = bdrv_snapshot_load_tmp(bs, id_or_name, NULL, &local_err);
389     if (ret == -ENOENT || ret == -EINVAL) {
390         error_free(local_err);
391         local_err = NULL;
392         ret = bdrv_snapshot_load_tmp(bs, NULL, id_or_name, &local_err);
393     }
394 
395     error_propagate(errp, local_err);
396 
397     return ret;
398 }
399 
400 
401 /* Group operations. All block drivers are involved.
402  * These functions will properly handle dataplane (take aio_context_acquire
403  * when appropriate for appropriate block drivers) */
404 
405 bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs)
406 {
407     bool ok = true;
408     BlockDriverState *bs;
409     BdrvNextIterator it;
410 
411     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
412         AioContext *ctx = bdrv_get_aio_context(bs);
413 
414         aio_context_acquire(ctx);
415         if (bdrv_is_inserted(bs) && !bdrv_is_read_only(bs)) {
416             ok = bdrv_can_snapshot(bs);
417         }
418         aio_context_release(ctx);
419         if (!ok) {
420             bdrv_next_cleanup(&it);
421             goto fail;
422         }
423     }
424 
425 fail:
426     *first_bad_bs = bs;
427     return ok;
428 }
429 
430 int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs,
431                              Error **err)
432 {
433     int ret = 0;
434     BlockDriverState *bs;
435     BdrvNextIterator it;
436     QEMUSnapshotInfo sn1, *snapshot = &sn1;
437 
438     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
439         AioContext *ctx = bdrv_get_aio_context(bs);
440 
441         aio_context_acquire(ctx);
442         if (bdrv_can_snapshot(bs) &&
443                 bdrv_snapshot_find(bs, snapshot, name) >= 0) {
444             ret = bdrv_snapshot_delete_by_id_or_name(bs, name, err);
445         }
446         aio_context_release(ctx);
447         if (ret < 0) {
448             bdrv_next_cleanup(&it);
449             goto fail;
450         }
451     }
452 
453 fail:
454     *first_bad_bs = bs;
455     return ret;
456 }
457 
458 
459 int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs)
460 {
461     int err = 0;
462     BlockDriverState *bs;
463     BdrvNextIterator it;
464 
465     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
466         AioContext *ctx = bdrv_get_aio_context(bs);
467 
468         aio_context_acquire(ctx);
469         if (bdrv_can_snapshot(bs)) {
470             err = bdrv_snapshot_goto(bs, name);
471         }
472         aio_context_release(ctx);
473         if (err < 0) {
474             bdrv_next_cleanup(&it);
475             goto fail;
476         }
477     }
478 
479 fail:
480     *first_bad_bs = bs;
481     return err;
482 }
483 
484 int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs)
485 {
486     QEMUSnapshotInfo sn;
487     int err = 0;
488     BlockDriverState *bs;
489     BdrvNextIterator it;
490 
491     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
492         AioContext *ctx = bdrv_get_aio_context(bs);
493 
494         aio_context_acquire(ctx);
495         if (bdrv_can_snapshot(bs)) {
496             err = bdrv_snapshot_find(bs, &sn, name);
497         }
498         aio_context_release(ctx);
499         if (err < 0) {
500             bdrv_next_cleanup(&it);
501             goto fail;
502         }
503     }
504 
505 fail:
506     *first_bad_bs = bs;
507     return err;
508 }
509 
510 int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
511                              BlockDriverState *vm_state_bs,
512                              uint64_t vm_state_size,
513                              BlockDriverState **first_bad_bs)
514 {
515     int err = 0;
516     BlockDriverState *bs;
517     BdrvNextIterator it;
518 
519     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
520         AioContext *ctx = bdrv_get_aio_context(bs);
521 
522         aio_context_acquire(ctx);
523         if (bs == vm_state_bs) {
524             sn->vm_state_size = vm_state_size;
525             err = bdrv_snapshot_create(bs, sn);
526         } else if (bdrv_can_snapshot(bs)) {
527             sn->vm_state_size = 0;
528             err = bdrv_snapshot_create(bs, sn);
529         }
530         aio_context_release(ctx);
531         if (err < 0) {
532             bdrv_next_cleanup(&it);
533             goto fail;
534         }
535     }
536 
537 fail:
538     *first_bad_bs = bs;
539     return err;
540 }
541 
542 BlockDriverState *bdrv_all_find_vmstate_bs(void)
543 {
544     BlockDriverState *bs;
545     BdrvNextIterator it;
546 
547     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
548         AioContext *ctx = bdrv_get_aio_context(bs);
549         bool found;
550 
551         aio_context_acquire(ctx);
552         found = bdrv_can_snapshot(bs);
553         aio_context_release(ctx);
554 
555         if (found) {
556             bdrv_next_cleanup(&it);
557             break;
558         }
559     }
560     return bs;
561 }
562