All of lore.kernel.org
 help / color / mirror / Atom feed
From: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
To: qemu-devel@nongnu.org
Cc: kwolf@redhat.com, peter.maydell@linaro.org, mst@redhat.com,
	jasowang@redhat.com, quintela@redhat.com, dovgaluk@ispras.ru,
	kraxel@redhat.com, pbonzini@redhat.com
Subject: [Qemu-devel] [PATCH v8 6/9] blkreplay: create temporary overlay for underlaying devices
Date: Thu, 26 Jan 2017 15:34:46 +0300	[thread overview]
Message-ID: <20170126123445.5412.77839.stgit@PASHA-ISP> (raw)
In-Reply-To: <20170126123411.5412.44769.stgit@PASHA-ISP>

This patch allows using '-snapshot' behavior in record/replay mode.
blkreplay layer creates temporary overlays on top of underlaying
disk images. It is needed, because creating an overlay over blkreplay
breaks the determinism.

Signed-off-by: Pavel Dovgalyuk <pavel.dovgaluk@ispras.ru>
---
 block/blkreplay.c |   76 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 stubs/replay.c    |    1 +
 vl.c              |    2 +
 3 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/block/blkreplay.c b/block/blkreplay.c
index 8a03d62..172642f 100644
--- a/block/blkreplay.c
+++ b/block/blkreplay.c
@@ -14,12 +14,76 @@
 #include "block/block_int.h"
 #include "sysemu/replay.h"
 #include "qapi/error.h"
+#include "qapi/qmp/qstring.h"
 
 typedef struct Request {
     Coroutine *co;
     QEMUBH *bh;
 } Request;
 
+static BlockDriverState *blkreplay_append_snapshot(BlockDriverState *bs,
+                                                   Error **errp)
+{
+    int ret;
+    BlockDriverState *bs_snapshot;
+    int64_t total_size;
+    QemuOpts *opts = NULL;
+    char tmp_filename[PATH_MAX + 1];
+    QDict *snapshot_options = qdict_new();
+
+    /* Prepare options QDict for the overlay file */
+    qdict_put(snapshot_options, "file.driver",
+              qstring_from_str("file"));
+    qdict_put(snapshot_options, "driver",
+              qstring_from_str("qcow2"));
+
+    /* Create temporary file */
+    ret = get_tmp_filename(tmp_filename, PATH_MAX + 1);
+    if (ret < 0) {
+        error_setg_errno(errp, -ret, "Could not get temporary filename");
+        goto out;
+    }
+    qdict_put(snapshot_options, "file.filename",
+              qstring_from_str(tmp_filename));
+
+    /* Get the required size from the image */
+    total_size = bdrv_getlength(bs);
+    if (total_size < 0) {
+        error_setg_errno(errp, -total_size, "Could not get image size");
+        goto out;
+    }
+
+    opts = qemu_opts_create(bdrv_qcow2.create_opts, NULL, 0, &error_abort);
+    qemu_opt_set_number(opts, BLOCK_OPT_SIZE, total_size, &error_abort);
+    ret = bdrv_create(&bdrv_qcow2, tmp_filename, opts, errp);
+    qemu_opts_del(opts);
+    if (ret < 0) {
+        error_prepend(errp, "Could not create temporary overlay '%s': ",
+                      tmp_filename);
+        goto out;
+    }
+
+    bs_snapshot = bdrv_open(NULL, NULL, snapshot_options,
+                            BDRV_O_RDWR | BDRV_O_TEMPORARY, errp);
+    snapshot_options = NULL;
+    if (!bs_snapshot) {
+        ret = -EINVAL;
+        goto out;
+    }
+
+    /* bdrv_append() consumes a strong reference to bs_snapshot (i.e. it will
+     * call bdrv_unref() on it), so in order to be able to return one, we have
+     * to increase bs_snapshot's refcount here */
+    bdrv_ref(bs_snapshot);
+    bdrv_append(bs_snapshot, bs);
+
+    return bs_snapshot;
+
+out:
+    QDECREF(snapshot_options);
+    return NULL;
+}
+
 static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
                           Error **errp)
 {
@@ -35,6 +99,14 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
         goto fail;
     }
 
