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

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 "sysemu.h"
                     20: #include "buffered_file.h"
                     21: #include "block.h"
                     22: #include "qemu_socket.h"
                     23: 
                     24: //#define DEBUG_MIGRATION_FD
                     25: 
                     26: #ifdef DEBUG_MIGRATION_FD
                     27: #define dprintf(fmt, ...) \
                     28:     do { printf("migration-fd: " fmt, ## __VA_ARGS__); } while (0)
                     29: #else
                     30: #define dprintf(fmt, ...) \
                     31:     do { } while (0)
                     32: #endif
                     33: 
                     34: static int fd_errno(FdMigrationState *s)
                     35: {
                     36:     return errno;
                     37: }
                     38: 
                     39: static int fd_write(FdMigrationState *s, const void * buf, size_t size)
                     40: {
                     41:     return write(s->fd, buf, size);
                     42: }
                     43: 
                     44: static int fd_close(FdMigrationState *s)
                     45: {
                     46:     dprintf("fd_close\n");
                     47:     if (s->fd != -1) {
                     48:         close(s->fd);
                     49:         s->fd = -1;
                     50:     }
                     51:     return 0;
                     52: }
                     53: 
                     54: MigrationState *fd_start_outgoing_migration(Monitor *mon,
                     55:                                            const char *fdname,
                     56:                                            int64_t bandwidth_limit,
                     57:                                            int detach,
                     58:                                            int blk,
                     59:                                            int inc)
                     60: {
                     61:     FdMigrationState *s;
                     62: 
                     63:     s = qemu_mallocz(sizeof(*s));
                     64: 
                     65:     s->fd = monitor_get_fd(mon, fdname);
                     66:     if (s->fd == -1) {
                     67:         dprintf("fd_migration: invalid file descriptor identifier\n");
                     68:         goto err_after_alloc;
                     69:     }
                     70: 
                     71:     if (fcntl(s->fd, F_SETFL, O_NONBLOCK) == -1) {
                     72:         dprintf("Unable to set nonblocking mode on file descriptor\n");
                     73:         goto err_after_open;
                     74:     }
                     75: 
                     76:     s->get_error = fd_errno;
                     77:     s->write = fd_write;
                     78:     s->close = fd_close;
                     79:     s->mig_state.cancel = migrate_fd_cancel;
                     80:     s->mig_state.get_status = migrate_fd_get_status;
                     81:     s->mig_state.release = migrate_fd_release;
                     82: 
                     83:     s->mig_state.blk = blk;
                     84:     s->mig_state.shared = inc;
                     85: 
                     86:     s->state = MIG_STATE_ACTIVE;
                     87:     s->mon = NULL;
                     88:     s->bandwidth_limit = bandwidth_limit;
                     89: 
                     90:     if (!detach) {
                     91:         migrate_fd_monitor_suspend(s, mon);
                     92:     }
                     93: 
                     94:     migrate_fd_connect(s);
                     95:     return &s->mig_state;
                     96: 
                     97: err_after_open:
                     98:     close(s->fd);
                     99: err_after_alloc:
                    100:     qemu_free(s);
                    101:     return NULL;
                    102: }
                    103: 
                    104: static void fd_accept_incoming_migration(void *opaque)
                    105: {
                    106:     QEMUFile *f = opaque;
                    107:     int ret;
                    108: 
                    109:     ret = qemu_loadvm_state(f);
                    110:     if (ret < 0) {
                    111:         fprintf(stderr, "load of migration failed\n");
                    112:         goto err;
                    113:     }
                    114:     qemu_announce_self();
                    115:     dprintf("successfully loaded vm state\n");
                    116:     /* we've successfully migrated, close the fd */
                    117:     qemu_set_fd_handler2(qemu_stdio_fd(f), NULL, NULL, NULL, NULL);
                    118:     if (autostart)
                    119:         vm_start();
                    120: 
                    121: err:
                    122:     qemu_fclose(f);
                    123: }
                    124: 
                    125: int fd_start_incoming_migration(const char *infd)
                    126: {
                    127:     int fd;
                    128:     QEMUFile *f;
                    129: 
                    130:     dprintf("Attempting to start an incoming migration via fd\n");
                    131: 
                    132:     fd = strtol(infd, NULL, 0);
                    133:     f = qemu_fdopen(fd, "rb");
                    134:     if(f == NULL) {
                    135:         dprintf("Unable to apply qemu wrapper to file descriptor\n");
                    136:         return -errno;
                    137:     }
                    138: 
                    139:     qemu_set_fd_handler2(fd, NULL, fd_accept_incoming_migration, NULL,
                    140:                         (void *)(unsigned long)f);
                    141: 
                    142:     return 0;
                    143: }

unix.superglobalmegacorp.com