block: Add errp to bdrv_snapshot_goto()
Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Reviewed-by: John Snow <jsnow@redhat.com>
This commit is contained in:
parent
1f4ad7d3b8
commit
0b62bcbc61
|
@ -177,18 +177,21 @@ int bdrv_snapshot_create(BlockDriverState *bs,
|
||||||
}
|
}
|
||||||
|
|
||||||
int bdrv_snapshot_goto(BlockDriverState *bs,
|
int bdrv_snapshot_goto(BlockDriverState *bs,
|
||||||
const char *snapshot_id)
|
const char *snapshot_id,
|
||||||
|
Error **errp)
|
||||||
{
|
{
|
||||||
BlockDriver *drv = bs->drv;
|
BlockDriver *drv = bs->drv;
|
||||||
int ret, open_ret;
|
int ret, open_ret;
|
||||||
int64_t len;
|
int64_t len;
|
||||||
|
|
||||||
if (!drv) {
|
if (!drv) {
|
||||||
|
error_setg(errp, "Block driver is closed");
|
||||||
return -ENOMEDIUM;
|
return -ENOMEDIUM;
|
||||||
}
|
}
|
||||||
|
|
||||||
len = bdrv_getlength(bs);
|
len = bdrv_getlength(bs);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
|
error_setg_errno(errp, -len, "Cannot get block device size");
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
/* We should set all bits in all enabled dirty bitmaps, because dirty
|
/* We should set all bits in all enabled dirty bitmaps, because dirty
|
||||||
|
@ -200,13 +203,18 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
|
||||||
bdrv_set_dirty(bs, 0, len);
|
bdrv_set_dirty(bs, 0, len);
|
||||||
|
|
||||||
if (drv->bdrv_snapshot_goto) {
|
if (drv->bdrv_snapshot_goto) {
|
||||||
return drv->bdrv_snapshot_goto(bs, snapshot_id);
|
ret = drv->bdrv_snapshot_goto(bs, snapshot_id);
|
||||||
|
if (ret < 0) {
|
||||||
|
error_setg_errno(errp, -ret, "Failed to load snapshot");
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bs->file) {
|
if (bs->file) {
|
||||||
BlockDriverState *file;
|
BlockDriverState *file;
|
||||||
QDict *options = qdict_clone_shallow(bs->options);
|
QDict *options = qdict_clone_shallow(bs->options);
|
||||||
QDict *file_options;
|
QDict *file_options;
|
||||||
|
Error *local_err = NULL;
|
||||||
|
|
||||||
file = bs->file->bs;
|
file = bs->file->bs;
|
||||||
/* Prevent it from getting deleted when detached from bs */
|
/* Prevent it from getting deleted when detached from bs */
|
||||||
|
@ -220,13 +228,15 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
|
||||||
bdrv_unref_child(bs, bs->file);
|
bdrv_unref_child(bs, bs->file);
|
||||||
bs->file = NULL;
|
bs->file = NULL;
|
||||||
|
|
||||||
ret = bdrv_snapshot_goto(file, snapshot_id);
|
ret = bdrv_snapshot_goto(file, snapshot_id, errp);
|
||||||
open_ret = drv->bdrv_open(bs, options, bs->open_flags, NULL);
|
open_ret = drv->bdrv_open(bs, options, bs->open_flags, &local_err);
|
||||||
QDECREF(options);
|
QDECREF(options);
|
||||||
if (open_ret < 0) {
|
if (open_ret < 0) {
|
||||||
bdrv_unref(file);
|
bdrv_unref(file);
|
||||||
bs->drv = NULL;
|
bs->drv = NULL;
|
||||||
return open_ret;
|
/* A bdrv_snapshot_goto() error takes precedence */
|
||||||
|
error_propagate(errp, local_err);
|
||||||
|
return ret < 0 ? ret : open_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(bs->file->bs == file);
|
assert(bs->file->bs == file);
|
||||||
|
@ -234,6 +244,7 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
error_setg(errp, "Block driver does not support snapshots");
|
||||||
return -ENOTSUP;
|
return -ENOTSUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +478,7 @@ int bdrv_all_goto_snapshot(const char *name, BlockDriverState **first_bad_bs)
|
||||||
|
|
||||||
aio_context_acquire(ctx);
|
aio_context_acquire(ctx);
|
||||||
if (bdrv_can_snapshot(bs)) {
|
if (bdrv_can_snapshot(bs)) {
|
||||||
err = bdrv_snapshot_goto(bs, name);
|
err = bdrv_snapshot_goto(bs, name, NULL);
|
||||||
}
|
}
|
||||||
aio_context_release(ctx);
|
aio_context_release(ctx);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
|
|
@ -57,7 +57,8 @@ int bdrv_can_snapshot(BlockDriverState *bs);
|
||||||
int bdrv_snapshot_create(BlockDriverState *bs,
|
int bdrv_snapshot_create(BlockDriverState *bs,
|
||||||
QEMUSnapshotInfo *sn_info);
|
QEMUSnapshotInfo *sn_info);
|
||||||
int bdrv_snapshot_goto(BlockDriverState *bs,
|
int bdrv_snapshot_goto(BlockDriverState *bs,
|
||||||
const char *snapshot_id);
|
const char *snapshot_id,
|
||||||
|
Error **errp);
|
||||||
int bdrv_snapshot_delete(BlockDriverState *bs,
|
int bdrv_snapshot_delete(BlockDriverState *bs,
|
||||||
const char *snapshot_id,
|
const char *snapshot_id,
|
||||||
const char *name,
|
const char *name,
|
||||||
|
|
|
@ -2989,10 +2989,10 @@ static int img_snapshot(int argc, char **argv)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SNAPSHOT_APPLY:
|
case SNAPSHOT_APPLY:
|
||||||
ret = bdrv_snapshot_goto(bs, snapshot_name);
|
ret = bdrv_snapshot_goto(bs, snapshot_name, &err);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
error_report("Could not apply snapshot '%s': %d (%s)",
|
error_reportf_err(err, "Could not apply snapshot '%s': ",
|
||||||
snapshot_name, ret, strerror(-ret));
|
snapshot_name);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue