qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Andrey Gruzdev <andrey.gruzdev@virtuozzo.com>
To: qemu-devel@nongnu.org
Cc: Den Lunev <den@openvz.org>, Eric Blake <eblake@redhat.com>,
	Paolo Bonzini <pbonzini@redhat.com>,
	Juan Quintela <quintela@redhat.com>,
	"Dr . David Alan Gilbert" <dgilbert@redhat.com>,
	Markus Armbruster <armbru@redhat.com>,
	Peter Xu <peterx@redhat.com>,
	Andrey Gruzdev <andrey.gruzdev@virtuozzo.com>
Subject: [RFC PATCH 3/9] migration/snap-tool: Preparations to run code in main loop context
Date: Wed, 17 Mar 2021 19:32:16 +0300	[thread overview]
Message-ID: <20210317163222.182609-4-andrey.gruzdev@virtuozzo.com> (raw)
In-Reply-To: <20210317163222.182609-1-andrey.gruzdev@virtuozzo.com>

Major part of code is using QEMUFile and block layer routines, thus to
take advantage from concurrent I/O operations we need to use coroutines
and run in the the main loop context.

Signed-off-by: Andrey Gruzdev <andrey.gruzdev@virtuozzo.com>
---
 include/qemu-snap.h  |  3 +++
 meson.build          |  2 +-
 qemu-snap-handlers.c | 38 ++++++++++++++++++++++++++
 qemu-snap.c          | 63 ++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 105 insertions(+), 1 deletion(-)
 create mode 100644 qemu-snap-handlers.c

diff --git a/include/qemu-snap.h b/include/qemu-snap.h
index b8e48bfcbb..b6fd779b13 100644
--- a/include/qemu-snap.h
+++ b/include/qemu-snap.h
@@ -32,4 +32,7 @@ typedef struct SnapLoadState {
 SnapSaveState *snap_save_get_state(void);
 SnapLoadState *snap_load_get_state(void);
 
+int coroutine_fn snap_save_state_main(SnapSaveState *sn);
+int coroutine_fn snap_load_state_main(SnapLoadState *sn);
+
 #endif /* QEMU_SNAP_H */
diff --git a/meson.build b/meson.build
index 11564165ba..252c55d6a3 100644
--- a/meson.build
+++ b/meson.build
@@ -2324,7 +2324,7 @@ if have_tools
              dependencies: [block, qemuutil], install: true)
   qemu_nbd = executable('qemu-nbd', files('qemu-nbd.c'),
                dependencies: [blockdev, qemuutil, gnutls], install: true)
