]> git.proxmox.com Git - qemu.git/commitdiff
Allow monitor interaction when using migrate -exec
authorChris Lalancette <clalance@redhat.com>
Mon, 25 May 2009 14:38:23 +0000 (16:38 +0200)
committerAnthony Liguori <aliguori@us.ibm.com>
Wed, 27 May 2009 14:47:39 +0000 (09:47 -0500)
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 <clalance@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
hw/hw.h
migration-exec.c
savevm.c

diff --git a/hw/hw.h b/hw/hw.h
index d0cf598204500e3437f66dbe652fa400974f1195..83ab3bccabde53f5516aa8225291bc7787bf263f 100644 (file)
--- a/hw/hw.h
+++ b/hw/hw.h
@@ -37,6 +37,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);
index 6ed322a9894df8de6fd807ca7058f44c19e5fe11..8e622437fb7b07a5b40e32e39c1fbb6c31bd38fb 100644 (file)
@@ -108,17 +108,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) {
@@ -127,11 +121,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;
 }
index cd833504e2f6055b893d722ce7b2af68f6378e3c..cb6cd2e4361ef98754f29925ba4a4bf33d734834 100644 (file)
--- a/savevm.c
+++ b/savevm.c
@@ -224,7 +224,6 @@ QEMUFile *qemu_popen(FILE *popen_file, const char *mode)
     } else {
         s->file = qemu_fopen_ops(s, popen_put_buffer, NULL, popen_close, NULL);
     }
-    fprintf(stderr, "qemu_popen: returning result of qemu_fopen_ops\n");
     return s->file;
 }
 
@@ -240,6 +239,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));