>From e7066ce85e969e43c8142f4845bc843e9d53f5e4 Mon Sep 17 00:00:00 2001 From: Charles Duffy Date: Fri, 28 Aug 2009 23:18:49 -0500 Subject: [PATCH 2/2] stop using popen for incoming migrations --- migration-exec.c | 51 +++++++++++++++++++++++++++++++-------------------- 1 files changed, 31 insertions(+), 20 deletions(-) diff --git a/migration-exec.c b/migration-exec.c index c36e756..3dfea18 100644 --- a/migration-exec.c +++ b/migration-exec.c @@ -31,10 +31,10 @@ do { } while (0) #endif -// opaque is pid typedef struct ExecMigrationState { pid_t pid; + int fd; /* only used for incoming */ } ExecMigrationState; static int exec_errno(FdMigrationState *s) @@ -68,9 +68,9 @@ static int exec_close(FdMigrationState *s) return status; } -static pid_t exec_start_migration(const char *command, int *fd) { +static pid_t exec_start_migration(const char *command, int *fd, unsigned char incoming) { const char *argv[] = { "sh", "-c", command, NULL }; - int fds[2]; + int fds[2], parent_fd, child_fd; pid_t pid; if (pipe(fds) == -1) { @@ -78,6 +78,16 @@ static pid_t exec_start_migration(const char *command, int *fd) { return 0; } + if(incoming) { + /* child writes, parent reads */ + parent_fd = fds[0]; + child_fd = fds[1]; + } else { + /* parent writes, child reads */ + parent_fd = fds[1]; + child_fd = fds[0]; + } + pid = fork(); if(pid == -1) { close(fds[0]); @@ -86,16 +96,14 @@ static pid_t exec_start_migration(const char *command, int *fd) { return 0; } else if (pid == 0) { /* child process */ - close(fds[1]); - dup2(fds[0], STDIN_FILENO); + close(parent_fd); + dup2(child_fd, incoming ? STDOUT_FILENO : STDIN_FILENO); execv("/bin/sh", (char **)argv); exit(1); } - close(fds[0]); - - fcntl(fds[1], O_NONBLOCK); - - *fd = fds[1]; + close(child_fd); + fcntl(parent_fd, O_NONBLOCK); + *fd = parent_fd; return pid; } @@ -106,7 +114,7 @@ MigrationState *exec_start_outgoing_migration(const char *command, FdMigrationState *s; int fd, pid; - pid = exec_start_migration(command, &fd); + pid = exec_start_migration(command, &fd, 0); if(!pid) return NULL; s = qemu_mallocz(sizeof(*s)); @@ -136,7 +144,8 @@ MigrationState *exec_start_outgoing_migration(const char *command, /* helper for incoming case */ static void exec_accept_incoming_migration(void *opaque) { - QEMUFile *f = opaque; + ExecMigrationState *s = opaque; + QEMUFile *f = qemu_popen(fdopen(s->fd, "rb"), "r"); int ret; ret = qemu_loadvm_state(f); @@ -153,22 +162,24 @@ static void exec_accept_incoming_migration(void *opaque) err: qemu_fclose(f); + do { + waitpid(s->pid, NULL, 0); + } while (ret == -1 && errno == EINTR); + qemu_free(s); } int exec_start_incoming_migration(const char *command) { - QEMUFile *f; + ExecMigrationState *s; + + s = qemu_mallocz(sizeof(*s)); - 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"); + s->pid = exec_start_migration(command, &(s->fd), 1); + if(!s->pid) { return -errno; } - qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, - exec_accept_incoming_migration, NULL, - (void *)(unsigned long)f); + qemu_set_fd_handler2(s->fd, NULL, exec_accept_incoming_migration, NULL, (void*)s); return 0; } -- 1.6.4