migration-tcp.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. /*
  2. * QEMU live migration
  3. *
  4. * Copyright IBM, Corp. 2008
  5. *
  6. * Authors:
  7. * Anthony Liguori <aliguori@us.ibm.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. #include "qemu-common.h"
  14. #include "qemu_socket.h"
  15. #include "migration.h"
  16. #include "qemu-char.h"
  17. #include "sysemu.h"
  18. #include "console.h"
  19. #include "buffered_file.h"
  20. #include "block.h"
  21. //#define DEBUG_MIGRATION_TCP
  22. #ifdef DEBUG_MIGRATION_TCP
  23. #define dprintf(fmt, ...) \
  24. do { printf("migration-tcp: " fmt, ## __VA_ARGS__); } while (0)
  25. #else
  26. #define dprintf(fmt, ...) \
  27. do { } while (0)
  28. #endif
  29. static int socket_errno(FdMigrationState *s)
  30. {
  31. return socket_error();
  32. }
  33. static int socket_write(FdMigrationState *s, const void * buf, size_t size)
  34. {
  35. return send(s->fd, buf, size, 0);
  36. }
  37. static int tcp_close(FdMigrationState *s)
  38. {
  39. dprintf("tcp_close\n");
  40. if (s->fd != -1) {
  41. close(s->fd);
  42. s->fd = -1;
  43. }
  44. return 0;
  45. }
  46. static void tcp_wait_for_connect(void *opaque)
  47. {
  48. FdMigrationState *s = opaque;
  49. int val, ret;
  50. socklen_t valsize = sizeof(val);
  51. dprintf("connect completed\n");
  52. do {
  53. ret = getsockopt(s->fd, SOL_SOCKET, SO_ERROR, &val, &valsize);
  54. } while (ret == -1 && (s->get_error(s)) == EINTR);
  55. if (ret < 0) {
  56. migrate_fd_error(s);
  57. return;
  58. }
  59. qemu_set_fd_handler2(s->fd, NULL, NULL, NULL, NULL);
  60. if (val == 0)
  61. migrate_fd_connect(s);
  62. else {
  63. dprintf("error connecting %d\n", val);
  64. migrate_fd_error(s);
  65. }
  66. }
  67. MigrationState *tcp_start_outgoing_migration(const char *host_port,
  68. int64_t bandwidth_limit,
  69. int async)
  70. {
  71. struct sockaddr_in addr;
  72. FdMigrationState *s;
  73. int ret;
  74. if (parse_host_port(&addr, host_port) < 0)
  75. return NULL;
  76. s = qemu_mallocz(sizeof(*s));
  77. s->get_error = socket_errno;
  78. s->write = socket_write;
  79. s->close = tcp_close;
  80. s->mig_state.cancel = migrate_fd_cancel;
  81. s->mig_state.get_status = migrate_fd_get_status;
  82. s->mig_state.release = migrate_fd_release;
  83. s->state = MIG_STATE_ACTIVE;
  84. s->detach = !async;
  85. s->bandwidth_limit = bandwidth_limit;
  86. s->fd = socket(PF_INET, SOCK_STREAM, 0);
  87. if (s->fd == -1) {
  88. qemu_free(s);
  89. return NULL;
  90. }
  91. socket_set_nonblock(s->fd);
  92. if (s->detach == 1) {
  93. dprintf("detaching from monitor\n");
  94. monitor_suspend();
  95. s->detach = 2;
  96. }
  97. do {
  98. ret = connect(s->fd, (struct sockaddr *)&addr, sizeof(addr));
  99. if (ret == -1)
  100. ret = -(s->get_error(s));
  101. if (ret == -EINPROGRESS || ret == -EWOULDBLOCK)
  102. qemu_set_fd_handler2(s->fd, NULL, NULL, tcp_wait_for_connect, s);
  103. } while (ret == -EINTR);
  104. if (ret < 0 && ret != -EINPROGRESS && ret != -EWOULDBLOCK) {
  105. dprintf("connect failed\n");
  106. close(s->fd);
  107. qemu_free(s);
  108. return NULL;
  109. } else if (ret >= 0)
  110. migrate_fd_connect(s);
  111. return &s->mig_state;
  112. }
  113. static void tcp_accept_incoming_migration(void *opaque)
  114. {
  115. struct sockaddr_in addr;
  116. socklen_t addrlen = sizeof(addr);
  117. int s = (unsigned long)opaque;
  118. QEMUFile *f;
  119. int c, ret;
  120. do {
  121. c = accept(s, (struct sockaddr *)&addr, &addrlen);
  122. } while (c == -1 && socket_error() == EINTR);
  123. dprintf("accepted migration\n");
  124. if (c == -1) {
  125. fprintf(stderr, "could not accept migration connection\n");
  126. return;
  127. }
  128. f = qemu_fopen_socket(c);
  129. if (f == NULL) {
  130. fprintf(stderr, "could not qemu_fopen socket\n");
  131. goto out;
  132. }
  133. ret = qemu_loadvm_state(f);
  134. if (ret < 0) {
  135. fprintf(stderr, "load of migration failed\n");
  136. goto out_fopen;
  137. }
  138. qemu_announce_self();
  139. dprintf("successfully loaded vm state\n");
  140. /* we've successfully migrated, close the server socket */
  141. qemu_set_fd_handler2(s, NULL, NULL, NULL, NULL);
  142. close(s);
  143. if (autostart)
  144. vm_start();
  145. out_fopen:
  146. qemu_fclose(f);
  147. out:
  148. close(c);
  149. }
  150. int tcp_start_incoming_migration(const char *host_port)
  151. {
  152. struct sockaddr_in addr;
  153. int val;
  154. int s;
  155. if (parse_host_port(&addr, host_port) < 0) {
  156. fprintf(stderr, "invalid host/port combination: %s\n", host_port);
  157. return -EINVAL;
  158. }
  159. s = socket(PF_INET, SOCK_STREAM, 0);
  160. if (s == -1)
  161. return -socket_error();
  162. val = 1;
  163. setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char *)&val, sizeof(val));
  164. if (bind(s, (struct sockaddr *)&addr, sizeof(addr)) == -1)
  165. goto err;
  166. if (listen(s, 1) == -1)
  167. goto err;
  168. qemu_set_fd_handler2(s, NULL, tcp_accept_incoming_migration, NULL,
  169. (void *)(unsigned long)s);
  170. return 0;
  171. err:
  172. close(s);
  173. return -socket_error();
  174. }