MigrationState *tcp_start_outgoing_migration(const char *host_port, int64_t bandwidth_limit, int detach, int blk, int inc) { struct sockaddr_in addr; FdMigrationState *s; int ret; if (parse_host_port(&addr, host_port) < 0) return NULL; s = qemu_mallocz(sizeof(*s)); s->get_error = socket_errno; s->write = socket_write; s->close = tcp_close; s->mig_state.cancel = migrate_fd_cancel; s->mig_state.get_status = migrate_fd_get_status; s->mig_state.release = migrate_fd_release; s->mig_state.blk = blk; s->mig_state.shared = inc; s->state = MIG_STATE_ACTIVE; s->mon_resume = NULL; s->bandwidth_limit = bandwidth_limit; s->fd = socket(PF_INET, SOCK_STREAM, 0); if (s->fd == -1) { qemu_free(s); return NULL; } socket_set_nonblock(s->fd); if (!detach) migrate_fd_monitor_suspend(s); do { ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)); if (ret == -1) ret = -(s->get_error(s)); if (ret == -EINPROGRESS || ret == -EWOULDBLOCK) qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s); } while (ret == -EINTR); if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) { dprintf("connect failed\n"); close(s->fd); qemu_free(s); return NULL; } else if (ret >= 0) migrate_fd_connect(s); return &s->mig_state; }
MigrationState *exec_start_outgoing_migration(Monitor *mon, const char *command, int64_t bandwidth_limit, int detach, int blk, int inc) { FdMigrationState *s; FILE *f; s = qemu_mallocz(sizeof(*s)); f = popen(command, "w"); if (f == NULL) { dprintf("Unable to popen exec target\n"); goto err_after_alloc; } s->fd = fileno(f); if (s->fd == -1) { dprintf("Unable to retrieve file descriptor for popen'd handle\n"); goto err_after_open; } socket_set_nonblock(s->fd); s->opaque = qemu_popen(f, "w"); s->close = exec_close; s->get_error = file_errno; s->write = file_write; s->mig_state.cancel = migrate_fd_cancel; s->mig_state.get_status = migrate_fd_get_status; s->mig_state.release = migrate_fd_release; s->mig_state.blk = blk; s->mig_state.shared = inc; s->state = MIG_STATE_ACTIVE; s->mon = NULL; s->bandwidth_limit = bandwidth_limit; if (!detach) { migrate_fd_monitor_suspend(s, mon); } migrate_fd_connect(s); return &s->mig_state; err_after_open: pclose(f); err_after_alloc: qemu_free(s); return NULL; }
MigrationState *tcp_start_outgoing_migration(const char *host_port, int64_t bandwidth_limit, int detach) { SockAddress addr; FdMigrationState *s; int ret; if (parse_host_port(&addr, host_port) < 0) return NULL; s = g_malloc0(sizeof(*s)); s->get_error = socket_errno; s->write = socket_write; s->close = tcp_close; s->mig_state.cancel = migrate_fd_cancel; s->mig_state.get_status = migrate_fd_get_status; s->mig_state.release = migrate_fd_release; s->state = MIG_STATE_ACTIVE; s->mon_resume = NULL; s->bandwidth_limit = bandwidth_limit; s->fd = socket_create_inet(SOCKET_STREAM); if (s->fd == -1) { g_free(s); return NULL; } socket_set_nonblock(s->fd); if (!detach) migrate_fd_monitor_suspend(s); do { ret = socket_connect(s->fd, &addr); if (ret == -1) ret = -(s->get_error(s)); if (ret == -EINPROGRESS || ret == -EWOULDBLOCK || ret == -EAGAIN) qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s); } while (ret == -EINTR); if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK && ret != -EAGAIN) { dprintf("connect failed\n"); socket_close(s->fd); g_free(s); return NULL; } else if (ret >= 0) migrate_fd_connect(s); return &s->mig_state; }
MigrationState *exec_start_outgoing_migration(const char *command, int64_t bandwidth_limit, int detach) { FdMigrationState *s; FILE *f; s = qemu_mallocz(sizeof(*s)); f = popen(command, "w"); if (f == NULL) { dprintf("Unable to popen exec target\n"); goto err_after_alloc; } s->fd = fileno(f); if (s->fd == -1) { dprintf("Unable to retrieve file descriptor for popen'd handle\n"); goto err_after_open; } if (fcntl(s->fd, F_SETFD, O_NONBLOCK) == -1) { dprintf("Unable to set nonblocking mode on file descriptor\n"); goto err_after_open; } s->opaque = qemu_popen(f, "w"); s->close = exec_close; s->get_error = file_errno; s->write = file_write; s->mig_state.cancel = migrate_fd_cancel; s->mig_state.get_status = migrate_fd_get_status; s->mig_state.release = migrate_fd_release; s->state = MIG_STATE_ACTIVE; s->mon_resume = NULL; s->bandwidth_limit = bandwidth_limit; if (!detach) migrate_fd_monitor_suspend(s); migrate_fd_connect(s); return &s->mig_state; err_after_open: pclose(f); err_after_alloc: qemu_free(s); return NULL; }
MigrationState *fd_start_outgoing_migration(Monitor *mon, const char *fdname, int64_t bandwidth_limit, int detach, int blk, int inc) { FdMigrationState *s; s = qemu_mallocz(sizeof(*s)); s->fd = monitor_get_fd(mon, fdname); if (s->fd == -1) { DPRINTF("fd_migration: invalid file descriptor identifier\n"); goto err_after_alloc; } if (fcntl(s->fd, F_SETFL, O_NONBLOCK) == -1) { DPRINTF("Unable to set nonblocking mode on file descriptor\n"); goto err_after_open; } s->get_error = fd_errno; s->write = fd_write; s->close = fd_close; s->mig_state.cancel = migrate_fd_cancel; s->mig_state.get_status = migrate_fd_get_status; s->mig_state.release = migrate_fd_release; s->mig_state.blk = blk; s->mig_state.shared = inc; s->state = MIG_STATE_ACTIVE; s->mon = NULL; s->bandwidth_limit = bandwidth_limit; if (!detach) { migrate_fd_monitor_suspend(s, mon); } migrate_fd_connect(s); return &s->mig_state; err_after_open: close(s->fd); err_after_alloc: qemu_free(s); return NULL; }
MigrationState *tcp_start_outgoing_migration(Monitor *mon, const char *host_port, int64_t bandwidth_limit, int detach, int blk, int inc, Error **errp) { FdMigrationState *s; s = qemu_mallocz(sizeof(*s)); s->get_error = socket_errno; s->write = socket_write; s->close = tcp_close; s->mig_state.cancel = migrate_fd_cancel; s->mig_state.get_status = migrate_fd_get_status; s->mig_state.release = migrate_fd_release; s->mig_state.blk = blk; s->mig_state.shared = inc; s->state = MIG_STATE_ACTIVE; trace_migrate_set_state(MIG_STATE_ACTIVE); s->mon = NULL; s->bandwidth_limit = bandwidth_limit; if (!detach) { migrate_fd_monitor_suspend(s, mon); } s->fd = inet_nonblocking_connect(host_port, tcp_wait_for_connect, s, errp); if (error_is_set(errp)) { migrate_fd_error(s); qemu_free(s); return NULL; } return &s->mig_state; }
static MigrationState *migrate_init(Monitor *mon, int detach, int blk, int inc) { MigrationState *s = migrate_get_current(); int64_t bandwidth_limit = s->bandwidth_limit; memset(s, 0, sizeof(*s)); s->bandwidth_limit = bandwidth_limit; s->blk = blk; s->shared = inc; /* s->mon is used for two things: - pass fd in fd migration - suspend/resume monitor for not detached migration */ s->mon = mon; s->bandwidth_limit = bandwidth_limit; s->state = MIG_STATE_SETUP; if (!detach) { migrate_fd_monitor_suspend(s, mon); } return s; }
MigrationState *unix_start_outgoing_migration(Monitor *mon, const char *path, int64_t bandwidth_limit, int detach, int blk, int inc) { FdMigrationState *s; struct sockaddr_un addr; int ret; addr.sun_family = AF_UNIX; snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", path); s = g_malloc0(sizeof(*s)); s->get_error = unix_errno; s->write = unix_write; s->close = unix_close; s->mig_state.cancel = migrate_fd_cancel; s->mig_state.get_status = migrate_fd_get_status; s->mig_state.release = migrate_fd_release; s->mig_state.blk = blk; s->mig_state.shared = inc; s->state = MIG_STATE_ACTIVE; s->mon = NULL; s->bandwidth_limit = bandwidth_limit; s->fd = qemu_socket(PF_UNIX, SOCK_STREAM, 0); if (s->fd < 0) { DPRINTF("Unable to open socket"); goto err_after_alloc; } socket_set_nonblock(s->fd); do { ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr)); if (ret == -1) ret = -(s->get_error(s)); if (ret == -EINPROGRESS || ret == -EWOULDBLOCK) qemu_set_fd_handler2(s->fd, NULL, NULL, unix_wait_for_connect, s); } while (ret == -EINTR); if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) { DPRINTF("connect failed\n"); goto err_after_open; } if (!detach) { migrate_fd_monitor_suspend(s, mon); } if (ret >= 0) migrate_fd_connect(s); return &s->mig_state; err_after_open: close(s->fd); err_after_alloc: g_free(s); return NULL; }