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

1.1       root        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
1.1.1.2   root       26: #define DPRINTF(fmt, ...) \
1.1       root       27:     do { printf("migration-fd: " fmt, ## __VA_ARGS__); } while (0)
                     28: #else
1.1.1.2   root       29: #define DPRINTF(fmt, ...) \
1.1       root       30:     do { } while (0)
                     31: #endif
                     32: 
1.1.1.4 ! root       33: static int fd_errno(MigrationState *s)
1.1       root       34: {
                     35:     return errno;
                     36: }
                     37: 
1.1.1.4 ! root       38: static int fd_write(MigrationState *s, const void * buf, size_t size)
1.1       root       39: {
                     40:     return write(s->fd, buf, size);
                     41: }
                     42: 
1.1.1.4 ! root       43: static int fd_close(MigrationState *s)
1.1       root       44: {
1.1.1.4 ! root       45:     struct stat st;
        !            46:     int ret;
        !            47: 
1.1.1.2   root       48:     DPRINTF("fd_close\n");
1.1       root       49:     if (s->fd != -1) {
1.1.1.4 ! root       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);
1.1       root       64:         s->fd = -1;
1.1.1.4 ! root       65:         if (ret != 0) {
        !            66:             ret = -errno;
        !            67:             perror("migration-fd: close");
        !            68:             return ret;
        !            69:         }
1.1       root       70:     }
                     71:     return 0;
                     72: }
                     73: 
1.1.1.4 ! root       74: int fd_start_outgoing_migration(MigrationState *s, const char *fdname)
1.1       root       75: {
1.1.1.4 ! root       76:     s->fd = monitor_get_fd(s->mon, fdname);
1.1       root       77:     if (s->fd == -1) {
1.1.1.2   root       78:         DPRINTF("fd_migration: invalid file descriptor identifier\n");
1.1.1.4 ! root       79:         goto err_after_get_fd;
1.1       root       80:     }
                     81: 
                     82:     if (fcntl(s->fd, F_SETFL, O_NONBLOCK) == -1) {
1.1.1.2   root       83:         DPRINTF("Unable to set nonblocking mode on file descriptor\n");
1.1       root       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);
1.1.1.4 ! root       92:     return 0;
1.1       root       93: 
                     94: err_after_open:
                     95:     close(s->fd);
1.1.1.4 ! root       96: err_after_get_fd:
        !            97:     return -1;
1.1       root       98: }
                     99: 
                    100: static void fd_accept_incoming_migration(void *opaque)
                    101: {
                    102:     QEMUFile *f = opaque;
                    103: 
1.1.1.2   root      104:     process_incoming_migration(f);
1.1       root      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: 
1.1.1.2   root      114:     DPRINTF("Attempting to start an incoming migration via fd\n");
1.1       root      115: 
                    116:     fd = strtol(infd, NULL, 0);
                    117:     f = qemu_fdopen(fd, "rb");
                    118:     if(f == NULL) {
1.1.1.2   root      119:         DPRINTF("Unable to apply qemu wrapper to file descriptor\n");
1.1       root      120:         return -errno;
                    121:     }
                    122: 
1.1.1.2   root      123:     qemu_set_fd_handler2(fd, NULL, fd_accept_incoming_migration, NULL, f);
1.1       root      124: 
                    125:     return 0;
                    126: }

unix.superglobalmegacorp.com