Beispiel #1
0
static void verify_pwritev2(unsigned int n)
{
	int i;
	char preadbuf[CHUNK];
	struct tcase *tc = &tcases[n];

	SAFE_PWRITE(1, fd, initbuf, sizeof(initbuf), 0);
	SAFE_LSEEK(fd, tc->seek_off, SEEK_SET);

	TEST(pwritev2(fd, wr_iovec, tc->count, tc->write_off, 0));
	if (TST_RET < 0) {
		tst_res(TFAIL | TTERRNO, "pwritev2() failed");
		return;
	}

	if (TST_RET != tc->size) {
		tst_res(TFAIL, "pwritev2() wrote %li bytes, expected %zi",
			 TST_RET, tc->size);
		return;
	}

	if (SAFE_LSEEK(fd, 0, SEEK_CUR) != tc->exp_off) {
		tst_res(TFAIL, "pwritev2() had changed file offset");
		return;
	}

	memset(preadbuf, 0, CHUNK);

	if (tc->write_off != -1)
		SAFE_PREAD(1, fd, preadbuf, tc->size, tc->write_off);
	else
		SAFE_PREAD(1, fd, preadbuf, tc->size, tc->seek_off);

	for (i = 0; i < tc->size; i++) {
		if (preadbuf[i] != 0x61)
			break;
	}

	if (i != tc->size) {
		tst_res(TFAIL, "buffer wrong at %i have %c expected 'a'",
			 i, preadbuf[i]);
		return;
	}

	tst_res(TPASS, "pwritev2() wrote %zi bytes successfully "
		 "with content 'a' expectedly ", tc->size);
}
Beispiel #2
0
void verify_preadv(unsigned int n)
{
	int i;
	char *vec;
	struct tcase *tc = &tcases[n];

	vec = rd_iovec[0].iov_base;
	memset(vec, 0x00, CHUNK);

	SAFE_LSEEK(fd, 0, SEEK_SET);

	TEST(preadv(fd, rd_iovec, tc->count, tc->offset));
	if (TST_RET < 0) {
		tst_res(TFAIL | TTERRNO, "Preadv(2) failed");
		return;
	}

	if (TST_RET != tc->size) {
		tst_res(TFAIL, "Preadv(2) read %li bytes, expected %zi",
			 TST_RET, tc->size);
		return;
	}

	for (i = 0; i < tc->size; i++) {
		if (vec[i] != tc->content)
			break;
	}

	if (i < tc->size) {
		tst_res(TFAIL, "Buffer wrong at %i have %02x expected %02x",
			 i, vec[i], tc->content);
		return;
	}

	if (SAFE_LSEEK(fd, 0, SEEK_CUR) != 0) {
		tst_res(TFAIL, "Preadv(2) has changed file offset");
		return;
	}

	tst_res(TPASS, "Preadv(2) read %zi bytes successfully "
		 "with content '%c' expectedly", tc->size, tc->content);
}
Beispiel #3
0
static void verify_read(void)
{
	SAFE_LSEEK(fd, 0, SEEK_SET);

	TEST(read(fd, buf, SIZE));

	if (TEST_RETURN == -1)
		tst_res(TFAIL | TTERRNO, "read(2) failed");
	else
		tst_res(TPASS, "read(2) returned %ld", TEST_RETURN);
}
Beispiel #4
0
static void test_append(void)
{
	off_t len1, len2;

	TEST(open(TEST_FILE, O_RDWR | O_APPEND, 0777));

	if (TEST_RETURN == -1) {
		tst_resm(TFAIL | TTERRNO, "open failed");
		return;
	}

	len1 = SAFE_LSEEK(cleanup, TEST_RETURN, 0, SEEK_CUR);
	SAFE_WRITE(cleanup, 1, TEST_RETURN, TEST_FILE, sizeof(TEST_FILE));
	len2 = SAFE_LSEEK(cleanup, TEST_RETURN, 0, SEEK_CUR);
	SAFE_CLOSE(cleanup, TEST_RETURN);

	if (len2 > len1)
		tst_resm(TPASS, "test O_APPEND for open success");
	else
		tst_resm(TFAIL, "test O_APPEND for open failed");
}
Beispiel #5
0
int main(void)
{
	int fd, stdout_fd;
	char msg[4096], *pos;
	FILE *f;

	setup();

	/* redirect stdout to file */
	stdout_fd = dup(fileno(stdout));
	fd = SAFE_OPEN(NULL, OUTPUT_FNAME, O_RDWR | O_CREAT, 0666);
	TEST(dup2(fd, fileno(stdout)));
	if (TEST_RETURN == -1)
		tst_brkm(TBROK | TTERRNO, cleanup, "dup2");

	errno = EPERM;
	TEST_ERRNO = EPERM;
	TEST_RETURN = EINVAL;
	tst_resm(TINFO | TRERRNO, "test");
	tst_old_flush();

	/* restore stdout */
	TEST(dup2(stdout_fd, fileno(stdout)));
	if (TEST_RETURN == -1)
		tst_brkm(TBROK | TTERRNO, cleanup, "dup2");

	/* read file and verify that output is as expected */
	SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
	f = fdopen(fd, "r");
	if (!f)
		tst_brkm(TBROK | TERRNO, cleanup, "fdopen");
	if (!fgets(msg, sizeof(msg), f))
		tst_brkm(TBROK, cleanup, "fgets");
	fclose(f);

	pos = strchr(msg, '\n');
	if (pos != NULL)
		*pos = '\0';

	tst_resm(TINFO, "%s", msg);
	if (strstr(msg, "EPERM"))
		tst_resm(TFAIL, "EPERM shouldn't be in TRERRNO output");
	if (strstr(msg, "EINVAL"))
		tst_resm(TPASS, "EINVAL should be in TRERRNO output");
	else
		tst_resm(TFAIL, "EINVAL not found in TRERRNO output");

	cleanup();
	tst_exit();
}
Beispiel #6
0
static void check_file_data(const char exp_buf[], size_t size)
{
    char rbuf[size];

    tst_resm(TINFO, "reading the file, compare with expected buffer");

    SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
    SAFE_READ(cleanup, 1, fd, rbuf, size);

    if (memcmp(exp_buf, rbuf, size)) {
        if (verbose) {
            tst_resm_hexd(TINFO, exp_buf, size, "expected:");
            tst_resm_hexd(TINFO, rbuf, size, "but read:");
        }
        tst_brkm(TFAIL, cleanup, "not expected file data");
    }
}
Beispiel #7
0
int main(int ac, char **av)
{
	int lc, i, fail;
	char *msg, *vec;

	if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL)
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		tst_count = 0;

		SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);

		if (readv(fd, rd_iovec, 0) == -1)
			tst_resm(TFAIL | TERRNO, "readv failed unexpectedly");
		else
			tst_resm(TPASS, "readv read 0 io vectors");

		memset(rd_iovec[0].iov_base, 0x00, CHUNK);

		if (readv(fd, rd_iovec, 3) != CHUNK) {
			tst_resm(TFAIL, "readv failed reading %d bytes, "
				 "followed by two NULL vectors", CHUNK);
		} else {
			fail = 0;
			vec = rd_iovec[0].iov_base;

			for (i = 0; i < CHUNK; i++) {
				if (vec[i] != 0x42)
					fail++;
			}

			if (fail)
				tst_resm(TFAIL, "Wrong buffer content");
			else
				tst_resm(TPASS, "readv passed reading %d bytes "
				         "followed by two NULL vectors", CHUNK);
		}
	}

	cleanup();
	tst_exit();
}
Beispiel #8
0
void testfunc_append(void)
{
	off_t file_offset;

	SAFE_FILE_PRINTF(cleanup, TEST_FILE, "test file");

	TEST(openat(AT_FDCWD, TEST_FILE, O_APPEND | O_RDWR, 0777));

	if (TEST_RETURN == -1) {
		tst_resm(TFAIL | TTERRNO, "openat failed");
		return;
	}

	SAFE_WRITE(cleanup, 1, TEST_RETURN, STR, sizeof(STR) - 1);

	file_offset = SAFE_LSEEK(cleanup, TEST_RETURN, 0, SEEK_CUR);

	if (file_offset > (off_t)(sizeof(STR) - 1))
		tst_resm(TPASS, "test O_APPEND for openat success");
	else
		tst_resm(TFAIL, "test O_APPEND for openat failed");

	SAFE_CLOSE(cleanup, TEST_RETURN);
}
Beispiel #9
0
int main(int ac, char **av)
{
	int lc, i;
	int len, stop;

	tst_parse_opts(ac, av, NULL, NULL);

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		/*
		 * generate events
		 */
		fd = SAFE_OPEN(cleanup, fname, O_RDWR);

		for (i = 0; i < max_events; i++) {
			SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
			SAFE_READ(cleanup, 1, fd, buf, BUF_SIZE);
			SAFE_LSEEK(cleanup, fd, 0, SEEK_SET);
			SAFE_WRITE(cleanup, 1, fd, buf, BUF_SIZE);
		}

		SAFE_CLOSE(cleanup, fd);

		stop = 0;
		while (!stop) {
			/*
			 * get list on events
			 */
			len = read(fd_notify, event_buf, EVENT_BUF_LEN);
			if (len < 0) {
				tst_brkm(TBROK | TERRNO, cleanup,
					 "read(%d, buf, %zu) failed",
					 fd_notify, EVENT_BUF_LEN);
			}

			/*
			 * check events
			 */
			i = 0;
			while (i < len) {
				struct inotify_event *event;

				event = (struct inotify_event *)&event_buf[i];
				if (event->mask != IN_ACCESS &&
				    event->mask != IN_MODIFY &&
				    event->mask != IN_OPEN &&
				    event->mask != IN_Q_OVERFLOW) {
					tst_resm(TFAIL,
						 "get event: wd=%d mask=%x "
						 "cookie=%u (expected 0) len=%u",
						 event->wd, event->mask,
						 event->cookie, event->len);
					stop = 1;
					break;
				}
				if (event->mask == IN_Q_OVERFLOW) {
					if (event->len != 0 ||
					    event->cookie != 0 ||
					    event->wd != -1) {
						tst_resm(TFAIL,
							 "invalid overflow event: "
							 "wd=%d mask=%x "
							 "cookie=%u len=%u",
							 event->wd, event->mask,
							 event->cookie,
							 event->len);
						stop = 1;
						break;
					}
					if ((int)(i + EVENT_SIZE) != len) {
						tst_resm(TFAIL,
							 "overflow event is not last");
						stop = 1;
						break;
					}
					tst_resm(TPASS, "get event: wd=%d "
						 "mask=%x cookie=%u len=%u",
						 event->wd, event->mask,
						 event->cookie, event->len);
					stop = 1;
					break;
				}
				i += EVENT_SIZE + event->len;
			}
		}
	}

	cleanup();
	tst_exit();
}
Beispiel #10
0
void *thread_fn_01(void *arg)
{
	int i;
	unsigned char buf[write_size];
	int fd = SAFE_OPEN(fname, O_RDWR);

	memset(buf, (intptr_t)arg, write_size);

	struct flock64 lck = {
		.l_whence = SEEK_SET,
		.l_start  = 0,
		.l_len    = 1,
	};

	for (i = 0; i < writes_num; ++i) {
		lck.l_type = F_WRLCK;
		my_fcntl(fd, F_OFD_SETLKW, &lck);

		SAFE_LSEEK(fd, 0, SEEK_END);
		SAFE_WRITE(1, fd, buf, write_size);

		lck.l_type = F_UNLCK;
		my_fcntl(fd, F_OFD_SETLKW, &lck);

		sched_yield();
	}

	SAFE_CLOSE(fd);

	return NULL;
}