+    /* Add temporary snapshot to preserve the image */
+    if (!replay_snapshot
+        && !blkreplay_append_snapshot(bs->file->bs, &local_err)) {
+        ret = -EINVAL;
+        error_propagate(errp, local_err);
+        goto fail;
+    }
+
     ret = 0;
 fail:
     if (ret < 0) {
@@ -45,6 +117,10 @@ fail:
 
 static void blkreplay_close(BlockDriverState *bs)
 {
+    if (!replay_snapshot) {
+        /* Unref created snapshot file */
+        bdrv_unref(bs->file->bs);
+    }
 }
 
 static int64_t blkreplay_getlength(BlockDriverState *bs)
diff --git a/stubs/replay.c b/stubs/replay.c
index d9a6da9..e43e467 100644
--- a/stubs/replay.c
+++ b/stubs/replay.c
@@ -3,6 +3,7 @@
 #include "sysemu/sysemu.h"
 
 ReplayMode replay_mode;
+char *replay_snapshot;
 
 int64_t replay_save_clock(unsigned int kind, int64_t clock)
 {
diff --git a/vl.c b/vl.c
index 52a6ac8..def0520 100644
--- a/vl.c
+++ b/vl.c
@@ -4474,7 +4474,7 @@ int main(int argc, char **argv, char **envp)
     }
 
     /* open the virtual block devices */
-    if (snapshot || replay_mode != REPLAY_MODE_NONE) {
+    if (snapshot) {
         qemu_opts_foreach(qemu_find_opts("drive"), drive_enable_snapshot,
                           NULL, NULL);
     }

  parent reply	other threads:[~2017-01-26 12:34 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-01-26 12:34 [Qemu-devel] [PATCH v8 0/9] replay additions Pavel Dovgalyuk
2017-01-26 12:34 ` [Qemu-devel] [PATCH v8 1/9] replay: exception replay fix Pavel Dovgalyuk
2017-01-26 12:34 ` [Qemu-devel] [PATCH v8 2/9] icount: exit cpu loop on expire Pavel Dovgalyuk
2017-01-26 13:02   ` Paolo Bonzini
2017-01-26 13:37     ` Pavel Dovgalyuk
2017-01-26 14:28       ` Paolo Bonzini
2017-01-26 14:32         ` Pavel Dovgalyuk
2017-01-26 14:44           ` Paolo Bonzini
2017-01-27  6:09             ` Pavel Dovgalyuk
2017-01-27 11:02               ` Paolo Bonzini
2017-01-26 12:34 ` [Qemu-devel] [PATCH v8 3/9] apic: save apic_delivered flag Pavel Dovgalyuk
2017-01-26 12:49   ` Paolo Bonzini
2017-01-26 13:03     ` Pavel Dovgalyuk
2017-01-26 13:06       ` Paolo Bonzini
2017-01-26 13:07         ` Pavel Dovgalyuk
2017-01-26 12:34 ` [Qemu-devel] [PATCH v8 4/9] integratorcp: adding vmstate for save/restore Pavel Dovgalyuk
2017-01-26 12:34 ` [Qemu-devel] [PATCH v8 5/9] block: implement bdrv_snapshot_goto for blkreplay Pavel Dovgalyuk
2017-01-26 12:34 ` Pavel Dovgalyuk [this message]
2017-01-26 12:34 ` [Qemu-devel] [PATCH v8 7/9] replay: disable default snapshot for record/replay Pavel Dovgalyuk
2017-01-26 12:34 ` [Qemu-devel] [PATCH v8 8/9] audio: make audio poll timer deterministic Pavel Dovgalyuk
2017-01-26 12:35 ` [Qemu-devel] [PATCH v8 9/9] replay: add record/replay for audio passthrough Pavel Dovgalyuk
2017-01-26 13:05 ` [Qemu-devel] [PATCH v8 0/9] replay additions Paolo Bonzini

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170126123445.5412.77839.stgit@PASHA-ISP \
    --to=pavel.dovgaluk@ispras.ru \
    --cc=dovgaluk@ispras.ru \
    --cc=jasowang@redhat.com \
    --cc=kraxel@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=mst@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peter.maydell@linaro.org \
    --cc=qemu-devel@nongnu.org \
    --cc=quintela@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.