Lines Matching +full:total +full:- +full:timeout
10 * later. See the COPYING file in the top-level directory.
15 * - main should get parameters from the command line.
16 * - implement all request handlers. Still not implemented:
19 * - test for broken requests and virtqueue.
20 * - implement features defined by Virtio 1.0 spec.
21 * - support mergeable buffers and indirect descriptors.
22 * - implement clean shutdown.
23 * - implement non-blocking writes to UDP backend.
24 * - implement polling strategy.
25 * - implement clean starting/stopping of vq processing
26 * - implement clean starting/stopping of used and buffers
36 #include "standard-headers/linux/virtio_net.h"
37 #include "libvhost-user.h"
91 FD_ZERO(&dispr->fdset); in dispatcher_init()
92 dispr->max_sock = -1; in dispatcher_init()
103 return -1; in dispatcher_add()
106 dispr->events[sock].ctx = ctx; in dispatcher_add()
107 dispr->events[sock].callback = cb; in dispatcher_add()
109 FD_SET(sock, &dispr->fdset); in dispatcher_add()
110 if (sock > dispr->max_sock) { in dispatcher_add()
111 dispr->max_sock = sock; in dispatcher_add()
114 sock, dispr->max_sock); in dispatcher_add()
125 return -1; in dispatcher_remove()
128 FD_CLR(sock, &dispr->fdset); in dispatcher_remove()
133 /* timeout in us */
135 dispatcher_wait(Dispatcher *dispr, uint32_t timeout) in dispatcher_wait() argument
138 tv.tv_sec = timeout / 1000000; in dispatcher_wait()
139 tv.tv_usec = timeout % 1000000; in dispatcher_wait()
141 fd_set fdset = dispr->fdset; in dispatcher_wait()
144 int rc = select(dispr->max_sock + 1, &fdset, 0, 0, &tv); in dispatcher_wait()
146 if (rc == -1) { in dispatcher_wait()
150 /* Timeout */ in dispatcher_wait()
158 for (sock = 0; sock < dispr->max_sock + 1; sock++) { in dispatcher_wait()
163 if (FD_ISSET(sock, &fdset) && FD_ISSET(sock, &dispr->fdset)) { in dispatcher_wait()
164 Event *e = &dispr->events[sock]; in dispatcher_wait()
165 e->callback(sock, e->ctx); in dispatcher_wait()
177 int hdrlen = vubr->hdrlen; in vubr_handle_tx()
192 out_num = elem->out_num; in vubr_handle_tx()
193 out_sg = elem->out_sg; in vubr_handle_tx()
195 fprintf(stderr, "virtio-net header not in first element\n"); in vubr_handle_tx()
205 hdrlen, -1); in vubr_handle_tx()
211 .msg_name = (struct sockaddr *) &vubr->backend_udp_dest, in vubr_handle_tx()
217 ret = sendmsg(vubr->backend_udp_sock, &msg, 0); in vubr_handle_tx()
218 } while (ret == -1 && (errno == EAGAIN || errno == EINTR)); in vubr_handle_tx()
220 if (ret == -1) { in vubr_handle_tx()
245 assert(bytes >= cur->iov_len); in iov_restore_front()
246 bytes -= cur->iov_len; in iov_restore_front()
249 cur->iov_base -= bytes; in iov_restore_front()
250 cur->iov_len += bytes; in iov_restore_front()
259 if (bytes < iov->iov_len) { in iov_truncate()
260 iov->iov_len = bytes; in iov_truncate()
264 bytes -= iov->iov_len; in iov_truncate()
274 VuDev *dev = &vubr->vudev; in vubr_backend_recv_cb()
280 int hdrlen = vubr->hdrlen; in vubr_backend_recv_cb()
299 ssize_t ret, total = 0; in vubr_backend_recv_cb() local
307 if (elem->in_num < 1) { in vubr_backend_recv_cb()
308 fprintf(stderr, "virtio-net contains no in buffers\n"); in vubr_backend_recv_cb()
312 sg = elem->in_sg; in vubr_backend_recv_cb()
313 num = elem->in_num; in vubr_backend_recv_cb()
317 sg, elem->in_num, in vubr_backend_recv_cb()
321 iov_from_buf(sg, elem->in_num, 0, &hdr, sizeof hdr); in vubr_backend_recv_cb()
322 total += hdrlen; in vubr_backend_recv_cb()
328 .msg_name = (struct sockaddr *) &vubr->backend_udp_dest, in vubr_backend_recv_cb()
334 ret = RETRY_ON_EINTR(recvmsg(vubr->backend_udp_sock, &msg, 0)); in vubr_backend_recv_cb()
337 iov_restore_front(elem->in_sg, sg, hdrlen); in vubr_backend_recv_cb()
340 if (ret == -1) { in vubr_backend_recv_cb()
349 total += ret; in vubr_backend_recv_cb()
350 iov_truncate(elem->in_sg, elem->in_num, total); in vubr_backend_recv_cb()
351 vu_queue_fill(dev, vq, elem, total, i++); in vubr_backend_recv_cb()
377 if (!vu_dispatch(&vubr->vudev)) { in vubr_receive_cb()
393 wd->cb(wd->dev, VU_WATCH_IN, wd->data); in watch_cb()
404 wd->cb = cb; in vubr_set_watch()
405 wd->data = data; in vubr_set_watch()
406 wd->dev = dev; in vubr_set_watch()
407 dispatcher_add(&vubr->dispatcher, fd, wd, watch_cb); in vubr_set_watch()
415 dispatcher_remove(&vubr->dispatcher, fd); in vubr_remove_watch()
428 switch (vmsg->request) { in vubr_process_msg()
447 vubr->hdrlen = 12; in vubr_set_features()
449 vubr->hdrlen = 10; in vubr_set_features()
467 if (started && vubr->notifier.fd >= 0) { in vubr_queue_set_started()
468 vu_set_queue_host_notifier(dev, vq, vubr->notifier.fd, in vubr_queue_set_started()
485 dispatcher_remove(&vubr->dispatcher, dev->sock); in vubr_panic()
486 vubr->quit = 1; in vubr_panic()
512 if (conn_fd == -1) { in vubr_accept_cb()
517 if (!vu_init(&dev->vudev, in vubr_accept_cb()
525 fprintf(stderr, "Failed to initialize libvhost-user\n"); in vubr_accept_cb()
529 dispatcher_add(&dev->dispatcher, conn_fd, ctx, vubr_receive_cb); in vubr_accept_cb()
530 dispatcher_remove(&dev->dispatcher, sock); in vubr_accept_cb()
547 dev->sock = socket(AF_UNIX, SOCK_STREAM, 0); in vubr_new()
548 if (dev->sock == -1) { in vubr_new()
552 dev->notifier.fd = -1; in vubr_new()
561 if (bind(dev->sock, (struct sockaddr *) &un, len) == -1) { in vubr_new()
565 if (listen(dev->sock, 1) == -1) { in vubr_new()
572 if (connect(dev->sock, (struct sockaddr *)&un, len) == -1) { in vubr_new()
576 if (!vu_init(&dev->vudev, in vubr_new()
578 dev->sock, in vubr_new()
584 fprintf(stderr, "Failed to initialize libvhost-user\n"); in vubr_new()
591 dispatcher_init(&dev->dispatcher); in vubr_new()
593 dispatcher_add(&dev->dispatcher, dev->sock, (void *)dev, cb); in vubr_new()
607 uint16_t *n = vubr->notifier.addr + pagesize * qidx; in notifier_thread()
639 fd = g_file_open_tmp("vubr-XXXXXX", NULL, NULL); in vubr_host_notifier_setup()
655 if (pthread_create(&thread, NULL, notifier_thread, &dev->vudev) != 0) { in vubr_host_notifier_setup()
659 dev->notifier.fd = fd; in vubr_host_notifier_setup()
660 dev->notifier.addr = addr; in vubr_host_notifier_setup()
661 dev->notifier.thread = thread; in vubr_host_notifier_setup()
668 if (!inet_aton(host, &saddr->sin_addr)) { in vubr_set_host()
679 saddr->sin_addr = *(struct in_addr *)he->h_addr; in vubr_set_host()
715 dev->backend_udp_dest = (struct sockaddr_in) { in vubr_backend_udp_setup()
719 vubr_set_host(&dev->backend_udp_dest, remote_host); in vubr_backend_udp_setup()
722 if (sock == -1) { in vubr_backend_udp_setup()
726 if (bind(sock, (struct sockaddr *)&si_local, sizeof(si_local)) == -1) { in vubr_backend_udp_setup()
730 dev->backend_udp_sock = sock; in vubr_backend_udp_setup()
731 dispatcher_add(&dev->dispatcher, sock, dev, vubr_backend_recv_cb); in vubr_backend_udp_setup()
739 while (!dev->quit) { in vubr_run()
740 /* timeout 200ms */ in vubr_run()
741 dispatcher_wait(&dev->dispatcher, 200000); in vubr_run()
752 return -1; in vubr_parse_host_port()
780 while ((opt = getopt(argc, argv, "l:r:u:cH")) != -1) { in main()
824 vu_deinit(&dev->vudev); in main()
830 fprintf(stderr, "[-c] [-H] [-u ud_socket_path] [-l lhost:lport] [-r rhost:rport]\n"); in main()
831 fprintf(stderr, "\t-u path to unix domain socket. default: %s\n", in main()
833 fprintf(stderr, "\t-l local host and port. default: %s:%s\n", in main()
835 fprintf(stderr, "\t-r remote host and port. default: %s:%s\n", in main()
837 fprintf(stderr, "\t-c client mode\n"); in main()
838 fprintf(stderr, "\t-H use host notifier\n"); in main()