@@ -4668,3 +4668,31 @@ void bdrv_ext_snapshot_img_create(BlockDriverState *old_bs,
options, img_size,
flags, errp);
}
+
+int bdrv_ext_snapshot_reopen(BlockDriverState *bs, int bdrv_flags,
+ Error **errp)
+{
+ Error *local_err = NULL;
+ int ret = -ENOTSUP;
+
+ if (!bs->file || !bs->file->drv) {
+ error_setg(errp, "Block driver not reachable.");
+ return ret;
+ }
+
+ if (!bs->file->drv->bdrv_ext_snapshot_reopen) {
+ error_set(errp, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
+ bdrv_get_format_name(bs->file),
+ bdrv_get_device_name(bs),
+ "external snapshots");
+ return ret;
+ }
+
+ ret = bs->file->drv->bdrv_ext_snapshot_reopen(bs, bdrv_flags, &local_err);
+
+ if (error_is_set(&local_err)) {
+ error_propagate(errp, local_err);
+ }
+
+ return ret;
+}
@@ -348,6 +348,7 @@ static BlockDriver bdrv_cow = {
.create_options = cow_create_options,
.bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
+ .bdrv_ext_snapshot_reopen = bdrv_reopen,
};
static void bdrv_cow_init(void)
@@ -892,6 +892,7 @@ static BlockDriver bdrv_qcow = {
.create_options = qcow_create_options,
.bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
+ .bdrv_ext_snapshot_reopen = bdrv_reopen,
};
static void bdrv_qcow_init(void)
@@ -1719,6 +1719,7 @@ static BlockDriver bdrv_qcow2 = {
.bdrv_check = qcow2_check,
.bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
+ .bdrv_ext_snapshot_reopen = bdrv_reopen,
};
static void bdrv_qcow2_init(void)
@@ -1587,6 +1587,7 @@ static BlockDriver bdrv_qed = {
.bdrv_check = bdrv_qed_check,
.bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
+ .bdrv_ext_snapshot_reopen = bdrv_reopen,
};
static void bdrv_qed_init(void)
@@ -2087,6 +2087,7 @@ BlockDriver bdrv_sheepdog = {
.create_options = sd_create_options,
.bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
+ .bdrv_ext_snapshot_reopen = bdrv_reopen,
};
static void bdrv_sheepdog_init(void)
@@ -1697,6 +1697,7 @@ static BlockDriver bdrv_vmdk = {
.create_options = vmdk_create_options,
.bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
+ .bdrv_ext_snapshot_reopen = bdrv_reopen,
};
static void bdrv_vmdk_init(void)
@@ -2876,6 +2876,7 @@ static BlockDriver bdrv_vvfat = {
.protocol_name = "fat",
.bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
+ .bdrv_ext_snapshot_reopen = bdrv_reopen,
};
static void bdrv_vvfat_init(void)
@@ -817,8 +817,9 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
/* We don't need (or want) to use the transactional
* bdrv_reopen_multiple() across all the entries at once, because we
* don't want to abort all of them if one of them fails the reopen */
- bdrv_reopen(states->new_bs, states->new_bs->open_flags & ~BDRV_O_RDWR,
- NULL);
+ bdrv_ext_snapshot_reopen(states->new_bs,
+ states->new_bs->open_flags & ~BDRV_O_RDWR,
+ NULL);
}
/* success */
@@ -141,6 +141,8 @@ BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue,
BlockDriverState *bs, int flags);
int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp);
int bdrv_reopen(BlockDriverState *bs, int bdrv_flags, Error **errp);
+int bdrv_ext_snapshot_reopen(BlockDriverState *bs, int bdrv_flags,
+ Error **errp);
int bdrv_reopen_prepare(BDRVReopenState *reopen_state,
BlockReopenQueue *queue, Error **errp);
void bdrv_reopen_commit(BDRVReopenState *reopen_state);
@@ -209,6 +209,10 @@ struct BlockDriver {
const char *base_fmt,
char *options, uint64_t img_size,
int flags, Error **errp);
+ /* for generic block driver implementing snapshot in a generic way this
+ field must point to bdrv_reopen */
+ int (*bdrv_ext_snapshot_reopen)(BlockDriverState *bs, int bdrv_flags,
+ Error **errp);
QLIST_ENTRY(BlockDriver) list;
};
Protocols like quorum will be able to queue multiple reopens. Signed-off-by: Benoit Canet <benoit@irqsave.net> --- block.c | 28 ++++++++++++++++++++++++++++ block/cow.c | 1 + block/qcow.c | 1 + block/qcow2.c | 1 + block/qed.c | 1 + block/sheepdog.c | 1 + block/vmdk.c | 1 + block/vvfat.c | 1 + blockdev.c | 5 +++-- include/block/block.h | 2 ++ include/block/block_int.h | 4 ++++ 11 files changed, 44 insertions(+), 2 deletions(-)