| 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 "qemu/cutils.h" |
| 15 | #include "channel.h" |
| 16 | #include "exec.h" |
| 17 | #include "fd.h" |
| 18 | #include "file.h" |
| 19 | #include "io/channel-socket.h" |
| 20 | #include "io/channel-tls.h" |
| 21 | #include "migration.h" |
| 22 | #include "multifd.h" |
| 23 | #include "options.h" |
| 24 | #include "qapi/clone-visitor.h" |
| 25 | #include "qapi/qapi-types-migration.h" |
| 26 | #include "qapi/qapi-visit-migration.h" |
| 27 | #include "qapi/error.h" |
| 28 | #include "qemu-file.h" |
| 29 | #include "qemu/yank.h" |
| 30 | #include "rdma.h" |
| 31 | #include "savevm.h" |
| 32 | #include "socket.h" |
| 33 | #include "tls.h" |
| 34 | #include "trace.h" |
| 35 | #include "yank_functions.h" |
| 36 | |
| 37 | void migration_connect_outgoing(MigrationState *s, MigrationAddress *addr, |
| 38 | Error **errp) |
| 39 | { |
| 40 | g_autoptr(QIOChannel) ioc = NULL; |
| 41 | |
| 42 | if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) { |
| 43 | SocketAddress *saddr = &addr->u.socket; |
| 44 | if (saddr->type == SOCKET_ADDRESS_TYPE_INET || |
| 45 | saddr->type == SOCKET_ADDRESS_TYPE_UNIX || |
| 46 | saddr->type == SOCKET_ADDRESS_TYPE_VSOCK) { |
| 47 | socket_connect_outgoing(s, saddr, errp); |
| 48 | /* |
| 49 | * async: after the socket is connected, calls |
| 50 | * migration_channel_connect_outgoing() directly. |
| 51 | */ |
| 52 | return; |
| 53 | |
| 54 | } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) { |
| 55 | ioc = fd_connect_outgoing(s, saddr->u.fd.str, errp); |
| 56 | } |
| 57 | #ifdef CONFIG_RDMA |
| 58 | } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) { |
| 59 | ioc = rdma_connect_outgoing(s, &addr->u.rdma, errp); |
| 60 | #endif |
| 61 | } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) { |
| 62 | ioc = exec_connect_outgoing(s, addr->u.exec.args, errp); |
| 63 | } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) { |
| 64 | ioc = file_connect_outgoing(s, &addr->u.file, errp); |
| 65 | } else { |
| 66 | error_setg(errp, "uri is not a valid migration protocol"); |
| 67 | } |
| 68 | |
| 69 | if (ioc) { |
| 70 | migration_channel_connect_outgoing(s, ioc); |
| 71 | } |
| 72 | |
| 73 | return; |
| 74 | } |
| 75 | |
| 76 | void migration_connect_incoming(MigrationAddress *addr, Error **errp) |
| 77 | { |
| 78 | if (addr->transport == MIGRATION_ADDRESS_TYPE_SOCKET) { |
| 79 | SocketAddress *saddr = &addr->u.socket; |
| 80 | if (saddr->type == SOCKET_ADDRESS_TYPE_INET || |
| 81 | saddr->type == SOCKET_ADDRESS_TYPE_UNIX || |
| 82 | saddr->type == SOCKET_ADDRESS_TYPE_VSOCK) { |
| 83 | socket_connect_incoming(saddr, errp); |
| 84 | } else if (saddr->type == SOCKET_ADDRESS_TYPE_FD) { |
| 85 | fd_connect_incoming(saddr->u.fd.str, errp); |
| 86 | } |
| 87 | #ifdef CONFIG_RDMA |
| 88 | } else if (addr->transport == MIGRATION_ADDRESS_TYPE_RDMA) { |
| 89 | rdma_connect_incoming(&addr->u.rdma, errp); |
| 90 | #endif |
| 91 | } else if (addr->transport == MIGRATION_ADDRESS_TYPE_EXEC) { |
| 92 | exec_connect_incoming(addr->u.exec.args, errp); |
| 93 | } else if (addr->transport == MIGRATION_ADDRESS_TYPE_FILE) { |
| 94 | file_connect_incoming(&addr->u.file, errp); |
| 95 | } else { |
| 96 | error_setg(errp, "unknown migration protocol"); |
| 97 | } |
| 98 | |
| 99 | /* |
| 100 | * async: the above routines all wait for the incoming connection |
| 101 | * and call back to migration_channel_process_incoming() to start |
| 102 | * the migration. |
| 103 | */ |
| 104 | } |
| 105 | |
| 106 | bool migration_has_main_and_multifd_channels(void) |
| 107 | { |
| 108 | MigrationIncomingState *mis = migration_incoming_get_current(); |
| 109 | if (!mis->from_src_file) { |
| 110 | /* main channel not established */ |
| 111 | return false; |
| 112 | } |
| 113 | |
| 114 | if (migrate_multifd() && !multifd_recv_all_channels_created()) { |
| 115 | return false; |
| 116 | } |
| 117 | |
| 118 | /* main and all multifd channels are established */ |
| 119 | return true; |
| 120 | } |
| 121 | |
| 122 | /** |
| 123 | * @migration_has_all_channels: We have received all channels that we need |
| 124 | * |
| 125 | * Returns true when we have got connections to all the channels that |
| 126 | * we need for migration. |
| 127 | */ |
| 128 | bool migration_has_all_channels(void) |
| 129 | { |
| 130 | if (!migration_has_main_and_multifd_channels()) { |
| 131 | return false; |
| 132 | } |
| 133 | |
| 134 | MigrationIncomingState *mis = migration_incoming_get_current(); |
| 135 | if (migrate_postcopy_preempt() && !mis->postcopy_qemufile_dst) { |
| 136 | return false; |
| 137 | } |
| 138 | |
| 139 | return true; |
| 140 | } |
| 141 | |
| 142 | static MigChannelType migration_channel_identify(MigrationIncomingState *mis, |
| 143 | QIOChannel *ioc, Error **errp) |
| 144 | { |
| 145 | MigChannelType channel = CH_NONE; |
| 146 | uint32_t channel_magic = 0; |
| 147 | int ret = 0; |
| 148 | |
| 149 | if (!migration_has_main_and_multifd_channels()) { |
| 150 | if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_READ_MSG_PEEK)) { |
| 151 | /* |
| 152 | * With multiple channels, it is possible that we receive channels |
| 153 | * out of order on destination side, causing incorrect mapping of |
| 154 | * source channels on destination side. Check channel MAGIC to |
| 155 | * decide type of channel. Please note this is best effort, |
| 156 | * postcopy preempt channel does not send any magic number so |
| 157 | * avoid it for postcopy live migration. Also tls live migration |
| 158 | * already does tls handshake while initializing main channel so |
| 159 | * with tls this issue is not possible. |
| 160 | */ |
| 161 | ret = migration_channel_read_peek(ioc, (void *)&channel_magic, |
| 162 | sizeof(channel_magic), errp); |
| 163 | if (ret != 0) { |
| 164 | goto out; |
| 165 | } |
| 166 | |
| 167 | channel_magic = be32_to_cpu(channel_magic); |
| 168 | if (channel_magic == QEMU_VM_FILE_MAGIC) { |
| 169 | channel = CH_MAIN; |
| 170 | } else if (channel_magic == MULTIFD_MAGIC) { |
| 171 | assert(migrate_multifd()); |
| 172 | channel = CH_MULTIFD; |
| 173 | } else if (!mis->from_src_file && |
| 174 | mis->state == MIGRATION_STATUS_POSTCOPY_PAUSED) { |
| 175 | /* reconnect main channel for postcopy recovery */ |
| 176 | channel = CH_MAIN; |
| 177 | } else { |
| 178 | error_setg(errp, "unknown channel magic: %u", channel_magic); |
| 179 | } |
| 180 | } else if (mis->from_src_file && migrate_multifd()) { |
| 181 | /* |
| 182 | * Non-peekable channels like tls/file are processed as |
| 183 | * multifd channels when multifd is enabled. |
| 184 | */ |
| 185 | channel = CH_MULTIFD; |
| 186 | } else if (!mis->from_src_file) { |
| 187 | channel = CH_MAIN; |
| 188 | } else { |
| 189 | error_setg(errp, "non-peekable channel used without multifd"); |
| 190 | } |
| 191 | } else { |
| 192 | assert(migrate_postcopy_preempt()); |
| 193 | channel = CH_POSTCOPY; |
| 194 | } |
| 195 | |
| 196 | out: |
| 197 | return channel; |
| 198 | } |
| 199 | |
| 200 | /** |
| 201 | * @migration_channel_process_incoming - Create new incoming migration channel |
| 202 | * |
| 203 | * Notice that TLS is special. For it we listen in a listener socket, |
| 204 | * and then create a new client socket from the TLS library. |
| 205 | * |
| 206 | * @ioc: Channel to which we are connecting |
| 207 | */ |
| 208 | void migration_channel_process_incoming(QIOChannel *ioc) |
| 209 | { |
| 210 | MigrationIncomingState *mis = migration_incoming_get_current(); |
| 211 | Error *local_err = NULL; |
| 212 | MigChannelType ch; |
| 213 | |
| 214 | trace_migration_set_incoming_channel( |
| 215 | ioc, object_get_typename(OBJECT(ioc))); |
| 216 | |
| 217 | if (migrate_channel_requires_tls_upgrade(ioc)) { |
| 218 | migration_tls_channel_process_incoming(ioc, &local_err); |
| 219 | } else { |
| 220 | migration_ioc_register_yank(ioc); |
| 221 | ch = migration_channel_identify(mis, ioc, &local_err); |
| 222 | if (!ch) { |
| 223 | goto out; |
| 224 | } |
| 225 | |
| 226 | if (migration_incoming_setup(ioc, ch, &local_err)) { |
| 227 | migration_start_incoming(); |
| 228 | } |
| 229 | } |
| 230 | out: |
| 231 | if (local_err) { |
| 232 | error_report_err(local_err); |
| 233 | migrate_set_state(&mis->state, mis->state, MIGRATION_STATUS_FAILED); |
| 234 | if (mis->exit_on_error) { |
| 235 | exit(EXIT_FAILURE); |
| 236 | } |
| 237 | } |
| 238 | } |
| 239 | |
| 240 | void migration_channel_connect_outgoing(MigrationState *s, QIOChannel *ioc) |
| 241 | { |
| 242 | trace_migration_set_outgoing_channel(ioc, object_get_typename(OBJECT(ioc))); |
| 243 | |
| 244 | if (migrate_channel_requires_tls_upgrade(ioc)) { |
| 245 | Error *local_err = NULL; |
| 246 | |
| 247 | migration_tls_channel_connect(s, ioc, &local_err); |
| 248 | if (local_err) { |
| 249 | migration_connect_error_propagate(s, local_err); |
| 250 | } |
| 251 | |
| 252 | /* |
| 253 | * async: the above will call back to this function after |
| 254 | * the TLS handshake is successfully completed. |
| 255 | */ |
| 256 | return; |
| 257 | } |
| 258 | |
| 259 | migration_ioc_register_yank(ioc); |
| 260 | migration_outgoing_setup(ioc); |
| 261 | migration_start_outgoing(s); |
| 262 | } |
| 263 | |
| 264 | |
| 265 | /** |
| 266 | * @migration_channel_read_peek - Peek at migration channel, without |
| 267 | * actually removing it from channel buffer. |
| 268 | * |
| 269 | * @ioc: the channel object |
| 270 | * @buf: the memory region to read data into |
| 271 | * @buflen: the number of bytes to read in @buf |
| 272 | * @errp: pointer to a NULL-initialized error object |
| 273 | * |
| 274 | * Returns 0 if successful, returns -1 and sets @errp if fails. |
| 275 | */ |
| 276 | int migration_channel_read_peek(QIOChannel *ioc, |
| 277 | const char *buf, |
| 278 | const size_t buflen, |
| 279 | Error **errp) |
| 280 | { |
| 281 | ssize_t len = 0; |
| 282 | struct iovec iov = { .iov_base = (char *)buf, .iov_len = buflen }; |
| 283 | |
| 284 | while (true) { |
| 285 | len = qio_channel_readv_full(ioc, &iov, 1, NULL, NULL, |
| 286 | QIO_CHANNEL_READ_FLAG_MSG_PEEK, errp); |
| 287 | |
| 288 | if (len < 0 && len != QIO_CHANNEL_ERR_BLOCK) { |
| 289 | return -1; |
| 290 | } |
| 291 | |
| 292 | if (len == 0) { |
| 293 | error_setg(errp, "Failed to peek at channel"); |
| 294 | return -1; |
| 295 | } |
| 296 | |
| 297 | if (len == buflen) { |
| 298 | break; |
| 299 | } else if (len == QIO_CHANNEL_ERR_BLOCK) { |
| 300 | qio_channel_wait_cond(ioc, G_IO_IN); |
| 301 | } else { |
| 302 | /* |
| 303 | * When partially ready, we can't use qio_channel_wait_cond() |
| 304 | * because it will return immediately. Apply a manual wait. |
| 305 | */ |
| 306 | assert(!qemu_in_coroutine()); |
| 307 | g_usleep(1000); |
| 308 | } |
| 309 | } |
| 310 | |
| 311 | return 0; |
| 312 | } |
| 313 | |
| 314 | static bool migrate_channels_parse(MigrationChannelList *channels, |
| 315 | MigrationChannel **main_channelp, |
| 316 | MigrationChannel **cpr_channelp, |
| 317 | Error **errp) |
| 318 | { |
| 319 | MigrationChannel *channelv[MIGRATION_CHANNEL_TYPE__MAX] = { NULL }; |
| 320 | |
| 321 | if (!cpr_channelp && channels->next) { |
| 322 | error_setg(errp, "Channel list must have only one entry, " |
| 323 | "for type 'main'"); |
| 324 | return false; |
| 325 | } |
| 326 | |
| 327 | for ( ; channels; channels = channels->next) { |
| 328 | MigrationChannelType type; |
| 329 | |
| 330 | type = channels->value->channel_type; |
| 331 | if (channelv[type]) { |
| 332 | error_setg(errp, "Channel list has more than one %s entry", |
| 333 | MigrationChannelType_str(type)); |
| 334 | return false; |
| 335 | } |
| 336 | channelv[type] = channels->value; |
| 337 | } |
| 338 | |
| 339 | if (cpr_channelp) { |
| 340 | *cpr_channelp = QAPI_CLONE(MigrationChannel, |
| 341 | channelv[MIGRATION_CHANNEL_TYPE_CPR]); |
| 342 | |
| 343 | if (migrate_mode() == MIG_MODE_CPR_TRANSFER && !*cpr_channelp) { |
| 344 | error_setg(errp, "missing 'cpr' migration channel"); |
| 345 | return false; |
| 346 | } |
| 347 | } |
| 348 | |
| 349 | *main_channelp = QAPI_CLONE(MigrationChannel, |
| 350 | channelv[MIGRATION_CHANNEL_TYPE_MAIN]); |
| 351 | |
| 352 | if (!(*main_channelp)->addr) { |
| 353 | error_setg(errp, "Channel list has no main entry"); |
| 354 | return false; |
| 355 | } |
| 356 | |
| 357 | return true; |
| 358 | } |
| 359 | |
| 360 | bool migrate_uri_parse(const char *uri, MigrationChannel **channel, |
| 361 | Error **errp) |
| 362 | { |
| 363 | g_autoptr(MigrationChannel) val = g_new0(MigrationChannel, 1); |
| 364 | g_autoptr(MigrationAddress) addr = g_new0(MigrationAddress, 1); |
| 365 | InetSocketAddress *isock = &addr->u.rdma; |
| 366 | strList **tail = &addr->u.exec.args; |
| 367 | |
| 368 | if (strstart(uri, "exec:", NULL)) { |
| 369 | addr->transport = MIGRATION_ADDRESS_TYPE_EXEC; |
| 370 | #ifdef WIN32 |
| 371 | QAPI_LIST_APPEND(tail, g_strdup(exec_get_cmd_path())); |
| 372 | QAPI_LIST_APPEND(tail, g_strdup("/c")); |
| 373 | #else |
| 374 | QAPI_LIST_APPEND(tail, g_strdup("/bin/sh")); |
| 375 | QAPI_LIST_APPEND(tail, g_strdup("-c")); |
| 376 | #endif |
| 377 | QAPI_LIST_APPEND(tail, g_strdup(uri + strlen("exec:"))); |
| 378 | } else if (strstart(uri, "rdma:", NULL)) { |
| 379 | if (inet_parse(isock, uri + strlen("rdma:"), errp)) { |
| 380 | qapi_free_InetSocketAddress(isock); |
| 381 | return false; |
| 382 | } |
| 383 | addr->transport = MIGRATION_ADDRESS_TYPE_RDMA; |
| 384 | } else if (strstart(uri, "tcp:", NULL) || |
| 385 | strstart(uri, "unix:", NULL) || |
| 386 | strstart(uri, "vsock:", NULL) || |
| 387 | strstart(uri, "fd:", NULL)) { |
| 388 | addr->transport = MIGRATION_ADDRESS_TYPE_SOCKET; |
| 389 | SocketAddress *saddr = socket_parse(uri, errp); |
| 390 | if (!saddr) { |
| 391 | return false; |
| 392 | } |
| 393 | addr->u.socket.type = saddr->type; |
| 394 | addr->u.socket.u = saddr->u; |
| 395 | /* Don't free the objects inside; their ownership moved to "addr" */ |
| 396 | g_free(saddr); |
| 397 | } else if (strstart(uri, "file:", NULL)) { |
| 398 | addr->transport = MIGRATION_ADDRESS_TYPE_FILE; |
| 399 | addr->u.file.filename = g_strdup(uri + strlen("file:")); |
| 400 | if (file_parse_offset(addr->u.file.filename, &addr->u.file.offset, |
| 401 | errp)) { |
| 402 | return false; |
| 403 | } |
| 404 | } else { |
| 405 | error_setg(errp, "unknown migration protocol: %s", uri); |
| 406 | return false; |
| 407 | } |
| 408 | |
| 409 | val->channel_type = MIGRATION_CHANNEL_TYPE_MAIN; |
| 410 | val->addr = g_steal_pointer(&addr); |
| 411 | *channel = g_steal_pointer(&val); |
| 412 | return true; |
| 413 | } |
| 414 | |
| 415 | bool migration_channel_parse_input(const char *uri, |
| 416 | MigrationChannelList *channels, |
| 417 | MigrationChannel **main_channelp, |
| 418 | MigrationChannel **cpr_channelp, |
| 419 | Error **errp) |
| 420 | { |
| 421 | if (!uri == !channels) { |
| 422 | error_setg(errp, "need either 'uri' or 'channels' argument"); |
| 423 | return false; |
| 424 | } |
| 425 | |
| 426 | if (channels) { |
| 427 | return migrate_channels_parse(channels, main_channelp, cpr_channelp, |
| 428 | errp); |
| 429 | } else { |
| 430 | return migrate_uri_parse(uri, main_channelp, errp); |
| 431 | } |
| 432 | } |