qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [Qemu-block] [PATCH v3 3/9] libqos: Add migration helpe


From: John Snow
Subject: Re: [Qemu-devel] [Qemu-block] [PATCH v3 3/9] libqos: Add migration helpers
Date: Mon, 04 May 2015 13:52:14 -0400
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0



On 05/04/2015 08:07 AM, Kevin Wolf wrote:
Am 30.04.2015 um 20:07 hat John Snow geschrieben:
libqos.c:
     -set_context for addressing which commands go where
     -migrate performs the actual migration

malloc.c:
     - Structure of the allocator is adjusted slightly with
       a second-tier malloc to make swapping around the allocators
       easy when we "migrate" the lists from the source to the destination.

Signed-off-by: John Snow <address@hidden>
---
  tests/libqos/libqos.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++
  tests/libqos/libqos.h |  2 ++
  tests/libqos/malloc.c | 74 ++++++++++++++++++++++++++++++++++-----------
  tests/libqos/malloc.h |  1 +
  4 files changed, 144 insertions(+), 17 deletions(-)

diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
index 7e72078..ac1bae1 100644
--- a/tests/libqos/libqos.c
+++ b/tests/libqos/libqos.c
@@ -1,5 +1,6 @@
  #include <stdio.h>
  #include <stdlib.h>
+#include <string.h>
  #include <glib.h>
  #include <unistd.h>
  #include <fcntl.h>
@@ -62,6 +63,89 @@ void qtest_shutdown(QOSState *qs)
      g_free(qs);
  }

+void set_context(QOSState *s)
+{
+    global_qtest = s->qts;
+}
+
+static QDict *qmp_execute(const char *command)
+{
+    char *fmt;
+    QDict *rsp;
+
+    fmt = g_strdup_printf("{ 'execute': '%s' }", command);
+    rsp = qmp(fmt);
+    g_free(fmt);
+
+    return rsp;
+}
+
+void migrate(QOSState *from, QOSState *to, const char *uri)
+{
+    const char *st;
+    char *s;
+    QDict *rsp, *sub;
+    bool running;
+
+    set_context(from);
+
+    /* Is the machine currently running? */
+    rsp = qmp_execute("query-status");
+    g_assert(qdict_haskey(rsp, "return"));
+    sub = qdict_get_qdict(rsp, "return");
+    g_assert(qdict_haskey(sub, "running"));
+    running = qdict_get_bool(sub, "running");
+    QDECREF(rsp);
+
+    /* Issue the migrate command. */
+    s = g_strdup_printf("{ 'execute': 'migrate',"
+                        "'arguments': { 'uri': '%s' } }",
+                        uri);
+    rsp = qmp(s);
+    g_free(s);
+    g_assert(qdict_haskey(rsp, "return"));
+    QDECREF(rsp);
+
+    /* Wait for STOP event, but only if we were running: */
+    if (running) {
+        qmp_eventwait("STOP");
+    }
+
+    /* If we were running, we can wait for an event. */
+    if (running) {
+        migrate_allocator(from->alloc, to->alloc);
+        set_context(to);
+        qmp_eventwait("RESUME");
+        return;
+    }
+
+    /* Otherwise, we need to wait: poll until migration is completed. */
+    while (1) {
+        rsp = qmp_execute("query-migrate");
+        g_assert(qdict_haskey(rsp, "return"));
+        sub = qdict_get_qdict(rsp, "return");
+        g_assert(qdict_haskey(sub, "status"));
+        st = qdict_get_str(sub, "status");
+
+        /* "setup", "active", "completed", "failed", "cancelled" */
+        if (strcmp(st, "completed") == 0) {
+            QDECREF(rsp);
+            break;
+        }
+
+        if ((strcmp(st, "setup") == 0) || (strcmp(st, "active") == 0)) {
+            QDECREF(rsp);
+            continue;

Wouldn't it be nicer to sleep a bit before retrying?


I actually figured that all the string and stream manipulation for sending and receiving QMP queries was "enough sleep" because of how quick a migration without any guest should complete -- in practice this loop doesn't ever seem to trigger more than once.

If you still think sleep is necessary, I can add some very small sleep in a separate patch, or when I merge the tree. Something like:

g_usleep(5000) /* 5 msec */

+        }
+
+        fprintf(stderr, "Migration did not complete, status: %s\n", st);
+        g_assert_not_reached();
+    }
+
+    migrate_allocator(from->alloc, to->alloc);
+    set_context(to);
+}

Kevin




reply via email to

[Prev in Thread] Current Thread [Next in Thread]