static void test01(void)
{
	intptr_t i;
	int k;
	pthread_t id[thread_cnt];
	int res[thread_cnt];
	unsigned char buf[write_size];

	tst_res(TINFO, "write to a file inside threads with OFD locks");

	int fd = SAFE_OPEN(fname, O_CREAT | O_TRUNC | O_RDWR, 0600);

	memset(res, 0, sizeof(res));

	spawn_threads(id, thread_fn_01);
	wait_threads(id);

	tst_res(TINFO, "verifying file's data");
	SAFE_LSEEK(fd, 0, SEEK_SET);
	for (i = 0; i < writes_num * thread_cnt; ++i) {
		SAFE_READ(1, fd, buf, write_size);

		if (buf[0] >= thread_cnt) {
			tst_res(TFAIL, "unexpected data read");
			return;
		}

		++res[buf[0]];

		for (k = 1; k < write_size; ++k) {
			if (buf[0] != buf[k]) {
				tst_res(TFAIL, "unexpected data read");
				return;
			}
		}
	}

	for (i = 0; i < thread_cnt; ++i) {
		if (res[i] != writes_num) {
			tst_res(TFAIL, "corrupted data found");
			return;
		}
	}
	SAFE_CLOSE(fd);

	tst_res(TPASS, "OFD locks synchronized access between threads");
}
Beispiel #11
0
static void test_partially_valid_iovec(int initial_file_offset)
{
	int i, fd;
	unsigned char buffer[BUFSIZE], fpattern[BUFSIZE], tmp[BUFSIZE];
	long off_after;
	struct iovec wr_iovec[] = {
		{ buffer, CHUNK },
		{ bad_addr, CHUNK },
		{ buffer + CHUNK, CHUNK },
		{ buffer + CHUNK * 2, CHUNK },
	};

	tst_res(TINFO, "starting test with initial file offset: %d ",
		initial_file_offset);

	for (i = 0; i < BUFSIZE; i++)
		buffer[i] = i % (CHUNK - 1);

	memset(fpattern, 0xff, BUFSIZE);
	tst_fill_file(TESTFILE, 0xff, CHUNK, BUFSIZE / CHUNK);

	fd = SAFE_OPEN(TESTFILE, O_RDWR, 0644);
	SAFE_LSEEK(fd, initial_file_offset, SEEK_SET);
	TEST(writev(fd, wr_iovec, ARRAY_SIZE(wr_iovec)));
	off_after = (long) SAFE_LSEEK(fd, 0, SEEK_CUR);

	/* bad errno */
	if (TEST_RETURN == -1 && TEST_ERRNO != EFAULT) {
		tst_res(TFAIL | TTERRNO, "unexpected errno");
		SAFE_CLOSE(fd);
		return;
	}

	/* nothing has been written */
	if (TEST_RETURN == -1 && TEST_ERRNO == EFAULT) {
		tst_res(TINFO, "got EFAULT");
		/* initial file content remains untouched */
		SAFE_LSEEK(fd, 0, SEEK_SET);
		SAFE_READ(1, fd, tmp, BUFSIZE);
		if (memcmp(tmp, fpattern, BUFSIZE))
			tst_res(TFAIL, "file was written to");
		else
			tst_res(TPASS, "file stayed untouched");

		/* offset hasn't changed */
		if (off_after == initial_file_offset)
			tst_res(TPASS, "offset stayed unchanged");
		else
			tst_res(TFAIL, "offset changed to %ld",
				off_after);

		SAFE_CLOSE(fd);
		return;
	}

	/* writev() wrote more bytes than bytes preceding invalid iovec */
	tst_res(TINFO, "writev() has written %ld bytes", TEST_RETURN);
	if (TEST_RETURN > (long) wr_iovec[0].iov_len) {
		tst_res(TFAIL, "writev wrote more than expected");
		SAFE_CLOSE(fd);
		return;
	}

	/* file content matches written bytes */
	SAFE_LSEEK(fd, initial_file_offset, SEEK_SET);
	SAFE_READ(1, fd, tmp, TEST_RETURN);
	if (memcmp(tmp, wr_iovec[0].iov_base, TEST_RETURN) == 0) {
		tst_res(TPASS, "file has expected content");
	} else {
		tst_res(TFAIL, "file has unexpected content");
		tst_res_hexd(TFAIL, wr_iovec[0].iov_base, TEST_RETURN,
				"expected:");
		tst_res_hexd(TFAIL, tmp, TEST_RETURN,
				"actual file content:");
	}

	/* file offset has been updated according to written bytes */
	if (off_after == initial_file_offset + TEST_RETURN)
		tst_res(TPASS, "offset at %ld as expected", off_after);
	else
		tst_res(TFAIL, "offset unexpected %ld", off_after);

	SAFE_CLOSE(fd);
}
Beispiel #12
0
/* read_testfile - mmap testfile and read every page.
 * This functions measures how many I/O and time it takes to fully
 * read contents of test file.
 *
 * @do_readahead: call readahead prior to reading file content?
 * @fname: name of file to test
 * @fsize: how many bytes to read/mmap
 * @read_bytes: returns difference of bytes read, parsed from /proc/<pid>/io
 * @usec: returns how many microsecond it took to go over fsize bytes
 * @cached: returns cached kB from /proc/meminfo
 */
