File:  [Qemu by Fabrice Bellard] / qemu / migration-fd.c
Revision 1.1.1.4 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 19:16:39 2018 UTC (3 years, 1 month ago) by root
Branches: qemu, MAIN
CVS tags: qemu1001, HEAD
qemu 1.0.1

    1: /*
    2:  * QEMU live migration via generic fd
    3:  *
    4:  * Copyright Red Hat, Inc. 2009
    5:  *
    6:  * Authors:
    7:  *  Chris Lalancette <clalance@redhat.com>
    8:  *
    9:  * This work is licensed under the terms of the GNU GPL, version 2.  See
   10:  * the COPYING file in the top-level directory.
   11:  *
   12:  */
   13: 
   14: #include "qemu-common.h"
   15: #include "qemu_socket.h"
   16: #include "migration.h"
   17: #include "monitor.h"
   18: #include "qemu-char.h"
   19: #include "buffered_file.h"
   20: #include "block.h"
   21: #include "qemu_socket.h"
   22: 
   23: //#define DEBUG_MIGRATION_FD
   24: 
   25: #ifdef DEBUG_MIGRATION_FD
   26: #define DPRINTF(fmt, ...) \
   27:     do { printf("migration-fd: " fmt, ## __VA_ARGS__); } while (0)
   28: #else
   29: #define DPRINTF(fmt, ...) \
   30:     do { } while (0)
   31: #endif
   32: 
   33: static int fd_errno(MigrationState *s)
   34: {
   35:     return errno;
   36: }
   37: 
   38: static int fd_write(MigrationState *s, const void * buf, size_t size)
   39: {
   40:     return write(s->fd, buf, size);
   41: }
   42: 
   43: static int fd_close(MigrationState *s)
   44: {
   45:     struct stat st;
   46:     int ret;
   47: 
   48:     DPRINTF("fd_close\n");
   49:     if (s->fd != -1) {
   50:         ret = fstat(s->fd, &st);
   51:         if (ret == 0 && S_ISREG(st.st_mode)) {
   52:             /*
   53:              * If the file handle is a regular file make sure the
   54:              * data is flushed to disk before signaling success.
   55:              */
   56:             ret = fsync(s->fd);
   57:             if (ret != 0) {
   58:                 ret = -errno;
   59:                 perror("migration-fd: fsync");
   60:                 return ret;
   61:             }
   62:         }
   63:         ret = close(s->fd);
   64:         s->fd = -1;
   65:         if (ret != 0) {
   66:             ret = -errno;
   67:             perror("migration-fd: close");
   68:             return ret;
   69:         }
   70:     }
   71:     return 0;
   72: }
   73: 
   74: int fd_start_outgoing_migration(MigrationState *s, const char *fdname)
   75: {
   76:     s->fd = monitor_get_fd(s->mon, fdname);
   77:     if (s->fd == -1) {
   78:         DPRINTF("fd_migration: invalid file descriptor identifier\n");
   79:         goto err_after_get_fd;
   80:     }
   81: 
   82:     if (fcntl(s->fd, F_SETFL, O_NONBLOCK) == -1) {
   83:         DPRINTF("Unable to set nonblocking mode on file descriptor\n");
   84:         goto err_after_open;
   85:     }
   86: 
   87:     s->get_error = fd_errno;
   88:     s->write = fd_write;
   89:     s->close = fd_close;
   90: 
   91:     migrate_fd_connect(s);
   92:     return 0;
   93: 
   94: err_after_open:
   95:     close(s->fd);
   96: err_after_get_fd:
   97:     return -1;
   98: }
   99: 
  100: static void fd_accept_incoming_migration(void *opaque)
  101: {
  102:     QEMUFile *f = opaque;
  103: 
  104:     process_incoming_migration(f);
  105:     qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
  106:     qemu_fclose(f);
  107: }
  108: 
  109: int fd_start_incoming_migration(const char *infd)
  110: {
  111:     int fd;
  112:     QEMUFile *f;
  113: 
  114:     DPRINTF("Attempting to start an incoming migration via fd\n");
  115: 
  116:     fd = strtol(infd, NULL, 0);
  117:     f = qemu_fdopen(fd, "rb");
  118:     if(f == NULL) {
  119:         DPRINTF("Unable to apply qemu wrapper to file descriptor\n");
  120:         return -errno;
  121:     }
  122: 
  123:     qemu_set_fd_handler2(fd, NULL, fd_accept_incoming_migration, NULL, f);
  124: 
  125:     return 0;
  126: }

unix.superglobalmegacorp.com