Ejemplo n.º 1
0
/*
 * Perform a simple write test of our initialized data buffer to the provided
 * file descriptor.
 */
static void
aio_write_test(struct aio_context *ac)
{
	struct aiocb aio, *aiop;
	ssize_t len;
	int error;

	bzero(&aio, sizeof(aio));
	aio.aio_buf = ac->ac_buffer;
	aio.aio_nbytes = ac->ac_buflen;
	aio.aio_fildes = ac->ac_write_fd;
	aio.aio_offset = 0;

	aio_timeout_start(ac->ac_test, "aio_write_test", ac->ac_seconds);

	if (aio_write(&aio) < 0) {
		if (errno == EINTR) {
			if (aio_notpresent)
				errno = EOPNOTSUPP;
			if (aio_timedout) {
				aio_cleanup(ac);
				errx(-1, "FAIL: %s: aio_write_test: "
				    "aio_write: timed out", ac->ac_test);
			}
		}
		aio_cleanup(ac);
		errx(-1, "FAIL: %s: aio_write_test: aio_write: %s",
		    ac->ac_test, strerror(errno));
	}

	len = aio_waitcomplete(&aiop, NULL);
	if (len < 0) {
		if (errno == EINTR) {
			if (aio_notpresent)
				errno = EOPNOTSUPP;
			if (aio_timedout) {
				aio_cleanup(ac);
				errx(-1, "FAIL: %s: aio_write_test: "
				    "aio_waitcomplete: timed out",
				    ac->ac_test);
			}
		}
		aio_cleanup(ac);
		errx(-1, "FAIL: %s: aio_write_test: aio_waitcomplete: %s",
		    ac->ac_test, strerror(errno));
	}

	aio_timeout_stop(ac->ac_test, "aio_write_test");

	if (len != ac->ac_buflen) {
		aio_cleanup(ac);
		errx(-1, "FAIL: %s: aio_write_test: aio_waitcomplete: short "
		    "write (%d)", ac->ac_test, len);
	}
}
Ejemplo n.º 2
0
ATF_TC_BODY(aio_socket_two_reads, tc)
{
	struct ioreq {
		struct aiocb iocb;
		char buffer[1024];
	} ioreq[2];
	struct aiocb *iocb;
	unsigned i;
	int s[2];
	char c;

	ATF_REQUIRE_KERNEL_MODULE("aio");
#if __FreeBSD_version < 1100101
	aft_tc_skip("kernel version %d is too old (%d required)",
	    __FreeBSD_version, 1100101);
#endif

	ATF_REQUIRE(socketpair(PF_UNIX, SOCK_STREAM, 0, s) != -1);

	/* Queue two read requests. */
	memset(&ioreq, 0, sizeof(ioreq));
	for (i = 0; i < nitems(ioreq); i++) {
		ioreq[i].iocb.aio_nbytes = sizeof(ioreq[i].buffer);
		ioreq[i].iocb.aio_fildes = s[0];
		ioreq[i].iocb.aio_buf = ioreq[i].buffer;
		ATF_REQUIRE(aio_read(&ioreq[i].iocb) == 0);
	}

	/* Send a single byte.  This should complete one request. */
	c = 0xc3;
	ATF_REQUIRE(write(s[1], &c, sizeof(c)) == 1);

	ATF_REQUIRE(aio_waitcomplete(&iocb, NULL) == 1);

	/* Determine which request completed and verify the data was read. */
	if (iocb == &ioreq[0].iocb)
		i = 0;
	else
		i = 1;
	ATF_REQUIRE(ioreq[i].buffer[0] == c);

	i ^= 1;

	/*
	 * Try to cancel the other request.  On broken systems this
	 * will fail and the process will hang on exit.
	 */
	ATF_REQUIRE(aio_error(&ioreq[i].iocb) == EINPROGRESS);
	ATF_REQUIRE(aio_cancel(s[0], &ioreq[i].iocb) == AIO_CANCELED);

	close(s[1]);
	close(s[0]);
}
Ejemplo n.º 3
0
/*
 * Perform a simple read test of our initialized data buffer from the
 * provided file descriptor.
 */