-  qemu_snap = executable('qemu-snap', files('qemu-snap.c'),
+  qemu_snap = executable('qemu-snap', files('qemu-snap.c', 'qemu-snap-handlers.c'),
                dependencies: [blockdev, qemuutil, migration], install: true)
 
   subdir('storage-daemon')
diff --git a/qemu-snap-handlers.c b/qemu-snap-handlers.c
new file mode 100644
index 0000000000..bdc1911909
--- /dev/null
+++ b/qemu-snap-handlers.c
@@ -0,0 +1,38 @@
+/*
+ * QEMU External Snapshot Utility
+ *
+ * Copyright Virtuozzo GmbH, 2021
+ *
+ * Authors:
+ *  Andrey Gruzdev   <andrey.gruzdev@virtuozzo.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later. See the COPYING file in the top-level directory.
+ */
+
+#include "qemu/osdep.h"
+#include "sysemu/block-backend.h"
+#include "qemu/coroutine.h"
+#include "qemu/cutils.h"
+#include "qemu/bitmap.h"
+#include "qemu/error-report.h"
+#include "io/channel-buffer.h"
+#include "migration/qemu-file-channel.h"
+#include "migration/qemu-file.h"
+#include "migration/savevm.h"
+#include "migration/ram.h"
+#include "qemu-snap.h"
+
+/* Save snapshot data from incoming migration stream */
+int coroutine_fn snap_save_state_main(SnapSaveState *sn)
+{
+    /* TODO: implement */
+    return 0;
+}
+
+/* Load snapshot data and send it with outgoing migration stream */
+int coroutine_fn snap_load_state_main(SnapLoadState *sn)
+{
+    /* TODO: implement */
+    return 0;
+}
diff --git a/qemu-snap.c b/qemu-snap.c
index c9f8d7166a..ec56aa55d2 100644
--- a/qemu-snap.c
+++ b/qemu-snap.c
@@ -44,6 +44,14 @@
 #define OPT_CACHE   256
 #define OPT_AIO     257
 
+/* Snapshot task execution state */
+typedef struct SnapTaskState {
+    QEMUBH *bh;                 /* BH to enter task's coroutine */
+    Coroutine *co;              /* Coroutine to execute task */
+
+    int ret;                    /* Return code, -EINPROGRESS until complete */
+} SnapTaskState;
+
 /* Parameters for snapshot saving */
 typedef struct SnapSaveParams {
     const char *filename;       /* QCOW2 image file name */
@@ -177,6 +185,51 @@ static BlockBackend *snap_open(const char *filename, int flags)
     return blk;
 }
 
+static void coroutine_fn do_snap_save_co(void *opaque)
+{
+    SnapTaskState *task_state = opaque;
+    SnapSaveState *sn = snap_save_get_state();
+
+    /* Enter main routine */
+    task_state->ret = snap_save_state_main(sn);
+}
+
+static void coroutine_fn do_snap_load_co(void *opaque)
+{
+    SnapTaskState *task_state = opaque;
+    SnapLoadState *sn = snap_load_get_state();
+
+    /* Enter main routine */
+    task_state->ret = snap_load_state_main(sn);
+}
+
+/* We use BH to enter coroutine from the main loop context */
+static void enter_co_bh(void *opaque)
+{
+    SnapTaskState *task_state = opaque;
+
+    qemu_coroutine_enter(task_state->co);
+    /* Delete BH once we entered coroutine from the main loop */
+    qemu_bh_delete(task_state->bh);
+    task_state->bh = NULL;
+}
+
+static int run_snap_task(CoroutineEntry *entry)
+{
+    SnapTaskState task_state;
+
+    task_state.bh = qemu_bh_new(enter_co_bh, &task_state);
+    task_state.co = qemu_coroutine_create(entry, &task_state);
+    task_state.ret = -EINPROGRESS;
+
+    qemu_bh_schedule(task_state.bh);
+    while (task_state.ret == -EINPROGRESS) {
+        main_loop_wait(false);
+    }
+
+    return task_state.ret;
+}
+
 static int snap_save(const SnapSaveParams *params)
 {
     SnapSaveState *sn;
@@ -191,6 +244,11 @@ static int snap_save(const SnapSaveParams *params)
         goto fail;
     }
 
+    res = run_snap_task(do_snap_save_co);
+    if (res) {
+        error_report("Failed to save snapshot: error=%d", res);
+    }
+
 fail:
     snap_save_destroy_state();
 
@@ -210,6 +268,11 @@ static int snap_load(SnapLoadParams *params)
         goto fail;
     }
 
+    res = run_snap_task(do_snap_load_co);
+    if (res) {
+        error_report("Failed to load snapshot: error=%d", res);
+    }
+
 fail:
     snap_load_destroy_state();
 
-- 
2.25.1



  parent reply	other threads:[~2021-03-17 16:52 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-17 16:32 [RFC PATCH 0/9] migration/snap-tool: External snapshot utility Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 1/9] migration/snap-tool: Introduce qemu-snap tool Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 2/9] migration/snap-tool: Snapshot image create/open routines for " Andrey Gruzdev
2021-03-17 16:32 ` Andrey Gruzdev [this message]
2021-03-17 16:32 ` [RFC PATCH 4/9] migration/snap-tool: Introduce qemu_ftell2() routine to qemu-file.c Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 5/9] migration/snap-tool: Block layer AIO support and file utility routines Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 6/9] migration/snap-tool: Move RAM_SAVE_FLAG_xxx defines to migration/ram.h Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 7/9] migration/snap-tool: Complete implementation of snapshot saving Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 8/9] migration/snap-tool: Implementation of snapshot loading in precopy Andrey Gruzdev
2021-03-17 16:32 ` [RFC PATCH 9/9] migration/snap-tool: Implementation of snapshot loading in postcopy Andrey Gruzdev
2021-03-29  8:11 ` [RFC PATCH 0/9] migration/snap-tool: External snapshot utility Andrey Gruzdev
2021-04-15 23:50 ` Peter Xu
2021-04-16 12:27   ` Andrey Gruzdev

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=20210317163222.182609-4-andrey.gruzdev@virtuozzo.com \
    --to=andrey.gruzdev@virtuozzo.com \
    --cc=armbru@redhat.com \
    --cc=den@openvz.org \
    --cc=dgilbert@redhat.com \
    --cc=eblake@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).