From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:34749) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YpKXY-0002bl-L5 for qemu-devel@nongnu.org; Mon, 04 May 2015 13:52:25 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YpKXX-00075P-4t for qemu-devel@nongnu.org; Mon, 04 May 2015 13:52:24 -0400 Message-ID: <5547B1CE.1020308@redhat.com> Date: Mon, 04 May 2015 13:52:14 -0400 From: John Snow MIME-Version: 1.0 References: <1430417242-11859-1-git-send-email-jsnow@redhat.com> <1430417242-11859-4-git-send-email-jsnow@redhat.com> <20150504120727.GF3676@noname.str.redhat.com> In-Reply-To: <20150504120727.GF3676@noname.str.redhat.com> Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [Qemu-devel] [Qemu-block] [PATCH v3 3/9] libqos: Add migration helpers List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Kevin Wolf Cc: marc.mari.barcelo@gmail.com, pbonzini@redhat.com, qemu-block@nongnu.org, qemu-devel@nongnu.org, stefanha@redhat.com 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 >> --- >> 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 >> #include >> +#include >> #include >> #include >> #include >> @@ -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 >