1 /* 2 * QEMU I/O channels 3 * 4 * Copyright (c) 2015 Red Hat, Inc. 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 * 19 */ 20 21 #include "qemu/osdep.h" 22 #include "io/channel.h" 23 #include "qapi/error.h" 24 #include "qemu/main-loop.h" 25 #include "qemu/module.h" 26 #include "qemu/iov.h" 27 28 bool qio_channel_has_feature(QIOChannel *ioc, 29 QIOChannelFeature feature) 30 { 31 return ioc->features & (1 << feature); 32 } 33 34 35 void qio_channel_set_feature(QIOChannel *ioc, 36 QIOChannelFeature feature) 37 { 38 ioc->features |= (1 << feature); 39 } 40 41 42 void qio_channel_set_name(QIOChannel *ioc, 43 const char *name) 44 { 45 g_free(ioc->name); 46 ioc->name = g_strdup(name); 47 } 48 49 50 ssize_t qio_channel_readv_full(QIOChannel *ioc, 51 const struct iovec *iov, 52 size_t niov, 53 int **fds, 54 size_t *nfds, 55 Error **errp) 56 { 57 QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); 58 59 if ((fds || nfds) && 60 !qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS)) { 61 error_setg_errno(errp, EINVAL, 62 "Channel does not support file descriptor passing"); 63 return -1; 64 } 65 66 return klass->io_readv(ioc, iov, niov, fds, nfds, errp); 67 } 68 69 70 ssize_t qio_channel_writev_full(QIOChannel *ioc, 71 const struct iovec *iov, 72 size_t niov, 73 int *fds, 74 size_t nfds, 75 Error **errp) 76 { 77 QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); 78 79 if ((fds || nfds) && 80 !qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS)) { 81 error_setg_errno(errp, EINVAL, 82 "Channel does not support file descriptor passing"); 83 return -1; 84 } 85 86 return klass->io_writev(ioc, iov, niov, fds, nfds, errp); 87 } 88 89 90 int qio_channel_readv_all_eof(QIOChannel *ioc, 91 const struct iovec *iov, 92 size_t niov, 93 Error **errp) 94 { 95 int ret = -1; 96 struct iovec *local_iov = g_new(struct iovec, niov); 97 struct iovec *local_iov_head = local_iov; 98 unsigned int nlocal_iov = niov; 99 bool partial = false; 100 101 nlocal_iov = iov_copy(local_iov, nlocal_iov, 102 iov, niov, 103 0, iov_size(iov, niov)); 104 105 while (nlocal_iov > 0) { 106 ssize_t len; 107 len = qio_channel_readv(ioc, local_iov, nlocal_iov, errp); 108 if (len == QIO_CHANNEL_ERR_BLOCK) { 109 if (qemu_in_coroutine()) { 110 qio_channel_yield(ioc, G_IO_IN); 111 } else { 112 qio_channel_wait(ioc, G_IO_IN); 113 } 114 continue; 115 } else if (len < 0) { 116 goto cleanup; 117 } else if (len == 0) { 118 if (partial) { 119 error_setg(errp, 120 "Unexpected end-of-file before all bytes were read"); 121 } else { 122 ret = 0; 123 } 124 goto cleanup; 125 } 126 127 partial = true; 128 iov_discard_front(&local_iov, &nlocal_iov, len); 129 } 130 131 ret = 1; 132 133 cleanup: 134 g_free(local_iov_head); 135 return ret; 136 } 137 138 int qio_channel_readv_all(QIOChannel *ioc, 139 const struct iovec *iov, 140 size_t niov, 141 Error **errp) 142 { 143 int ret = qio_channel_readv_all_eof(ioc, iov, niov, errp); 144 145 if (ret == 0) { 146 ret = -1; 147 error_setg(errp, 148 "Unexpected end-of-file before all bytes were read"); 149 } else if (ret == 1) { 150 ret = 0; 151 } 152 return ret; 153 } 154 155 int qio_channel_writev_all(QIOChannel *ioc, 156 const struct iovec *iov, 157 size_t niov, 158 Error **errp) 159 { 160 int ret = -1; 161 struct iovec *local_iov = g_new(struct iovec, niov); 162 struct iovec *local_iov_head = local_iov; 163 unsigned int nlocal_iov = niov; 164 165 nlocal_iov = iov_copy(local_iov, nlocal_iov, 166 iov, niov, 167 0, iov_size(iov, niov)); 168 169 while (nlocal_iov > 0) { 170 ssize_t len; 171 len = qio_channel_writev(ioc, local_iov, nlocal_iov, errp); 172 if (len == QIO_CHANNEL_ERR_BLOCK) { 173 if (qemu_in_coroutine()) { 174 qio_channel_yield(ioc, G_IO_OUT); 175 } else { 176 qio_channel_wait(ioc, G_IO_OUT); 177 } 178 continue; 179 } 180 if (len < 0) { 181 goto cleanup; 182 } 183 184 iov_discard_front(&local_iov, &nlocal_iov, len); 185 } 186 187 ret = 0; 188 cleanup: 189 g_free(local_iov_head); 190 return ret; 191 } 192 193 ssize_t qio_channel_readv(QIOChannel *ioc, 194 const struct iovec *iov, 195 size_t niov, 196 Error **errp) 197 { 198 return qio_channel_readv_full(ioc, iov, niov, NULL, NULL, errp); 199 } 200 201 202 ssize_t qio_channel_writev(QIOChannel *ioc, 203 const struct iovec *iov, 204 size_t niov, 205 Error **errp) 206 { 207 return qio_channel_writev_full(ioc, iov, niov, NULL, 0, errp); 208 } 209 210 211 ssize_t qio_channel_read(QIOChannel *ioc, 212 char *buf, 213 size_t buflen, 214 Error **errp) 215 { 216 struct iovec iov = { .iov_base = buf, .iov_len = buflen }; 217 return qio_channel_readv_full(ioc, &iov, 1, NULL, NULL, errp); 218 } 219 220 221 ssize_t qio_channel_write(QIOChannel *ioc, 222 const char *buf, 223 size_t buflen, 224 Error **errp) 225 { 226 struct iovec iov = { .iov_base = (char *)buf, .iov_len = buflen }; 227 return qio_channel_writev_full(ioc, &iov, 1, NULL, 0, errp); 228 } 229 230 231 int qio_channel_read_all_eof(QIOChannel *ioc, 232 char *buf, 233 size_t buflen, 234 Error **errp) 235 { 236 struct iovec iov = { .iov_base = buf, .iov_len = buflen }; 237 return qio_channel_readv_all_eof(ioc, &iov, 1, errp); 238 } 239 240 241 int qio_channel_read_all(QIOChannel *ioc, 242 char *buf, 243 size_t buflen, 244 Error **errp) 245 { 246 struct iovec iov = { .iov_base = buf, .iov_len = buflen }; 247 return qio_channel_readv_all(ioc, &iov, 1, errp); 248 } 249 250 251 int qio_channel_write_all(QIOChannel *ioc, 252 const char *buf, 253 size_t buflen, 254 Error **errp) 255 { 256 struct iovec iov = { .iov_base = (char *)buf, .iov_len = buflen }; 257 return qio_channel_writev_all(ioc, &iov, 1, errp); 258 } 259 260 261 int qio_channel_set_blocking(QIOChannel *ioc, 262 bool enabled, 263 Error **errp) 264 { 265 QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); 266 return klass->io_set_blocking(ioc, enabled, errp); 267 } 268 269 270 int qio_channel_close(QIOChannel *ioc, 271 Error **errp) 272 { 273 QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); 274 return klass->io_close(ioc, errp); 275 } 276 277 278 GSource *qio_channel_create_watch(QIOChannel *ioc, 279 GIOCondition condition) 280 { 281 QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); 282 GSource *ret = klass->io_create_watch(ioc, condition); 283 284 if (ioc->name) { 285 g_source_set_name(ret, ioc->name); 286 } 287 288 return ret; 289 } 290 291 292 void qio_channel_set_aio_fd_handler(QIOChannel *ioc, 293 AioContext *ctx, 294 IOHandler *io_read, 295 IOHandler *io_write, 296 void *opaque) 297 { 298 QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); 299 300 klass->io_set_aio_fd_handler(ioc, ctx, io_read, io_write, opaque); 301 } 302 303 guint qio_channel_add_watch_full(QIOChannel *ioc, 304 GIOCondition condition, 305 QIOChannelFunc func, 306 gpointer user_data, 307 GDestroyNotify notify, 308 GMainContext *context) 309 { 310 GSource *source; 311 guint id; 312 313 source = qio_channel_create_watch(ioc, condition); 314 315 g_source_set_callback(source, (GSourceFunc)func, user_data, notify); 316 317 id = g_source_attach(source, context); 318 g_source_unref(source); 319 320 return id; 321 } 322 323 guint qio_channel_add_watch(QIOChannel *ioc, 324 GIOCondition condition, 325 QIOChannelFunc func, 326 gpointer user_data, 327 GDestroyNotify notify) 328 { 329 return qio_channel_add_watch_full(ioc, condition, func, 330 user_data, notify, NULL); 331 } 332 333 GSource *qio_channel_add_watch_source(QIOChannel *ioc, 334 GIOCondition condition, 335 QIOChannelFunc func, 336 gpointer user_data, 337 GDestroyNotify notify, 338 GMainContext *context) 339 { 340 GSource *source; 341 guint id; 342 343 id = qio_channel_add_watch_full(ioc, condition, func, 344 user_data, notify, context); 345 source = g_main_context_find_source_by_id(context, id); 346 g_source_ref(source); 347 return source; 348 } 349 350 351 int qio_channel_shutdown(QIOChannel *ioc, 352 QIOChannelShutdown how, 353 Error **errp) 354 { 355 QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); 356 357 if (!klass->io_shutdown) { 358 error_setg(errp, "Data path shutdown not supported"); 359 return -1; 360 } 361 362 return klass->io_shutdown(ioc, how, errp); 363 } 364 365 366 void qio_channel_set_delay(QIOChannel *ioc, 367 bool enabled) 368 { 369 QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); 370 371 if (klass->io_set_delay) { 372 klass->io_set_delay(ioc, enabled); 373 } 374 } 375 376 377 void qio_channel_set_cork(QIOChannel *ioc, 378 bool enabled) 379 { 380 QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); 381 382 if (klass->io_set_cork) { 383 klass->io_set_cork(ioc, enabled); 384 } 385 } 386 387 388 off_t qio_channel_io_seek(QIOChannel *ioc, 389 off_t offset, 390 int whence, 391 Error **errp) 392 { 393 QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); 394 395 if (!klass->io_seek) { 396 error_setg(errp, "Channel does not support random access"); 397 return -1; 398 } 399 400 return klass->io_seek(ioc, offset, whence, errp); 401 } 402 403 404 static void qio_channel_restart_read(void *opaque) 405 { 406 QIOChannel *ioc = opaque; 407 Coroutine *co = ioc->read_coroutine; 408 409 /* Assert that aio_co_wake() reenters the coroutine directly */ 410 assert(qemu_get_current_aio_context() == 411 qemu_coroutine_get_aio_context(co)); 412 aio_co_wake(co); 413 } 414 415 static void qio_channel_restart_write(void *opaque) 416 { 417 QIOChannel *ioc = opaque; 418 Coroutine *co = ioc->write_coroutine; 419 420 /* Assert that aio_co_wake() reenters the coroutine directly */ 421 assert(qemu_get_current_aio_context() == 422 qemu_coroutine_get_aio_context(co)); 423 aio_co_wake(co); 424 } 425 426 static void qio_channel_set_aio_fd_handlers(QIOChannel *ioc) 427 { 428 IOHandler *rd_handler = NULL, *wr_handler = NULL; 429 AioContext *ctx; 430 431 if (ioc->read_coroutine) { 432 rd_handler = qio_channel_restart_read; 433 } 434 if (ioc->write_coroutine) { 435 wr_handler = qio_channel_restart_write; 436 } 437 438 ctx = ioc->ctx ? ioc->ctx : iohandler_get_aio_context(); 439 qio_channel_set_aio_fd_handler(ioc, ctx, rd_handler, wr_handler, ioc); 440 } 441 442 void qio_channel_attach_aio_context(QIOChannel *ioc, 443 AioContext *ctx) 444 { 445 assert(!ioc->read_coroutine); 446 assert(!ioc->write_coroutine); 447 ioc->ctx = ctx; 448 } 449 450 void qio_channel_detach_aio_context(QIOChannel *ioc) 451 { 452 ioc->read_coroutine = NULL; 453 ioc->write_coroutine = NULL; 454 qio_channel_set_aio_fd_handlers(ioc); 455 ioc->ctx = NULL; 456 } 457 458 void coroutine_fn qio_channel_yield(QIOChannel *ioc, 459 GIOCondition condition) 460 { 461 assert(qemu_in_coroutine()); 462 if (condition == G_IO_IN) { 463 assert(!ioc->read_coroutine); 464 ioc->read_coroutine = qemu_coroutine_self(); 465 } else if (condition == G_IO_OUT) { 466 assert(!ioc->write_coroutine); 467 ioc->write_coroutine = qemu_coroutine_self(); 468 } else { 469 abort(); 470 } 471 qio_channel_set_aio_fd_handlers(ioc); 472 qemu_coroutine_yield(); 473 474 /* Allow interrupting the operation by reentering the coroutine other than 475 * through the aio_fd_handlers. */ 476 if (condition == G_IO_IN && ioc->read_coroutine) { 477 ioc->read_coroutine = NULL; 478 qio_channel_set_aio_fd_handlers(ioc); 479 } else if (condition == G_IO_OUT && ioc->write_coroutine) { 480 ioc->write_coroutine = NULL; 481 qio_channel_set_aio_fd_handlers(ioc); 482 } 483 } 484 485 486 static gboolean qio_channel_wait_complete(QIOChannel *ioc, 487 GIOCondition condition, 488 gpointer opaque) 489 { 490 GMainLoop *loop = opaque; 491 492 g_main_loop_quit(loop); 493 return FALSE; 494 } 495 496 497 void qio_channel_wait(QIOChannel *ioc, 498 GIOCondition condition) 499 { 500 GMainContext *ctxt = g_main_context_new(); 501 GMainLoop *loop = g_main_loop_new(ctxt, TRUE); 502 GSource *source; 503 504 source = qio_channel_create_watch(ioc, condition); 505 506 g_source_set_callback(source, 507 (GSourceFunc)qio_channel_wait_complete, 508 loop, 509 NULL); 510 511 g_source_attach(source, ctxt); 512 513 g_main_loop_run(loop); 514 515 g_source_unref(source); 516 g_main_loop_unref(loop); 517 g_main_context_unref(ctxt); 518 } 519 520 521 static void qio_channel_finalize(Object *obj) 522 { 523 QIOChannel *ioc = QIO_CHANNEL(obj); 524 525 g_free(ioc->name); 526 527 #ifdef _WIN32 528 if (ioc->event) { 529 CloseHandle(ioc->event); 530 } 531 #endif 532 } 533 534 static const TypeInfo qio_channel_info = { 535 .parent = TYPE_OBJECT, 536 .name = TYPE_QIO_CHANNEL, 537 .instance_size = sizeof(QIOChannel), 538 .instance_finalize = qio_channel_finalize, 539 .abstract = true, 540 .class_size = sizeof(QIOChannelClass), 541 }; 542 543 544 static void qio_channel_register_types(void) 545 { 546 type_register_static(&qio_channel_info); 547 } 548 549 550 type_init(qio_channel_register_types); 551