From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1M8bJx-0001Id-49 for qemu-devel@nongnu.org; Mon, 25 May 2009 10:38:33 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1M8bJs-00019j-8Y for qemu-devel@nongnu.org; Mon, 25 May 2009 10:38:32 -0400 Received: from [199.232.76.173] (port=35080 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1M8bJs-00019V-1H for qemu-devel@nongnu.org; Mon, 25 May 2009 10:38:28 -0400 Received: from mx2.redhat.com ([66.187.237.31]:54955) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1M8bJr-0000jS-I4 for qemu-devel@nongnu.org; Mon, 25 May 2009 10:38:27 -0400 Received: from int-mx2.corp.redhat.com (int-mx2.corp.redhat.com [172.16.27.26]) by mx2.redhat.com (8.13.8/8.13.8) with ESMTP id n4PEcQEL030101 for ; Mon, 25 May 2009 10:38:26 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx2.corp.redhat.com (8.13.1/8.13.1) with ESMTP id n4PEcP57024212 for ; Mon, 25 May 2009 10:38:25 -0400 Received: from localhost.localdomain (vpn-12-111.rdu.redhat.com [10.11.12.111]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id n4PEcOQk013659 for ; Mon, 25 May 2009 10:38:24 -0400 Message-ID: <4A1AAD5F.2070403@redhat.com> Date: Mon, 25 May 2009 16:38:23 +0200 From: Chris Lalancette MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------050505030105080603070208" Subject: [Qemu-devel] [PATCH]: Allow monitor interaction when using migrate -exec List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org This is a multi-part message in MIME format. --------------050505030105080603070208 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit All, I've recently been playing around with migration via exec. Unfortunately, when starting the incoming qemu process with "-incoming exec:cmd", it suffers the same problem that -incoming tcp used to suffer; namely, that you can't interact with the monitor until after the migration has happened. This causes problems for libvirt usage of -incoming exec, since libvirt expects to be able to access the monitor ahead of time. This fairly simple patch allows you to access the monitor both before and after the migration has completed using exec. (note: developed/tested with qemu-kvm, but applies perfectly fine to qemu) Signed-off-by: Chris Lalancette --------------050505030105080603070208 Content-Type: text/x-patch; name="qemu-exec-incoming-migration.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="qemu-exec-incoming-migration.patch" diff --git a/hw/hw.h b/hw/hw.h index a3f5717..c835800 100644 --- a/hw/hw.h +++ b/hw/hw.h @@ -51,6 +51,7 @@ QEMUFile *qemu_fopen(const char *filename, const char *mode); QEMUFile *qemu_fopen_socket(int fd); QEMUFile *qemu_popen(FILE *popen_file, const char *mode); QEMUFile *qemu_popen_cmd(const char *command, const char *mode); +int qemu_popen_fd(QEMUFile *f); void qemu_fflush(QEMUFile *f); int qemu_fclose(QEMUFile *f); void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size); diff --git a/migration-exec.c b/migration-exec.c index f0869a1..0dd5aff 100644 --- a/migration-exec.c +++ b/migration-exec.c @@ -104,17 +104,11 @@ err_after_alloc: return NULL; } -int exec_start_incoming_migration(const char *command) +static void exec_accept_incoming_migration(void *opaque) { + QEMUFile *f = opaque; int ret; - QEMUFile *f; - dprintf("Attempting to start an incoming migration\n"); - f = qemu_popen_cmd(command, "r"); - if(f == NULL) { - dprintf("Unable to apply qemu wrapper to popen file\n"); - return -errno; - } vm_stop(0); /* just in case */ ret = qemu_loadvm_state(f); if (ret < 0) { @@ -123,11 +117,28 @@ int exec_start_incoming_migration(const char *command) } qemu_announce_self(); dprintf("successfully loaded vm state\n"); + /* we've successfully migrated, close the fd */ + qemu_set_fd_handler2(qemu_popen_fd(f), NULL, NULL, NULL, NULL); vm_start(); - qemu_fclose(f); - return 0; err: qemu_fclose(f); - return -errno; +} + +int exec_start_incoming_migration(const char *command) +{ + QEMUFile *f; + + dprintf("Attempting to start an incoming migration\n"); + f = qemu_popen_cmd(command, "r"); + if(f == NULL) { + dprintf("Unable to apply qemu wrapper to popen file\n"); + return -errno; + } + + qemu_set_fd_handler2(qemu_popen_fd(f), NULL, + exec_accept_incoming_migration, NULL, + (void *)(unsigned long)f); + + return 0; } diff --git a/savevm.c b/savevm.c index 68ffd03..248aea3 100644 --- a/savevm.c +++ b/savevm.c @@ -244,7 +244,6 @@ QEMUFile *qemu_popen(FILE *popen_file, const char *mode) } else { s->file = qemu_fopen_ops(s, popen_put_buffer, NULL, popen_close, NULL, NULL); } - fprintf(stderr, "qemu_popen: returning result of qemu_fopen_ops\n"); return s->file; } @@ -260,6 +259,17 @@ QEMUFile *qemu_popen_cmd(const char *command, const char *mode) return qemu_popen(popen_file, mode); } +int qemu_popen_fd(QEMUFile *f) +{ + QEMUFilePopen *p; + int fd; + + p = (QEMUFilePopen *)f->opaque; + fd = fileno(p->popen_file); + + return fd; +} + QEMUFile *qemu_fopen_socket(int fd) { QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket)); --------------050505030105080603070208--