1 /* 2 * QEMU live migration channel operations 3 * 4 * Copyright Red Hat, Inc. 2016 5 * 6 * Authors: 7 * Daniel P. Berrange <berrange@redhat.com> 8 * 9 * Contributions after 2012-01-13 are licensed under the terms of the 10 * GNU GPL, version 2 or (at your option) any later version. 11 */ 12 13 #include "qemu/osdep.h" 14 #include "channel.h" 15 #include "tls.h" 16 #include "migration.h" 17 #include "qemu-file.h" 18 #include "trace.h" 19 #include "qapi/error.h" 20 #include "io/channel-tls.h" 21 #include "io/channel-socket.h" 22 #include "qemu/yank.h" 23 #include "yank_functions.h" 24 25 /** 26 * @migration_channel_process_incoming - Create new incoming migration channel 27 * 28 * Notice that TLS is special. For it we listen in a listener socket, 29 * and then create a new client socket from the TLS library. 30 * 31 * @ioc: Channel to which we are connecting 32 */ 33 void migration_channel_process_incoming(QIOChannel *ioc) 34 { 35 MigrationState *s = migrate_get_current(); 36 MigrationIncomingState *mis = migration_incoming_get_current(); 37 Error *local_err = NULL; 38 39 trace_migration_set_incoming_channel( 40 ioc, object_get_typename(OBJECT(ioc))); 41 42 if (migrate_channel_requires_tls_upgrade(ioc)) { 43 migration_tls_channel_process_incoming(s, ioc, &local_err); 44 } else { 45 migration_ioc_register_yank(ioc); 46 migration_ioc_process_incoming(ioc, &local_err); 47 } 48 49 if (local_err) { 50 error_report_err(local_err); 51 migrate_set_state(&s->state, s->state, MIGRATION_STATUS_FAILED); 52 if (mis->exit_on_error) { 53 exit(EXIT_FAILURE); 54 } 55 } 56 } 57 58 59 /** 60 * @migration_channel_connect - Create new outgoing migration channel 61 * 62 * @s: Current migration state 63 * @ioc: Channel to which we are connecting 64 * @hostname: Where we want to connect 65 * @error: Error indicating failure to connect, free'd here 66 */ 67 void migration_channel_connect(MigrationState *s, 68 QIOChannel *ioc, 69 const char *hostname, 70 Error *error) 71 { 72 trace_migration_set_outgoing_channel( 73 ioc, object_get_typename(OBJECT(ioc)), hostname, error); 74 75 if (!error) { 76 if (migrate_channel_requires_tls_upgrade(ioc)) { 77 migration_tls_channel_connect(s, ioc, hostname, &error); 78 79 if (!error) { 80 /* tls_channel_connect will call back to this 81 * function after the TLS handshake, 82 * so we mustn't call migration_connect until then 83 */ 84 85 return; 86 } 87 } else { 88 QEMUFile *f = qemu_file_new_output(ioc); 89 90 migration_ioc_register_yank(ioc); 91 92 qemu_mutex_lock(&s->qemu_file_lock); 93 s->to_dst_file = f; 94 qemu_mutex_unlock(&s->qemu_file_lock); 95 } 96 } 97 migration_connect(s, error); 98 error_free(error); 99 } 100 101 102 /** 103 * @migration_channel_read_peek - Peek at migration channel, without 104 * actually removing it from channel buffer. 105 * 106 * @ioc: the channel object 107 * @buf: the memory region to read data into 108 * @buflen: the number of bytes to read in @buf 109 * @errp: pointer to a NULL-initialized error object 110 * 111 * Returns 0 if successful, returns -1 and sets @errp if fails. 112 */ 113 int migration_channel_read_peek(QIOChannel *ioc, 114 const char *buf, 115 const size_t buflen, 116 Error **errp) 117 { 118 ssize_t len = 0; 119 struct iovec iov = { .iov_base = (char *)buf, .iov_len = buflen }; 120 121 while (true) { 122 len = qio_channel_readv_full(ioc, &iov, 1, NULL, NULL, 123 QIO_CHANNEL_READ_FLAG_MSG_PEEK, errp); 124 125 if (len < 0 && len != QIO_CHANNEL_ERR_BLOCK) { 126 return -1; 127 } 128 129 if (len == 0) { 130 error_setg(errp, "Failed to peek at channel"); 131 return -1; 132 } 133 134 if (len == buflen) { 135 break; 136 } 137 138 /* 1ms sleep. */ 139 if (qemu_in_coroutine()) { 140 qemu_co_sleep_ns(QEMU_CLOCK_REALTIME, 1000000); 141 } else { 142 g_usleep(1000); 143 } 144 } 145 146 return 0; 147 } 148