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