File:  [Qemu by Fabrice Bellard] / qemu / migration-exec.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:51:04 2018 UTC (3 years, 2 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0105, qemu0104, qemu0103, qemu0102, qemu0101, qemu0100, HEAD
qemu 0.10.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 "console.h"
   22: #include "buffered_file.h"
   23: #include "block.h"
   24: 
   25: //#define DEBUG_MIGRATION_EXEC
   26: 
   27: #ifdef DEBUG_MIGRATION_EXEC
   28: #define dprintf(fmt, ...) \
   29:     do { printf("migration-exec: " fmt, ## __VA_ARGS__); } while (0)
   30: #else
   31: #define dprintf(fmt, ...) \
   32:     do { } while (0)
   33: #endif
   34: 
   35: static int file_errno(FdMigrationState *s)
   36: {
   37:     return errno;
   38: }
   39: 
   40: static int file_write(FdMigrationState *s, const void * buf, size_t size)
   41: {
   42:     return write(s->fd, buf, size);
   43: }
   44: 
   45: static int exec_close(FdMigrationState *s)
   46: {
   47:     dprintf("exec_close\n");
   48:     if (s->opaque) {
   49:         qemu_fclose(s->opaque);
   50:         s->opaque = NULL;
   51:         s->fd = -1;
   52:     }
   53:     return 0;
   54: }
   55: 
   56: MigrationState *exec_start_outgoing_migration(const char *command,
   57:                                              int64_t bandwidth_limit,
   58:                                              int async)
   59: {
   60:     FdMigrationState *s;
   61:     FILE *f;
   62: 
   63:     s = qemu_mallocz(sizeof(*s));
   64: 
   65:     f = popen(command, "w");
   66:     if (f == NULL) {
   67:         dprintf("Unable to popen exec target\n");
   68:         goto err_after_alloc;
   69:     }
   70: 
   71:     s->fd = fileno(f);
   72:     if (s->fd == -1) {
   73:         dprintf("Unable to retrieve file descriptor for popen'd handle\n");
   74:         goto err_after_open;
   75:     }
   76: 
   77:     if (fcntl(s->fd, F_SETFD, O_NONBLOCK) == -1) {
   78:         dprintf("Unable to set nonblocking mode on file descriptor\n");
   79:         goto err_after_open;
   80:     }
   81: 
   82:     s->opaque = qemu_popen(f, "w");
   83: 
   84:     s->close = exec_close;
   85:     s->get_error = file_errno;
   86:     s->write = file_write;
   87:     s->mig_state.cancel = migrate_fd_cancel;
   88:     s->mig_state.get_status = migrate_fd_get_status;
   89:     s->mig_state.release = migrate_fd_release;
   90: 
   91:     s->state = MIG_STATE_ACTIVE;
   92:     s->detach = !async;
   93:     s->bandwidth_limit = bandwidth_limit;
   94: 
   95:     if (s->detach == 1) {
   96:         dprintf("detaching from monitor\n");
   97:         monitor_suspend();
   98:         s->detach = 2;
   99:     }
  100: 
  101:     migrate_fd_connect(s);
  102:     return &s->mig_state;
  103: 
  104: err_after_open:
  105:     pclose(f);
  106: err_after_alloc:
  107:     qemu_free(s);
  108:     return NULL;
  109: }
  110: 
  111: int exec_start_incoming_migration(const char *command)
  112: {
  113:     int ret;
  114:     QEMUFile *f;
  115: 
  116:     dprintf("Attempting to start an incoming migration\n");
  117:     f = qemu_popen_cmd(command, "r");
  118:     if(f == NULL) {
  119:         dprintf("Unable to apply qemu wrapper to popen file\n");
  120:         return -errno;
  121:     }
  122:     vm_stop(0); /* just in case */
  123:     ret = qemu_loadvm_state(f);
  124:     if (ret < 0) {
  125:         fprintf(stderr, "load of migration failed\n");
  126:         goto err;
  127:     }
  128:     qemu_announce_self();
  129:     dprintf("successfully loaded vm state\n");
  130:     vm_start();
  131:     qemu_fclose(f);
  132:     return 0;
  133: 
  134: err:
  135:     qemu_fclose(f);
  136:     return -errno;
  137: }

unix.superglobalmegacorp.com