xref: /openbmc/qemu/block/snapshot.c (revision 709395f8)
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->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_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  */
340 int 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 
368 int 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 
392 bool 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 
412 fail:
413     *first_bad_bs = bs;
414     return ok;
415 }
416 
417 int 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 
441 fail:
442     *first_bad_bs = bs;
443     return ret;
444 }
445 
446 
447 int 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 
468 fail:
469     *first_bad_bs = bs;
470     return ret;
471 }
472 
473 int 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 
494 fail:
495     *first_bad_bs = bs;
496     return err;
497 }
498 
499 int 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 
526 fail:
527     *first_bad_bs = bs;
528     return err;
529 }
530 
531 BlockDriverState *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