/* * vionet_rx * * Enqueue data that was received on a tap file descriptor * to the vionet device queue. */ static int vionet_rx(struct vionet_dev *dev) { char buf[PAGE_SIZE]; int hasdata, num_enq = 0, spc = 0; ssize_t sz; do { sz = read(dev->fd, buf, sizeof buf); if (sz == -1) { /* * If we get EAGAIN, No data is currently available. * Do not treat this as an error. */ if (errno != EAGAIN) log_warn("unexpected read error on vionet " "device"); } else if (sz != 0) num_enq += vionet_enq_rx(dev, buf, sz, &spc); else if (sz == 0) { log_debug("process_rx: no data"); hasdata = 0; break; } hasdata = fd_hasdata(dev->fd); } while (spc && hasdata); dev->rx_pending = hasdata; return (num_enq); }
int vionet_process_rx(void) { int i, num_enq, spc, hasdata; ssize_t sz; char *buf; struct pollfd pfd; num_enq = 0; buf = malloc(PAGE_SIZE); for (i = 0 ; i < nr_vionet; i++) { if (!vionet[i].rx_added) continue; spc = 1; hasdata = 1; bzero(buf, PAGE_SIZE); bzero(&pfd, sizeof(struct pollfd)); pfd.fd = vionet[i].fd; pfd.events = POLLIN; while (spc && hasdata) { hasdata = poll(&pfd, 1, 0); if (hasdata == 1) { sz = read(vionet[i].fd, buf, PAGE_SIZE); if (sz != 0) { num_enq += vionet_enq_rx(&vionet[i], buf, sz, &spc); } else if (sz == 0) { fprintf(stderr, "process_rx: no data" "\n\r"); hasdata = 0; } } } } free(buf); /* * XXX returns the number of packets enqueued across all vionet, which * may not be right for VMs with more than one vionet. */ return (num_enq); }