Annotation of qemu/migration-exec.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  * QEMU live migration
                      3:  *
                      4:  * Copyright IBM, Corp. 2008
                      5:  * Copyright Dell MessageOne 2008
                      6:  *
                      7:  * Authors:
                      8:  *  Anthony Liguori   <aliguori@us.ibm.com>
                      9:  *  Charles Duffy     <charles_duffy@messageone.com>
                     10:  *
                     11:  * This work is licensed under the terms of the GNU GPL, version 2.  See
                     12:  * the COPYING file in the top-level directory.
                     13:  *
                     14:  */
                     15: 
                     16: #include "qemu-common.h"
                     17: #include "qemu_socket.h"
                     18: #include "migration.h"
                     19: #include "qemu-char.h"
                     20: #include "sysemu.h"
                     21: #include "buffered_file.h"
                     22: #include "block.h"
1.1.1.4 ! root       23: #include <sys/types.h>
        !            24: #include <sys/wait.h>
1.1       root       25: 
                     26: //#define DEBUG_MIGRATION_EXEC
                     27: 
                     28: #ifdef DEBUG_MIGRATION_EXEC
1.1.1.4 ! root       29: #define DPRINTF(fmt, ...) \
1.1       root       30:     do { printf("migration-exec: " fmt, ## __VA_ARGS__); } while (0)
                     31: #else
1.1.1.4 ! root       32: #define DPRINTF(fmt, ...) \
1.1       root       33:     do { } while (0)
                     34: #endif
                     35: 
                     36: static int file_errno(FdMigrationState *s)
                     37: {
                     38:     return errno;
                     39: }
                     40: 
                     41: static int file_write(FdMigrationState *s, const void * buf, size_t size)
                     42: {
                     43:     return write(s->fd, buf, size);
                     44: }
                     45: 
                     46: static int exec_close(FdMigrationState *s)
                     47: {
1.1.1.4 ! root       48:     int ret = 0;
        !            49:     DPRINTF("exec_close\n");
1.1       root       50:     if (s->opaque) {
1.1.1.4 ! root       51:         ret = qemu_fclose(s->opaque);
1.1       root       52:         s->opaque = NULL;
                     53:         s->fd = -1;
1.1.1.4 ! root       54:         if (ret != -1 &&
        !            55:             WIFEXITED(ret)
        !            56:             && WEXITSTATUS(ret) == 0) {
        !            57:             ret = 0;
        !            58:         } else {
        !            59:             ret = -1;
        !            60:         }
1.1       root       61:     }
1.1.1.4 ! root       62:     return ret;
1.1       root       63: }
                     64: 
1.1.1.3   root       65: MigrationState *exec_start_outgoing_migration(Monitor *mon,
                     66:                                               const char *command,
                     67:                                              int64_t bandwidth_limit,
                     68:                                              int detach,
                     69:                                              int blk,
                     70:                                              int inc)
1.1       root       71: {
                     72:     FdMigrationState *s;
                     73:     FILE *f;
                     74: 
                     75:     s = qemu_mallocz(sizeof(*s));
                     76: 
                     77:     f = popen(command, "w");
                     78:     if (f == NULL) {
1.1.1.4 ! root       79:         DPRINTF("Unable to popen exec target\n");
1.1       root       80:         goto err_after_alloc;
                     81:     }
                     82: 
                     83:     s->fd = fileno(f);
                     84:     if (s->fd == -1) {
1.1.1.4 ! root       85:         DPRINTF("Unable to retrieve file descriptor for popen'd handle\n");
1.1       root       86:         goto err_after_open;
                     87:     }
                     88: 
1.1.1.2   root       89:     socket_set_nonblock(s->fd);
1.1       root       90: 
                     91:     s->opaque = qemu_popen(f, "w");
                     92: 
                     93:     s->close = exec_close;
                     94:     s->get_error = file_errno;
                     95:     s->write = file_write;
                     96:     s->mig_state.cancel = migrate_fd_cancel;
                     97:     s->mig_state.get_status = migrate_fd_get_status;
                     98:     s->mig_state.release = migrate_fd_release;
                     99: 
1.1.1.3   root      100:     s->mig_state.blk = blk;
                    101:     s->mig_state.shared = inc;
                    102: 
1.1       root      103:     s->state = MIG_STATE_ACTIVE;
1.1.1.3   root      104:     s->mon = NULL;
1.1       root      105:     s->bandwidth_limit = bandwidth_limit;
                    106: 
1.1.1.3   root      107:     if (!detach) {
                    108:         migrate_fd_monitor_suspend(s, mon);
                    109:     }
1.1       root      110: 
                    111:     migrate_fd_connect(s);
                    112:     return &s->mig_state;
                    113: 
                    114: err_after_open:
                    115:     pclose(f);
                    116: err_after_alloc:
                    117:     qemu_free(s);
                    118:     return NULL;
                    119: }
                    120: 
1.1.1.2   root      121: static void exec_accept_incoming_migration(void *opaque)
1.1       root      122: {
1.1.1.2   root      123:     QEMUFile *f = opaque;
1.1       root      124: 
1.1.1.4 ! root      125:     process_incoming_migration(f);
1.1.1.3   root      126:     qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
1.1       root      127:     qemu_fclose(f);
1.1.1.2   root      128: }
                    129: 
                    130: int exec_start_incoming_migration(const char *command)
                    131: {
                    132:     QEMUFile *f;
                    133: 
1.1.1.4 ! root      134:     DPRINTF("Attempting to start an incoming migration\n");
1.1.1.2   root      135:     f = qemu_popen_cmd(command, "r");
                    136:     if(f == NULL) {
1.1.1.4 ! root      137:         DPRINTF("Unable to apply qemu wrapper to popen file\n");
1.1.1.2   root      138:         return -errno;
                    139:     }
                    140: 
1.1.1.3   root      141:     qemu_set_fd_handler2(qemu_stdio_fd(f), NULL,
1.1.1.4 ! root      142:                         exec_accept_incoming_migration, NULL, f);
1.1.1.2   root      143: 
                    144:     return 0;
1.1       root      145: }

unix.superglobalmegacorp.com