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