static void
aio_read_test(struct aio_context *ac)
{
	struct aiocb aio, *aiop;
	ssize_t len;

	ATF_REQUIRE_KERNEL_MODULE("aio");

	bzero(ac->ac_buffer, ac->ac_buflen);
	bzero(&aio, sizeof(aio));
	aio.aio_buf = ac->ac_buffer;
	aio.aio_nbytes = ac->ac_buflen;
	aio.aio_fildes = ac->ac_read_fd;
	aio.aio_offset = 0;

	aio_timeout_start(ac->ac_seconds);

	if (aio_read(&aio) < 0) {
		if (errno == EINTR) {
			if (aio_timedout) {
				aio_cleanup(ac);
				atf_tc_fail("aio_write timed out");
			}
		}
		aio_cleanup(ac);
		atf_tc_fail("aio_read failed: %s", strerror(errno));
	}

	len = aio_waitcomplete(&aiop, NULL);
	if (len < 0) {
		if (errno == EINTR) {
			if (aio_timedout) {
				aio_cleanup(ac);
				atf_tc_fail("aio_waitcomplete timed out");
			}
		}
		aio_cleanup(ac);
		atf_tc_fail("aio_waitcomplete failed: %s", strerror(errno));
	}

	aio_timeout_stop();

	if (len != ac->ac_buflen) {
		aio_cleanup(ac);
		atf_tc_fail("aio_waitcomplete short read (%jd)",
		    (intmax_t)len);
	}

	if (aio_test_buffer(ac->ac_buffer, ac->ac_buflen, ac->ac_seed) == 0) {
		aio_cleanup(ac);
		atf_tc_fail("buffer mismatched");
	}
}
Ejemplo n.º 4
0
int
main(int argc, char *argv[])
{
	int fd;
	struct stat sb;
	struct aiocb *aio;
	char **abuf;
	const char *fn;
	int aio_len;
	int io_size, nrun;
	off_t file_size, offset;
	struct aiocb *a;
	int i, n;
        struct timeval st, et, rt;
        float f_rt;
	iot_t iowhat;


	if (argc < 6) {
		printf("Usage: %s <file> <io size> <number of runs> <concurrency> <ro|wo|rw>\n", argv[0]);
		exit(1);
	}

	fn = argv[1];
	io_size = atoi(argv[2]);
	nrun = atoi(argv[3]);
	aio_len = atoi(argv[4]);
	if (strcmp(argv[5], "ro") == 0) {
		iowhat = IOT_READ;
	} else if (strcmp(argv[5], "rw") == 0) {
		iowhat = IOT_READ | IOT_WRITE;
	} else if (strcmp(argv[5], "wo") == 0) {
		iowhat = IOT_WRITE;
	} else {
		fprintf(stderr, "needs to be ro, rw, wo!\n");
		exit(1);
	}

	/*
	 * Random returns values between 0 and (2^32)-1; only good for 4 gig.
	 * Lets instead treat random() as returning a block offset w/ block size
	 * being "io_size", so we can handle > 4 gig files.
	 */
	if (iowhat == IOT_READ)
		fd = open(fn, O_RDONLY | O_DIRECT);
	else if (iowhat == IOT_WRITE)
		fd = open(fn, O_WRONLY | O_DIRECT);
	else
		fd = open(fn, O_RDWR | O_DIRECT);

	if (fd < 0) {
		perror("open");
		exit(1);
	}
	if (fstat(fd, &sb) < 0) {
		perror("fstat");
		exit(1);
	}
	if (S_ISREG(sb.st_mode)) {
		file_size = sb.st_size;
	} else if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
		file_size = disk_getsize(fd);
	} else {
		perror("unknown file type\n");
		exit(1);
	}
	printf("File: %s; File size %jd bytes\n", fn, (intmax_t)file_size);

	aio = calloc(aio_len, sizeof(struct aiocb));
	abuf = calloc(aio_len, sizeof(char *));
	for (i = 0; i < aio_len; i++) {
		abuf[i] = calloc(1, io_size * sizeof(char));
	}

	/* Fill with the initial contents */
        gettimeofday(&st, NULL);
	for (i = 0; i < aio_len; i++) {
                offset = random() % (file_size / io_size);
                offset *= io_size;
		set_aio(aio + i, choose_aio(iowhat), fd, offset, io_size, abuf[i]);
	}

	for (i = 0; i < nrun; i++) {
		aio_waitcomplete(&a, NULL);
		n = a - aio;
		assert(n < aio_len);
		assert(n >= 0);
                offset = random() % (file_size / io_size);
                offset *= io_size;
		set_aio(aio + n, choose_aio(iowhat), fd, offset, io_size, abuf[n]);
	}

        gettimeofday(&et, NULL);
        timersub(&et, &st, &rt);
        f_rt = ((float) (rt.tv_usec)) / 1000000.0;
        f_rt += (float) (rt.tv_sec);
        printf("Runtime: %.2f seconds, ", f_rt);
        printf("Op rate: %.2f ops/sec, ", ((float) (nrun))  / f_rt);
        printf("Avg transfer rate: %.2f bytes/sec\n", ((float) (nrun)) * ((float)io_size) / f_rt);



	exit(0);
}
Ejemplo n.º 5
0
ATF_TC_BODY(aio_large_read_test, tc)
{
	char pathname[PATH_MAX];
	struct aiocb cb, *cbp;
	ssize_t nread;
	size_t len;
	int fd;
#ifdef __LP64__
	int clamped;
#endif

	ATF_REQUIRE_KERNEL_MODULE("aio");
	ATF_REQUIRE_UNSAFE_AIO();

#ifdef __LP64__
	len = sizeof(clamped);
	if (sysctlbyname("debug.iosize_max_clamp", &clamped, &len, NULL, 0) ==
	    -1)
		atf_libc_error(errno, "Failed to read debug.iosize_max_clamp");
#endif

	/* Determine the maximum supported read(2) size. */
	len = SSIZE_MAX;
#ifdef __LP64__
	if (clamped)
		len = INT_MAX;
#endif

	strcpy(pathname, PATH_TEMPLATE);
	fd = mkstemp(pathname);
	ATF_REQUIRE_MSG(fd != -1, "mkstemp failed: %s", strerror(errno));

	unlink(pathname);

	memset(&cb, 0, sizeof(cb));
	cb.aio_nbytes = len;
	cb.aio_fildes = fd;
	cb.aio_buf = NULL;
	if (aio_read(&cb) == -1)
		atf_tc_fail("aio_read() of maximum read size failed: %s",
		    strerror(errno));

	nread = aio_waitcomplete(&cbp, NULL);
	if (nread == -1)
		atf_tc_fail("aio_waitcomplete() failed: %s", strerror(errno));
	if (nread != 0)
		atf_tc_fail("aio_read() from empty file returned data: %zd",
		    nread);

	memset(&cb, 0, sizeof(cb));
	cb.aio_nbytes = len + 1;
	cb.aio_fildes = fd;
	cb.aio_buf = NULL;
	if (aio_read(&cb) == -1) {
		if (errno == EINVAL)
			goto finished;
		atf_tc_fail("aio_read() of too large read size failed: %s",
		    strerror(errno));
	}

	nread = aio_waitcomplete(&cbp, NULL);
	if (nread == -1) {
		if (errno == EINVAL)
			goto finished;
		atf_tc_fail("aio_waitcomplete() failed: %s", strerror(errno));
	}
	atf_tc_fail("aio_read() of too large read size returned: %zd", nread);

finished:
	close(fd);
}