Commit 8a43b1ea7fd02a8e9a5c5ef58017b1bd059663bb

Authored by Chris Lalancette
Committed by Anthony Liguori
1 parent c16b5a2c

Allow monitor interaction when using migrate -exec

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>
@@ -51,6 +51,7 @@ QEMUFile *qemu_fopen(const char *filename, const char *mode); @@ -51,6 +51,7 @@ QEMUFile *qemu_fopen(const char *filename, const char *mode);
51 QEMUFile *qemu_fopen_socket(int fd); 51 QEMUFile *qemu_fopen_socket(int fd);
52 QEMUFile *qemu_popen(FILE *popen_file, const char *mode); 52 QEMUFile *qemu_popen(FILE *popen_file, const char *mode);
53 QEMUFile *qemu_popen_cmd(const char *command, const char *mode); 53 QEMUFile *qemu_popen_cmd(const char *command, const char *mode);
  54 +int qemu_popen_fd(QEMUFile *f);
54 void qemu_fflush(QEMUFile *f); 55 void qemu_fflush(QEMUFile *f);
55 int qemu_fclose(QEMUFile *f); 56 int qemu_fclose(QEMUFile *f);
56 void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size); 57 void qemu_put_buffer(QEMUFile *f, const uint8_t *buf, int size);
migration-exec.c
@@ -104,17 +104,11 @@ err_after_alloc: @@ -104,17 +104,11 @@ err_after_alloc:
104 return NULL; 104 return NULL;
105 } 105 }
106 106
107 -int exec_start_incoming_migration(const char *command) 107 +static void exec_accept_incoming_migration(void *opaque)
108 { 108 {
  109 + QEMUFile *f = opaque;
109 int ret; 110 int ret;
110 - QEMUFile *f;  
111 111
112 - dprintf("Attempting to start an incoming migration\n");  
113 - f = qemu_popen_cmd(command, "r");  
114 - if(f == NULL) {  
115 - dprintf("Unable to apply qemu wrapper to popen file\n");  
116 - return -errno;  
117 - }  
118 vm_stop(0); /* just in case */ 112 vm_stop(0); /* just in case */
119 ret = qemu_loadvm_state(f); 113 ret = qemu_loadvm_state(f);
120 if (ret < 0) { 114 if (ret < 0) {
@@ -123,11 +117,28 @@ int exec_start_incoming_migration(const char *command) @@ -123,11 +117,28 @@ int exec_start_incoming_migration(const char *command)
123 } 117 }
124 qemu_announce_self(); 118 qemu_announce_self();
125 dprintf("successfully loaded vm state\n"); 119 dprintf("successfully loaded vm state\n");
  120 + /* we've successfully migrated, close the fd */
  121 + qemu_set_fd_handler2(qemu_popen_fd(f), NULL, NULL, NULL, NULL);
126 vm_start(); 122 vm_start();
127 - qemu_fclose(f);  
128 - return 0;  
129 123
130 err: 124 err:
131 qemu_fclose(f); 125 qemu_fclose(f);
132 - return -errno; 126 +}
  127 +
  128 +int exec_start_incoming_migration(const char *command)
  129 +{
  130 + QEMUFile *f;
  131 +
  132 + dprintf("Attempting to start an incoming migration\n");
  133 + f = qemu_popen_cmd(command, "r");
  134 + if(f == NULL) {
  135 + dprintf("Unable to apply qemu wrapper to popen file\n");
  136 + return -errno;
  137 + }
  138 +
  139 + qemu_set_fd_handler2(qemu_popen_fd(f), NULL,
  140 + exec_accept_incoming_migration, NULL,
  141 + (void *)(unsigned long)f);
  142 +
  143 + return 0;
133 } 144 }
savevm.c
@@ -244,7 +244,6 @@ QEMUFile *qemu_popen(FILE *popen_file, const char *mode) @@ -244,7 +244,6 @@ QEMUFile *qemu_popen(FILE *popen_file, const char *mode)
244 } else { 244 } else {
245 s->file = qemu_fopen_ops(s, popen_put_buffer, NULL, popen_close, NULL, NULL); 245 s->file = qemu_fopen_ops(s, popen_put_buffer, NULL, popen_close, NULL, NULL);
246 } 246 }
247 - fprintf(stderr, "qemu_popen: returning result of qemu_fopen_ops\n");  
248 return s->file; 247 return s->file;
249 } 248 }
250 249
@@ -260,6 +259,17 @@ QEMUFile *qemu_popen_cmd(const char *command, const char *mode) @@ -260,6 +259,17 @@ QEMUFile *qemu_popen_cmd(const char *command, const char *mode)
260 return qemu_popen(popen_file, mode); 259 return qemu_popen(popen_file, mode);
261 } 260 }
262 261
  262 +int qemu_popen_fd(QEMUFile *f)
  263 +{
  264 + QEMUFilePopen *p;
  265 + int fd;
  266 +
  267 + p = (QEMUFilePopen *)f->opaque;
  268 + fd = fileno(p->popen_file);
  269 +
  270 + return fd;
  271 +}
  272 +
263 QEMUFile *qemu_fopen_socket(int fd) 273 QEMUFile *qemu_fopen_socket(int fd)
264 { 274 {
265 QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket)); 275 QEMUFileSocket *s = qemu_mallocz(sizeof(QEMUFileSocket));