static int readv_test(uint repeat, uint msgsz, bool var)
{
	uint i;
	ssize_t rc;
	size_t  msg_len;
	int  echo_fd = -1;
	char tx_buf [msgsz];
	char rx0_buf[msgsz];
	char rx1_buf[msgsz];
	struct iovec iovs[2]= {{rx0_buf, 0}, {rx1_buf, 0}};

	if (!opt_silent) {
		printf("%s: repeat %u: msgsz %u: variable %s\n",
			__func__, repeat, msgsz, var ? "true" : "false");
	}

	echo_fd = tipc_connect(dev_name, echo_name);
	if (echo_fd < 0) {
		fprintf(stderr, "Failed to connect to service\n");
		return echo_fd;
	}

	for (i = 0; i < repeat; i++) {

		msg_len = msgsz;
		if (opt_variable && msgsz) {
			msg_len = rand() % msgsz;
		}

		iovs[0].iov_len = msg_len / 3;
		iovs[1].iov_len = msg_len - iovs[0].iov_len;

		memset(tx_buf,  i + 1, sizeof(tx_buf));
		memset(rx0_buf, i + 2, iovs[0].iov_len);
		memset(rx1_buf, i + 3, iovs[1].iov_len);

		rc = write(echo_fd, tx_buf, msg_len);
		if (rc < 0) {
			perror("readv_test: write");
			break;
		}

		if ((size_t)rc != msg_len) {
			fprintf(stderr,
				"%s: %s: data size mismatch (%zd vs. %zd)\n",
				__func__, "write", (size_t)rc, msg_len);
			break;
		}

		rc = readv(echo_fd, iovs, 2);
		if (rc < 0) {
			perror("readv_test: readv");
			break;
		}

		if ((size_t)rc != msg_len) {
			fprintf(stderr,
				"%s: %s: data size mismatch (%zd vs. %zd)\n",
				__func__, "write", (size_t)rc, msg_len);
			break;
		}

		if (memcmp(rx0_buf, tx_buf, iovs[0].iov_len)) {
			fprintf(stderr, "%s: data mismatch: buf 0\n", __func__);
			break;
		}

		if (memcmp(rx1_buf, tx_buf + iovs[0].iov_len, iovs[1].iov_len)) {
			fprintf(stderr, "%s: data mismatch, buf 1\n", __func__);
			break;
		}
	}

	tipc_close(echo_fd);

	if (!opt_silent) {
		printf("%s: done\n",__func__);
	}

	return 0;
}
Beispiel #2
0
int citp_pipe_splice_write(citp_fdinfo* fdi, int alien_fd, loff_t* alien_off,
                           size_t olen, int flags,
                           citp_lib_context_t* lib_context)
{
  citp_pipe_fdi* epi = fdi_to_pipe_fdi(fdi);
  int len_in_bufs = OO_PIPE_SIZE_TO_BUFS(olen);
  struct iovec iov_on_stack[CITP_PIPE_SPLICE_WRITE_STACK_IOV_LEN];
  struct iovec* iov = iov_on_stack;
  int want_buf_count;
  int rc;
  int bytes_to_read;
  int len = olen;
  int no_more = 1; /* for now we only run single loop */
  int written_total = 0;
  int non_block = (flags & SPLICE_F_NONBLOCK) || (epi->pipe->aflags &
      (CI_PFD_AFLAG_NONBLOCK << CI_PFD_AFLAG_WRITER_SHIFT));
  if( fdi_is_reader(fdi) ) {
    errno = EINVAL;
    return -1;
  }
  if( alien_off ) {
    /* TODO support this */
    errno = ENOTSUP;
    return -1;
  }
  do {
    int count;
    int iov_num;
    int bytes_to_write;
    struct ci_pipe_pkt_list pkts = {};
    struct ci_pipe_pkt_list pkts2;
    want_buf_count = len_in_bufs;
    /* We might need to wait for buffers here on the first iteration */
    rc = ci_pipe_zc_alloc_buffers(epi->ni, epi->pipe, want_buf_count,
                                  MSG_NOSIGNAL | (non_block || written_total ?
                                  MSG_DONTWAIT : 0),
                                  &pkts);
    if( rc < 0 && written_total ) {
      /* whatever the error we need to report already written_bytes */
      rc = written_total;
      break;
    }
    else if( rc < 0 )
      break;
    else if( pkts.count == 0 && non_block ) {
      errno = EAGAIN;
      rc = -1;
      break;
    }
    else
      ci_assert_gt(pkts.count, 0);
    count = pkts.count;

    if( count > CITP_PIPE_SPLICE_WRITE_STACK_IOV_LEN ) {
      void* niov = realloc(iov == iov_on_stack ? NULL : iov,
                           sizeof(*iov) * len_in_bufs);
      if( niov == NULL )
        /* we can still move quite a few pkts */
        count = CITP_PIPE_SPLICE_WRITE_STACK_IOV_LEN;
      else
        niov = iov;
    }

    ci_assert_ge(count, 1);

    iov_num = count;
    pkts2 = pkts;
    bytes_to_read = ci_pipe_list_to_iovec(epi->ni, epi->pipe, iov, &iov_num,
                                          &pkts2, len);

    citp_exit_lib_if(lib_context, TRUE);
    /* Note: the following call might be non-blocking as well as blocking */
    rc = readv(alien_fd, iov, count);
    citp_reenter_lib(lib_context);

    if( rc > 0 ) {
      bytes_to_write = rc;
      written_total += bytes_to_write;
      len -= bytes_to_write;
      no_more |= bytes_to_write < bytes_to_read;
    }
    else {
      bytes_to_write = 0;
      no_more = 1;
    }

    {
      /* pipe zc_write will write non_empty buffers and release the empty
       * ones */
      int rc2 = ci_pipe_zc_write(epi->ni, epi->pipe, &pkts, bytes_to_write,
                  CI_PIPE_ZC_WRITE_FLAG_FORCE | MSG_DONTWAIT | MSG_NOSIGNAL);
      (void) rc2;
      ci_assert_equal(rc2, bytes_to_write);
    }
    /* for now we will not be doing second iteration, to allow for that
     * we'd need to have guarantee that read will not block
     * e.g. insight into type of fd and a nonblokcing operation
     * (to name a valid case: socket, recvmsg) */
  } while( ! no_more );

  if( iov != iov_on_stack )
    free(iov);
  if( rc > 0 )
    return written_total;
  if( rc < 0 && errno == EPIPE && ! (flags & MSG_NOSIGNAL) ) {
    ci_sys_ioctl(ci_netif_get_driver_handle(epi->ni),
                 OO_IOC_KILL_SELF_SIGPIPE, NULL);
  }
  return rc;
}
Beispiel #3
0
static void dotest(int testers, int me, int fd)
{
	char *bits, *hold_bits;
	char val;
	int count, collide, chunk, whenmisc, xfr, i;

	/* Stuff for the readv call */
	struct	iovec	r_iovec[MAXIOVCNT];
	int	r_ioveclen;

	/* Stuff for the writev call */
	struct	iovec	val_iovec[MAXIOVCNT];

	struct	iovec	zero_iovec[MAXIOVCNT];
	int	w_ioveclen;

	nchunks = max_size / csize;
	whenmisc = 0;

	if ((bits = malloc((nchunks+7) / 8)) == NULL) {
		tst_resm(TBROK, "\tmalloc failed(bits)");
		tst_exit();
	}
	if ((hold_bits = malloc((nchunks+7) / 8)) == NULL) {
		tst_resm(TBROK, "\tmalloc failed(hlod_bits)");
		tst_exit();
	}

	/*Allocate memory for the iovec buffers and init the iovec arrays
	 */
	r_ioveclen = w_ioveclen = csize / MAXIOVCNT;

		/* Please note that the above statement implies that csize
		 * be evenly divisible by MAXIOVCNT.
		 */

	for (i = 0; i < MAXIOVCNT; i++) {
		if ((r_iovec[i].iov_base = calloc(r_ioveclen, 1)) == NULL) {
			tst_resm(TFAIL, "\tmalloc failed(r_iovec[i].iov_base)");
			tst_exit();
		}
		r_iovec[i].iov_len = r_ioveclen;

		/* Allocate unused memory areas between all the buffers to
		 * make things more diffult for the OS.
		 */

		if (malloc((i+1)*8) == NULL) {
			tst_resm(TBROK, "\tmalloc failed((i+1)*8)");
			tst_exit();
		}
		if ((val_iovec[i].iov_base = calloc(w_ioveclen, 1)) == NULL) {
			tst_resm(TBROK, "\tmalloc failed(val_iovec[i]");
			exit(1);
		}
		val_iovec[i].iov_len = w_ioveclen;

		if (malloc((i+1)*8) == NULL) {
			tst_resm(TBROK, "\tmalloc failed((i+1)*8)");
			tst_exit();
		}
		if ((zero_iovec[i].iov_base = calloc(w_ioveclen, 1)) == NULL) {
			tst_resm(TBROK, "\tmalloc failed(zero_iover)");
			tst_exit();
		}
		zero_iovec[i].iov_len = w_ioveclen;

		if (malloc((i+1)*8) == NULL) {
			tst_resm(TBROK, "\tmalloc failed((i+1)*8)");
			tst_exit();
		}
	}
	/*
	 * No init sectors; allow file to be sparse.
	 */
	val = (64/testers) * me + 1;

	/*
	 * For each iteration:
	 *	zap bits array
	 *	loop
	 *		pick random chunk, read it.
	 *		if corresponding bit off {
	 *			verify = 0. (sparse file)
	 *			++count;
	 *		} else
	 *			verify = val.
	 *		write "val" on it.
	 *		repeat unitl count = nchunks.
	 *	++val.
         */

	 srand(getpid());
	 if (misc_intvl)
	 	whenmisc = NEXTMISC;

	 while (iterations-- > 0) {
		for (i = 0; i < NMISC; i++)
			misc_cnt[i] = 0;
		ftruncate(fd,0);
		file_max = 0;
		memset(bits, 0, (nchunks+7) / 8);
		memset(hold_bits, 0, (nchunks+7) / 8);

		/* Have to fill the val and zero iov buffers in a different manner
		 */
		for (i = 0; i < MAXIOVCNT; i++) {
			memset(val_iovec[i].iov_base,val,val_iovec[i].iov_len);
			memset(zero_iovec[i].iov_base,0,zero_iovec[i].iov_len);

		}
		count = 0;
		collide = 0;
		while (count < nchunks) {
			chunk = rand() % nchunks;
			/*
			 * Read it.
			 */
			if (lseek64(fd, CHUNK(chunk), 0) < 0) {
				tst_resm(TFAIL, "\tTest[%d]: lseek64(0) fail at %Lx, errno = %d.",
					me, CHUNK(chunk), errno);
				tst_exit();
			}
			if ((xfr = readv(fd, &r_iovec[0], MAXIOVCNT)) < 0) {
				tst_resm(TFAIL, "\tTest[%d]: readv fail at %Lx, errno = %d.",
					me, CHUNK(chunk), errno);
				tst_exit();
			}
			/*
			 * If chunk beyond EOF just write on it.
			 * Else if bit off, haven't seen it yet.
			 * Else, have.  Verify values.
			 */
			if (CHUNK(chunk) >= file_max) {
				bits[chunk/8] |= (1<<(chunk%8));
				++count;
			} else if ((bits[chunk/8] & (1<<(chunk%8))) == 0) {
				if (xfr != csize) {
					tst_resm(TFAIL, "\tTest[%d]: xfr=%d != %d, zero read.",
						me, xfr, csize);
					tst_exit();
				}
				for (i = 0; i < MAXIOVCNT; i++) {
					if (memcmp(r_iovec[i].iov_base, zero_iovec[i].iov_base, r_iovec[i].iov_len)) {
						tst_resm(TFAIL,
					  	"\tTest[%d] bad verify @ 0x%Lx for val %d count %d xfr %d file_max 0x%x, should be 0.",
							me, CHUNK(chunk), val, count, xfr, file_max);
						tst_resm(TINFO, "\tTest[%d]: last_trunc = 0x%x.",
							me, last_trunc);
						sync();
						ft_dumpiov(&r_iovec[i]);
						ft_dumpbits(bits, (nchunks+7)/8);
						ft_orbits(hold_bits, bits, (nchunks+7)/8);
						tst_resm(TINFO, "\tHold ");
						ft_dumpbits(hold_bits, (nchunks+7)/8);
						tst_exit();
					}
				}
				bits[chunk/8] |= (1<<(chunk%8));
				++count;
			} else {
				if (xfr != csize) {
					tst_resm(TFAIL, "\tTest[%d]: xfr=%d != %d, val read.",
						me, xfr, csize);
					tst_exit();
				}
				++collide;
				for (i = 0; i < MAXIOVCNT; i++) {
					if (memcmp(r_iovec[i].iov_base, val_iovec[i].iov_base, r_iovec[i].iov_len)) {
						tst_resm(TFAIL, "\tTest[%d] bad verify @ 0x%Lx for val %d count %d xfr %d file_max 0x%x.",
							me, CHUNK(chunk), val, count, xfr, file_max);
						tst_resm(TINFO, "\tTest[%d]: last_trunc = 0x%x.",
							me, last_trunc);
						sync();
						ft_dumpiov(&r_iovec[i]);
						ft_dumpbits(bits, (nchunks+7)/8);
						ft_orbits(hold_bits, bits, (nchunks+7)/8);
						tst_resm(TINFO, "\tHold ");
						ft_dumpbits(hold_bits, (nchunks+7)/8);
						tst_exit();
					}
				}
			}
			/*
			 * Writev it.
			 */
			if (lseek64(fd, -((off64_t)xfr), 1) <  0) {
				tst_resm(TFAIL, "\tTest[%d]: lseek64(1) fail at %Lx, errno = %d.",
					me, CHUNK(chunk), errno);
				tst_exit();
			}
			if ((xfr = writev(fd, &val_iovec[0], MAXIOVCNT)) < csize) {
				if (errno == ENOSPC) {
					tst_resm(TFAIL, "\tTest[%d]: no space, exiting.", me);
					fsync(fd);
					tst_exit();
				}
				tst_resm(TFAIL, "\tTest[%d]: writev fail at %Lx xfr %d, errno = %d.",
					me, CHUNK(chunk), xfr, errno);
				tst_exit();
			}
			if (CHUNK(chunk) + csize > file_max)
				file_max = CHUNK(chunk) + csize;
			/*
			 * If hit "misc" interval, do it.
			 */
			if (misc_intvl && --whenmisc <= 0) {
				ft_orbits(hold_bits, bits, (nchunks+7)/8);
				domisc(me, fd, bits);
				whenmisc = NEXTMISC;
			}
			if (count + collide > 2 * nchunks)
				break;
		}

		/*
		 * End of iteration, maybe before doing all chunks.
		 */
		fsync(fd);
		++misc_cnt[m_fsync];
		//tst_resm(TINFO, "\tTest{%d} val %d done, count = %d, collide = {%d}",
		//		me, val, count, collide);
		//for (i = 0; i < NMISC; i++)
		//	tst_resm(TINFO, "\t\tTest{%d}: {%d} %s's.", me, misc_cnt[i], m_str[i]);
		++val;
	}
}
Beispiel #4
0
int main(void)
{
	int nbytes;

	/* Fill the buf_list[0] and buf_list[1] with 0 zeros */
        buf_list[0] = buf1;
        buf_list[1] = buf2;
        memset(buf_list[0], 0, K_1);
        memset(buf_list[1], 0, K_1);
                                                                                
        if ((fd = open(f_name, O_WRONLY | O_CREAT, 0666)) < 0) {
             fprintf(stderr, "open(2) failed: fname = %s, errno = %d\n",
			 f_name, errno);
		return 1;
        } else if ((nbytes = write(fd, buf_list[1], K_1)) != K_1) {
		fprintf(stderr, "write(2) failed: nbytes = %d, errno = %d\n",
			 nbytes, errno);
                return 1;
        }
        if (close(fd) < 0) {
        	fprintf(stderr, "close failed: errno = %d\n", errno);
                return 1;
	}
        fprintf(stderr, "Test file created.\n"); 
        if ((fd = open(f_name, O_RDWR, 0666)) < 0) {
               	fprintf(stderr, "open failed: fname = %s, errno = %d\n",
                        f_name, errno);
                return 1;
	}
 
        lseek(fd, 0, 0);
        if (writev(fd, wr_iovec, 2) < 0) {
		if (errno == EFAULT) 
                	fprintf(stderr, "Received EFAULT as expected\n");
                else 
                	fprintf(stderr, "Expected EFAULT, got %d\n", errno);
                lseek(fd, K_1, 0);
                if ((nbytes = read(fd, buf_list[0], CHUNK)) != 0) 
                	fprintf(stderr, "Expected nbytes = 0, got %d\n", nbytes);
        } 
	else 
        	fprintf(stderr, "Error writev returned a positive value\n");
	// Now check invalid vector count
        if (writev(fd, wr_iovec, -1) < 0) {
 		if (errno == EINVAL) 
                	fprintf(stderr, "Received EINVAL as expected\n");
                else 
                	fprintf(stderr, "expected errno = EINVAL, got %d\n", errno);
 	}
	else 
        	fprintf(stderr, "Error writev returned a positive value\n");
        if (readv(fd, wr_iovec, -1) < 0) {
 		if (errno == EINVAL) 
                	fprintf(stderr, "Received EINVAL as expected\n");
                else 
                	fprintf(stderr, "expected errno = EINVAL, got %d\n", errno);
 	}
	else 
        	fprintf(stderr, "Error writev returned a positive value\n");

        unlink(f_name);
        
	return 0;
}
Beispiel #5
0
static ssize_t pcap_sg_read_pcap_pkt(int fd, struct pcap_pkthdr *hdr,
				     uint8_t *packet, size_t len)
{
	/* In contrast to writing, reading gets really ugly ... */
	spinlock_lock(&lock);
	if (likely(avail - used >= sizeof(*hdr) &&
		   iov[c].iov_len - iov_used >= sizeof(*hdr))) {
		__memcpy_small(hdr, iov[c].iov_base + iov_used, sizeof(*hdr));
		iov_used += sizeof(*hdr);
		used += sizeof(*hdr);
	} else {
		size_t remainder, offset = 0;
		if (avail - used < sizeof(*hdr))
			return -ENOMEM;
		offset = iov[c].iov_len - iov_used;
		remainder = sizeof(*hdr) - offset;
		assert(offset + remainder == sizeof(*hdr));
		__memcpy_small(hdr, iov[c].iov_base + iov_used, offset);
		used += offset;
		iov_used = 0;
		c++;
		if (c == IOVSIZ) {
			/* We need to refetch! */
			c = 0;
			avail = readv(fd, iov, IOVSIZ);
			if (avail < 0)
				return -EIO;
			used = 0;
		}
		/* Now we copy the remainder and go on with business ... */
		__memcpy_small(hdr, iov[c].iov_base + iov_used, remainder);
		iov_used += remainder;
		used += remainder;
	}
	if (likely(avail - used >= hdr->len &&
		   iov[c].iov_len - iov_used >= hdr->len)) {
		__memcpy(packet, iov[c].iov_base + iov_used, hdr->len);
		iov_used += hdr->len;
		used += hdr->len;
	} else {
		size_t remainder, offset = 0;
		if (avail - used < hdr->len)
			return -ENOMEM;
		offset = iov[c].iov_len - iov_used;
		remainder = hdr->len - offset;
		assert(offset + remainder == hdr->len);
		__memcpy(packet, iov[c].iov_base + iov_used, offset);
		used += offset;
		iov_used = 0;
		c++;
		if (c == IOVSIZ) {
			/* We need to refetch! */
			c = 0;
			avail = readv(fd, iov, IOVSIZ);
			if (avail < 0)
				return -EIO;
			used = 0;
		}
		/* Now we copy the remainder and go on with business ... */
		__memcpy(packet, iov[c].iov_base + iov_used, remainder);
		iov_used += remainder;
		used += remainder;
	}
	spinlock_unlock(&lock);
	if (unlikely(hdr->len == 0))
		return -EINVAL; /* Bogus packet */
	return sizeof(*hdr) + hdr->len;
}
Beispiel #6
0
static void dotest(int testers, int me, int fd)
{
	char *bits;
	char val, val0;
	int count, collide, chunk, whenmisc, xfr, i;

	/* Stuff for the readv call */
	struct iovec r_iovec[MAXIOVCNT];
	int r_ioveclen;

	/* Stuff for the writev call */
	struct iovec val0_iovec[MAXIOVCNT];
	struct iovec val_iovec[MAXIOVCNT];
	int w_ioveclen;

	nchunks = max_size / (testers * csize);
	whenmisc = 0;

	if ((bits = malloc((nchunks + 7) / 8)) == NULL) {
		tst_resm(TBROK, "\tmalloc failed(bits)");
		tst_exit();
	}

	/* Allocate memory for the iovec buffers and init the iovec arrays */
	r_ioveclen = w_ioveclen = csize / MAXIOVCNT;

	/* Please note that the above statement implies that csize
	 * be evenly divisible by MAXIOVCNT.
	 */
	for (i = 0; i < MAXIOVCNT; i++) {
		if ((r_iovec[i].iov_base = malloc(r_ioveclen)) == NULL) {
			tst_resm(TBROK, "\tmalloc failed(iov_base)");
			tst_exit();
		}
		r_iovec[i].iov_len = r_ioveclen;

		/* Allocate unused memory areas between all the buffers to
		 * make things more diffult for the OS.
		 */
		if (malloc((i + 1) * 8) == NULL) {
			tst_resm(TBROK, "\tmalloc failed((i+1)*8)");
			tst_exit();
		}

		if ((val0_iovec[i].iov_base = malloc(w_ioveclen)) == NULL) {
			tst_resm(TBROK, "\tmalloc failed(val0_iovec)");
			tst_exit();
		}

		val0_iovec[i].iov_len = w_ioveclen;

		if (malloc((i + 1) * 8) == NULL) {
			tst_resm(TBROK, "\tmalloc failed((i+1)*8)");
			tst_exit();
		}

		if ((val_iovec[i].iov_base = malloc(w_ioveclen)) == NULL) {
			tst_resm(TBROK, "\tmalloc failed(iov_base)");
			tst_exit();
		}
		val_iovec[i].iov_len = w_ioveclen;

		if (malloc((i + 1) * 8) == NULL) {
			tst_resm(TBROK, "\tmalloc failed(((i+1)*8)");
			tst_exit();
		}
	}

	/*
	 * No init sectors; file-sys makes 0 to start.
	 */
	val = (64 / testers) * me + 1;
	val0 = 0;

	/*
	 * For each iteration:
	 *      zap bits array
	 *      loop:
	 *              pick random chunk, read it.
	 *              if corresponding bit off {
	 *                      verify == 0. (sparse file)
	 *                      ++count;
	 *              } else
	 *                      verify == val.
	 *              write "val" on it.
	 *              repeat until count = nchunks.
	 *      ++val.
	 */
	srand(getpid());

	if (misc_intvl)
		whenmisc = NEXTMISC;

	while (iterations-- > 0) {
		for (i = 0; i < NMISC; i++)
			misc_cnt[i] = 0;
		memset(bits, 0, (nchunks + 7) / 8);
		/* Have to fill the val0 and val iov buffers in a different manner
		 */
		for (i = 0; i < MAXIOVCNT; i++) {
			memset(val0_iovec[i].iov_base, val0,
			       val0_iovec[i].iov_len);
			memset(val_iovec[i].iov_base, val,
			       val_iovec[i].iov_len);

		}

		count = 0;
		collide = 0;

		while (count < nchunks) {
			chunk = rand() % nchunks;
			/*
			 * Read it.
			 */
			if (lseek64(fd, CHUNK(chunk), 0) < 0) {
				tst_resm(TFAIL,
					 "\tTest[%d]: lseek64(0) fail at %"
					 PRIx64 "x, errno = %d.", me,
					 CHUNK(chunk), errno);
				tst_exit();
			}
			if ((xfr = readv(fd, &r_iovec[0], MAXIOVCNT)) < 0) {
				tst_resm(TFAIL,
					 "\tTest[%d]: readv fail at %" PRIx64
					 "x, errno = %d.", me, CHUNK(chunk),
					 errno);
				tst_exit();
			}
			/*
			 * If chunk beyond EOF just write on it.
			 * Else if bit off, haven't seen it yet.
			 * Else, have.  Verify values.
			 */
			if (xfr == 0) {
				bits[chunk / 8] |= (1 << (chunk % 8));
			} else if ((bits[chunk / 8] & (1 << (chunk % 8))) == 0) {
				if (xfr != csize) {
					tst_resm(TFAIL,
						 "\tTest[%d]: xfr=%d != %d, zero read.",
						 me, xfr, csize);
					tst_exit();
				}
				for (i = 0; i < MAXIOVCNT; i++) {
					if (memcmp
					    (r_iovec[i].iov_base,
					     val0_iovec[i].iov_base,
					     r_iovec[i].iov_len)) {
						tst_resm(TFAIL,
							 "\tTest[%d] bad verify @ 0x%"
							 PRIx64
							 " for val %d count %d xfr %d.",
							 me, CHUNK(chunk), val0,
							 count, xfr);
						ft_dumpiov(&r_iovec[i]);
						ft_dumpbits(bits,
							    (nchunks + 7) / 8);
						tst_exit();
					}
				}
				bits[chunk / 8] |= (1 << (chunk % 8));
				++count;
			} else {
				if (xfr != csize) {
					tst_resm(TFAIL,
						 "\tTest[%d]: xfr=%d != %d, val read.",
						 me, xfr, csize);
					tst_exit();
				}
				++collide;
				for (i = 0; i < MAXIOVCNT; i++) {
					if (memcmp
					    (r_iovec[i].iov_base,
					     val_iovec[i].iov_base,
					     r_iovec[i].iov_len)) {
						tst_resm(TFAIL,
							 "\tTest[%d] bad verify @ 0x%"
							 PRIx64
							 " for val %d count %d xfr %d.",
							 me, CHUNK(chunk), val,
							 count, xfr);
						ft_dumpiov(&r_iovec[i]);
						ft_dumpbits(bits,
							    (nchunks + 7) / 8);
						tst_exit();
					}
				}
			}
			/*
			 * Write it.
			 */
			if (lseek64(fd, -xfr, 1) < 0) {
				tst_resm(TFAIL,
					 "\tTest[%d]: lseek64(1) fail at %"
					 PRIx64 ", errno = %d.", me,
					 CHUNK(chunk), errno);
				tst_exit();
			}
			if ((xfr =
			     writev(fd, &val_iovec[0], MAXIOVCNT)) < csize) {
				if (errno == ENOSPC) {
					tst_resm(TFAIL,
						 "\tTest[%d]: no space, exiting.",
						 me);
					fsync(fd);
					tst_exit();
				}
				tst_resm(TFAIL,
					 "\tTest[%d]: writev fail at %" PRIx64
					 "x xfr %d, errno = %d.", me,
					 CHUNK(chunk), xfr, errno);
				tst_exit();
			}
			/*
			 * If hit "misc" interval, do it.
			 */
			if (misc_intvl && --whenmisc <= 0) {
				domisc(me, fd);
				whenmisc = NEXTMISC;
			}
			if (count + collide > 2 * nchunks)
				break;
		}

		/*
		 * End of iteration, maybe before doing all chunks.
		 */

		if (count < nchunks) {
			//tst_resm(TINFO, "\tTest{%d} val %d stopping @ %d, collide = {%d}.",
			//              me, val, count, collide);
			for (i = 0; i < nchunks; i++) {
				if ((bits[i / 8] & (1 << (i % 8))) == 0) {
					if (lseek64(fd, CHUNK(i), 0) <
					    (off64_t) 0) {
						tst_resm(TFAIL,
							 "\tTest[%d]: lseek64 fail at %"
							 PRIx64
							 "x, errno = %d.", me,
							 CHUNK(i), errno);
						tst_exit();
					}
					if (writev(fd, &val_iovec[0], MAXIOVCNT)
					    != csize) {
						tst_resm(TFAIL,
							 "\tTest[%d]: writev fail at %"
							 PRIx64
							 "x, errno = %d.", me,
							 CHUNK(i), errno);
						tst_exit();
					}
				}
			}
		}

		fsync(fd);
		++misc_cnt[m_fsync];
		//tst_resm(TINFO, "\tTest[%d] val %d done, count = %d, collide = %d.",
		//              me, val, count, collide);
		//for (i = 0; i < NMISC; i++)
		//      tst_resm(TINFO, "\t\tTest[%d]: %d %s's.", me, misc_cnt[i], m_str[i]);
		val0 = val++;
	}
}
Beispiel #7
0
int doErrorTest(void)
{
  FILE         *fp;
  int           fd;
  struct iovec  vec[4];
  int           rc;

  /*
   * Open and close the file to get a bad file descriptor
   */
  fp = fopen(TESTFILE, "wt");
  if ( fp == NULL ) {
    printf( "fopen for error 1: %d=%s\n", errno, strerror(errno));
    return FALSE;
  }
  fd = fileno(fp);
  fclose(fp);

  /* writev -- bad file descriptor */
  puts("writev bad file descriptor -- EBADF");
  rc = writev(fd, vec, 4);
  if ( (rc != -1) || (errno != EBADF) ) {
    printf( "writev error 1: %d=%s\n", errno, strerror(errno) );
    return FALSE;
  }

  /* readv -- bad file descriptor */
  puts("readv bad file descriptor -- EBADF");
  rc = read(fd, vec, 4);
  if ( (rc != -1) || (errno != EBADF) ) {
    printf( "readv error 1: %d=%s\n", errno, strerror(errno) );
    return FALSE;
  }

  /*
   * Open the file for the rest of the tests
   */
  fp = fopen(TESTFILE, "w+");
  if ( fp == NULL ) {
    printf( "fopen for error 2: %d=%s\n", errno, strerror(errno));
    return FALSE;
  }
  fd = fileno(fp);

  /* writev --  bad iovec pointer */
  puts("writev bad iovec pointer -- EINVAL");
  rc = writev(fd, NULL, 4);
  if ( (rc != -1) || (errno != EINVAL) ) {
    printf( "writev error 2: %d=%s\n", errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /* readv --  bad iovec pointer */
  puts("readv bad iovec pointer -- EINVAL");
  rc = readv(fd, NULL, 4);
  if ( (rc != -1) || (errno != EINVAL) ) {
    printf( "readv error 2: %d=%s\n", errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /* writev --  bad iovcnt 0 */
  puts("readv bad iovcnt of 0 -- EINVAL");
  rc = writev(fd, vec, 0);
  if ( (rc != -1) || (errno != EINVAL) ) {
    printf( "writev error 3: %d=%s\n", errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /* readv --  bad iovcnt 0 */
  puts("readv bad iovcnt of 0 -- EINVAL");
  rc = readv(fd, vec, 0);
  if ( (rc != -1) || (errno != EINVAL) ) {
    printf( "readv error 3: %d=%s\n", errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /* writev --  bad iovcnt negative */
  puts("writev bad iovcnt negative -- EINVAL");
  rc = writev(fd, vec, -2);
  if ( (rc != -1) || (errno != EINVAL) ) {
    printf( "writev error 4: %d=%s\n", errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /* readv --  bad iovcnt negative */
  puts("readv bad iovcnt negative -- EINVAL");
  rc = readv(fd, vec, -100);
  if ( (rc != -1) || (errno != EINVAL) ) {
    printf( "readv error 4: %d=%s\n", errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /* writev --  bad iov[i].iov_base */
  vec[0].iov_base = vec;
  vec[0].iov_len = 100;
  vec[1].iov_base = NULL;
  vec[1].iov_len = 100;
  puts("writev bad iov[i].iov_base -- EINVAL");
  rc = writev(fd, vec, 2);
  if ( (rc != -1) || (errno != EINVAL) ) {
    printf( "writev error 5: %d=%s\n", errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /*  readv --  bad iov[i].iov_base */
  vec[0].iov_base = vec;
  vec[0].iov_len = 100;
  vec[1].iov_base = NULL;
  vec[1].iov_len = 100;
  puts("readv bad iov[i].iov_base -- EINVAL");
  rc = readv(fd, vec, 2);
  if ( (rc != -1) || (errno != EINVAL) ) {
    printf( "readv error 5: %d=%s\n", errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /*  writev --  bad iov[i].iov_len < 0 */
  vec[0].iov_base = vec;
  vec[0].iov_len = 100;
  vec[1].iov_base = vec;
  vec[1].iov_len = -10;
  puts("writev bad iov[i].iov_len < 0 -- EINVAL");
  rc = writev(fd, vec, 2);
  if ( (rc != -1) || (errno != EINVAL) ) {
    printf( "writev error 6: %d=%s\n", errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /*  readv --  bad iov[i].iov_len = 0 */
  vec[0].iov_base = vec;
  vec[0].iov_len = 100;
  vec[1].iov_base = vec;
  vec[1].iov_len = -1024;
  puts("readv bad iov[i].iov_len = 0 -- EINVAL");
  rc = readv(fd, vec, 2);
  if ( (rc != -1) || (errno != EINVAL) ) {
    printf( "readv error 6: %d=%s\n", errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /*  writev --  iov_len total overflows */
  vec[0].iov_base = vec;
  vec[0].iov_len = SIZE_MAX;
  vec[1].iov_base = vec;
  vec[1].iov_len = SIZE_MAX;
  vec[2].iov_base = vec;
  vec[2].iov_len = SIZE_MAX;
  puts("writev iov_len total overflows -- EINVAL");
  rc = writev(fd, vec, 3);
  if ( (rc != -1) || (errno != EINVAL) ) {
    printf( "writev error 7: rc=%d %d=%s\n", rc, errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /*  readv --  iov_len total overflows */
  vec[0].iov_base = vec;
  vec[0].iov_len = SIZE_MAX;
  vec[1].iov_base = vec;
  vec[1].iov_len = SIZE_MAX;
  puts("readv iov_len total overflows -- EINVAL");
  rc = readv(fd, vec, 2);
  if ( (rc != -1) || (errno != EINVAL) ) {
    printf( "read error 7: rc=%d %d=%s\n", rc, errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /*  writev --  all zero length buffers */
  vec[0].iov_base = vec;
  vec[0].iov_len = 0;
  vec[1].iov_base = vec;
  vec[1].iov_len = 0;
  puts("writev iov_len works with no effect -- OK");
  rc = writev(fd, vec, 2);
  if ( (rc != 0) ) {
    printf( "writev error 8: %d=%s\n", errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  /*  readv --  all zero length buffers */
  vec[0].iov_base = vec;
  vec[0].iov_len = 0;
  vec[1].iov_base = vec;
  vec[1].iov_len = 0;
  puts("readv iov_len works with no effect -- OK");
  rc = readv(fd, vec, 2);
  if ( (rc != 0) ) {
    printf( "readv error 8: %d=%s\n", errno, strerror(errno) );
    fclose(fp);
    return FALSE;
  }

  fclose(fp);
  return TRUE;
}
Beispiel #8
0
void do_with_fd(
  int         fd,
  const char *description
)
{
  struct stat       stat_buff;
  struct iovec      vec[4];
  off_t             res;
  int               status;

  printf("ftruncate %s\n", description);
  status = ftruncate(fd, 40);
  rtems_test_assert( status == -1 );
  printf( "%d: %s\n", errno, strerror( errno ) );
  rtems_test_assert( errno == EBADF );

  printf("_fcntl_r %s\n", description);
  status = _fcntl_r( NULL, fd, F_SETFD, 1 );
  rtems_test_assert( status == -1 );
  printf( "%d: %s\n", errno, strerror( errno ) );
  rtems_test_assert( errno == EBADF );

  printf("fdatasync %s\n", description);
  status = fdatasync( fd );
  rtems_test_assert( status == -1 );
  printf( "%d: %s\n", errno, strerror( errno ) );
  rtems_test_assert( errno == EBADF );

  printf("fstat %s\n", description);
  status = fstat( fd, &stat_buff );
  rtems_test_assert( status == -1 );
  printf( "%d: %s\n", errno, strerror( errno ) );
  rtems_test_assert( errno == EBADF );

  printf("fsync %s\n", description);
  status = fsync( fd );
  rtems_test_assert( status == -1 );
  printf( "%d: %s\n", errno, strerror( errno ) );
  rtems_test_assert( errno == EBADF );

  printf("ioctl %s\n", description);
  status = ioctl( fd, 0 );
  rtems_test_assert( status == -1 );
  printf( "%d: %s\n", errno, strerror( errno ) );
  rtems_test_assert( errno == EBADF );

  printf("_lseek_r %s\n", description);
  res = _lseek_r (NULL, fd, 0, SEEK_SET);
  rtems_test_assert( res == -1 );
  printf( "%d: %s\n", errno, strerror( errno ) );
  rtems_test_assert( errno == EBADF );

  printf("readv %s\n", description);
  status = readv(fd, vec, 4);
  rtems_test_assert( status == -1 );
  printf( "%d: %s\n", errno, strerror( errno ) );
  rtems_test_assert( errno == EBADF );

  printf("writev %s\n", description);
  status = writev(fd, vec, 4);
  rtems_test_assert( status == -1 );
  printf( "%d: %s\n", errno, strerror( errno ) );
  rtems_test_assert( errno == EBADF );

  printf("write %s\n", description);
  status = write(fd, "1234", 4);
  rtems_test_assert( status == -1 );
  printf( "%d: %s\n", errno, strerror( errno ) );
  rtems_test_assert( errno == EBADF );
}
Beispiel #9
0
      tempfd = fd = mkstemp (fname);
      if (fd == -1)
	FAIL_EXIT1 ("mkstemp failed: %m");
      unlink (fname);

      xpthread_barrier_wait (&b2);
    }

  xpthread_barrier_wait (&b2);

  ssize_t s;
  pthread_cleanup_push (cl, NULL);

  char buf[100];
  struct iovec iov[1] = { [0] = { .iov_base = buf, .iov_len = sizeof (buf) } };
  s = readv (fd, iov, 1);

  pthread_cleanup_pop (0);

  FAIL_EXIT1 ("readv returns with %zd", s);
}


static void *
tf_write  (void *arg)
{
  int fd;

  if (arg == NULL)
    fd = fds[1];
  else
Beispiel #10
0
void primorial_gaps(const char *store, uint64_t num) {
  uint64_t reprimes[REPRIMES + 1];
  uint64_t primes[SMALLPRIMES];

  printf("1 = 3 - 2\n");
  printf("2 = 5 - 3\n");
  printf("4 = 11 - 7\n");

  uint64_t pcount = reprime_generate(reprimes, primes, SMALLPRIMES);

  uint64_t last_prime = 13;
  uint64_t greatest_gap = 4;

  int i;

  for (i = 0; i < pcount; i++) {
    if (primes[i] - last_prime > greatest_gap) {
      greatest_gap = primes[i] - last_prime;
      printf("%llu = %llu - %llu\n", (unsigned long long)greatest_gap, (unsigned long long)primes[i], (unsigned long long)last_prime);
    }

    last_prime = primes[i];
  }

  struct iovec vectors[2];
  unsigned char junk[8192 - REPRIMES / 8];

  vectors[0].iov_base = junk;
  vectors[0].iov_len = 8192 - REPRIMES / 8;

  unsigned char reprime_bits[REPRIMES / 8];

  vectors[1].iov_base = reprime_bits;
  vectors[1].iov_len = REPRIMES / 8;

  int fd = open(store, O_RDONLY);

  if (fd == -1) {
    fprintf(stderr, "could not open file: %s\n", store);
    exit(IO_ERR);
  }

  struct stat st;

  if (fstat(fd, &st) == -1) {
    fprintf(stderr, "could not stat file: %s\n", store);
    close(fd);
    exit(IO_ERR);
  }

  off_t pages = st.st_size / 8192;
  off_t page;

  for (page = 1; page <= pages; page++) {
    if (readv(fd, vectors, 2) != 8192) {
      fprintf(stderr, "could not read full page\n");
      close(fd);
      exit(IO_ERR);
    }

    uint64_t base = (uint64_t)MODULUS * page;
    int reprime_offset;

    for (reprime_offset = 0; reprime_offset < REPRIMES; reprime_offset++) {
      if (reprime_bits[reprime_offset / 8] & (1U << reprime_offset % 8)) {
	uint64_t current_prime = base + reprimes[reprime_offset];
	uint64_t current_gap = current_prime - last_prime;

	if (current_gap > greatest_gap) {
	  printf("%llu = %llu - %llu\n", (unsigned long long)current_gap, (unsigned long long)current_prime, (unsigned long long)last_prime);
	  greatest_gap = current_gap;
	}

	last_prime = current_prime;
      }
    }
  }

  close(fd);
  exit(0);
}
Beispiel #11
0
int MPID_nem_tcp_module_lmt_start_recv (MPIDI_VC_t *vc, MPID_Request *req)
{
    int mpi_errno = MPI_SUCCESS;
    int ret;
    MPIDI_msg_sz_t data_sz;
    int dt_contig;
    MPI_Aint dt_true_lb;
    MPID_Datatype * dt_ptr;
    MPIDI_msg_sz_t last;
    int nb;
    int r_len;
    MPIDI_CH3I_VC *vc_ch = (MPIDI_CH3I_VC *)vc->channel_private;
    MPIDI_STATE_DECL(MPID_STATE_MPID_NEM_TCP_MODULE_LMT_START_RECV);

    MPIDI_FUNC_ENTER(MPID_STATE_MPID_NEM_TCP_MODULE_LMT_START_RECV);

    free_cookie (vc_ch->net.tcp.lmt_cookie);

    if (!vc_ch->net.tcp.lmt_connected)
    {
        int len;
        struct sockaddr_in saddr;
        int connfd;

        len = sizeof (saddr);
        connfd = accept (vc_ch->net.tcp.lmt_desc, (struct sockaddr *)&saddr, &len);
        MPIU_ERR_CHKANDJUMP2 (connfd == -1, mpi_errno, MPI_ERR_OTHER, "**sock|poll|accept", "**sock|poll|accept %d %s", errno, strerror (errno));

        /* close listen fd */
        do
            ret = close (vc_ch->net.tcp.lmt_desc);
        while (ret == -1 && errno == EINTR);
        MPIU_ERR_CHKANDJUMP2 (ret == -1, mpi_errno, MPI_ERR_OTHER, "**closesocket", "**closesocket %s %d", strerror (errno), errno);

        /* set lmt_desc to new connected fd */
        vc_ch->net.tcp.lmt_desc = connfd;
        vc_ch->net.tcp.lmt_connected = 1;

        //        ret = fcntl (vc_ch->net.tcp.lmt_desc, F_SETFL, O_NONBLOCK);
        //        MPIU_ERR_CHKANDJUMP2 (ret == -1, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %s %d", strerror (errno), errno);
    }

    MPIDI_Datatype_get_info (req->dev.user_count, req->dev.datatype, dt_contig, data_sz, dt_ptr, dt_true_lb);

    if (data_sz > vc_ch->net.tcp.lmt_s_len)
    {
        data_sz = vc_ch->net.tcp.lmt_s_len;
    }
    else if (data_sz < vc_ch->net.tcp.lmt_s_len)
    {
        /* message will be truncated */
        r_len = data_sz;
 	req->status.MPI_ERROR = MPIU_ERR_SET2 (mpi_errno, MPI_ERR_TRUNCATE, "**truncate", "**truncate %d %d", vc_ch->net.tcp.lmt_s_len, r_len);
    }

    MPID_Segment_init (req->dev.user_buf, req->dev.user_count, req->dev.datatype, &req->dev.segment, 0);
    req->dev.segment_first = 0;
    req->dev.segment_size = data_sz;
    req->dev.iov_count = MPID_IOV_LIMIT;
    req->dev.iov_offset = 0;
    last = data_sz;

    do
    {
        int iov_offset;
        int left_to_recv;

        MPID_Segment_unpack_vector (&req->dev.segment, req->dev.segment_first, &last, req->dev.iov, &req->dev.iov_count);

        left_to_recv = last - req->dev.segment_first;
        iov_offset = 0;

#ifdef TESTING_CHUNKING
        {
            char *buf = req->dev.iov[0].MPID_IOV_BUF;
            int l;
            while (left_to_recv)
            {
                if (left_to_recv > CHUNK)
                    l = CHUNK;
                else
                    l = left_to_recv;

                do
                    nb = read (vc_ch->net.tcp.lmt_desc, buf, l);
                while (nb == -1 && errno == EINTR);
                MPIU_ERR_CHKANDJUMP (nb == -1, mpi_errno, MPI_ERR_OTHER, "**sock_writev");

                left_to_recv -= nb;
                buf += nb;
            }
            MPIDI_CH3U_Request_complete (req);
            goto fn_exit;
        }
#endif

        do
            nb = readv (vc_ch->net.tcp.lmt_desc, &req->dev.iov[iov_offset], req->dev.iov_count - iov_offset);
        while (nb == -1 && errno == EINTR);
        MPIU_ERR_CHKANDJUMP2 (nb == -1, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %s %d", strerror (errno), errno);
        MPIU_ERR_CHKANDJUMP (nb == 0, mpi_errno, MPI_ERR_OTHER, "**fail");

        left_to_recv -= nb;
        while (left_to_recv)
        { /* recv rest of iov */
            while (nb >= req->dev.iov[iov_offset].MPID_IOV_LEN)
            { /* update iov to reflect sent bytes */
                nb -= req->dev.iov[iov_offset].MPID_IOV_LEN;
                ++iov_offset;
            }
            req->dev.iov[iov_offset].MPID_IOV_BUF = (char *)req->dev.iov[iov_offset].MPID_IOV_BUF + nb;
            req->dev.iov[iov_offset].MPID_IOV_LEN -= nb;

            do
                nb = readv (vc_ch->net.tcp.lmt_desc, &req->dev.iov[iov_offset], req->dev.iov_count - iov_offset);
            while (nb == -1 && errno == EINTR);
            MPIU_ERR_CHKANDJUMP2 (nb == -1, mpi_errno, MPI_ERR_OTHER, "**fail", "**fail %s %d", strerror (errno), errno);
            MPIU_ERR_CHKANDJUMP (nb == 0, mpi_errno, MPI_ERR_OTHER, "**fail");
            left_to_recv -= nb;
        }
    }
    while (last < data_sz);

    MPIDI_CH3U_Request_complete (req);

 fn_exit:
    MPIDI_FUNC_EXIT(MPID_STATE_MPID_NEM_TCP_MODULE_LMT_START_RECV);
    return mpi_errno;
 fn_fail:
    goto fn_exit;
}
Beispiel #12
0
/*
 * Read from so's socket into sb_snd, updating all relevant sbuf fields
 * NOTE: This will only be called if it is select()ed for reading, so
 * a read() of 0 (or less) means it's disconnected
 */
int
soread(struct socket *so)
{
	int n, nn;
	struct sbuf *sb = &so->so_snd;
	struct iovec iov[2];

	DEBUG_CALL("soread");
	DEBUG_ARG("so = %p", so);

	/*
	 * No need to check if there's enough room to read.
	 * soread wouldn't have been called if there weren't
	 */
	sopreprbuf(so, iov, &n);

#ifdef HAVE_READV
	nn = readv(so->s, (struct iovec *)iov, n);
	DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
#else
	nn = qemu_recv(so->s, iov[0].iov_base, iov[0].iov_len,0);
#endif
	if (nn <= 0) {
		if (nn < 0 && (errno == EINTR || errno == EAGAIN))
			return 0;
		else {
			int err;
			socklen_t slen = sizeof err;

			err = errno;
			if (nn == 0) {
				getsockopt(so->s, SOL_SOCKET, SO_ERROR,
					   &err, &slen);
			}

			DEBUG_MISC((dfd, " --- soread() disconnected, nn = %d, errno = %d-%s\n", nn, errno,strerror(errno)));
			sofcantrcvmore(so);

			if (err == ECONNRESET || err == ECONNREFUSED
			    || err == ENOTCONN || err == EPIPE) {
				tcp_drop(sototcpcb(so), err);
			} else {
				tcp_sockclosed(sototcpcb(so));
			}
			return -1;
		}
	}

#ifndef HAVE_READV
	/*
	 * If there was no error, try and read the second time round
	 * We read again if n = 2 (ie, there's another part of the buffer)
	 * and we read as much as we could in the first read
	 * We don't test for <= 0 this time, because there legitimately
	 * might not be any more data (since the socket is non-blocking),
	 * a close will be detected on next iteration.
	 * A return of -1 won't (shouldn't) happen, since it didn't happen above
	 */
	if (n == 2 && nn == iov[0].iov_len) {
            int ret;
            ret = qemu_recv(so->s, iov[1].iov_base, iov[1].iov_len,0);
            if (ret > 0)
                nn += ret;
        }

	DEBUG_MISC((dfd, " ... read nn = %d bytes\n", nn));
#endif

	/* Update fields */
	sb->sb_cc += nn;
	sb->sb_wptr += nn;
	if (sb->sb_wptr >= (sb->sb_data + sb->sb_datalen))
		sb->sb_wptr -= sb->sb_datalen;
	return nn;
}
Beispiel #13
0
int32_t TransportUDP::read(uint8_t* buffer, uint32_t size)
{
  {
    boost::mutex::scoped_lock lock(close_mutex_);
    if (closed_)
    {
      ROSCPP_LOG_DEBUG("Tried to read on a closed socket [%d]", sock_);
      return -1;
    }
  }

  ROS_ASSERT((int32_t)size > 0);

  uint32_t bytes_read = 0;

  while (bytes_read < size)
  {
    TransportUDPHeader header;

    // Get the data either from the reorder buffer or the socket
    // copy_bytes will contain the read size.
    // from_previous is true if the data belongs to the previous UDP datagram.
    uint32_t copy_bytes = 0;
    bool from_previous = false;
    if (reorder_bytes_)
    {
      if (reorder_start_ != reorder_buffer_)
      {
        from_previous = true;
      }

      copy_bytes = std::min(size - bytes_read, reorder_bytes_);
      header = reorder_header_;
      memcpy(buffer + bytes_read, reorder_start_, copy_bytes);
      reorder_bytes_ -= copy_bytes;
      reorder_start_ += copy_bytes;
    }
    else
    {
      if (data_filled_ == 0)
      {
#if defined(WIN32)
    	SSIZE_T num_bytes = 0;
        DWORD received_bytes = 0;
        DWORD flags = 0;
        WSABUF iov[2];
        iov[0].buf = reinterpret_cast<char*>(&header);
        iov[0].len = sizeof(header);
        iov[1].buf = reinterpret_cast<char*>(data_buffer_);
        iov[1].len = max_datagram_size_ - sizeof(header);
		int rc  = WSARecv(sock_, iov, 2, &received_bytes, &flags, NULL, NULL);
		if ( rc == SOCKET_ERROR) {
		  num_bytes = -1;
		} else {
			num_bytes = received_bytes;
		}
#else
        ssize_t num_bytes;
        struct iovec iov[2];
        iov[0].iov_base = &header;
        iov[0].iov_len = sizeof(header);
        iov[1].iov_base = data_buffer_;
        iov[1].iov_len = max_datagram_size_ - sizeof(header);
        // Read a datagram with header
        num_bytes = readv(sock_, iov, 2);
#endif
        if (num_bytes < 0)
        {
          if ( last_socket_error_is_would_block() )
          {
            num_bytes = 0;
            break;
          }
          else
          {
            ROSCPP_LOG_DEBUG("readv() failed with error [%s]",  last_socket_error_string());
            close();
            break;
          }
        }
        else if (num_bytes == 0)
        {
          ROSCPP_LOG_DEBUG("Socket [%d] received 0/%d bytes, closing", sock_, size);
          close();
          return -1;
        }
        else if (num_bytes < (unsigned) sizeof(header))
        {
          ROS_ERROR("Socket [%d] received short header (%d bytes): %s", sock_, int(num_bytes),  last_socket_error_string());
          close();
          return -1;
        }

		num_bytes -= sizeof(header);
        data_filled_ = num_bytes;
        data_start_ = data_buffer_;
      }
      else
      {
        from_previous = true;
      }

      copy_bytes = std::min(size - bytes_read, data_filled_);
      // Copy from the data buffer, whether it has data left in it from a previous datagram or
      // was just filled by readv()
      memcpy(buffer + bytes_read, data_start_, copy_bytes);
      data_filled_ -= copy_bytes;
      data_start_ += copy_bytes;
    }


    if (from_previous)
    {
      // We are simply reading data from the last UDP datagram, nothing to
      // parse
      bytes_read += copy_bytes;
    }
    else
    {
      // This datagram is new, process header
      switch (header.op_)
      {
        case ROS_UDP_DATA0:
          if (current_message_id_)
          {
            ROS_DEBUG("Received new message [%d:%d], while still working on [%d] (block %d of %d)", header.message_id_, header.block_, current_message_id_, last_block_ + 1, total_blocks_);
            reorder_header_ = header;

            // Copy the entire data buffer to the reorder buffer, as we will
            // need to replay this UDP datagram in the next call.
            reorder_bytes_ = data_filled_ + (data_start_ - data_buffer_);
            memcpy(reorder_buffer_, data_buffer_, reorder_bytes_);
            reorder_start_ = reorder_buffer_;
            current_message_id_ = 0;
            total_blocks_ = 0;
            last_block_ = 0;

            data_filled_ = 0;
            data_start_ = data_buffer_;
            return -1;
          }
          total_blocks_ = header.block_;
          last_block_ = 0;
          current_message_id_ = header.message_id_;
          break;
        case ROS_UDP_DATAN:
          if (header.message_id_ != current_message_id_)
          {
            ROS_DEBUG("Message Id mismatch: %d != %d", header.message_id_, current_message_id_);
            data_filled_ = 0; // discard datagram
            return 0;
          }
          if (header.block_ != last_block_ + 1)
          {
            ROS_DEBUG("Expected block %d, received %d", last_block_ + 1, header.block_);
            data_filled_ = 0; // discard datagram
            return 0;
          }
          last_block_ = header.block_;

          break;
        default:
          ROS_ERROR("Unexpected UDP header OP [%d]", header.op_);
          return -1;
      }

      bytes_read += copy_bytes;

      if (last_block_ == (total_blocks_ - 1))
      {
        current_message_id_ = 0;
        break;
      }
    }
  }

  return bytes_read;
}
Beispiel #14
0
int
run_file_tests(char *testfile)
{
    int ret = -1;
    struct stat buf;

    assert(testfile);
    fprintf(stdout, "Testing creat");
    ret = creat(testfile, S_IRWXU);
    check_err(ret, "creat", 2);

    fprintf(stdout, "Testing close");
    ret = close(ret);
    check_err(ret, "close", 2);

    fprintf(stdout, "Testing open");
    ret = open(testfile, O_RDONLY);
    check_err(ret, "open", 2);

    fprintf(stdout, "Testing read");
    ret = read(0, NULL, 0);
    check_err(ret, "read", 2);

    fprintf(stdout, "Testing readv");
    ret = readv(0, NULL, 0);
    check_err(ret, "readv", 2);

    fprintf(stdout, "Testing pread");
    ret = pread(0, NULL, 0, 0);
    check_err(ret, "pread", 2);

    fprintf(stdout, "Testing write");
    ret = write(0, NULL, 0);
    check_err(ret, "write", 2);

    fprintf(stdout, "Testing writev");
    ret = writev(0, NULL, 0);
    check_err(ret, "writev", 2);

    fprintf(stdout, "Testing pwrite");
    ret = pwrite(0, NULL, 0, 0);
    check_err(ret, "pwrite", 2);

    fprintf(stdout, "Testing lseek");
    ret = lseek(0, 0, 0);
    check_err(ret, "lseek", 2);

    fprintf(stdout, "Testing dup");
    ret = dup(0);
    check_err(ret, "dup", 2);

    fprintf(stdout, "Testing dup2");
    ret = dup2(0, 0);
    check_err(ret, "dup2", 2);

    fprintf(stdout, "Testing fchmod");
    ret = fchmod(0, 0);
    check_err(ret, "fchmod", 2);

    fprintf(stdout, "Testing fchown");
    ret = fchown(0, 0, 0);
    check_err(ret, "fchown", 2);

    fprintf(stdout, "Testing fsync");
    ret = fsync(0);
    check_err(ret, "fsync", 2);

    fprintf(stdout, "Testing ftruncate");
    ret = ftruncate(0, 0);
    check_err(ret, "ftruncate", 1);

    fprintf(stdout, "Testing fstat");
    ret = fstat(0, &buf);
    check_err(ret, "fstat", 1);

    fprintf(stdout, "Testing sendfile");
    ret = sendfile(0, 0, NULL, 0);
    check_err(ret, "sendfile", 1);

    fprintf(stdout, "Testing fcntl");
    ret = fcntl(0, 0, NULL);
    check_err(ret, "fcntl", 2);

    fprintf(stdout, "Testing close");
    ret = close(ret);
    check_err(ret, "close", 2);

    fprintf(stdout, "Testing remove");
    ret = remove(testfile);
    check_err(ret, "remove", 2);

    return ret;
}
Beispiel #15
0
ssize_t ARSAL_Socket_Readv (int sockfd, const struct iovec *iov, int iovcnt)
{
    return readv (sockfd, iov, iovcnt);
}
Beispiel #16
0
/*****************************************************************************
 * Readv commands.
 *****************************************************************************/
static int libc_readv ( dvdcss_t dvdcss, const struct iovec *p_iovec,
                        int i_blocks )
{
#if defined( _WIN32 )
    int i_index, i_len, i_total = 0;
    unsigned char *p_base;
    int i_bytes;

    for( i_index = i_blocks;
         i_index;
         i_index--, p_iovec++ )
    {
        i_len  = p_iovec->iov_len;
        p_base = p_iovec->iov_base;

        if( i_len <= 0 )
        {
            continue;
        }

        i_bytes = read( dvdcss->i_fd, p_base, i_len );

        if( i_bytes < 0 )
        {
            /* One of the reads failed, too bad.
             * We won't even bother returning the reads that went OK,
             * and as in the POSIX spec the file position is left
             * unspecified after a failure */
            dvdcss->i_pos = -1;
            return -1;
        }

        i_total += i_bytes;
        i_total /= DVDCSS_BLOCK_SIZE;

        if( i_bytes != i_len )
        {
            /* We reached the end of the file or a signal interrupted
             * the read. Return a partial read. */
            int i_seek;

            dvdcss->i_pos = -1;
            i_seek = libc_seek( dvdcss, i_total );
            if( i_seek < 0 )
            {
                return i_seek;
            }

            /* We have to return now so that i_pos isn't clobbered */
            return i_total;
        }
    }

    dvdcss->i_pos += i_total;
    return i_total;
#else
    int i_read = readv( dvdcss->i_fd, p_iovec, i_blocks );

    if( i_read < 0 )
    {
        dvdcss->i_pos = -1;
        return i_read;
    }

    i_read /= DVDCSS_BLOCK_SIZE;
    dvdcss->i_pos += i_read;
    return i_read;
#endif
}
Beispiel #17
0
void RtpH264_Run(int sfd, RtpH264_OnPicture onPicture)
{
#define INBUF_SIZE (1024 * 128)
  uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
  /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
  memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);

  AVFrame *picture = avcodec_alloc_frame();
  AVPacket avpkt;
  av_init_packet(&avpkt);
  int frame_count = 0;

  unsigned short sequence = 0;
  unsigned int timestamp = 0;
  
  while(1)  {
    //int ready = 0;
    fd_set rfds;
    FD_ZERO(&rfds);
    FD_SET(sfd, &rfds);

    struct timeval timeout;  /*Timer for operation select*/
    timeout.tv_sec = 0;
    timeout.tv_usec = 10000; /*10 ms*/

    if(select(sfd+1, &rfds, 0, 0, &timeout) <= 0) {
      if(bStop)
        break;
      else
        continue;
    }

    if(FD_ISSET(sfd, &rfds) <= 0)
      continue;
    
    rtp_hdr_t rtp;
    unsigned char buf[64];
    memset(buf, 0, 64);
    int r = recv(sfd, buf, sizeof(rtp_hdr_t) + 8, MSG_PEEK);  /*  Peek data from socket, so that we could determin how to read data from socket*/
    if(r <= sizeof(rtp_hdr_t) || r == -1)  {
      recv(sfd, buf, sizeof(rtp_hdr_t) + 8, 0); /*Read invalid packet*/
      printf("Warning !!! Invalid packet\n");
      continue; /*Invalid packet ???*/
    }

    int ready = 0;

    /*  Handle H.264 RTP Header */
    /* +---------------+
    *  |0|1|2|3|4|5|6|7|
    *  +-+-+-+-+-+-+-+-+
    *  |F|NRI|  Type   |
    *  +---------------+
    *
    * F must be 0.
    */
    unsigned char nal_ref_idc, nal_unit_type;
    unsigned char *header = buf + sizeof(rtp_hdr_t);  /*  NAL Header  */
    nal_ref_idc = (header[0] & 0x60) >> 5;  /*  NRI */
//printf("nal_ref_idc = %d\n", nal_ref_idc);
    nal_unit_type = header[0] & 0x1f;       /*  Type  */
//printf("nal_unit_type = %d\n", nal_unit_type);

    switch (nal_unit_type) {
      case 0:
      case 30:
      case 31:
        /* undefined */
        break;
      case 25:
        /* STAP-B    Single-time aggregation packet     5.7.1 */
        /* 2 byte extra header for DON */
        /* fallthrough */
      case 24:
        /* STAP-A    Single-time aggregation packet     5.7.1 */
        break;
      case 26:
        /* MTAP16    Multi-time aggregation packet      5.7.2 */
        /* fallthrough, not implemented */
      case 27:
        /* MTAP24    Multi-time aggregation packet      5.7.2 */
        break;
      case 28:
        /* FU-A      Fragmentation unit                 5.8 */
      case 29:  {
        /* FU-B      Fragmentation unit                 5.8 */
        /* +---------------+
        * |0|1|2|3|4|5|6|7|
        * +-+-+-+-+-+-+-+-+
        * |S|E|R|  Type   |
        * +---------------+
        *
        * R is reserved and always 0
        */

        /*Really read packet*/
        struct iovec data[3];

        data[0].iov_base = &rtp;
        data[0].iov_len = sizeof(rtp_hdr_t);

        if(nal_unit_type == 28) {
          /* strip off FU indicator and FU header bytes */
          data[1].iov_base = buf;
          data[1].iov_len = 2;
        } else if(nal_unit_type == 29) {
          /* strip off FU indicator and FU header and DON bytes */
          data[1].iov_base = buf;
          data[1].iov_len = 4;
        }
        
        /* NAL unit starts here */
        if((header[1] & 0x80) == 0x80)  {
          data[2].iov_base = &inbuf[5];
          data[2].iov_len = INBUF_SIZE - 5;
          
          r = readv(sfd, data, 3);
          if(r <= (sizeof(rtp_hdr_t) + 2))  {
            printf("Socket read fail !!!\n");
            goto cleanup;
          }

          unsigned char fu_indicator = buf[0];
          unsigned char fu_header = buf[1];
          
          timestamp = ntohl(rtp.ts);
          sequence = ntohs(rtp.seq);            
          
          inbuf[0] = 0x00;
          inbuf[1] = 0x00;
          inbuf[2] = 0x00;
          inbuf[3] = 0x01;
          inbuf[4] = (fu_indicator & 0xe0) | (fu_header & 0x1f);
          if(nal_unit_type == 28)
            avpkt.size = (r - sizeof(rtp_hdr_t) - 2 + 5);
          else if(nal_unit_type == 29)
            avpkt.size = (r - sizeof(rtp_hdr_t) - 4 + 5);
          avpkt.data = inbuf;
//printf("nalu = %d\n", fu_header & 0x1f);
          
          if((fu_header & 0x1f) == 7)
            avpkt.flags |= PKT_FLAG_KEY;
//          avpkt.pts = frame_count++;
//printf("avpkt.pts = %d\n", avpkt.pts);          
          break;
        } else  {
          data[2].iov_base = inbuf + avpkt.size;
          data[2].iov_len = INBUF_SIZE - avpkt.size;

          r = readv(sfd, data, 3);

          //unsigned char fu_indicator = buf[0];
          unsigned char fu_header = buf[1];

          if(r <= (sizeof(rtp_hdr_t) + 2) || r == -1)  {
            printf("Socket read fail !!!\n");
            goto cleanup;
          }

          if(ntohl(rtp.ts) != timestamp)  {
            printf("Miss match timestamp %d ( expect %d )\n", ntohl(rtp.ts), timestamp);
          }

          if(ntohs(rtp.seq) != ++sequence)  {
            printf("Wrong sequence number %u ( expect %u )\n", ntohs(rtp.seq), sequence);
          }

          if(nal_unit_type == 28)
            avpkt.size += (r - sizeof(rtp_hdr_t) - 2);
          else if(nal_unit_type == 29)
            avpkt.size += (r - sizeof(rtp_hdr_t) - 4);
//printf("frame size : %d\n", avpkt.size);
        }
        
        /* NAL unit ends  */
        if((header[1] & 0x40) == 0x40)  {
          ready = 1;  /*We are done, go to decode*/
          break;
        }

        break;
      }
      default:  {
        /* 1-23   NAL unit  Single NAL unit packet per H.264   5.6 */
        /* the entire payload is the output buffer */
        struct iovec data[2];

        data[0].iov_base = &rtp;
        data[0].iov_len = sizeof(rtp_hdr_t);

        inbuf[0] = 0x00;
        inbuf[1] = 0x00;
        inbuf[2] = 0x00;
        inbuf[3] = 0x01;

        data[1].iov_base = &inbuf[4];
        data[1].iov_len = INBUF_SIZE - 4;

        r = readv(sfd, data, 2);
        if(r <= sizeof(rtp_hdr_t) || r == -1)  {
          printf("Socket read fail !!!\n");
          goto cleanup;
        }

        avpkt.size = (r - sizeof(rtp_hdr_t) + 4);
        avpkt.data = inbuf;
        
        ready = 1;  /*We are done, go to decode*/

        break;
      }
    }

    int got_picture;
    while(ready && avpkt.size > 0) {
      avpkt.pts = ++frame_count;
//printf("frame size : %d\n", avpkt.size);
//printf("avpkt.dts = %d\n", avpkt.dts);
//      int len = avcodec_decode_video(context, picture, &got_picture, avpkt.data, avpkt.size);
      int len = avcodec_decode_video2(context, picture, &got_picture, &avpkt);
//printf("context->coded_frame->pts = %d\n", context->coded_frame->pts);  /*  0 */
//printf("picture->pts = %d\n", picture->pts);
//printf("picture->pict_type = %d\n", picture->pict_type);
//printf("picture->key_frame = %d\n", picture->key_frame);
//printf("picture->interlaced_frame = %d\n", picture->interlaced_frame);
//printf("avpkt.duration = %d\n", avpkt.duration);
      
      Mp4Mux_WriteVideo(&avpkt, timestamp);

      if(len < 0) {
        fprintf(stderr, "Error while decoding frame\n");
        av_init_packet(&avpkt);
        break;
      }
      
      if(got_picture) {
//        printf("Decode length : %d\n", len);
//        fflush(stdout);
        /* the picture is allocated by the decoder. no need to
               free it */
        if(onPicture)
          onPicture(picture->data[0], picture->linesize[0], context->width, context->height);

        av_init_packet(&avpkt);
        break;
      }
      avpkt.size -= len;
      avpkt.data += len;
    }
  }

cleanup:
  av_free(picture);
  
  return;
}
Beispiel #18
0
int main(int argc, char **argv)
{	int	x = 0;
	char	*args[10];

	setuid(2);

	signal(SIGCHLD, sigchld);
	do_signals();

	x += getpid();
	x += getppid();
	x += getuid();
	x += getgid();
	x += setsid();
	x += seteuid();
	x += setegid();
	lseek(0, 0, -1);
	kill(0, 0);
	signal(99, 0);
	signal(SIGINT, int_handler);
	signal(SIGSEGV, segv_handler);
//	*(int *) 0 = 0;
	pipe(0);
	munmap(0, 0);
	mincore(0, 0);
	shmget(0);
	shmat(0);

	line = __LINE__;
	poll(-1, 0, 0);
	signal(SIGSEGV, SIG_IGN);
//	ppoll(-1, -1, -1, 0);
	signal(SIGSEGV, SIG_DFL);
	sched_yield();
	readv(-1, 0, 0, 0);
	writev(-1, 0, 0, 0);
	msync(0, 0, 0);
	fsync(-1);
	fdatasync(-1);
	semget(0, 0, 0);
	semctl(0, 0, 0);
	uselib(NULL);
	pivot_root(0, 0);
	personality(-1);
	setfsuid(-1);
	flock(-1, 0);
	shmdt(0, 0, 0);
	times(0);
	mremap(0, 0, 0, 0, 0);
	madvise(0, 0, 0);
	fchown(-1, 0, 0);
	lchown(0, 0, 0);
	setreuid();
	setregid();
	link("/nonexistant", "/also-nonexistant");

	do_slow();

	symlink("/nothing", "/");
	rename("/", "/");
	mkdir("/junk/stuff////0", 0777);
	geteuid();
	getsid();
	getpgid();
	getresuid();
	getresgid();
	getpgid();
	ptrace(-1, 0, 0, 0);
	semop(0, 0, 0);
	capget(0, 0);

	line = __LINE__;
	gettimeofday(0, 0);
	settimeofday(0, 0);
	dup(-1);
	dup2(-1, -1);
	shmctl(0, 0, 0, 0);
	execve("/bin/nothing", "/bin/nothing", 0);
	alarm(9999);
	bind(0, 0, 0);
	socket(0, 0, 0);
	accept(0, 0, 0);
	listen(0);
	shutdown(0);
	getsockname(0, 0, 0);
	getpeername(0, 0, 0);
	truncate(0, 0);
	ftruncate(0, 0);
	line = __LINE__;
	if (vfork() == 0)
		exit(0);
	line = __LINE__;
	x = opendir("/", 0, 0);
	line = __LINE__;
	readdir(x, 0, 0);
	line = __LINE__;
	closedir(x);
	line = __LINE__;
	chroot("/");
	line = __LINE__;
	sigaction(0, 0, 0);
	line = __LINE__;
	sigprocmask(0, 0, 0);
	x += open("/nothing", 0);
	x += chdir("/nothing");
	x += mknod("/nothing/nothing", 0);
	x += ioctl();
	execve("/nothing", NULL, NULL);
	line = __LINE__;
	x += close(-2);
	line = __LINE__;
	if (fork() == 0)
		exit(0);
	line = __LINE__;
	clone(clone_func, 0, 0, 0);
	line = __LINE__;
	brk(0);
	sbrk(0);
	line = __LINE__;
	mmap(0, 0, 0, 0, 0);
	line = __LINE__;
	uname(0);
	line = __LINE__;
	getcwd(0, 0);
	line = __LINE__;
	iopl(3);
	ioperm(0, 0, 0);
	mount(0, 0, 0, 0, 0);
	umount(0, 0);
	umount(0, 0, 0);
	swapon(0, 0);
	swapoff(0);
	sethostname(0);
	line = __LINE__;
	time(NULL);
	unlink("/nothing");
	line = __LINE__;
	rmdir("/nothing");
	chmod(0, 0);
	line = __LINE__;
# if defined(__i386) || defined(__amd64)
	modify_ldt(0);
# endif

	stat("/doing-nice", 0);
	nice(0);

	args[0] = "/bin/df";
	args[1] = "-l";
	args[2] = NULL;
	close(1);
	open("/dev/null", O_WRONLY);
	/***********************************************/
	/*   Some  syscalls  arent  available  direct  */
	/*   from  libc,  so get them here. We mostly  */
	/*   care  about  the  ones which have caused  */
	/*   implementation   difficulty  and  kernel  */
	/*   crashes - eventually we can be complete.  */
	/***********************************************/
	line = __LINE__;
	open("/system-dependent-syscalls-follow", 0);
	line = __LINE__;
	if (fork() == 0)
		exit(0);

	{int status;
	while (wait(&status) >= 0)
		;
	}

	sigaltstack(0, 0);

	/*vm86(0, 0);*/

	/***********************************************/
	/*   Some syscalls arent directly accessible,  */
	/*   e.g. legacy.			       */
	/***********************************************/
#if defined(__x86_64__)
	trace(__LINE__, "x64 syscalls");
	syscall(174, 0, 0, 0); // create_module
	syscall(176, 0, 0, 0); // delete_module
	syscall(178, 0, 0, 0); // query_module
#else
	trace(__LINE__, "x32 syscalls");
	syscall(0, 0, 0, 0); // restart_syscall
	syscall(34, 0, 0, 0); // nice
	syscall(59, 0, 0, 0); // oldolduname	
	syscall(109, 0, 0, 0); // olduname	
	if (fork() == 0)
		syscall(1, 0, 0, 0); // exit
#endif
	line = __LINE__;
	execve("/bin/df", args, NULL);

	fprintf(stderr, "Error: should not get here -- %s\n", strerror(errno));

	exit(1);
}
Beispiel #19
0
void cons_receiveq_fn(void *_vq) // host -> guest
{
	struct virtio_vq *vq = _vq;
	uint32_t head;
	uint32_t olen, ilen;
	uint32_t i, j;
	int num_read;
	struct iovec *iov;
	struct virtio_mmio_dev *dev = vq->vqdev->transport_dev;

	if (!vq)
		errx(1,
			"\n  %s:%d\n"
			"  Virtio device: (not sure which one): Error, device behavior.\n"
			"  The device must provide a valid virtio_vq as an argument to %s."
			, __FILE__, __LINE__, __func__);

	// NOTE: The virtio_next_avail_vq_desc will not write more than
	//       vq->vring.num entries to iov, and the device implementation
	//       (virtio_mmio.c) will not allow the driver to set vq->vring.num to a
	//       value greater than QueueNumMax (vq->qnum_max), so you are safe as
	//       long as your iov is at least vq->qnum_max iovecs in size.
	iov = malloc(vq->qnum_max * sizeof(struct iovec));

	if (vq->qready == 0x0)
		VIRTIO_DEV_ERRX(vq->vqdev,
			"The service function for queue '%s' was launched before the driver set QueueReady to 0x1."
			, vq->name);

	// NOTE: This will block in 2 places:
	//       - reading from stdin
	//       - reading from eventfd in virtio_next_avail_vq_desc
	while (1) {
		head = virtio_next_avail_vq_desc(vq, iov, &olen, &ilen);

		if (olen) {
			// virtio-v1.0-cs04 s5.3.6.1 Device Operation (console section)
			VIRTIO_DRI_ERRX(vq->vqdev,
				"The driver placed a device-readable buffer in the console device's receiveq.\n"
				"  See virtio-v1.0-cs04 s5.3.6.1 Device Operation");
		}

		// TODO: We may want to add some sort of console abort
		//       (e.g. type q and enter to quit)
		// readv from stdin as much as we can (to end of bufs or end of input)
		num_read = readv(0, iov, ilen);
		if (num_read < 0)
			VIRTIO_DEV_ERRX(vq->vqdev,
				"Encountered an error trying to read input from stdin (fd 0).");

		// You pass the number of bytes written to virtio_add_used_desc
		virtio_add_used_desc(vq, head, num_read);

		// Poke the guest however the mmio transport prefers
		// NOTE: assuming that the mmio transport was used for now.
		virtio_mmio_set_vring_irq(dev);
		if (dev->poke_guest)
			dev->poke_guest(dev->vec);
		else
			VIRTIO_DEV_ERRX(vq->vqdev,
				"The host MUST provide a way for device interrupts to be sent to the guest. The 'poke_guest' function pointer on the vq->vqdev->transport_dev (assumed to be a struct virtio_mmio_dev) was not set.");
	}
	free(iov);
}
Beispiel #20
0
/* net_receiveq_fn receives packets for the guest through the virtio networking
 * device and the _vq virtio queue.
 */
void net_receiveq_fn(void *_vq)
{
	struct virtio_vq *vq = _vq;
	uint32_t head;
	uint32_t olen, ilen;
	int num_read;
	struct iovec *iov;
	struct virtio_mmio_dev *dev = vq->vqdev->transport_dev;
	int fd;
	struct virtio_net_hdr_v1 *net_header;

	fd = open(data_path, O_RDWR);
	if (fd == -1)
		VIRTIO_DEV_ERRX(vq->vqdev, "Could not open data file for ether1.");

	if (!vq)
		VIRTIO_DEV_ERRX(vq->vqdev,
			"\n  %s:%d\n"
			"  Virtio device: (not sure which one): Error, device behavior.\n"
			"  The device must provide a valid virtio_vq as an argument to %s."
			, __FILE__, __LINE__, __func__);

	if (vq->qready == 0x0)
		VIRTIO_DEV_ERRX(vq->vqdev,
			"The service function for queue '%s' was launched before the driver set QueueReady to 0x1.",
			vq->name);

	iov = malloc(vq->qnum_max * sizeof(struct iovec));
	assert(iov != NULL);

	if (!dev->poke_guest) {
		free(iov);
		VIRTIO_DEV_ERRX(vq->vqdev,
		                "The 'poke_guest' function pointer was not set.");
	}

	for (;;) {
		head = virtio_next_avail_vq_desc(vq, iov, &olen, &ilen);
		if (olen) {
			free(iov);
			VIRTIO_DRI_ERRX(vq->vqdev,
				"The driver placed a device-readable buffer in the net device's receiveq.\n"
				"  See virtio-v1.0-cs04 s5.3.6.1 Device Operation");
		}

		/* For receive the virtio header is in iov[0], so we only want
		 * the packet to be read into iov[1] and above.
		 */
		num_read = readv(fd, iov + 1, ilen - 1);
		if (num_read < 0) {
			free(iov);
			VIRTIO_DEV_ERRX(vq->vqdev,
				"Encountered an error trying to read input from the ethernet device.");
		}

		/* See virtio spec virtio-v1.0-cs04 s5.1.6.3.2 Device Requirements:
		 * Setting Up Receive Buffers
		 *
		 * VIRTIO_NET_F_MRG_RXBUF is not currently negotiated.
		 * num_buffers will always be 1 if VIRTIO_NET_F_MRG_RXBUF is not
		 * negotiated.
		 */
		net_header = iov[0].iov_base;
		net_header->num_buffers = 1;
		virtio_add_used_desc(vq, head, num_read + VIRTIO_HEADER_SIZE);

		virtio_mmio_set_vring_irq(dev);
		dev->poke_guest(dev->vec);
	}
}
Beispiel #21
0
int doFunctionalTest(void) {
  FILE         *fp;
  int           fd;
  struct iovec  rdvec[4];
  struct iovec  wrvec[4];
  int           rc;


  /*
   * Setup the iovec
   */
  wrvec[0].iov_base = &PatternBuffer[0];
  wrvec[0].iov_len  = 100;
  wrvec[1].iov_base = &PatternBuffer[100];
  wrvec[1].iov_len  = 200;
  wrvec[2].iov_base = &PatternBuffer[300];
  wrvec[2].iov_len  = 300;
  wrvec[3].iov_base = &PatternBuffer[600];
  wrvec[3].iov_len  = 400;

  rdvec[0].iov_base = &ReadBuffer[0];
  rdvec[0].iov_len  = 400;
  rdvec[1].iov_base = &ReadBuffer[400];
  rdvec[1].iov_len  = 300;
  rdvec[2].iov_base = &ReadBuffer[700];
  rdvec[2].iov_len  = 200;
  rdvec[3].iov_base = &ReadBuffer[900];
  rdvec[3].iov_len  = 100;

  /*
   * Write the File
   */
  fp = fopen(TESTFILE, "wt");
  if ( fp == NULL ) {
    printf( "fopen for write: %d=%s\n", errno, strerror(errno));
    return FALSE;
  }
  fd = fileno(fp);

  rc = writev(fd, wrvec, 4);
  if ( rc <= 0 ) {
    printf( "writev: %d=%s\n", errno, strerror(errno) );
    return FALSE;
  }

  fclose(fp);

  puts("File written using writev .. OK");

  /*
   * Now read it back and check it
   */

  fp = fopen(TESTFILE, "rt");
  if ( fp == NULL ) {
    printf( "fopen for write: %d=%s\n", errno, strerror(errno));
    return FALSE;
  }
  fd = fileno(fp);

  rc = readv(fd, rdvec, 4);
  if ( rc <= 0 ) {
    printf( "rd: %d=%s\n", errno, strerror(errno) );
    return FALSE;
  }

  if ( memcmp( PatternBuffer, ReadBuffer, MAX_BUFFER ) ) {
    puts("readv .. Buffers do not match");
    return FALSE;
  }

  puts("File read using readv .. OK");

  return TRUE;
}
Beispiel #22
0
int main() {
	struct test_info info;
	int test, part, fd_random, fd_file1, fd_file2;

	double speeds[PARTS];
	
	int limitsr[] = {   0,   0,    0, 2000, 3000 };
	int limitsw[] = {   0,  80, 2000, 5000, 1000 };
	int sizes[]   = { 100, 100,  700,  500,  200 };
	int counts[]  = {  10,   5,  100,  200,  500 };
	
	iolimits(0);
	
	if ((fd_random = open(fromfile, O_RDONLY)) < 0 ) {
		fprintf(stderr, "Error in open (%s)!\n", fromfile);
		return 1;
	}
	if ((fd_file1 = open(file1, O_WRONLY | O_CREAT, 0666)) < 0 ) {
		fprintf(stderr, "Error in open (%s)!\n", file1);
		return 2;
	}
	if ((read(fd_random, buf, BUFLEN*VECLEN)) < 0) {
		fprintf(stderr, "Error in read (%s)!\n", fromfile);
		return 3;
	}
	if ((write(fd_file1, buf, BUFLEN*VECLEN)) < 0) {
		fprintf(stderr, "Error in read (%s)!\n", file1);
		return 4;
	}
	
	close(fd_random);
	close(fd_file1);
	
	iolimits(1);
	
	for (test = 0; test < TESTS; ++test) {
		int r, w, t, i;
		
		limit_read(MAJORr,MINORr,limitsr[test]);
		limit_write(MAJORw,MINORw,limitsw[test]);
	
		for (part = 0; part < PARTS; ++part) {
			int pos;
			t = 0; w = 0; r = 0;
			
			if ((fd_file1 = open(file1, O_CREAT | O_RDONLY, 0666)) < 0) {
				fprintf(stderr, "Error in open (%s)!\n", file1);
				break;
			}	
			if ((fd_file2 = open(file2, O_CREAT | O_WRONLY, 0666)) < 0) {
				fprintf(stderr, "Error in open (%s)!\n", file2);
				break;
			}	
			
			for (i = 0; i < VECLEN; ++i) {
				v[i].iov_base = buf + i*counts[test];
				v[i].iov_len = counts[test];
			}

			tic();			
			for (i = 0; i < sizes[test]; ++i) {
				if ((r += readv(fd_file1, v, VECLEN)) < 0) {
					fprintf(stderr, "Error in read (%s,%d,%d,%s)!\n", file1, i, errno, strerror(errno));
					break;
				}
				if ((w += writev(fd_file2, v, VECLEN)) < 0) {
					fprintf(stderr, "Error in write (%s,%d,%d,%s)!\n", file2,i, errno, strerror(errno));
					break;
				}
			}
			t = toc();
			if (r != w)
				fprintf(stderr, "w= %d r= %d ok= %d\n", w, r, sizes[test]*counts[test]*VECLEN); 
			assert(r == w);
			if (r != sizes[test]*counts[test]*VECLEN)
				fprintf(stderr, "r= %d ok= %d\n", r, sizes[test]*counts[test]*VECLEN); 
			
			speeds[part] = (1000.0E0) * ((double) w) / ((double) t); /*  (B / usec) = (10000000/1024) * (kB/s) */
			fprintf(stderr, "limit(read): %d, limit(write): %d, count: %dB, part: %d time: %d speed1: %f\n", 
				limitsr[test], limitsw[test], counts[test], part, t, speeds[part]);
			
			close(fd_file1);
			close(fd_file2);
		}
		
		info = analyse(speeds, PARTS);
		
		fprintf(stdout, "=> TEST %d.1 => limit(read): %dkB, limit(write): %dkB, data: %dB, count: %dB, avg: %fs, dev: %fs, len: %dparts\n", 
			test, limitsr[test], limitsw[test], sizes[test], counts[test], info.avg, info.dev, info.len);
		
		
		fflush(stdout);
	}
		
	iolimits(0);
	
	return 0;
}
Beispiel #23
0
//Lowest level method that we have control before firing a read or write
//operation. The return values are typically interpretted by the caller.
//IOPending flags are pushed to this method so that IOPending flag is not
//set or reset at different places in the code.
Int32 SQScratchFile::redriveVectorIO(Int32 index)
{
  ssize_t bytesCompleted = 0;
  ExBMOStats *bmoStats = scratchSpace_->bmoStats();
  //Other book keeping
  fileHandle_[index].IOPending = TRUE;

#ifdef _DEBUG
    // Regression testing support for simulating IO Pending state.
  	if (envIOPending_ &&
  		bmoStats &&
  		(type_ == PEND_READ) &&
  		(envIOBlockCount_ == bmoStats->getScratchReadCount()))
  	{
  		envIOBlockCount_ = -1; //avoid looping.
  		bytesCompleted = -1;
  		errno = EAGAIN;
  		return -1;
    }
#endif

  if(scratchSpace_->getScratchOverflowMode() == SCRATCH_MMAP)
  {
	struct iovec *temp = (struct iovec *)remainingAddr_;
	while(remainingVectorSize_ > 0)
	{
		if(type_ == PEND_READ)
		{
		  memcpy(temp->iov_base, (fileHandle_[index].mmap + readmmapCursor_), temp->iov_len);
		  readmmapCursor_ += temp->iov_len;
		  if(bmoStats) bmoStats->incScratchReadCount();
		}
		else
		{
		  memcpy((fileHandle_[index].mmap + writemmapCursor_), temp->iov_base , temp->iov_len);
		  writemmapCursor_ += temp->iov_len;
		  if(bmoStats) bmoStats->incScratchWriteCount();
		}
		bytesCompleted_ =+ temp->iov_len;
		remainingVectorSize_ --;
		temp++;
	}//while
	remainingAddr_ = 0; //Typically this address is invalid after reaching here.
  }
  else
  {
	  while(remainingVectorSize_ > 0)
	  {
		if(type_ == PEND_READ)
		{
		  bytesCompleted = readv(fileHandle_[index].fileNum, (struct iovec*)remainingAddr_, remainingVectorSize_);
		  if(bmoStats)
			bmoStats->incScratchReadCount();
		}
		else
		{
		  bytesCompleted = writev(fileHandle_[index].fileNum, (struct iovec*)remainingAddr_, remainingVectorSize_);
		  if(bmoStats)
			bmoStats->incScratchWriteCount();
		}

		if(bytesCompleted == -1)
		{
		  //This can happen at the very first call or subsequent interations.
		  //note that remaningAddr and remainingVectorSize is already adjusted 
		  //in previous iterations if they were successful.
		  return -1;
		}

		bytesCompleted_ =+ bytesCompleted;

		//Now readjust the remaining counters by deducting bytesWritten
		while(bytesCompleted > 0)
		{
		  struct iovec *temp = (struct iovec *)remainingAddr_;
		  
		  if(bytesCompleted >= temp->iov_len)
		  {
			//advance to next vector element
			bytesCompleted -= temp->iov_len;
			remainingVectorSize_ --;
			temp++;
			remainingAddr_ = (void *)temp;
		  }
		  else
		  {
			//adjust the vector element
			temp->iov_len -= bytesCompleted;
			temp->iov_base = (void *) ((char *) temp->iov_base + bytesCompleted);
			bytesCompleted = 0;
		  }
		}//while
	  }//while
  } //not MMAP

  //If we reach here, then remainingVectorSize_ is zero. write/read operation is 
  //fully complete.
  fileHandle_[index].IOPending = FALSE;
  return 0;
}
Beispiel #24
0
static ssize_t uv__fs_read(uv_fs_t* req) {
#if defined(__linux__)
  static int no_preadv;
#endif
  ssize_t result;

#if defined(_AIX)
  struct stat buf;
  if(fstat(req->file, &buf))
    return -1;
  if(S_ISDIR(buf.st_mode)) {
    errno = EISDIR;
    return -1;
  }
#endif /* defined(_AIX) */
  if (req->off < 0) {
    if (req->nbufs == 1)
      result = read(req->file, req->bufs[0].base, req->bufs[0].len);
    else
      result = readv(req->file, (struct iovec*) req->bufs, req->nbufs);
  } else {
    if (req->nbufs == 1) {
      result = pread(req->file, req->bufs[0].base, req->bufs[0].len, req->off);
      goto done;
    }

#if HAVE_PREADV
    result = preadv(req->file, (struct iovec*) req->bufs, req->nbufs, req->off);
#else
# if defined(__linux__)
    if (no_preadv) retry:
# endif
    {
      off_t nread;
      size_t index;

      nread = 0;
      index = 0;
      result = 1;
      do {
        if (req->bufs[index].len > 0) {
          result = pread(req->file,
                         req->bufs[index].base,
                         req->bufs[index].len,
                         req->off + nread);
          if (result > 0)
            nread += result;
        }
        index++;
      } while (index < req->nbufs && result > 0);
      if (nread > 0)
        result = nread;
    }
# if defined(__linux__)
    else {
      result = uv__preadv(req->file,
                          (struct iovec*)req->bufs,
                          req->nbufs,
                          req->off);
      if (result == -1 && errno == ENOSYS) {
        no_preadv = 1;
        goto retry;
      }
    }
# endif
#endif
  }

done:
  return result;
}
bool mca_btl_tcp_frag_recv(mca_btl_tcp_frag_t* frag, int sd)
{
    int cnt, dont_copy_data = 0;
    size_t i, num_vecs;
    mca_btl_base_endpoint_t* btl_endpoint = frag->endpoint;

 repeat:
    num_vecs = frag->iov_cnt;
#if MCA_BTL_TCP_ENDPOINT_CACHE
    if( 0 != btl_endpoint->endpoint_cache_length ) {
        size_t length;
        /* It's strange at the first look but cnt have to be set to the full amount of data
         * available. After going to advance_iov_position we will use cnt to detect if there
         * is still some data pending.
         */
        cnt = length = btl_endpoint->endpoint_cache_length;
        for( i = 0; i < frag->iov_cnt; i++ ) {
            if( length > frag->iov_ptr[i].iov_len )
                length = frag->iov_ptr[i].iov_len;
            if( (0 == dont_copy_data) || (length < frag->iov_ptr[i].iov_len) ) {
                memcpy( frag->iov_ptr[i].iov_base, btl_endpoint->endpoint_cache_pos, length );
            } else {
                frag->segments[0].seg_addr.pval = btl_endpoint->endpoint_cache_pos;
                frag->iov_ptr[i].iov_base = btl_endpoint->endpoint_cache_pos;
            }
            btl_endpoint->endpoint_cache_pos += length;
            btl_endpoint->endpoint_cache_length -= length;
            length = btl_endpoint->endpoint_cache_length;
            if( 0 == length ) {
                btl_endpoint->endpoint_cache_pos = btl_endpoint->endpoint_cache;
                break;
            }
        }
        goto advance_iov_position;
    }
    /* What's happens if all iovecs are used by the fragment ? It still work, as we reserve one
     * iovec for the caching in the fragment structure (the +1).
     */
    frag->iov_ptr[num_vecs].iov_base = btl_endpoint->endpoint_cache_pos;
    frag->iov_ptr[num_vecs].iov_len  = 
        mca_btl_tcp_component.tcp_endpoint_cache - btl_endpoint->endpoint_cache_length;
    num_vecs++;
#endif  /* MCA_BTL_TCP_ENDPOINT_CACHE */

    /* non-blocking read, but continue if interrupted */
    cnt = -1;
    while( cnt < 0 ) {
        cnt = readv(sd, frag->iov_ptr, num_vecs);
	if( 0 < cnt ) goto advance_iov_position;
	if( cnt == 0 ) {
	    mca_btl_tcp_endpoint_close(btl_endpoint);
	    return false;
	}
	switch(opal_socket_errno) {
	case EINTR:
	    continue;
	case EWOULDBLOCK:
	    return false;
	case EFAULT:
            BTL_ERROR(("mca_btl_tcp_frag_recv: readv error (%p, %d)\n\t%s(%d)\n",
                       frag->iov_ptr[0].iov_base, frag->iov_ptr[0].iov_len,
                       strerror(opal_socket_errno), frag->iov_cnt));
	    mca_btl_tcp_endpoint_close(btl_endpoint);
	    return false;
	default:
            BTL_ERROR(("mca_btl_tcp_frag_recv: readv failed: %s (%d)", 
                       strerror(opal_socket_errno),
                       opal_socket_errno));
	    mca_btl_tcp_endpoint_close(btl_endpoint);
	    return false;
	}
    };

 advance_iov_position:
    /* if the read didn't complete - update the iovec state */
    num_vecs = frag->iov_cnt;
    for( i = 0; i < num_vecs; i++ ) {
        if( cnt < (int)frag->iov_ptr->iov_len ) {
            frag->iov_ptr->iov_base = (ompi_iov_base_ptr_t)
                (((unsigned char*)frag->iov_ptr->iov_base) + cnt);
            frag->iov_ptr->iov_len -= cnt;
            cnt = 0;
            break;
	}
	cnt -= frag->iov_ptr->iov_len;
	frag->iov_idx++;
	frag->iov_ptr++;
	frag->iov_cnt--;
    }
#if MCA_BTL_TCP_ENDPOINT_CACHE
    btl_endpoint->endpoint_cache_length = cnt;
#endif  /* MCA_BTL_TCP_ENDPOINT_CACHE */

    /* read header */
    if(frag->iov_cnt == 0) {
        if (btl_endpoint->endpoint_nbo && frag->iov_idx == 1) MCA_BTL_TCP_HDR_NTOH(frag->hdr);
        switch(frag->hdr.type) {
        case MCA_BTL_TCP_HDR_TYPE_SEND:
            if(frag->iov_idx == 1 && frag->hdr.size) {
                frag->segments[0].seg_addr.pval = frag+1;
                frag->segments[0].seg_len = frag->hdr.size;
                frag->iov[1].iov_base = (IOVBASE_TYPE*)(frag->segments[0].seg_addr.pval);
                frag->iov[1].iov_len = frag->hdr.size;
                frag->iov_cnt++;
#ifndef __sparc
                /* The following cannot be done for sparc code 
                 * because it causes alignment errors when accessing
                 * structures later on in the btl and pml code.
                 */
                dont_copy_data = 1;
#endif
                goto repeat;
            }
            break;
        case MCA_BTL_TCP_HDR_TYPE_PUT:
            if(frag->iov_idx == 1) {
                frag->iov[1].iov_base = (IOVBASE_TYPE*)frag->segments;
                frag->iov[1].iov_len = frag->hdr.count * sizeof(mca_btl_base_segment_t);
                frag->iov_cnt++;
                goto repeat;
            } else if (frag->iov_idx == 2) {
                for( i = 0; i < frag->hdr.count; i++ ) {
                    frag->iov[i+2].iov_base = (IOVBASE_TYPE*)ompi_ptr_ltop(frag->segments[i].seg_addr.lval);
                    frag->iov[i+2].iov_len = frag->segments[i].seg_len;
                }
                frag->iov_cnt += frag->hdr.count;
                goto repeat;
            }
            break;
        case MCA_BTL_TCP_HDR_TYPE_GET:
        default:
            break;
        }
        return true;
    }
    return false;
}
Beispiel #26
0
Datei: root.c Projekt: smunix/ldc
void File::mmreadv()
{
    if (mmread())
        readv();
}
Beispiel #27
0
int NET_ReadV(int s, const struct iovec * vector, int count) {
    BLOCKING_IO_RETURN_INT( s, readv(s, vector, count) );
}
Beispiel #28
0
int t20(char *name)
{
        char file[MAX_PATH_LENGTH] = "";
        int fd;
        struct iovec iov[2];
        char buf[100];
        long ret;
        ENTER("trap app's general bad pointer for file i/o");
        snprintf(file, MAX_PATH_LENGTH, "%s/test_t20_file", lustre_path);

        fd = open(file, O_RDWR|O_CREAT, (mode_t)0666);
        if (fd < 0) {
                printf("error open file: %s\n", strerror(errno));
                return(-1);
        }

        ret = write(fd, NULL, 20);
        if (ret != -1 || errno != EFAULT) {
                printf("write 1: ret %lld, errno %d\n", (long long)ret, errno);
                return(1);
        }
        ret = write(fd, (void *)-1, 20);
        if (ret != -1 || errno != EFAULT) {
                printf("write 2: ret %lld, errno %d\n", (long long)ret, errno);
                return(1);
        }
        iov[0].iov_base = NULL;
        iov[0].iov_len = 10;
        iov[1].iov_base = (void *)-1;
        iov[1].iov_len = 10;
        ret = writev(fd, iov, 2);
        if (ret != -1 || errno != EFAULT) {
                printf("writev 1: ret %lld, errno %d\n", (long long)ret, errno);
                return(1);
        }
        iov[0].iov_base = NULL;
        iov[0].iov_len = 0;
        iov[1].iov_base = buf;
        iov[1].iov_len = sizeof(buf);
        ret = writev(fd, iov, 2);
        if (ret != sizeof(buf)) {
                printf("writev 2: ret %lld, error %d\n", (long long)ret, errno);
                return(1);
        }
        lseek(fd, 0, SEEK_SET);

        ret = read(fd, NULL, 20);
        if (ret != -1 || errno != EFAULT) {
                printf("read 1: ret %lld, errno %d\n", (long long)ret, errno);
                return(1);
        }
        ret = read(fd, (void *)-1, 20);
        if (ret != -1 || errno != EFAULT) {
                printf("read 2: ret %lld, error %d\n", (long long)ret, errno);
                return(1);
        }
        iov[0].iov_base = NULL;
        iov[0].iov_len = 10;
        iov[1].iov_base = (void *)-1;
        iov[1].iov_len = 10;
        ret = readv(fd, iov, 2);
        if (ret != -1 || errno != EFAULT) {
                printf("readv 1: ret %lld, error %d\n", (long long)ret, errno);
                return(1);
        }
        iov[0].iov_base = NULL;
        iov[0].iov_len = 0;
        iov[1].iov_base = buf;
        iov[1].iov_len = sizeof(buf);
        ret = readv(fd, iov, 2);
        if (ret != sizeof(buf)) {
                printf("readv 2: ret %lld, error %d\n", (long long)ret, errno);
                return(1);
        }

        close(fd);
        t_unlink(file);
        LEAVE();
}
/*
 * Implementation of a scattering read.  Will use the appropriate
 * vector based read call (currently readv on Linux).
 * 
 * This has a limit to the number of buffers that will be read.  It
 * will not make muliple readv calls.  This is to ensure that operations 
 * are atomic.  Currently it is limited to 16 buffers.  This is for 
 * compatibiliy with Sun.
 */
JNIEXPORT jlong JNICALL 
Java_gnu_java_nio_VMChannel_readScattering (JNIEnv *env, 
	jobject o __attribute__ ((__unused__)), 
	jint fd, 
	jobjectArray bbufs, 
	jint offset, 
	jint length)
{
  jint i;
/*   jboolean is_error = JNI_FALSE; */
/*   char *error_msg; */
  struct iovec buffers[JCL_IOV_MAX];
  struct JCL_buffer bi_list[JCL_IOV_MAX];
  ssize_t result;
  jint vec_len = length < JCL_IOV_MAX ? length : JCL_IOV_MAX;
  jlong bytes_read = 0;      
  
  /* Build the vector of buffers to read into */
  for (i = 0; i < vec_len; i++)
    {
      struct JCL_buffer* buf;
      jobject bbuf;
      
      buf = &bi_list[i];
      bbuf = (*env)->GetObjectArrayElement(env, bbufs, offset + i);
      
      JCL_init_buffer(env, buf, bbuf); 
      
      buffers[i].iov_base = &(buf->ptr[buf->position + buf->offset]);
      buffers[i].iov_len = buf->limit - buf->position;
      (*env)->DeleteLocalRef(env, bbuf);
    }
    
  /* Work the scattering magic */
  result = readv(fd, buffers, vec_len);
  bytes_read = (jlong) result;
  
  /* Handle the response */
  if (result < 0)
    {
      if (errno == EAGAIN) /* Non blocking */
        result = 0;
      else if (errno == EBADF) /* Bad fd */
        {
          JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read);
          JCL_ThrowException (env, NON_READABLE_CHANNEL_EXCEPTION, 
                              strerror(errno));
          return -1;
        } 
      else
        {
          JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read);
          JCL_ThrowException (env, IO_EXCEPTION, strerror(errno));
          return -1;
        }
      bytes_read = 0;
    }
  else if (result == 0) /* EOF */
    {
      result = -1;
    }
    
  JCL_cleanup_buffers(env, bi_list, vec_len, bbufs, offset, bytes_read);
                  
  return (jlong) result;
}
Beispiel #30
0
static void
pci_vtnet_tap_rx(struct pci_vtnet_softc *sc)
{
	struct iovec iov[VTNET_MAXSEGS], *riov;
	struct vqueue_info *vq;
	void *vrx;
	int len, n;
	uint16_t idx;

	/*
	 * Should never be called without a valid tap fd
	 */
	assert(sc->vsc_tapfd != -1);

	/*
	 * But, will be called when the rx ring hasn't yet
	 * been set up or the guest is resetting the device.
	 */
	if (!sc->vsc_rx_ready || sc->resetting) {
		/*
		 * Drop the packet and try later.
		 */
		(void) read(sc->vsc_tapfd, dummybuf, sizeof(dummybuf));
		return;
	}

	/*
	 * Check for available rx buffers
	 */
	vq = &sc->vsc_queues[VTNET_RXQ];
	if (!vq_has_descs(vq)) {
		/*
		 * Drop the packet and try later.  Interrupt on
		 * empty, if that's negotiated.
		 */
		(void) read(sc->vsc_tapfd, dummybuf, sizeof(dummybuf));
		vq_endchains(vq, 1);
		return;
	}

	do {
		/*
		 * Get descriptor chain.
		 */
		n = vq_getchain(vq, &idx, iov, VTNET_MAXSEGS, NULL);
		assert(n >= 1 && n <= VTNET_MAXSEGS);

		/*
		 * Get a pointer to the rx header, and use the
		 * data immediately following it for the packet buffer.
		 */
		vrx = iov[0].iov_base;
		riov = rx_iov_trim(iov, &n, sc->rx_vhdrlen);

		len = readv(sc->vsc_tapfd, riov, n);

		if (len < 0 && errno == EWOULDBLOCK) {
			/*
			 * No more packets, but still some avail ring
			 * entries.  Interrupt if needed/appropriate.
			 */
			vq_retchain(vq);
			vq_endchains(vq, 0);
			return;
		}

		/*
		 * The only valid field in the rx packet header is the
		 * number of buffers if merged rx bufs were negotiated.
		 */
		memset(vrx, 0, sc->rx_vhdrlen);

		if (sc->rx_merge) {
			struct virtio_net_rxhdr *vrxh;

			vrxh = vrx;
			vrxh->vrh_bufs = 1;
		}

		/*
		 * Release this chain and handle more chains.
		 */
		vq_relchain(vq, idx, len + sc->rx_vhdrlen);
	} while (vq_has_descs(vq));

	/* Interrupt if needed, including for NOTIFY_ON_EMPTY. */
	vq_endchains(vq, 1);
}