static void unix_accept_incoming_migration(void *opaque) { struct sockaddr_un addr; socklen_t addrlen = sizeof(addr); int s = (intptr_t)opaque; QEMUFile *f; int c, err; do { c = qemu_accept(s, (struct sockaddr *)&addr, &addrlen); err = errno; } while (c < 0 && err == EINTR); qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); close(s); DPRINTF("accepted migration\n"); if (c < 0) { error_report("could not accept migration connection (%s)", strerror(err)); return; } f = qemu_fopen_socket(c, "rb"); if (f == NULL) { error_report("could not qemu_fopen socket"); goto out; } process_incoming_migration(f); return; out: close(c); }
static void tcp_accept_incoming_migration(void *opaque) { struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); int s = (unsigned long)opaque; QEMUFile *f; int c; do { c = qemu_accept(s, (struct sockaddr *)&addr, &addrlen); } while (c == -1 && socket_error() == EINTR); DPRINTF("accepted migration\n"); if (c == -1) { fprintf(stderr, "could not accept migration connection\n"); return; } f = qemu_fopen_socket(c); if (f == NULL) { fprintf(stderr, "could not qemu_fopen socket\n"); goto out; } process_incoming_migration(f); qemu_fclose(f); out: qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); close(s); close(c); }
static void unix_wait_for_connect(int fd, void *opaque) { MigrationState *s = opaque; if (fd < 0) { DPRINTF("migrate connect error\n"); s->file = NULL; migrate_fd_error(s); } else { DPRINTF("migrate connect success\n"); s->file = qemu_fopen_socket(fd, "wb"); migrate_fd_connect(s); } }
static void tcp_accept_incoming_migration(void *opaque) { struct sockaddr_in addr; socklen_t addrlen = sizeof(addr); int s = (unsigned long)opaque; QEMUFile *f; int c, ret; do { c = accept(s, (struct sockaddr *)&addr, &addrlen); } while (c == -1 && socket_error() == EINTR); dprintf("accepted migration\n"); if (c == -1) { fprintf(stderr, "could not accept migration connection\n"); return; } f = qemu_fopen_socket(c); if (f == NULL) { fprintf(stderr, "could not qemu_fopen socket\n"); goto out; } vm_stop(0); /* just in case */ ret = qemu_loadvm_state(f); if (ret < 0) { fprintf(stderr, "load of migration failed\n"); goto out_fopen; } qemu_announce_self(); dprintf("successfully loaded vm state\n"); /* we've successfully migrated, close the server socket */ qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); close(s); vm_start(); out_fopen: qemu_fclose(f); out: close(c); }
static void tcp_accept_incoming_migration(void *opaque) { SockAddress addr; int s = (unsigned long)opaque; QEMUFile *f; int c, ret; c = socket_accept(s, &addr); dprintf("accepted migration\n"); if (c == -1) { fprintf(stderr, "could not accept migration connection\n"); return; } f = qemu_fopen_socket(c); if (f == NULL) { fprintf(stderr, "could not qemu_fopen socket\n"); goto out; } vm_stop(0); /* just in case */ ret = qemu_loadvm_state(f); if (ret < 0) { fprintf(stderr, "load of migration failed\n"); goto out_fopen; } qemu_announce_self(); dprintf("successfully loaded vm state\n"); /* we've successfully migrated, close the server socket */ qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL); socket_close(s); vm_start(); out_fopen: qemu_fclose(f); out: socket_close(c); }
/* * Give a QEMUFile* off the same socket but data in the opposite * direction. */ static QEMUFile *socket_dup_return_path(void *opaque) { QEMUFileSocket *qfs = opaque; int revfd; bool this_is_read; QEMUFile *result; if (qemu_file_get_error(qfs->file)) { /* If the forward file is in error, don't try and open a return */ return NULL; } /* I don't think there's a better way to tell which direction 'this' is */ this_is_read = qfs->file->ops->get_buffer != NULL; revfd = dup(qfs->fd); if (revfd == -1) { error_report("Error duplicating fd for return path: %s", strerror(errno)); return NULL; } result = qemu_fopen_socket(revfd, this_is_read ? "wb" : "rb"); if (!result) { close(revfd); } if (this_is_read) { /* The qemu_fopen_socket "wb" will mark the socket blocking, * which would be OK for the return path, but the semantics * of non-blocking is that it follows the underlying connection * not the fd number, and thus setting the return path non-blocking * ends up setting the forward path blocking, which we don't want */ qemu_set_nonblock(revfd); } return result; }