This patch adds parameter with suffix for overlay filenames. This parameter will be used by replay to automatically create overlay files based on drive images supplied to VM.
Signed-off-by: Pavel Dovgalyuk <pavel.dovga...@ispras.ru> --- block.c | 49 +++++++++++++++++++++++++++++++++++-------------- block/blkdebug.c | 2 +- block/blkverify.c | 5 +++-- block/cow.c | 2 +- block/qcow.c | 2 +- block/qcow2.c | 6 +++--- block/qed.c | 2 +- block/sheepdog.c | 4 ++-- block/vmdk.c | 8 ++++---- block/vvfat.c | 2 +- blockdev.c | 14 +++++++++----- include/block/block.h | 7 ++++--- qemu-img.c | 6 +++--- qemu-io.c | 7 +++---- qemu-nbd.c | 2 +- 15 files changed, 72 insertions(+), 46 deletions(-) diff --git a/block.c b/block.c index 8cf519b..a7633fe 100644 --- a/block.c +++ b/block.c @@ -35,6 +35,7 @@ #include "qmp-commands.h" #include "qemu/timer.h" #include "qapi-event.h" +#include "replay/replay.h" #ifdef CONFIG_BSD #include <sys/types.h> @@ -1222,7 +1223,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp) assert(bs->backing_hd == NULL); ret = bdrv_open(&backing_hd, *backing_filename ? backing_filename : NULL, NULL, options, - bdrv_backing_flags(bs->open_flags), back_drv, &local_err); + bdrv_backing_flags(bs->open_flags), back_drv, + &local_err, NULL); if (ret < 0) { bdrv_unref(backing_hd); backing_hd = NULL; @@ -1257,7 +1259,7 @@ free_exit: */ int bdrv_open_image(BlockDriverState **pbs, const char *filename, QDict *options, const char *bdref_key, int flags, - bool allow_none, Error **errp) + bool allow_none, Error **errp, const char *fname_suffix) { QDict *image_options; int ret; @@ -1284,14 +1286,16 @@ int bdrv_open_image(BlockDriverState **pbs, const char *filename, goto done; } - ret = bdrv_open(pbs, filename, reference, image_options, flags, NULL, errp); + ret = bdrv_open(pbs, filename, reference, image_options, flags, + NULL, errp, NULL); done: qdict_del(options, bdref_key); return ret; } -int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp) +int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp, + const char *fname_suffix) { /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ char *tmp_filename = g_malloc0(PATH_MAX + 1); @@ -1316,17 +1320,30 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp) total_size &= BDRV_SECTOR_MASK; /* Create the temporary image */ - ret = get_tmp_filename(tmp_filename, PATH_MAX + 1); - if (ret < 0) { - error_setg_errno(errp, -ret, "Could not get temporary filename"); - goto out; + /* We will not delete created file in record/replay mode */ + if (replay_mode != REPLAY_MODE_NONE && fname_suffix) { + ret = snprintf(tmp_filename, PATH_MAX + 1, "%s.%s", bs->filename, + fname_suffix); + if (ret < 0) { + goto out; + } + } else { + ret = get_tmp_filename(tmp_filename, PATH_MAX + 1); + if (ret < 0) { + error_setg_errno(errp, -ret, "Could not get temporary filename"); + goto out; + } } bdrv_qcow2 = bdrv_find_format("qcow2"); opts = qemu_opts_create(bdrv_qcow2->create_opts, NULL, 0, &error_abort); qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size); - ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err); + if (replay_mode == REPLAY_MODE_PLAY) { + ret = 0; + } else { + ret = bdrv_create(bdrv_qcow2, tmp_filename, opts, &local_err); + } qemu_opts_del(opts); if (ret < 0) { error_setg_errno(errp, -ret, "Could not create temporary overlay " @@ -1346,7 +1363,7 @@ int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp) bs_snapshot = bdrv_new("", &error_abort); ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options, - flags, bdrv_qcow2, &local_err); + flags, bdrv_qcow2, &local_err, NULL); if (ret < 0) { error_propagate(errp, local_err); goto out; @@ -1376,7 +1393,7 @@ out: */ int bdrv_open(BlockDriverState **pbs, const char *filename, const char *reference, QDict *options, int flags, - BlockDriver *drv, Error **errp) + BlockDriver *drv, Error **errp, const char *fname_suffix) { int ret; BlockDriverState *file = NULL, *bs; @@ -1457,13 +1474,16 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, } if (flags & BDRV_O_SNAPSHOT) { snapshot_flags = bdrv_temp_snapshot_flags(flags); + if (replay_mode != REPLAY_MODE_NONE) { + snapshot_flags &= ~BDRV_O_TEMPORARY; + } flags = bdrv_backing_flags(flags); } assert(file == NULL); ret = bdrv_open_image(&file, filename, options, "file", bdrv_inherited_flags(flags), - true, &local_err); + true, &local_err, NULL); if (ret < 0) { goto fail; } @@ -1506,7 +1526,8 @@ int bdrv_open(BlockDriverState **pbs, const char *filename, /* For snapshot=on, create a temporary qcow2 overlay. bs points to the * temporary snapshot afterwards. */ if (snapshot_flags) { - ret = bdrv_append_temp_snapshot(bs, snapshot_flags, &local_err); + ret = bdrv_append_temp_snapshot(bs, snapshot_flags, &local_err, + fname_suffix); if (local_err) { goto close_and_fail; } @@ -5600,7 +5621,7 @@ void bdrv_img_create(const char *filename, const char *fmt, bs = NULL; ret = bdrv_open(&bs, backing_file, NULL, NULL, back_flags, - backing_drv, &local_err); + backing_drv, &local_err, NULL); if (ret < 0) { error_setg_errno(errp, -ret, "Could not open '%s': %s", backing_file, diff --git a/block/blkdebug.c b/block/blkdebug.c index f51407d..151538a 100644 --- a/block/blkdebug.c +++ b/block/blkdebug.c @@ -412,7 +412,7 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags, /* Open the backing file */ assert(bs->file == NULL); ret = bdrv_open_image(&bs->file, qemu_opt_get(opts, "x-image"), options, "image", - flags | BDRV_O_PROTOCOL, false, &local_err); + flags | BDRV_O_PROTOCOL, false, &local_err, NULL); if (ret < 0) { error_propagate(errp, local_err); goto out; diff --git a/block/blkverify.c b/block/blkverify.c index 621b785..6530835 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -138,7 +138,8 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags, /* Open the raw file */ assert(bs->file == NULL); ret = bdrv_open_image(&bs->file, qemu_opt_get(opts, "x-raw"), options, - "raw", flags | BDRV_O_PROTOCOL, false, &local_err); + "raw", flags | BDRV_O_PROTOCOL, false, &local_err, + NULL); if (ret < 0) { error_propagate(errp, local_err); goto fail; @@ -147,7 +148,7 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags, /* Open the test file */ assert(s->test_file == NULL); ret = bdrv_open_image(&s->test_file, qemu_opt_get(opts, "x-image"), options, - "test", flags, false, &local_err); + "test", flags, false, &local_err, NULL); if (ret < 0) { error_propagate(errp, local_err); s->test_file = NULL; diff --git a/block/cow.c b/block/cow.c index 6ee4833..d99c4d7 100644 --- a/block/cow.c +++ b/block/cow.c @@ -345,7 +345,7 @@ static int cow_create(const char *filename, QemuOpts *opts, Error **errp) } ret = bdrv_open(&cow_bs, filename, NULL, NULL, - BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err); + BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err, NULL); if (ret < 0) { error_propagate(errp, local_err); goto exit; diff --git a/block/qcow.c b/block/qcow.c index a874056..6e21cea 100644 --- a/block/qcow.c +++ b/block/qcow.c @@ -720,7 +720,7 @@ static int qcow_create(const char *filename, QemuOpts *opts, Error **errp) qcow_bs = NULL; ret = bdrv_open(&qcow_bs, filename, NULL, NULL, - BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err); + BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err, NULL); if (ret < 0) { error_propagate(errp, local_err); goto cleanup; diff --git a/block/qcow2.c b/block/qcow2.c index 1e3ab6b..43ceb34 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -1653,7 +1653,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, bs = NULL; ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, - NULL, &local_err); + NULL, &local_err, NULL); if (ret < 0) { error_propagate(errp, local_err); return ret; @@ -1715,7 +1715,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, BlockDriver* drv = bdrv_find_format("qcow2"); assert(drv != NULL); ret = bdrv_open(&bs, filename, NULL, NULL, - BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv, &local_err); + BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, drv, &local_err, NULL); if (ret < 0) { error_propagate(errp, local_err); goto out; @@ -1767,7 +1767,7 @@ static int qcow2_create2(const char *filename, int64_t total_size, /* Reopen the image without BDRV_O_NO_FLUSH to flush it before returning */ ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_BACKING, - drv, &local_err); + drv, &local_err, NULL); if (local_err) { error_propagate(errp, local_err); goto out; diff --git a/block/qed.c b/block/qed.c index 7944832..e41c422 100644 --- a/block/qed.c +++ b/block/qed.c @@ -593,7 +593,7 @@ static int qed_create(const char *filename, uint32_t cluster_size, bs = NULL; ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_PROTOCOL, NULL, - &local_err); + &local_err, NULL); if (ret < 0) { error_propagate(errp, local_err); return ret; diff --git a/block/sheepdog.c b/block/sheepdog.c index 8d9350c..bb3dfef 100644 --- a/block/sheepdog.c +++ b/block/sheepdog.c @@ -1576,7 +1576,7 @@ static int sd_prealloc(const char *filename, Error **errp) int ret; ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, - NULL, errp); + NULL, errp, NULL); if (ret < 0) { goto out_with_err_set; } @@ -1739,7 +1739,7 @@ static int sd_create(const char *filename, QemuOpts *opts, bs = NULL; ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_PROTOCOL, NULL, - errp); + errp, NULL); if (ret < 0) { goto out; } diff --git a/block/vmdk.c b/block/vmdk.c index 0517bba..09587cb 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -809,7 +809,7 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs, desc_file_path, fname); extent_file = NULL; ret = bdrv_open(&extent_file, extent_path, NULL, NULL, - bs->open_flags | BDRV_O_PROTOCOL, NULL, errp); + bs->open_flags | BDRV_O_PROTOCOL, NULL, errp, NULL); if (ret) { return ret; } @@ -1545,7 +1545,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize, assert(bs == NULL); ret = bdrv_open(&bs, filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_PROTOCOL, - NULL, &local_err); + NULL, &local_err, NULL); if (ret < 0) { error_propagate(errp, local_err); goto exit; @@ -1803,7 +1803,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp) if (backing_file) { BlockDriverState *bs = NULL; ret = bdrv_open(&bs, backing_file, NULL, NULL, BDRV_O_NO_BACKING, NULL, - errp); + errp, NULL); if (ret != 0) { goto exit; } @@ -1879,7 +1879,7 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp) } assert(new_bs == NULL); ret = bdrv_open(&new_bs, filename, NULL, NULL, - BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err); + BDRV_O_RDWR | BDRV_O_PROTOCOL, NULL, &local_err, NULL); if (ret < 0) { error_propagate(errp, local_err); goto exit; diff --git a/block/vvfat.c b/block/vvfat.c index 70176b1..f86f890 100644 --- a/block/vvfat.c +++ b/block/vvfat.c @@ -2939,7 +2939,7 @@ static int enable_write_target(BDRVVVFATState *s, Error **errp) s->qcow = NULL; ret = bdrv_open(&s->qcow, s->qcow_filename, NULL, NULL, BDRV_O_RDWR | BDRV_O_CACHE_WB | BDRV_O_NO_FLUSH, - bdrv_qcow, errp); + bdrv_qcow, errp, NULL); if (ret < 0) { goto err; } diff --git a/blockdev.c b/blockdev.c index 48bd9a3..8173401 100644 --- a/blockdev.c +++ b/blockdev.c @@ -44,6 +44,7 @@ #include "qmp-commands.h" #include "trace.h" #include "sysemu/arch_init.h" +#include "replay/replay.h" static QTAILQ_HEAD(drivelist, DriveInfo) drives = QTAILQ_HEAD_INITIALIZER(drives); @@ -520,7 +521,8 @@ static DriveInfo *blockdev_init(const char *file, QDict *bs_opts, bdrv_flags |= ro ? 0 : BDRV_O_RDWR; QINCREF(bs_opts); - ret = bdrv_open(&dinfo->bdrv, file, NULL, bs_opts, bdrv_flags, drv, &error); + ret = bdrv_open(&dinfo->bdrv, file, NULL, bs_opts, bdrv_flags, drv, + &error, replay_image_suffix); if (ret < 0) { error_setg(errp, "could not open disk image %s: %s", @@ -1367,7 +1369,7 @@ static void external_snapshot_prepare(BlkTransactionState *common, * extended QMP command? */ assert(state->new_bs == NULL); ret = bdrv_open(&state->new_bs, new_image_file, NULL, options, - flags | BDRV_O_NO_BACKING, drv, &local_err); + flags | BDRV_O_NO_BACKING, drv, &local_err, NULL); /* We will manually add the backing_hd field to the bs later */ if (ret != 0) { error_propagate(errp, local_err); @@ -1616,7 +1618,8 @@ static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename, Error *local_err = NULL; int ret; - ret = bdrv_open(&bs, filename, NULL, NULL, bdrv_flags, drv, &local_err); + ret = bdrv_open(&bs, filename, NULL, NULL, bdrv_flags, drv, &local_err, + NULL); if (ret < 0) { error_propagate(errp, local_err); return; @@ -2108,7 +2111,8 @@ void qmp_drive_backup(const char *device, const char *target, } target_bs = NULL; - ret = bdrv_open(&target_bs, target, NULL, NULL, flags, drv, &local_err); + ret = bdrv_open(&target_bs, target, NULL, NULL, flags, drv, &local_err, + NULL); if (ret < 0) { error_propagate(errp, local_err); return; @@ -2282,7 +2286,7 @@ void qmp_drive_mirror(const char *device, const char *target, */ target_bs = NULL; ret = bdrv_open(&target_bs, target, NULL, options, - flags | BDRV_O_NO_BACKING, drv, &local_err); + flags | BDRV_O_NO_BACKING, drv, &local_err, NULL); if (ret < 0) { error_propagate(errp, local_err); return; diff --git a/include/block/block.h b/include/block/block.h index f08471d..95e6d1c 100644 --- a/include/block/block.h +++ b/include/block/block.h @@ -211,13 +211,14 @@ int bdrv_parse_cache_flags(const char *mode, int *flags); int bdrv_parse_discard_flags(const char *mode, int *flags); int bdrv_open_image(BlockDriverState **pbs, const char *filename, QDict *options, const char *bdref_key, int flags, - bool allow_none, Error **errp); + bool allow_none, Error **errp, const char *fname_suffix); void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd); int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp); -int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp); +int bdrv_append_temp_snapshot(BlockDriverState *bs, int flags, Error **errp, + const char *fname_suffix); int bdrv_open(BlockDriverState **pbs, const char *filename, const char *reference, QDict *options, int flags, - BlockDriver *drv, Error **errp); + BlockDriver *drv, Error **errp, const char *fname_suffix); BlockReopenQueue *bdrv_reopen_queue(BlockReopenQueue *bs_queue, BlockDriverState *bs, int flags); int bdrv_reopen_multiple(BlockReopenQueue *bs_queue, Error **errp); diff --git a/qemu-img.c b/qemu-img.c index d4518e7..30fd609 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -320,7 +320,7 @@ static BlockDriverState *bdrv_new_open(const char *id, drv = NULL; } - ret = bdrv_open(&bs, filename, NULL, NULL, flags, drv, &local_err); + ret = bdrv_open(&bs, filename, NULL, NULL, flags, drv, &local_err, NULL); if (ret < 0) { error_report("Could not open '%s': %s", filename, error_get_pretty(local_err)); @@ -2383,7 +2383,7 @@ static int img_rebase(int argc, char **argv) bs_old_backing = bdrv_new("old_backing", &error_abort); bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name)); ret = bdrv_open(&bs_old_backing, backing_name, NULL, NULL, BDRV_O_FLAGS, - old_backing_drv, &local_err); + old_backing_drv, &local_err, NULL); if (ret) { error_report("Could not open old backing file '%s': %s", backing_name, error_get_pretty(local_err)); @@ -2393,7 +2393,7 @@ static int img_rebase(int argc, char **argv) if (out_baseimg[0]) { bs_new_backing = bdrv_new("new_backing", &error_abort); ret = bdrv_open(&bs_new_backing, out_baseimg, NULL, NULL, - BDRV_O_FLAGS, new_backing_drv, &local_err); + BDRV_O_FLAGS, new_backing_drv, &local_err, NULL); if (ret) { error_report("Could not open new backing file '%s': %s", out_baseimg, error_get_pretty(local_err)); diff --git a/qemu-io.c b/qemu-io.c index b55a550..2c5029e 100644 --- a/qemu-io.c +++ b/qemu-io.c @@ -60,7 +60,7 @@ static int openfile(char *name, int flags, int growable, QDict *opts) if (growable) { if (bdrv_open(&qemuio_bs, name, NULL, opts, flags | BDRV_O_PROTOCOL, - NULL, &local_err)) + NULL, &local_err, NULL)) { fprintf(stderr, "%s: can't open%s%s: %s\n", progname, name ? " device " : "", name ?: "", @@ -71,9 +71,8 @@ static int openfile(char *name, int flags, int growable, QDict *opts) } else { qemuio_bs = bdrv_new("hda", &error_abort); - if (bdrv_open(&qemuio_bs, name, NULL, opts, flags, NULL, &local_err) - < 0) - { + if (bdrv_open(&qemuio_bs, name, NULL, opts, flags, NULL, + &local_err, NULL) < 0) { fprintf(stderr, "%s: can't open%s%s: %s\n", progname, name ? " device " : "", name ?: "", error_get_pretty(local_err)); diff --git a/qemu-nbd.c b/qemu-nbd.c index 626e584..e780d1c 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -663,7 +663,7 @@ int main(int argc, char **argv) bs = bdrv_new("hda", &error_abort); srcpath = argv[optind]; - ret = bdrv_open(&bs, srcpath, NULL, NULL, flags, drv, &local_err); + ret = bdrv_open(&bs, srcpath, NULL, NULL, flags, drv, &local_err, NULL); if (ret < 0) { errno = -ret; err(EXIT_FAILURE, "Failed to bdrv_open '%s': %s", argv[optind],