block: add ability to specify list of blockdevs during snapshot
When running snapshot operations, there are various rules for which blockdevs are included/excluded. While this provides reasonable default behaviour, there are scenarios that are not well handled by the default logic. Some of the conditions do not have a single correct answer. Thus there needs to be a way for the mgmt app to provide an explicit list of blockdevs to perform snapshots across. This can be achieved by passing a list of node names that should be used. Reviewed-by: Eric Blake <eblake@redhat.com> Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> Message-Id: <20210204124834.774401-5-berrange@redhat.com> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
This commit is contained in:
parent
f61fe11aa6
commit
cf3a74c94f
@ -902,7 +902,7 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
|||||||
SnapshotEntry *snapshot_entry;
|
SnapshotEntry *snapshot_entry;
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
|
||||||
bs = bdrv_all_find_vmstate_bs(&err);
|
bs = bdrv_all_find_vmstate_bs(false, NULL, &err);
|
||||||
if (!bs) {
|
if (!bs) {
|
||||||
error_report_err(err);
|
error_report_err(err);
|
||||||
return;
|
return;
|
||||||
@ -954,7 +954,7 @@ void hmp_info_snapshots(Monitor *mon, const QDict *qdict)
|
|||||||
total = 0;
|
total = 0;
|
||||||
for (i = 0; i < nb_sns; i++) {
|
for (i = 0; i < nb_sns; i++) {
|
||||||
SnapshotEntry *next_sn;
|
SnapshotEntry *next_sn;
|
||||||
if (bdrv_all_find_snapshot(sn_tab[i].name, NULL) == 0) {
|
if (bdrv_all_find_snapshot(sn_tab[i].name, false, NULL, NULL) == 0) {
|
||||||
global_snapshots[total] = i;
|
global_snapshots[total] = i;
|
||||||
total++;
|
total++;
|
||||||
QTAILQ_FOREACH(image_entry, &image_list, next) {
|
QTAILQ_FOREACH(image_entry, &image_list, next) {
|
||||||
|
174
block/snapshot.c
174
block/snapshot.c
@ -447,6 +447,41 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int bdrv_all_get_snapshot_devices(bool has_devices, strList *devices,
|
||||||
|
GList **all_bdrvs,
|
||||||
|
Error **errp)
|
||||||
|
{
|
||||||
|
g_autoptr(GList) bdrvs = NULL;
|
||||||
|
|
||||||
|
if (has_devices) {
|
||||||
|
if (!devices) {
|
||||||
|
error_setg(errp, "At least one device is required for snapshot");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (devices) {
|
||||||
|
BlockDriverState *bs = bdrv_find_node(devices->value);
|
||||||
|
if (!bs) {
|
||||||
|
error_setg(errp, "No block device node '%s'", devices->value);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
bdrvs = g_list_append(bdrvs, bs);
|
||||||
|
devices = devices->next;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
BlockDriverState *bs;
|
||||||
|
BdrvNextIterator it;
|
||||||
|
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
||||||
|
bdrvs = g_list_append(bdrvs, bs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*all_bdrvs = g_steal_pointer(&bdrvs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool bdrv_all_snapshots_includes_bs(BlockDriverState *bs)
|
static bool bdrv_all_snapshots_includes_bs(BlockDriverState *bs)
|
||||||
{
|
{
|
||||||
if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
|
if (!bdrv_is_inserted(bs) || bdrv_is_read_only(bs)) {
|
||||||
@ -462,43 +497,59 @@ static bool bdrv_all_snapshots_includes_bs(BlockDriverState *bs)
|
|||||||
* These functions will properly handle dataplane (take aio_context_acquire
|
* These functions will properly handle dataplane (take aio_context_acquire
|
||||||
* when appropriate for appropriate block drivers) */
|
* when appropriate for appropriate block drivers) */
|
||||||
|
|
||||||
bool bdrv_all_can_snapshot(Error **errp)
|
bool bdrv_all_can_snapshot(bool has_devices, strList *devices,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs;
|
g_autoptr(GList) bdrvs = NULL;
|
||||||
BdrvNextIterator it;
|
GList *iterbdrvs;
|
||||||
|
|
||||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterbdrvs = bdrvs;
|
||||||
|
while (iterbdrvs) {
|
||||||
|
BlockDriverState *bs = iterbdrvs->data;
|
||||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||||
bool ok = true;
|
bool ok = true;
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
aio_context_acquire(ctx);
|
||||||
if (bdrv_all_snapshots_includes_bs(bs)) {
|
if (devices || bdrv_all_snapshots_includes_bs(bs)) {
|
||||||
ok = bdrv_can_snapshot(bs);
|
ok = bdrv_can_snapshot(bs);
|
||||||
}
|
}
|
||||||
aio_context_release(ctx);
|
aio_context_release(ctx);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
error_setg(errp, "Device '%s' is writable but does not support "
|
error_setg(errp, "Device '%s' is writable but does not support "
|
||||||
"snapshots", bdrv_get_device_or_node_name(bs));
|
"snapshots", bdrv_get_device_or_node_name(bs));
|
||||||
bdrv_next_cleanup(&it);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iterbdrvs = iterbdrvs->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_all_delete_snapshot(const char *name, Error **errp)
|
int bdrv_all_delete_snapshot(const char *name,
|
||||||
|
bool has_devices, strList *devices,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs;
|
g_autoptr(GList) bdrvs = NULL;
|
||||||
BdrvNextIterator it;
|
GList *iterbdrvs;
|
||||||
QEMUSnapshotInfo sn1, *snapshot = &sn1;
|
|
||||||
|
|
||||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterbdrvs = bdrvs;
|
||||||
|
while (iterbdrvs) {
|
||||||
|
BlockDriverState *bs = iterbdrvs->data;
|
||||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||||
|
QEMUSnapshotInfo sn1, *snapshot = &sn1;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
aio_context_acquire(ctx);
|
||||||
if (bdrv_all_snapshots_includes_bs(bs) &&
|
if ((devices || bdrv_all_snapshots_includes_bs(bs)) &&
|
||||||
bdrv_snapshot_find(bs, snapshot, name) >= 0)
|
bdrv_snapshot_find(bs, snapshot, name) >= 0)
|
||||||
{
|
{
|
||||||
ret = bdrv_snapshot_delete(bs, snapshot->id_str,
|
ret = bdrv_snapshot_delete(bs, snapshot->id_str,
|
||||||
@ -508,61 +559,80 @@ int bdrv_all_delete_snapshot(const char *name, Error **errp)
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_prepend(errp, "Could not delete snapshot '%s' on '%s': ",
|
error_prepend(errp, "Could not delete snapshot '%s' on '%s': ",
|
||||||
name, bdrv_get_device_or_node_name(bs));
|
name, bdrv_get_device_or_node_name(bs));
|
||||||
bdrv_next_cleanup(&it);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iterbdrvs = iterbdrvs->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int bdrv_all_goto_snapshot(const char *name, Error **errp)
|
int bdrv_all_goto_snapshot(const char *name,
|
||||||
|
bool has_devices, strList *devices,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs;
|
g_autoptr(GList) bdrvs = NULL;
|
||||||
BdrvNextIterator it;
|
GList *iterbdrvs;
|
||||||
|
|
||||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterbdrvs = bdrvs;
|
||||||
|
while (iterbdrvs) {
|
||||||
|
BlockDriverState *bs = iterbdrvs->data;
|
||||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
aio_context_acquire(ctx);
|
||||||
if (bdrv_all_snapshots_includes_bs(bs)) {
|
if (devices || bdrv_all_snapshots_includes_bs(bs)) {
|
||||||
ret = bdrv_snapshot_goto(bs, name, errp);
|
ret = bdrv_snapshot_goto(bs, name, errp);
|
||||||
}
|
}
|
||||||
aio_context_release(ctx);
|
aio_context_release(ctx);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_prepend(errp, "Could not load snapshot '%s' on '%s': ",
|
error_prepend(errp, "Could not load snapshot '%s' on '%s': ",
|
||||||
name, bdrv_get_device_or_node_name(bs));
|
name, bdrv_get_device_or_node_name(bs));
|
||||||
bdrv_next_cleanup(&it);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iterbdrvs = iterbdrvs->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_all_find_snapshot(const char *name, Error **errp)
|
int bdrv_all_find_snapshot(const char *name,
|
||||||
|
bool has_devices, strList *devices,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
QEMUSnapshotInfo sn;
|
g_autoptr(GList) bdrvs = NULL;
|
||||||
BlockDriverState *bs;
|
GList *iterbdrvs;
|
||||||
BdrvNextIterator it;
|
|
||||||
|
|
||||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterbdrvs = bdrvs;
|
||||||
|
while (iterbdrvs) {
|
||||||
|
BlockDriverState *bs = iterbdrvs->data;
|
||||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||||
|
QEMUSnapshotInfo sn;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
aio_context_acquire(ctx);
|
||||||
if (bdrv_all_snapshots_includes_bs(bs)) {
|
if (devices || bdrv_all_snapshots_includes_bs(bs)) {
|
||||||
ret = bdrv_snapshot_find(bs, &sn, name);
|
ret = bdrv_snapshot_find(bs, &sn, name);
|
||||||
}
|
}
|
||||||
aio_context_release(ctx);
|
aio_context_release(ctx);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg(errp, "Could not find snapshot '%s' on '%s'",
|
error_setg(errp, "Could not find snapshot '%s' on '%s'",
|
||||||
name, bdrv_get_device_or_node_name(bs));
|
name, bdrv_get_device_or_node_name(bs));
|
||||||
bdrv_next_cleanup(&it);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iterbdrvs = iterbdrvs->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -571,12 +641,19 @@ int bdrv_all_find_snapshot(const char *name, Error **errp)
|
|||||||
int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
|
int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
|
||||||
BlockDriverState *vm_state_bs,
|
BlockDriverState *vm_state_bs,
|
||||||
uint64_t vm_state_size,
|
uint64_t vm_state_size,
|
||||||
|
bool has_devices, strList *devices,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs;
|
g_autoptr(GList) bdrvs = NULL;
|
||||||
BdrvNextIterator it;
|
GList *iterbdrvs;
|
||||||
|
|
||||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterbdrvs = bdrvs;
|
||||||
|
while (iterbdrvs) {
|
||||||
|
BlockDriverState *bs = iterbdrvs->data;
|
||||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -584,7 +661,7 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
|
|||||||
if (bs == vm_state_bs) {
|
if (bs == vm_state_bs) {
|
||||||
sn->vm_state_size = vm_state_size;
|
sn->vm_state_size = vm_state_size;
|
||||||
ret = bdrv_snapshot_create(bs, sn);
|
ret = bdrv_snapshot_create(bs, sn);
|
||||||
} else if (bdrv_all_snapshots_includes_bs(bs)) {
|
} else if (devices || bdrv_all_snapshots_includes_bs(bs)) {
|
||||||
sn->vm_state_size = 0;
|
sn->vm_state_size = 0;
|
||||||
ret = bdrv_snapshot_create(bs, sn);
|
ret = bdrv_snapshot_create(bs, sn);
|
||||||
}
|
}
|
||||||
@ -592,34 +669,43 @@ int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
|
|||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
error_setg(errp, "Could not create snapshot '%s' on '%s'",
|
error_setg(errp, "Could not create snapshot '%s' on '%s'",
|
||||||
sn->name, bdrv_get_device_or_node_name(bs));
|
sn->name, bdrv_get_device_or_node_name(bs));
|
||||||
bdrv_next_cleanup(&it);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
iterbdrvs = iterbdrvs->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockDriverState *bdrv_all_find_vmstate_bs(Error **errp)
|
BlockDriverState *bdrv_all_find_vmstate_bs(bool has_devices, strList *devices,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BlockDriverState *bs;
|
g_autoptr(GList) bdrvs = NULL;
|
||||||
BdrvNextIterator it;
|
GList *iterbdrvs;
|
||||||
|
|
||||||
for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
|
if (bdrv_all_get_snapshot_devices(has_devices, devices, &bdrvs, errp) < 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterbdrvs = bdrvs;
|
||||||
|
while (iterbdrvs) {
|
||||||
|
BlockDriverState *bs = iterbdrvs->data;
|
||||||
AioContext *ctx = bdrv_get_aio_context(bs);
|
AioContext *ctx = bdrv_get_aio_context(bs);
|
||||||
bool found;
|
bool found = false;
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
aio_context_acquire(ctx);
|
||||||
found = bdrv_all_snapshots_includes_bs(bs) && bdrv_can_snapshot(bs);
|
found = (devices || bdrv_all_snapshots_includes_bs(bs)) &&
|
||||||
|
bdrv_can_snapshot(bs);
|
||||||
aio_context_release(ctx);
|
aio_context_release(ctx);
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
bdrv_next_cleanup(&it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!bs) {
|
|
||||||
error_setg(errp, "No block device supports snapshots");
|
|
||||||
}
|
|
||||||
return bs;
|
return bs;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterbdrvs = iterbdrvs->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
error_setg(errp, "No block device supports snapshots");
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#ifndef SNAPSHOT_H
|
#ifndef SNAPSHOT_H
|
||||||
#define SNAPSHOT_H
|
#define SNAPSHOT_H
|
||||||
|
|
||||||
|
#include "qapi/qapi-builtin-types.h"
|
||||||
|
|
||||||
#define SNAPSHOT_OPT_BASE "snapshot."
|
#define SNAPSHOT_OPT_BASE "snapshot."
|
||||||
#define SNAPSHOT_OPT_ID "snapshot.id"
|
#define SNAPSHOT_OPT_ID "snapshot.id"
|
||||||
@ -77,15 +77,25 @@ int bdrv_snapshot_load_tmp_by_id_or_name(BlockDriverState *bs,
|
|||||||
* These functions will properly handle dataplane (take aio_context_acquire
|
* These functions will properly handle dataplane (take aio_context_acquire
|
||||||
* when appropriate for appropriate block drivers */
|
* when appropriate for appropriate block drivers */
|
||||||
|
|
||||||
bool bdrv_all_can_snapshot(Error **errp);
|
bool bdrv_all_can_snapshot(bool has_devices, strList *devices,
|
||||||
int bdrv_all_delete_snapshot(const char *name, Error **errp);
|
Error **errp);
|
||||||
int bdrv_all_goto_snapshot(const char *name, Error **errp);
|
int bdrv_all_delete_snapshot(const char *name,
|
||||||
int bdrv_all_find_snapshot(const char *name, Error **errp);
|
bool has_devices, strList *devices,
|
||||||
|
Error **errp);
|
||||||
|
int bdrv_all_goto_snapshot(const char *name,
|
||||||
|
bool has_devices, strList *devices,
|
||||||
|
Error **errp);
|
||||||
|
int bdrv_all_find_snapshot(const char *name,
|
||||||
|
bool has_devices, strList *devices,
|
||||||
|
Error **errp);
|
||||||
int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
|
int bdrv_all_create_snapshot(QEMUSnapshotInfo *sn,
|
||||||
BlockDriverState *vm_state_bs,
|
BlockDriverState *vm_state_bs,
|
||||||
uint64_t vm_state_size,
|
uint64_t vm_state_size,
|
||||||
|
bool has_devices,
|
||||||
|
strList *devices,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
|
||||||
BlockDriverState *bdrv_all_find_vmstate_bs(Error **errp);
|
BlockDriverState *bdrv_all_find_vmstate_bs(bool has_devices, strList *devices,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -2786,18 +2786,18 @@ bool save_snapshot(const char *name, Error **errp)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bdrv_all_can_snapshot(errp)) {
|
if (!bdrv_all_can_snapshot(false, NULL, errp)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Delete old snapshots of the same name */
|
/* Delete old snapshots of the same name */
|
||||||
if (name) {
|
if (name) {
|
||||||
if (bdrv_all_delete_snapshot(name, errp) < 0) {
|
if (bdrv_all_delete_snapshot(name, false, NULL, errp) < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bs = bdrv_all_find_vmstate_bs(errp);
|
bs = bdrv_all_find_vmstate_bs(false, NULL, errp);
|
||||||
if (bs == NULL) {
|
if (bs == NULL) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -2862,9 +2862,9 @@ bool save_snapshot(const char *name, Error **errp)
|
|||||||
aio_context_release(aio_context);
|
aio_context_release(aio_context);
|
||||||
aio_context = NULL;
|
aio_context = NULL;
|
||||||
|
|
||||||
ret = bdrv_all_create_snapshot(sn, bs, vm_state_size, errp);
|
ret = bdrv_all_create_snapshot(sn, bs, vm_state_size, false, NULL, errp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
bdrv_all_delete_snapshot(sn->name, NULL);
|
bdrv_all_delete_snapshot(sn->name, false, NULL, NULL);
|
||||||
goto the_end;
|
goto the_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2974,15 +2974,15 @@ bool load_snapshot(const char *name, Error **errp)
|
|||||||
AioContext *aio_context;
|
AioContext *aio_context;
|
||||||
MigrationIncomingState *mis = migration_incoming_get_current();
|
MigrationIncomingState *mis = migration_incoming_get_current();
|
||||||
|
|
||||||
if (!bdrv_all_can_snapshot(errp)) {
|
if (!bdrv_all_can_snapshot(false, NULL, errp)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ret = bdrv_all_find_snapshot(name, errp);
|
ret = bdrv_all_find_snapshot(name, false, NULL, errp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bs_vm_state = bdrv_all_find_vmstate_bs(errp);
|
bs_vm_state = bdrv_all_find_vmstate_bs(false, NULL, errp);
|
||||||
if (!bs_vm_state) {
|
if (!bs_vm_state) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -3009,7 +3009,7 @@ bool load_snapshot(const char *name, Error **errp)
|
|||||||
/* Flush all IO requests so they don't interfere with the new state. */
|
/* Flush all IO requests so they don't interfere with the new state. */
|
||||||
bdrv_drain_all_begin();
|
bdrv_drain_all_begin();
|
||||||
|
|
||||||
ret = bdrv_all_goto_snapshot(name, errp);
|
ret = bdrv_all_goto_snapshot(name, false, NULL, errp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
goto err_drain;
|
goto err_drain;
|
||||||
}
|
}
|
||||||
|
@ -1158,7 +1158,7 @@ void hmp_delvm(Monitor *mon, const QDict *qdict)
|
|||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
const char *name = qdict_get_str(qdict, "name");
|
const char *name = qdict_get_str(qdict, "name");
|
||||||
|
|
||||||
bdrv_all_delete_snapshot(name, &err);
|
bdrv_all_delete_snapshot(name, false, NULL, &err);
|
||||||
hmp_handle_error(mon, err);
|
hmp_handle_error(mon, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,7 +148,7 @@ static char *replay_find_nearest_snapshot(int64_t icount,
|
|||||||
|
|
||||||
*snapshot_icount = -1;
|
*snapshot_icount = -1;
|
||||||
|
|
||||||
bs = bdrv_all_find_vmstate_bs(NULL);
|
bs = bdrv_all_find_vmstate_bs(false, NULL, NULL);
|
||||||
if (!bs) {
|
if (!bs) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
@ -159,7 +159,7 @@ static char *replay_find_nearest_snapshot(int64_t icount,
|
|||||||
aio_context_release(aio_context);
|
aio_context_release(aio_context);
|
||||||
|
|
||||||
for (i = 0; i < nb_sns; i++) {
|
for (i = 0; i < nb_sns; i++) {
|
||||||
if (bdrv_all_find_snapshot(sn_tab[i].name, NULL) == 0) {
|
if (bdrv_all_find_snapshot(sn_tab[i].name, false, NULL, NULL) == 0) {
|
||||||
if (sn_tab[i].icount != -1ULL
|
if (sn_tab[i].icount != -1ULL
|
||||||
&& sn_tab[i].icount <= icount
|
&& sn_tab[i].icount <= icount
|
||||||
&& (!nearest || nearest->icount < sn_tab[i].icount)) {
|
&& (!nearest || nearest->icount < sn_tab[i].icount)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user