xref: /openbmc/qemu/block/snapshot.c (revision 438c78da)
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 
35 QemuOptsList 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 
53 int 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->id_str, name) || !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  */
96 bool 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 
149 int 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 
166 int 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 
182 int 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  */
269 int 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 
304 int bdrv_snapshot_delete_by_id_or_name(BlockDriverState *bs,
305                                        const char *id_or_name,
306                                        Error **errp)
307 {
308     int ret;
309     Error *local_err = NULL;
310 
311     ret = bdrv_snapshot_delete(bs, id_or_name, NULL, &local_err);
312     if (ret == -ENOENT || ret == -EINVAL) {
313         error_free(local_err);
314         local_err = NULL;
315         ret = bdrv_snapshot_delete(bs, NULL, id_or_name, &local_err);
316     }
317 
318     if (ret < 0) {
319         error_propagate(errp, local_err);
320     }
321     return ret;
322 }
323 
324 int bdrv_snapshot_list(BlockDriverState *bs,
325                        QEMUSnapshotInfo **psn_info)
326 {
327     BlockDriver *drv = bs->drv;
328     if (!drv) {
329         return -ENOMEDIUM;
330     }
331     if (drv->bdrv_snapshot_list) {
332         return drv->bdrv_snapshot_list(bs, psn_info);
333     }
334     if (bs->file) {
335         return bdrv_snapshot_list(bs->file->bs, psn_info);
336     }
337     return -ENOTSUP;
338 }
339 
340 /**
341  * Temporarily load an internal snapshot by @snapshot_id and @name.
342  * @bs: block device used in the operation
343  * @snapshot_id: unique snapshot ID, or NULL
344  * @name: snapshot name, or NULL
345  * @errp: location to store error
346  *
347  * If both @snapshot_id and @name are specified, load the first one with
348  * id @snapshot_id and name @name.
349  * If only @snapshot_id is specified, load the first one with id
350  * @snapshot_id.
351  * If only @name is specified, load the first one with name @name.
352  * if none is specified, return -EINVAL.
353  *
354  * Returns: 0 on success, -errno on fail. If @bs is not inserted, return
355  * -ENOMEDIUM. If @bs is not readonly, return -EINVAL. If @bs did not support
356  * internal snapshot, return -ENOTSUP. If qemu can't find a matching @id and
357  * @name, return -ENOENT. If @errp != NULL, it will always be filled on
358  * failure.
359  */
360 int bdrv_snapshot_load_tmp(BlockDriverState *bs,
361                            const char *snapshot_id,
362                            const char *name,
363                            Error **errp)
364 {
365     BlockDriver *drv = bs->drv;
366 
367     if (!drv) {
368         error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, bdrv_get_device_name(bs));
369         return -ENOMEDIUM;
370     }
371     if (!snapshot_id && !name) {
372         error_setg(errp, "snapshot_id and name are both NULL");
373         return -EINVAL;
374     }
375     if (!bs->read_only) {
376         error_setg(errp, "Device is not readonly");
377         return -EINVAL;
378     }
379     if (drv->bdrv_snapshot_load_tmp) {
380         return drv->bdrv_snapshot_load_tmp(bs, snapshot_id, name, errp);
381     }
382     error_setg(errp, "Block format '%s' used by device '%s' "
383                "does not support temporarily loading internal snapshots",
384                drv->format_name, bdrv_get_device_name(bs));
385     return -ENOTSUP;
386 }
387 
388 int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
389                                          const char *id_or_name,
390                                          Error **errp)
391 {
392     int ret;
393     Error *local_err = NULL;
394 
395     ret = bdrv_snapshot_load_tmp(bs, id_or_name, NULL, &local_err);
396     if (ret == -ENOENT || ret == -EINVAL) {
397         error_free(local_err);
398         local_err = NULL;
399         ret = bdrv_snapshot_load_tmp(bs, NULL, id_or_name, &local_err);
400     }
401 
402     error_propagate(errp, local_err);
403 
404     return ret;
405 }
406 
407 
408 /* Group operations. All block drivers are involved.
409  * These functions will properly handle dataplane (take aio_context_acquire
410  * when appropriate for appropriate block drivers) */
411 
412 bool bdrv_all_can_snapshot(BlockDriverState **first_bad_bs)
413 {
414     bool ok = true;
415     BlockDriverState *bs;
416     BdrvNextIterator it;
417 
418     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
419         AioContext *ctx = bdrv_get_aio_context(bs);
420 
421         aio_context_acquire(ctx);
422         if (bdrv_is_inserted(bs) && !bdrv_is_read_only(bs)) {
423             ok = bdrv_can_snapshot(bs);
424         }
425         aio_context_release(ctx);
426         if (!ok) {
427             bdrv_next_cleanup(&it);
428             goto fail;
429         }
430     }
431 
432 fail:
433     *first_bad_bs = bs;
434     return ok;
435 }
436 
437 int bdrv_all_delete_snapshot(const char *name, BlockDriverState **first_bad_bs,
438                              Error **err)
439 {
440     int ret = 0;
441     BlockDriverState *bs;
442     BdrvNextIterator it;
443     QEMUSnapshotInfo sn1, *snapshot = &sn1;
444 
445     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
446         AioContext *ctx = bdrv_get_aio_context(bs);
447 
448         aio_context_acquire(ctx);
449         if (bdrv_can_snapshot(bs) &&
450                 bdrv_snapshot_find(bs, snapshot, name) >= 0) {
451             ret = bdrv_snapshot_delete_by_id_or_name(bs, name, err);
452         }
453         aio_context_release(ctx);
454         if (ret < 0) {
455             bdrv_next_cleanup(&it);
456             goto fail;
457         }
458     }
459 
460 fail:
461     *first_bad_bs = bs;
462     return ret;
463 }
464 
465 
466 int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs,
467                            Error **errp)
468 {
469     int ret = 0;
470     BlockDriverState *bs;
471     BdrvNextIterator it;
472 
473     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
474         AioContext *ctx = bdrv_get_aio_context(bs);
475 
476         aio_context_acquire(ctx);
477         if (bdrv_can_snapshot(bs)) {
478             ret = bdrv_snapshot_goto(bs, name, errp);
479         }
480         aio_context_release(ctx);
481         if (ret < 0) {
482             bdrv_next_cleanup(&it);
483             goto fail;
484         }
485     }
486 
487 fail:
488     *first_bad_bs = bs;
489     return ret;
490 }
491 
492 int bdrv_all_find_snapshot(const char *name, BlockDriverState **first_bad_bs)
493 {
494     QEMUSnapshotInfo sn;
495     int err = 0;
496     BlockDriverState *bs;
497     BdrvNextIterator it;
498 
499     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
500         AioContext *ctx = bdrv_get_aio_context(bs);
501 
502         aio_context_acquire(ctx);
503         if (bdrv_can_snapshot(bs)) {
504             err = bdrv_snapshot_find(bs, &sn, name);
505         }
506         aio_context_release(ctx);
507         if (err < 0) {
508             bdrv_next_cleanup(&it);
509             goto fail;
510         }
511     }
512 
513 fail:
514     *first_bad_bs = bs;
515     return err;
516 }
517 
518 int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
519                              BlockDriverState *vm_state_bs,
520                              uint64_t vm_state_size,
521                              BlockDriverState **first_bad_bs)
522 {
523     int err = 0;
524     BlockDriverState *bs;
525     BdrvNextIterator it;
526 
527     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
528         AioContext *ctx = bdrv_get_aio_context(bs);
529 
530         aio_context_acquire(ctx);
531         if (bs == vm_state_bs) {
532             sn->vm_state_size = vm_state_size;
533             err = bdrv_snapshot_create(bs, sn);
534         } else if (bdrv_can_snapshot(bs)) {
535             sn->vm_state_size = 0;
536             err = bdrv_snapshot_create(bs, sn);
537         }
538         aio_context_release(ctx);
539         if (err < 0) {
540             bdrv_next_cleanup(&it);
541             goto fail;
542         }
543     }
544 
545 fail:
546     *first_bad_bs = bs;
547     return err;
548 }
549 
550 BlockDriverState *bdrv_all_find_vmstate_bs(void)
551 {
552     BlockDriverState *bs;
553     BdrvNextIterator it;
554 
555     for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
556         AioContext *ctx = bdrv_get_aio_context(bs);
557         bool found;
558 
559         aio_context_acquire(ctx);
560         found = bdrv_can_snapshot(bs);
561         aio_context_release(ctx);
562 
563         if (found) {
564             bdrv_next_cleanup(&it);
565             break;
566         }
567     }
568     return bs;
569 }
570