socket.c 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /*
  2. * QEMU live migration via socket
  3. *
  4. * Copyright Red Hat, Inc. 2009-2016
  5. *
  6. * Authors:
  7. * Chris Lalancette <clalance@redhat.com>
  8. * Daniel P. Berrange <berrange@redhat.com>
  9. *
  10. * This work is licensed under the terms of the GNU GPL, version 2. See
  11. * the COPYING file in the top-level directory.
  12. *
  13. * Contributions after 2012-01-13 are licensed under the terms of the
  14. * GNU GPL, version 2 or (at your option) any later version.
  15. */
  16. #include "qemu/osdep.h"
  17. #include "qemu/cutils.h"
  18. #include "qemu/error-report.h"
  19. #include "qapi/error.h"
  20. #include "channel.h"
  21. #include "socket.h"
  22. #include "migration.h"
  23. #include "qemu-file.h"
  24. #include "io/channel-socket.h"
  25. #include "io/net-listener.h"
  26. #include "trace.h"
  27. #include "postcopy-ram.h"
  28. struct SocketOutgoingArgs {
  29. SocketAddress *saddr;
  30. } outgoing_args;
  31. void socket_send_channel_create(QIOTaskFunc f, void *data)
  32. {
  33. QIOChannelSocket *sioc = qio_channel_socket_new();
  34. qio_channel_socket_connect_async(sioc, outgoing_args.saddr,
  35. f, data, NULL, NULL);
  36. }
  37. QIOChannel *socket_send_channel_create_sync(Error **errp)
  38. {
  39. QIOChannelSocket *sioc = qio_channel_socket_new();
  40. if (!outgoing_args.saddr) {
  41. object_unref(OBJECT(sioc));
  42. error_setg(errp, "Initial sock address not set!");
  43. return NULL;
  44. }
  45. if (qio_channel_socket_connect_sync(sioc, outgoing_args.saddr, errp) < 0) {
  46. object_unref(OBJECT(sioc));
  47. return NULL;
  48. }
  49. return QIO_CHANNEL(sioc);
  50. }
  51. int socket_send_channel_destroy(QIOChannel *send)
  52. {
  53. /* Remove channel */
  54. object_unref(OBJECT(send));
  55. if (outgoing_args.saddr) {
  56. qapi_free_SocketAddress(outgoing_args.saddr);
  57. outgoing_args.saddr = NULL;
  58. }
  59. return 0;
  60. }
  61. struct SocketConnectData {
  62. MigrationState *s;
  63. char *hostname;
  64. };
  65. static void socket_connect_data_free(void *opaque)
  66. {
  67. struct SocketConnectData *data = opaque;
  68. if (!data) {
  69. return;
  70. }
  71. g_free(data->hostname);
  72. g_free(data);
  73. }
  74. static void socket_outgoing_migration(QIOTask *task,
  75. gpointer opaque)
  76. {
  77. struct SocketConnectData *data = opaque;
  78. QIOChannel *sioc = QIO_CHANNEL(qio_task_get_source(task));
  79. Error *err = NULL;
  80. if (qio_task_propagate_error(task, &err)) {
  81. trace_migration_socket_outgoing_error(error_get_pretty(err));
  82. goto out;
  83. }
  84. trace_migration_socket_outgoing_connected(data->hostname);
  85. if (migrate_use_zero_copy_send() &&
  86. !qio_channel_has_feature(sioc, QIO_CHANNEL_FEATURE_WRITE_ZERO_COPY)) {
  87. error_setg(&err, "Zero copy send feature not detected in host kernel");
  88. }
  89. out:
  90. migration_channel_connect(data->s, sioc, data->hostname, err);
  91. object_unref(OBJECT(sioc));
  92. }
  93. static void
  94. socket_start_outgoing_migration_internal(MigrationState *s,
  95. SocketAddress *saddr,
  96. Error **errp)
  97. {
  98. QIOChannelSocket *sioc = qio_channel_socket_new();
  99. struct SocketConnectData *data = g_new0(struct SocketConnectData, 1);
  100. data->s = s;
  101. /* in case previous migration leaked it */
  102. qapi_free_SocketAddress(outgoing_args.saddr);
  103. outgoing_args.saddr = saddr;
  104. if (saddr->type == SOCKET_ADDRESS_TYPE_INET) {
  105. data->hostname = g_strdup(saddr->u.inet.host);
  106. }
  107. qio_channel_set_name(QIO_CHANNEL(sioc), "migration-socket-outgoing");
  108. qio_channel_socket_connect_async(sioc,
  109. saddr,
  110. socket_outgoing_migration,
  111. data,
  112. socket_connect_data_free,
  113. NULL);
  114. }
  115. void socket_start_outgoing_migration(MigrationState *s,
  116. const char *str,
  117. Error **errp)
  118. {
  119. Error *err = NULL;
  120. SocketAddress *saddr = socket_parse(str, &err);
  121. if (!err) {
  122. socket_start_outgoing_migration_internal(s, saddr, &err);
  123. }
  124. error_propagate(errp, err);
  125. }
  126. static void socket_accept_incoming_migration(QIONetListener *listener,
  127. QIOChannelSocket *cioc,
  128. gpointer opaque)
  129. {
  130. trace_migration_socket_incoming_accepted();
  131. if (migration_has_all_channels()) {
  132. error_report("%s: Extra incoming migration connection; ignoring",
  133. __func__);
  134. return;
  135. }
  136. qio_channel_set_name(QIO_CHANNEL(cioc), "migration-socket-incoming");
  137. migration_channel_process_incoming(QIO_CHANNEL(cioc));
  138. }
  139. static void
  140. socket_incoming_migration_end(void *opaque)
  141. {
  142. QIONetListener *listener = opaque;
  143. qio_net_listener_disconnect(listener);
  144. object_unref(OBJECT(listener));
  145. }
  146. static void
  147. socket_start_incoming_migration_internal(SocketAddress *saddr,
  148. Error **errp)
  149. {
  150. QIONetListener *listener = qio_net_listener_new();
  151. MigrationIncomingState *mis = migration_incoming_get_current();
  152. size_t i;
  153. int num = 1;
  154. qio_net_listener_set_name(listener, "migration-socket-listener");
  155. if (migrate_use_multifd()) {
  156. num = migrate_multifd_channels();
  157. } else if (migrate_postcopy_preempt()) {
  158. num = RAM_CHANNEL_MAX;
  159. }
  160. if (qio_net_listener_open_sync(listener, saddr, num, errp) < 0) {
  161. object_unref(OBJECT(listener));
  162. return;
  163. }
  164. mis->transport_data = listener;
  165. mis->transport_cleanup = socket_incoming_migration_end;
  166. qio_net_listener_set_client_func_full(listener,
  167. socket_accept_incoming_migration,
  168. NULL, NULL,
  169. g_main_context_get_thread_default());
  170. for (i = 0; i < listener->nsioc; i++) {
  171. SocketAddress *address =
  172. qio_channel_socket_get_local_address(listener->sioc[i], errp);
  173. if (!address) {
  174. return;
  175. }
  176. migrate_add_address(address);
  177. qapi_free_SocketAddress(address);
  178. }
  179. }
  180. void socket_start_incoming_migration(const char *str, Error **errp)
  181. {
  182. Error *err = NULL;
  183. SocketAddress *saddr = socket_parse(str, &err);
  184. if (!err) {
  185. socket_start_incoming_migration_internal(saddr, &err);
  186. }
  187. qapi_free_SocketAddress(saddr);
  188. error_propagate(errp, err);
  189. }