File:  [Qemu by Fabrice Bellard] / qemu / migration-exec.c
Revision 1.1.1.7 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:35:23 2018 UTC (23 months, 1 week ago) by root
Branches: qemu, MAIN
CVS tags: qemu1101, HEAD
qemu 1.1.1

    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:  * Contributions after 2012-01-13 are licensed under the terms of the
   15:  * GNU GPL, version 2 or (at your option) any later version.
   16:  */
   17: 
   18: #include "qemu-common.h"
   19: #include "qemu_socket.h"
   20: #include "migration.h"
   21: #include "qemu-char.h"
   22: #include "buffered_file.h"
   23: #include "block.h"
   24: #include <sys/types.h>
   25: #include <sys/wait.h>
   26: 
   27: //#define DEBUG_MIGRATION_EXEC
   28: 
   29: #ifdef DEBUG_MIGRATION_EXEC
   30: #define DPRINTF(fmt, ...) \
   31:     do { printf("migration-exec: " fmt, ## __VA_ARGS__); } while (0)
   32: #else
   33: #define DPRINTF(fmt, ...) \
   34:     do { } while (0)
   35: #endif
   36: 
   37: static int file_errno(MigrationState *s)
   38: {
   39:     return errno;
   40: }
   41: 
   42: static int file_write(MigrationState *s, const void * buf, size_t size)
   43: {
   44:     return write(s->fd, buf, size);
   45: }
   46: 
   47: static int exec_close(MigrationState *s)
   48: {
   49:     int ret = 0;
   50:     DPRINTF("exec_close\n");
   51:     if (s->opaque) {
   52:         ret = qemu_fclose(s->opaque);
   53:         s->opaque = NULL;
   54:         s->fd = -1;
   55:         if (ret >= 0 && !(WIFEXITED(ret) && WEXITSTATUS(ret) == 0)) {
   56:             /* close succeeded, but non-zero exit code: */
   57:             ret = -EIO; /* fake errno value */
   58:         }
   59:     }
   60:     return ret;
   61: }
   62: 
   63: int exec_start_outgoing_migration(MigrationState *s, const char *command)
   64: {
   65:     FILE *f;
   66: 
   67:     f = popen(command, "w");
   68:     if (f == NULL) {
   69:         DPRINTF("Unable to popen exec target\n");
   70:         goto err_after_popen;
   71:     }
   72: 
   73:     s->fd = fileno(f);
   74:     if (s->fd == -1) {
   75:         DPRINTF("Unable to retrieve file descriptor for popen'd handle\n");
   76:         goto err_after_open;
   77:     }
   78: 
   79:     socket_set_nonblock(s->fd);
   80: 
   81:     s->opaque = qemu_popen(f, "w");
   82: 
   83:     s->close = exec_close;
   84:     s->get_error = file_errno;
   85:     s->write = file_write;
   86: 
   87:     migrate_fd_connect(s);
   88:     return 0;
   89: 
   90: err_after_open:
   91:     pclose(f);
   92: err_after_popen:
   93:     return -1;
   94: }
   95: 
   96: static void exec_accept_incoming_migration(void *opaque)
   97: {
   98:     QEMUFile *f = opaque;
   99: 
  100:     process_incoming_migration(f);
  101:     qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
  102:     qemu_fclose(f);
  103: }
  104: 
  105: int exec_start_incoming_migration(const char *command)
  106: {
  107:     QEMUFile *f;
  108: 
  109:     DPRINTF("Attempting to start an incoming migration\n");
  110:     f = qemu_popen_cmd(command, "r");
  111:     if(f == NULL) {
  112:         DPRINTF("Unable to apply qemu wrapper to popen file\n");
  113:         return -errno;
  114:     }
  115: 
  116:     qemu_set_fd_handler2(qemu_stdio_fd(f), NULL,
  117: 			 exec_accept_incoming_migration, NULL, f);
  118: 
  119:     return 0;
  120: }

unix.superglobalmegacorp.com