@@ -4626,3 +4626,45 @@ out:
bdrv_delete(bs);
}
}
+
+void bdrv_generic_ext_snapshot_img_create(BlockDriverState *bs,
+ const char *filename,
+ const char *fmt,
+ const char *base_filename,
+ const char *base_fmt,
+ char *options,
+ uint64_t img_size,
+ int flags,
+ Error **errp)
+{
+ bdrv_img_create(filename, fmt, base_filename, base_fmt, options, img_size,
+ flags, errp);
+}
+
+void bdrv_ext_snapshot_img_create(BlockDriverState *old_bs,
+ const char *filename, const char *fmt,
+ const char *base_filename,
+ const char *base_fmt,
+ char *options, uint64_t img_size,
+ int flags, Error **errp)
+{
+ if (!old_bs || !old_bs->file || !old_bs->file->drv) {
+ error_setg(errp, "Block driver not reachable.");
+ return;
+ }
+
+ if (!old_bs->file->drv->bdrv_ext_snapshot_img_create) {
+ error_set(errp, QERR_BLOCK_FORMAT_FEATURE_NOT_SUPPORTED,
+ bdrv_get_format_name(old_bs->file),
+ bdrv_get_device_name(old_bs),
+ "external snapshots");
+ return;
+ }
+
+ old_bs->file->drv->bdrv_ext_snapshot_img_create(old_bs->file,
+ filename, fmt,
+ base_filename,
+ base_fmt,
+ options, img_size,
+ flags, errp);
+}
@@ -584,6 +584,8 @@ static BlockDriver bdrv_blkdebug = {
.bdrv_debug_breakpoint = blkdebug_debug_breakpoint,
.bdrv_debug_resume = blkdebug_debug_resume,
.bdrv_debug_is_suspended = blkdebug_debug_is_suspended,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_blkdebug_init(void)
@@ -356,6 +356,8 @@ static BlockDriver bdrv_blkverify = {
.bdrv_aio_readv = blkverify_aio_readv,
.bdrv_aio_writev = blkverify_aio_writev,
.bdrv_aio_flush = blkverify_aio_flush,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_blkverify_init(void)
@@ -233,6 +233,8 @@ static BlockDriver bdrv_bochs = {
.bdrv_open = bochs_open,
.bdrv_read = bochs_co_read,
.bdrv_close = bochs_close,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_bochs_init(void)
@@ -185,6 +185,8 @@ static BlockDriver bdrv_cloop = {
.bdrv_open = cloop_open,
.bdrv_read = cloop_co_read,
.bdrv_close = cloop_close,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_cloop_init(void)
@@ -346,6 +346,8 @@ static BlockDriver bdrv_cow = {
.bdrv_co_is_allocated = cow_co_is_allocated,
.create_options = cow_create_options,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_cow_init(void)
@@ -561,6 +561,8 @@ static BlockDriver bdrv_http = {
.bdrv_getlength = curl_getlength,
.bdrv_aio_readv = curl_aio_readv,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static BlockDriver bdrv_https = {
@@ -573,6 +575,8 @@ static BlockDriver bdrv_https = {
.bdrv_getlength = curl_getlength,
.bdrv_aio_readv = curl_aio_readv,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static BlockDriver bdrv_ftp = {
@@ -585,6 +589,8 @@ static BlockDriver bdrv_ftp = {
.bdrv_getlength = curl_getlength,
.bdrv_aio_readv = curl_aio_readv,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static BlockDriver bdrv_ftps = {
@@ -597,6 +603,8 @@ static BlockDriver bdrv_ftps = {
.bdrv_getlength = curl_getlength,
.bdrv_aio_readv = curl_aio_readv,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static BlockDriver bdrv_tftp = {
@@ -609,6 +617,8 @@ static BlockDriver bdrv_tftp = {
.bdrv_getlength = curl_getlength,
.bdrv_aio_readv = curl_aio_readv,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void curl_block_init(void)
@@ -315,6 +315,8 @@ static BlockDriver bdrv_dmg = {
.bdrv_open = dmg_open,
.bdrv_read = dmg_co_read,
.bdrv_close = dmg_close,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_dmg_init(void)
@@ -566,6 +566,8 @@ static BlockDriver bdrv_gluster = {
.bdrv_aio_writev = qemu_gluster_aio_writev,
.bdrv_aio_flush = qemu_gluster_aio_flush,
.create_options = qemu_gluster_create_options,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static BlockDriver bdrv_gluster_tcp = {
@@ -581,6 +583,8 @@ static BlockDriver bdrv_gluster_tcp = {
.bdrv_aio_writev = qemu_gluster_aio_writev,
.bdrv_aio_flush = qemu_gluster_aio_flush,
.create_options = qemu_gluster_create_options,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static BlockDriver bdrv_gluster_unix = {
@@ -596,6 +600,8 @@ static BlockDriver bdrv_gluster_unix = {
.bdrv_aio_writev = qemu_gluster_aio_writev,
.bdrv_aio_flush = qemu_gluster_aio_flush,
.create_options = qemu_gluster_create_options,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static BlockDriver bdrv_gluster_rdma = {
@@ -611,6 +617,8 @@ static BlockDriver bdrv_gluster_rdma = {
.bdrv_aio_writev = qemu_gluster_aio_writev,
.bdrv_aio_flush = qemu_gluster_aio_flush,
.create_options = qemu_gluster_create_options,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_gluster_init(void)
@@ -978,6 +978,8 @@ static BlockDriver bdrv_iscsi = {
.bdrv_ioctl = iscsi_ioctl,
.bdrv_aio_ioctl = iscsi_aio_ioctl,
#endif
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static QemuOptsList qemu_iscsi_opts = {
@@ -572,6 +572,8 @@ static BlockDriver bdrv_nbd = {
.bdrv_co_flush_to_os = nbd_co_flush,
.bdrv_co_discard = nbd_co_discard,
.bdrv_getlength = nbd_getlength,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static BlockDriver bdrv_nbd_tcp = {
@@ -585,6 +587,8 @@ static BlockDriver bdrv_nbd_tcp = {
.bdrv_co_flush_to_os = nbd_co_flush,
.bdrv_co_discard = nbd_co_discard,
.bdrv_getlength = nbd_getlength,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static BlockDriver bdrv_nbd_unix = {
@@ -598,6 +602,8 @@ static BlockDriver bdrv_nbd_unix = {
.bdrv_co_flush_to_os = nbd_co_flush,
.bdrv_co_discard = nbd_co_discard,
.bdrv_getlength = nbd_getlength,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_nbd_init(void)
@@ -160,6 +160,8 @@ static BlockDriver bdrv_parallels = {
.bdrv_open = parallels_open,
.bdrv_read = parallels_co_read,
.bdrv_close = parallels_close,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_parallels_init(void)
@@ -890,6 +890,8 @@ static BlockDriver bdrv_qcow = {
.bdrv_get_info = qcow_get_info,
.create_options = qcow_create_options,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_qcow_init(void)
@@ -1717,6 +1717,8 @@ static BlockDriver bdrv_qcow2 = {
.create_options = qcow2_create_options,
.bdrv_check = qcow2_check,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_qcow2_init(void)
@@ -1585,6 +1585,8 @@ static BlockDriver bdrv_qed = {
.bdrv_change_backing_file = bdrv_qed_change_backing_file,
.bdrv_invalidate_cache = bdrv_qed_invalidate_cache,
.bdrv_check = bdrv_qed_check,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_qed_init(void)
@@ -1169,6 +1169,8 @@ static BlockDriver bdrv_file = {
= raw_get_allocated_file_size,
.create_options = raw_create_options,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
/***********************************************/
@@ -1467,6 +1469,8 @@ static BlockDriver bdrv_host_device = {
.bdrv_ioctl = hdev_ioctl,
.bdrv_aio_ioctl = hdev_aio_ioctl,
#endif
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
#ifdef __linux__
@@ -1590,6 +1594,8 @@ static BlockDriver bdrv_host_floppy = {
.bdrv_is_inserted = floppy_is_inserted,
.bdrv_media_changed = floppy_media_changed,
.bdrv_eject = floppy_eject,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
@@ -1696,6 +1702,8 @@ static BlockDriver bdrv_host_cdrom = {
/* generic scsi device */
.bdrv_ioctl = hdev_ioctl,
.bdrv_aio_ioctl = hdev_aio_ioctl,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
#endif /* __linux__ */
@@ -1814,6 +1822,8 @@ static BlockDriver bdrv_host_cdrom = {
.bdrv_is_inserted = cdrom_is_inserted,
.bdrv_eject = cdrom_eject,
.bdrv_lock_medium = cdrom_lock_medium,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
#endif /* __FreeBSD__ */
@@ -432,6 +432,8 @@ static BlockDriver bdrv_file = {
= raw_get_allocated_file_size,
.create_options = raw_create_options,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
/***********************************************/
@@ -552,6 +554,10 @@ static BlockDriver bdrv_host_device = {
.bdrv_getlength = raw_getlength,
.bdrv_get_allocated_file_size
= raw_get_allocated_file_size,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_file_init(void)
@@ -145,6 +145,8 @@ static BlockDriver bdrv_raw = {
.bdrv_create = raw_create,
.create_options = raw_create_options,
.bdrv_has_zero_init = raw_has_zero_init,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_raw_init(void)
@@ -958,6 +958,8 @@ static BlockDriver bdrv_rbd = {
.bdrv_snapshot_delete = qemu_rbd_snap_remove,
.bdrv_snapshot_list = qemu_rbd_snap_list,
.bdrv_snapshot_goto = qemu_rbd_snap_rollback,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_rbd_init(void)
@@ -2085,6 +2085,8 @@ BlockDriver bdrv_sheepdog = {
.bdrv_load_vmstate = sd_load_vmstate,
.create_options = sd_create_options,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_sheepdog_init(void)
@@ -778,6 +778,8 @@ static BlockDriver bdrv_vdi = {
.create_options = vdi_create_options,
.bdrv_check = vdi_check,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_vdi_init(void)
@@ -1695,6 +1695,8 @@ static BlockDriver bdrv_vmdk = {
.bdrv_get_allocated_file_size = vmdk_get_allocated_file_size,
.create_options = vmdk_create_options,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_vmdk_init(void)
@@ -810,6 +810,8 @@ static BlockDriver bdrv_vpc = {
.bdrv_write = vpc_co_write,
.create_options = vpc_create_options,
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_vpc_init(void)
@@ -2874,6 +2874,8 @@ static BlockDriver bdrv_vvfat = {
.bdrv_close = vvfat_close,
.bdrv_co_is_allocated = vvfat_co_is_allocated,
.protocol_name = "fat",
+
+ .bdrv_ext_snapshot_img_create = bdrv_generic_ext_snapshot_img_create,
};
static void bdrv_vvfat_init(void)
@@ -787,10 +787,10 @@ void qmp_transaction(BlockdevActionList *dev_list, Error **errp)
/* create new image w/backing file */
if (mode != NEW_IMAGE_MODE_EXISTING) {
- bdrv_img_create(new_image_file, format,
- states->old_bs->filename,
- states->old_bs->drv->format_name,
- NULL, -1, flags, &local_err);
+ bdrv_ext_snapshot_img_create(states->old_bs, new_image_file, format,
+ states->old_bs->filename,
+ states->old_bs->drv->format_name,
+ NULL, -1, flags, &local_err);
if (error_is_set(&local_err)) {
error_propagate(errp, local_err);
goto delete_and_fail;
@@ -346,6 +346,21 @@ int bdrv_load_vmstate(BlockDriverState *bs, uint8_t *buf,
void bdrv_img_create(const char *filename, const char *fmt,
const char *base_filename, const char *base_fmt,
char *options, uint64_t img_size, int flags, Error **errp);
+void bdrv_generic_ext_snapshot_img_create(BlockDriverState *bs,
+ const char *filename,
+ const char *fmt,
+ const char *base_filename,
+ const char *base_fmt,
+ char *options,
+ uint64_t img_size,
+ int flags,
+ Error **errp);
+void bdrv_ext_snapshot_img_create(BlockDriverState *old_bs,
+ const char *filename, const char *fmt,
+ const char *base_filename,
+ const char *base_fmt,
+ char *options, uint64_t img_size,
+ int flags, Error **errp);
void bdrv_set_buffer_alignment(BlockDriverState *bs, int align);
void *qemu_blockalign(BlockDriverState *bs, size_t size);
@@ -202,6 +202,14 @@ struct BlockDriver {
*/
int (*bdrv_has_zero_init)(BlockDriverState *bs);
+ /* for generic block drivers this field must point to bdrv_img_create */
+ void (*bdrv_ext_snapshot_img_create)(BlockDriverState *bs,
+ const char *filename, const char *fmt,
+ const char *base_filename,
+ const char *base_fmt,
+ char *options, uint64_t img_size,
+ int flags, Error **errp);
+
QLIST_ENTRY(BlockDriver) list;
};
This patch will allow protocols to implements snapshots as the image creation is now delegated to the block driver. Signed-off-by: Benoit Canet <benoit@irqsave.net> --- block.c | 42 ++++++++++++++++++++++++++++++++++++++++++ block/blkdebug.c | 2 ++ block/blkverify.c | 2 ++ block/bochs.c | 2 ++ block/cloop.c | 2 ++ block/cow.c | 2 ++ block/curl.c | 10 ++++++++++ block/dmg.c | 2 ++ block/gluster.c | 8 ++++++++ block/iscsi.c | 2 ++ block/nbd.c | 6 ++++++ block/parallels.c | 2 ++ block/qcow.c | 2 ++ block/qcow2.c | 2 ++ block/qed.c | 2 ++ block/raw-posix.c | 10 ++++++++++ block/raw-win32.c | 6 ++++++ block/raw.c | 2 ++ block/rbd.c | 2 ++ block/sheepdog.c | 2 ++ block/vdi.c | 2 ++ block/vmdk.c | 2 ++ block/vpc.c | 2 ++ block/vvfat.c | 2 ++ blockdev.c | 8 ++++---- include/block/block.h | 15 +++++++++++++++ include/block/block_int.h | 8 ++++++++ 27 files changed, 145 insertions(+), 4 deletions(-)