File:  [Qemu by Fabrice Bellard] / qemu / migration-exec.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:24:51 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu0150, qemu0141, qemu0140, qemu0130, HEAD
qemu 0.13.0

    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"
   23: #include <sys/types.h>
   24: #include <sys/wait.h>
   25: 
   26: //#define DEBUG_MIGRATION_EXEC
   27: 
   28: #ifdef DEBUG_MIGRATION_EXEC
   29: #define DPRINTF(fmt, ...) \
   30:     do { printf("migration-exec: " fmt, ## __VA_ARGS__); } while (0)
   31: #else
   32: #define DPRINTF(fmt, ...) \
   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: {
   48:     int ret = 0;
   49:     DPRINTF("exec_close\n");
   50:     if (s->opaque) {
   51:         ret = qemu_fclose(s->opaque);
   52:         s->opaque = NULL;
   53:         s->fd = -1;
   54:         if (ret != -1 &&
   55:             WIFEXITED(ret)
   56:             && WEXITSTATUS(ret) == 0) {
   57:             ret = 0;
   58:         } else {
   59:             ret = -1;
   60:         }
   61:     }
   62:     return ret;
   63: }
   64: 
   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)
   71: {
   72:     FdMigrationState *s;
   73:     FILE *f;
   74: 
   75:     s = qemu_mallocz(sizeof(*s));
   76: 
   77:     f = popen(command, "w");
   78:     if (f == NULL) {
   79:         DPRINTF("Unable to popen exec target\n");
   80:         goto err_after_alloc;
   81:     }
   82: 
   83:     s->fd = fileno(f);
   84:     if (s->fd == -1) {
   85:         DPRINTF("Unable to retrieve file descriptor for popen'd handle\n");
   86:         goto err_after_open;
   87:     }
   88: 
   89:     socket_set_nonblock(s->fd);
   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: 
  100:     s->mig_state.blk = blk;
  101:     s->mig_state.shared = inc;
  102: 
  103:     s->state = MIG_STATE_ACTIVE;
  104:     s->mon = NULL;
  105:     s->bandwidth_limit = bandwidth_limit;
  106: 
  107:     if (!detach) {
  108:         migrate_fd_monitor_suspend(s, mon);
  109:     }
  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: 
  121: static void exec_accept_incoming_migration(void *opaque)
  122: {
  123:     QEMUFile *f = opaque;
  124: 
  125:     process_incoming_migration(f);
  126:     qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
  127:     qemu_fclose(f);
  128: }
  129: 
  130: int exec_start_incoming_migration(const char *command)
  131: {
  132:     QEMUFile *f;
  133: 
  134:     DPRINTF("Attempting to start an incoming migration\n");
  135:     f = qemu_popen_cmd(command, "r");
  136:     if(f == NULL) {
  137:         DPRINTF("Unable to apply qemu wrapper to popen file\n");
  138:         return -errno;
  139:     }
  140: 
  141:     qemu_set_fd_handler2(qemu_stdio_fd(f), NULL,
  142: 			 exec_accept_incoming_migration, NULL, f);
  143: 
  144:     return 0;
  145: }

unix.superglobalmegacorp.com