xref: /openbmc/qemu/block/snapshot.c (revision ef929281f1ddb1ce74f5fe39377a88e6cc8237aa)
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/qstring.h"
32  #include "qemu/option.h"
33  #include "sysemu/block-backend.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      GLOBAL_STATE_CODE();
60  
61      ret = -ENOENT;
62      nb_sns = bdrv_snapshot_list(bs, &sn_tab);
63      if (nb_sns < 0) {
64          return ret;
65      }
66      for (i = 0; i < nb_sns; i++) {
67          sn = &sn_tab[i];
68          if (!strcmp(sn->name, name)) {
69              *sn_info = *sn;
70              ret = 0;
71              break;
72          }
73      }
74      g_free(sn_tab);
75      return ret;
76  }
77  
78  /**
79   * Look up an internal snapshot by @id and @name.
80   * @bs: block device to search
81   * @id: unique snapshot ID, or NULL
82   * @name: snapshot name, or NULL
83   * @sn_info: location to store information on the snapshot found
84   * @errp: location to store error, will be set only for exception
85   *
86   * This function will traverse snapshot list in @bs to search the matching
87   * one, @id and @name are the matching condition:
88   * If both @id and @name are specified, find the first one with id @id and
89   * name @name.
90   * If only @id is specified, find the first one with id @id.
91   * If only @name is specified, find the first one with name @name.
92   * if none is specified, abort().
93   *
94   * Returns: true when a snapshot is found and @sn_info will be filled, false
95   * when error or not found. If all operation succeed but no matching one is
96   * found, @errp will NOT be set.
97   */
98  bool bdrv_snapshot_find_by_id_and_name(BlockDriverState *bs,
99                                         const char *id,
100                                         const char *name,
101                                         QEMUSnapshotInfo *sn_info,
102                                         Error **errp)
103  {
104      QEMUSnapshotInfo *sn_tab, *sn;
105      int nb_sns, i;
106      bool ret = false;
107  
108      assert(id || name);
109      GLOBAL_STATE_CODE();
110  
111      nb_sns = bdrv_snapshot_list(bs, &sn_tab);
112      if (nb_sns < 0) {
113          error_setg_errno(errp, -nb_sns, "Failed to get a snapshot list");
114          return false;
115      } else if (nb_sns == 0) {
116          return false;
117      }
118  
119      if (id && name) {
120          for (i = 0; i < nb_sns; i++) {
121              sn = &sn_tab[i];
122              if (!strcmp(sn->id_str, id) && !strcmp(sn->name, name)) {
123                  *sn_info = *sn;
124                  ret = true;
125                  break;
126              }
127          }
128      } else if (id) {
129          for (i = 0; i < nb_sns; i++) {
130              sn = &sn_tab[i];
131              if (!strcmp(sn->id_str, id)) {
132                  *sn_info = *sn;
133                  ret = true;
134                  break;
135              }
136          }
137      } else if (name) {
138          for (i = 0; i < nb_sns; i++) {
139              sn = &sn_tab[i];
140              if (!strcmp(sn->name, name)) {
141                  *sn_info = *sn;
142                  ret = true;
143                  break;
144              }
145          }
146      }
147  
148      g_free(sn_tab);
149      return ret;
150  }
151  
152  /**
153   * Return a pointer to child of given BDS to which we can fall
154   * back if the given BDS does not support snapshots.
155   * Return NULL if there is no BDS to (safely) fall back to.
156   */
157  static BdrvChild * GRAPH_RDLOCK
158  bdrv_snapshot_fallback_child(BlockDriverState *bs)
159  {
160      BdrvChild *fallback = bdrv_primary_child(bs);
161      BdrvChild *child;
162  
163      GLOBAL_STATE_CODE();
164      assert_bdrv_graph_readable();
165  
166      /* We allow fallback only to primary child */
167      if (!fallback) {
168          return NULL;
169      }
170  
171      /*
172       * Check that there are no other children that would need to be
173       * snapshotted.  If there are, it is not safe to fall back to
174       * fallback.
175       */
176      QLIST_FOREACH(child, &bs->children, next) {
177          if (child->role & (BDRV_CHILD_DATA | BDRV_CHILD_METADATA |
178                             BDRV_CHILD_FILTERED) &&
179              child != fallback)
180          {
181              return NULL;
182          }
183      }
184  
185      return fallback;
186  }
187  
188  static BlockDriverState * GRAPH_RDLOCK
189  bdrv_snapshot_fallback(BlockDriverState *bs)
190  {
191      GLOBAL_STATE_CODE();
192      return child_bs(bdrv_snapshot_fallback_child(bs));
193  }
194  
195  int bdrv_can_snapshot(BlockDriverState *bs)
196  {
197      BlockDriver *drv = bs->drv;
198  
199      GLOBAL_STATE_CODE();
200  
201      if (!drv || !bdrv_is_inserted(bs) || !bdrv_is_writable(bs)) {
202          return 0;
203      }
204  
205      if (!drv->bdrv_snapshot_create) {
206          BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
207          if (fallback_bs) {
208              return bdrv_can_snapshot(fallback_bs);
209          }
210          return 0;
211      }
212  
213      return 1;
214  }
215  
216  int bdrv_snapshot_create(BlockDriverState *bs,
217                           QEMUSnapshotInfo *sn_info)
218  {
219      BlockDriver *drv = bs->drv;
220      BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
221  
222      GLOBAL_STATE_CODE();
223  
224      if (!drv) {
225          return -ENOMEDIUM;
226      }
227      if (drv->bdrv_snapshot_create) {
228          return drv->bdrv_snapshot_create(bs, sn_info);
229      }
230      if (fallback_bs) {
231          return bdrv_snapshot_create(fallback_bs, sn_info);
232      }
233      return -ENOTSUP;
234  }
235  
236  int bdrv_snapshot_goto(BlockDriverState *bs,
237                         const char *snapshot_id,
238                         Error **errp)
239  {
240      BlockDriver *drv = bs->drv;
241      BdrvChild *fallback;
242      int ret, open_ret;
243  
244      GLOBAL_STATE_CODE();
245  
246      if (!drv) {
247          error_setg(errp, "Block driver is closed");
248          return -ENOMEDIUM;
249      }
250  
251      if (!QLIST_EMPTY(&bs->dirty_bitmaps)) {
252          error_setg(errp, "Device has active dirty bitmaps");
253          return -EBUSY;
254      }
255  
256      if (drv->bdrv_snapshot_goto) {
257          ret = drv->bdrv_snapshot_goto(bs, snapshot_id);
258          if (ret < 0) {
259              error_setg_errno(errp, -ret, "Failed to load snapshot");
260          }
261          return ret;
262      }
263  
264      bdrv_graph_rdlock_main_loop();
265      fallback = bdrv_snapshot_fallback_child(bs);
266      bdrv_graph_rdunlock_main_loop();
267  
268      if (fallback) {
269          QDict *options;
270          QDict *file_options;
271          Error *local_err = NULL;
272          BlockDriverState *fallback_bs = fallback->bs;
273          char *subqdict_prefix = g_strdup_printf("%s.", fallback->name);
274  
275          options = qdict_clone_shallow(bs->options);
276  
277          /* Prevent it from getting deleted when detached from bs */
278          bdrv_ref(fallback_bs);
279  
280          qdict_extract_subqdict(options, &file_options, subqdict_prefix);
281          qobject_unref(file_options);
282          g_free(subqdict_prefix);
283  
284          /* Force .bdrv_open() below to re-attach fallback_bs on fallback */
285          qdict_put_str(options, fallback->name,
286                        bdrv_get_node_name(fallback_bs));
287  
288          /* Now close bs, apply the snapshot on fallback_bs, and re-open bs */
289          if (drv->bdrv_close) {
290              drv->bdrv_close(bs);
291          }
292  
293          /* .bdrv_open() will re-attach it */
294          bdrv_graph_wrlock();
295          bdrv_unref_child(bs, fallback);
296          bdrv_graph_wrunlock();
297  
298          ret = bdrv_snapshot_goto(fallback_bs, snapshot_id, errp);
299          open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err);
300          qobject_unref(options);
301          if (open_ret < 0) {
302              bdrv_unref(fallback_bs);
303              bs->drv = NULL;
304              /* A bdrv_snapshot_goto() error takes precedence */
305              error_propagate(errp, local_err);
306              return ret < 0 ? ret : open_ret;
307          }
308  
309          /*
310           * fallback was a primary child. It was closed above and set to NULL,
311           * but the .bdrv_open() call has opened it again, because we set the
312           * respective option (with the qdict_put_str() call above).
313           * Assert that .bdrv_open() has attached the right BDS as primary child.
314           */
315          bdrv_graph_rdlock_main_loop();
316          assert(bdrv_primary_bs(bs) == fallback_bs);
317          bdrv_graph_rdunlock_main_loop();
318  
319          bdrv_unref(fallback_bs);
320          return ret;
321      }
322  
323      error_setg(errp, "Block driver does not support snapshots");
324      return -ENOTSUP;
325  }
326  
327  /**
328   * Delete an internal snapshot by @snapshot_id and @name.
329   * @bs: block device used in the operation
330   * @snapshot_id: unique snapshot ID, or NULL
331   * @name: snapshot name, or NULL
332   * @errp: location to store error
333   *
334   * If both @snapshot_id and @name are specified, delete the first one with
335   * id @snapshot_id and name @name.
336   * If only @snapshot_id is specified, delete the first one with id
337   * @snapshot_id.
338   * If only @name is specified, delete the first one with name @name.
339   * if none is specified, return -EINVAL.
340   *
341   * Returns: 0 on success, -errno on failure. If @bs is not inserted, return
342   * -ENOMEDIUM. If @snapshot_id and @name are both NULL, return -EINVAL. If @bs
343   * does not support internal snapshot deletion, return -ENOTSUP. If @bs does
344   * not support parameter @snapshot_id or @name, or one of them is not correctly
345   * specified, return -EINVAL. If @bs can't find one matching @id and @name,
346   * return -ENOENT. If @errp != NULL, it will always be filled with error
347   * message on failure.
348   */
349  int bdrv_snapshot_delete(BlockDriverState *bs,
350                           const char *snapshot_id,
351                           const char *name,
352                           Error **errp)
353  {
354      BlockDriver *drv = bs->drv;
355      BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
356      int ret;
357  
358      GLOBAL_STATE_CODE();
359  
360      if (!drv) {
361          error_setg(errp, "Device '%s' has no medium",
362                     bdrv_get_device_name(bs));
363          return -ENOMEDIUM;
364      }
365      if (!snapshot_id && !name) {
366          error_setg(errp, "snapshot_id and name are both NULL");
367          return -EINVAL;
368      }
369  
370      /* drain all pending i/o before deleting snapshot */
371      bdrv_drained_begin(bs);
372  
373      if (drv->bdrv_snapshot_delete) {
374          ret = drv->bdrv_snapshot_delete(bs, snapshot_id, name, errp);
375      } else if (fallback_bs) {
376          ret = bdrv_snapshot_delete(fallback_bs, snapshot_id, name, errp);
377      } else {
378          error_setg(errp, "Block format '%s' used by device '%s' "
379                     "does not support internal snapshot deletion",
380                     drv->format_name, bdrv_get_device_name(bs));
381          ret = -ENOTSUP;
382      }
383  
384      bdrv_drained_end(bs);
385      return ret;
386  }
387  
388  int bdrv_snapshot_list(BlockDriverState *bs,
389                         QEMUSnapshotInfo **psn_info)
390  {
391      GLOBAL_STATE_CODE();
392      GRAPH_RDLOCK_GUARD_MAINLOOP();
393  
394      BlockDriver *drv = bs->drv;
395      BlockDriverState *fallback_bs = bdrv_snapshot_fallback(bs);
396  
397      if (!drv) {
398          return -ENOMEDIUM;
399      }
400      if (drv->bdrv_snapshot_list) {
401          return drv->bdrv_snapshot_list(bs, psn_info);
402      }
403      if (fallback_bs) {
404          return bdrv_snapshot_list(fallback_bs, psn_info);
405      }
406      return -ENOTSUP;
407  }
408  
409  /**
410   * Temporarily load an internal snapshot by @snapshot_id and @name.
411   * @bs: block device used in the operation
412   * @snapshot_id: unique snapshot ID, or NULL
413   * @name: snapshot name, or NULL
414   * @errp: location to store error
415   *
416   * If both @snapshot_id and @name are specified, load the first one with
417   * id @snapshot_id and name @name.
418   * If only @snapshot_id is specified, load the first one with id
419   * @snapshot_id.
420   * If only @name is specified, load the first one with name @name.
421   * if none is specified, return -EINVAL.
422   *
423   * Returns: 0 on success, -errno on fail. If @bs is not inserted, return
424   * -ENOMEDIUM. If @bs is not readonly, return -EINVAL. If @bs did not support
425   * internal snapshot, return -ENOTSUP. If qemu can't find a matching @id and
426   * @name, return -ENOENT. If @errp != NULL, it will always be filled on
427   * failure.
428   */
429  int bdrv_snapshot_load_tmp(BlockDriverState *bs,
430                             const char *snapshot_id,
431                             const char *name,
432                             Error **errp)
433  {
434      BlockDriver *drv = bs->drv;
435  
436      GLOBAL_STATE_CODE();
437      GRAPH_RDLOCK_GUARD_MAINLOOP();
438  
439      if (!drv) {
440          error_setg(errp, "Device '%s' has no medium",
441                     bdrv_get_device_name(bs));
442          return -ENOMEDIUM;
443      }
444      if (!snapshot_id && !name) {
445          error_setg(errp, "snapshot_id and name are both NULL");
446          return -EINVAL;
447      }
448      if (!bdrv_is_read_only(bs)) {
449          error_setg(errp, "Device is not readonly");
450          return -EINVAL;
451      }
452      if (drv->bdrv_snapshot_load_tmp) {
453          return drv->bdrv_snapshot_load_tmp(bs, snapshot_id, name, errp);
454      }
455      error_setg(errp, "Block format '%s' used by device '%s' "
456                 "does not support temporarily loading internal snapshots",
457                 drv->format_name, bdrv_get_device_name(bs));
458      return -ENOTSUP;
459  }
460  
461  int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
462                                           const char *id_or_name,
463                                           Error **errp)
464  {
465      int ret;
466      Error *local_err = NULL;
467  
468      GLOBAL_STATE_CODE();
469  
470      ret = bdrv_snapshot_load_tmp(bs, id_or_name, NULL, &local_err);
471      if (ret == -ENOENT || ret == -EINVAL) {
472          error_free(local_err);
473          local_err = NULL;
474          ret = bdrv_snapshot_load_tmp(bs, NULL, id_or_name, &local_err);
475      }
476  
477      error_propagate(errp, local_err);
478  
479      return ret;
480  }
481  
482  
483  static int GRAPH_RDLOCK
484  bdrv_all_get_snapshot_devices(bool has_devices, strList *devices,
485                                GList **all_bdrvs, Error **errp)
486  {
487      g_autoptr(GList) bdrvs = NULL;
488  
489      if (has_devices) {
490          if (!devices) {
491              error_setg(errp, "At least one device is required for snapshot");
492              return -1;
493          }
494  
495          while (devices) {
496              BlockDriverState *bs = bdrv_find_node(devices->value);
497              if (!bs) {
498                  error_setg(errp, "No block device node '%s'", devices->value);
499                  return -1;
500              }
501              bdrvs = g_list_append(bdrvs, bs);
502              devices = devices->next;
503          }
504      } else {
505          BlockDriverState *bs;
506          BdrvNextIterator it;
507          for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
508              bdrvs = g_list_append(bdrvs, bs);
509          }
510      }
511  
512      *all_bdrvs = g_steal_pointer(&bdrvs);
513      return 0;
514  }
515  
516  
517  static bool GRAPH_RDLOCK bdrv_all_snapshots_includes_bs(BlockDriverState *bs)
518  {
519      GLOBAL_STATE_CODE();
520      assert_bdrv_graph_readable();
521  
522      if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
523          return false;
524      }
525  
526      /* Include all nodes that are either in use by a BlockBackend, or that
527       * aren't attached to any node, but owned by the monitor. */
528      return bdrv_has_blk(bs) || QLIST_EMPTY(&bs->parents);
529  }
530  
531  /* Group operations. All block drivers are involved. */
532  
533  bool bdrv_all_can_snapshot(bool has_devices, strList *devices,
534                             Error **errp)
535  {
536      g_autoptr(GList) bdrvs = NULL;
537      GList *iterbdrvs;
538  
539      GLOBAL_STATE_CODE();
540      GRAPH_RDLOCK_GUARD_MAINLOOP();
541  
542      if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
543          return false;
544      }
545  
546      iterbdrvs = bdrvs;
547      while (iterbdrvs) {
548          BlockDriverState *bs = iterbdrvs->data;
549          bool ok = true;
550  
551          if (devices || bdrv_all_snapshots_includes_bs(bs)) {
552              ok = bdrv_can_snapshot(bs);
553          }
554          if (!ok) {
555              error_setg(errp, "Device '%s' is writable but does not support "
556                         "snapshots", bdrv_get_device_or_node_name(bs));
557              return false;
558          }
559  
560          iterbdrvs = iterbdrvs->next;
561      }
562  
563      return true;
564  }
565  
566  int bdrv_all_delete_snapshot(const char *name,
567                               bool has_devices, strList *devices,
568                               Error **errp)
569  {
570      ERRP_GUARD();
571      g_autoptr(GList) bdrvs = NULL;
572      GList *iterbdrvs;
573  
574      GLOBAL_STATE_CODE();
575      GRAPH_RDLOCK_GUARD_MAINLOOP();
576  
577      if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
578          return -1;
579      }
580  
581      iterbdrvs = bdrvs;
582      while (iterbdrvs) {
583          BlockDriverState *bs = iterbdrvs->data;
584          QEMUSnapshotInfo sn1, *snapshot = &sn1;
585          int ret = 0;
586  
587          if ((devices || bdrv_all_snapshots_includes_bs(bs)) &&
588              bdrv_snapshot_find(bs, snapshot, name) >= 0)
589          {
590              ret = bdrv_snapshot_delete(bs, snapshot->id_str,
591                                         snapshot->name, errp);
592          }
593          if (ret < 0) {
594              error_prepend(errp, "Could not delete snapshot '%s' on '%s': ",
595                            name, bdrv_get_device_or_node_name(bs));
596              return -1;
597          }
598  
599          iterbdrvs = iterbdrvs->next;
600      }
601  
602      return 0;
603  }
604  
605  
606  int bdrv_all_goto_snapshot(const char *name,
607                             bool has_devices, strList *devices,
608                             Error **errp)
609  {
610      ERRP_GUARD();
611      g_autoptr(GList) bdrvs = NULL;
612      GList *iterbdrvs;
613      int ret;
614  
615      GLOBAL_STATE_CODE();
616  
617      bdrv_graph_rdlock_main_loop();
618      ret = bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp);
619      bdrv_graph_rdunlock_main_loop();
620  
621      if (ret < 0) {
622          return -1;
623      }
624  
625      iterbdrvs = bdrvs;
626      while (iterbdrvs) {
627          BlockDriverState *bs = iterbdrvs->data;
628          bool all_snapshots_includes_bs;
629  
630          bdrv_graph_rdlock_main_loop();
631          all_snapshots_includes_bs = bdrv_all_snapshots_includes_bs(bs);
632          bdrv_graph_rdunlock_main_loop();
633  
634          ret = (devices || all_snapshots_includes_bs) ?
635                bdrv_snapshot_goto(bs, name, errp) : 0;
636          if (ret < 0) {
637              bdrv_graph_rdlock_main_loop();
638              error_prepend(errp, "Could not load snapshot '%s' on '%s': ",
639                            name, bdrv_get_device_or_node_name(bs));
640              bdrv_graph_rdunlock_main_loop();
641              return -1;
642          }
643  
644          iterbdrvs = iterbdrvs->next;
645      }
646  
647      return 0;
648  }
649  
650  int bdrv_all_has_snapshot(const char *name,
651                            bool has_devices, strList *devices,
652                            Error **errp)
653  {
654      g_autoptr(GList) bdrvs = NULL;
655      GList *iterbdrvs;
656  
657      GLOBAL_STATE_CODE();
658      GRAPH_RDLOCK_GUARD_MAINLOOP();
659  
660      if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
661          return -1;
662      }
663  
664      iterbdrvs = bdrvs;
665      while (iterbdrvs) {
666          BlockDriverState *bs = iterbdrvs->data;
667          QEMUSnapshotInfo sn;
668          int ret = 0;
669  
670          if (devices || bdrv_all_snapshots_includes_bs(bs)) {
671              ret = bdrv_snapshot_find(bs, &sn, name);
672          }
673          if (ret < 0) {
674              if (ret == -ENOENT) {
675                  return 0;
676              } else {
677                  error_setg_errno(errp, errno,
678                                   "Could not check snapshot '%s' on '%s'",
679                                   name, bdrv_get_device_or_node_name(bs));
680                  return -1;
681              }
682          }
683  
684          iterbdrvs = iterbdrvs->next;
685      }
686  
687      return 1;
688  }
689  
690  int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
691                               BlockDriverState *vm_state_bs,
692                               uint64_t vm_state_size,
693                               bool has_devices, strList *devices,
694                               Error **errp)
695  {
696      g_autoptr(GList) bdrvs = NULL;
697      GList *iterbdrvs;
698  
699      GLOBAL_STATE_CODE();
700      GRAPH_RDLOCK_GUARD_MAINLOOP();
701  
702      if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
703          return -1;
704      }
705  
706      iterbdrvs = bdrvs;
707      while (iterbdrvs) {
708          BlockDriverState *bs = iterbdrvs->data;
709          int ret = 0;
710  
711          if (bs == vm_state_bs) {
712              sn->vm_state_size = vm_state_size;
713              ret = bdrv_snapshot_create(bs, sn);
714          } else if (devices || bdrv_all_snapshots_includes_bs(bs)) {
715              sn->vm_state_size = 0;
716              ret = bdrv_snapshot_create(bs, sn);
717          }
718          if (ret < 0) {
719              error_setg(errp, "Could not create snapshot '%s' on '%s'",
720                         sn->name, bdrv_get_device_or_node_name(bs));
721              return -1;
722          }
723  
724          iterbdrvs = iterbdrvs->next;
725      }
726  
727      return 0;
728  }
729  
730  
731  BlockDriverState *bdrv_all_find_vmstate_bs(const char *vmstate_bs,
732                                             bool has_devices, strList *devices,
733                                             Error **errp)
734  {
735      g_autoptr(GList) bdrvs = NULL;
736      GList *iterbdrvs;
737  
738      GLOBAL_STATE_CODE();
739      GRAPH_RDLOCK_GUARD_MAINLOOP();
740  
741      if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
742          return NULL;
743      }
744  
745      iterbdrvs = bdrvs;
746      while (iterbdrvs) {
747          BlockDriverState *bs = iterbdrvs->data;
748          bool found = false;
749  
750          found = (devices || bdrv_all_snapshots_includes_bs(bs)) &&
751              bdrv_can_snapshot(bs);
752  
753          if (vmstate_bs) {
754              if (g_str_equal(vmstate_bs,
755                              bdrv_get_node_name(bs))) {
756                  if (found) {
757                      return bs;
758                  } else {
759                      error_setg(errp,
760                                 "vmstate block device '%s' does not support snapshots",
761                                 vmstate_bs);
762                      return NULL;
763                  }
764              }
765          } else if (found) {
766              return bs;
767          }
768  
769          iterbdrvs = iterbdrvs->next;
770      }
771  
772      if (vmstate_bs) {
773          error_setg(errp,
774                     "vmstate block device '%s' does not exist", vmstate_bs);
775      } else {
776          error_setg(errp,
777                     "no block device can store vmstate for snapshot");
778      }
779      return NULL;
780  }
781