static int read_testfile(struct tcase *tc, int do_readahead,
			 const char *fname, size_t fsize,
			 unsigned long *read_bytes, long long *usec,
			 unsigned long *cached)
{
	int fd;
	size_t i = 0;
	long read_bytes_start;
	unsigned char *p, tmp;
	off_t offset = 0;

	fd = SAFE_OPEN(fname, O_RDONLY);

	if (do_readahead) {
		do {
			TEST(tc->readahead(fd, offset, fsize - offset));
			if (TST_RET != 0) {
				SAFE_CLOSE(fd);
				return TST_ERR;
			}

			i++;
			offset += readahead_length;
		} while ((size_t)offset < fsize);
		tst_res(TINFO, "readahead calls made: %zu", i);
		*cached = get_cached_size();

		/* offset of file shouldn't change after readahead */
		offset = SAFE_LSEEK(fd, 0, SEEK_CUR);
		if (offset == 0)
			tst_res(TPASS, "offset is still at 0 as expected");
		else
			tst_res(TFAIL, "offset has changed to: %lu", offset);
	}

	tst_timer_start(CLOCK_MONOTONIC);
	read_bytes_start = get_bytes_read();

	p = SAFE_MMAP(NULL, fsize, PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0);

	/* for old kernels, where MAP_POPULATE doesn't work, touch each page */
	tmp = 0;
	for (i = 0; i < fsize; i += pagesize)
		tmp = tmp ^ p[i];
	/* prevent gcc from optimizing out loop above */
	if (tmp != 0)
		tst_brk(TBROK, "This line should not be reached");

	if (!do_readahead)
		*cached = get_cached_size();

	SAFE_MUNMAP(p, fsize);

	*read_bytes = get_bytes_read() - read_bytes_start;

	tst_timer_stop();
	*usec = tst_timer_elapsed_us();

	SAFE_CLOSE(fd);
	return 0;
}