Beispiel #1
0
static void test03(void)
{
    tst_resm(TINFO, "zeroing file space with FALLOC_FL_ZERO_RANGE");

    if (tst_kvercmp(3, 15, 0) < 0) {
        tst_brkm(TCONF, cleanup,
                 "FALLOC_FL_ZERO_RANGE needs Linux 3.15 or newer");
    }

    size_t alloc_size0 = get_allocsize();

    tst_resm(TINFO, "read current allocated file size '%zu'", alloc_size0);

    if (fallocate(fd, FALLOC_FL_ZERO_RANGE, block_size - 1,
                  block_size + 2) == -1) {
        if (errno == EOPNOTSUPP) {
            tst_brkm(TCONF, cleanup,
                     "FALLOC_FL_ZERO_RANGE not supported");
        }
        tst_brkm(TFAIL | TERRNO, cleanup, "fallocate failed");
    }

    /* The file hole in the specified range must be allocated and
     * filled with zeros. Check it.
     */
    size_t alloc_size1 = get_allocsize();

    tst_resm(TINFO, "allocated file size before '%zu' and after '%zu'",
             alloc_size0, alloc_size1);
    if ((alloc_size0 + block_size) != alloc_size1)
        tst_brkm(TFAIL, cleanup, "not expected allocated size");

    char exp_buf[buf_size];

    fill_tst_buf(exp_buf);
    memset(exp_buf + block_size - 1, 0, block_size + 2);

    check_file_data(exp_buf, buf_size);

    tst_resm(TPASS, "test-case succeeded");
}
Beispiel #2
0
static void setup(void)
{
	const char *mount_flags[] = {"noatime", "relatime", NULL};

	TEST_PAUSE;

	tst_sig(FORK, DEF_HANDLER, cleanup);

	tst_tmpdir();

	SAFE_MKDIR(cleanup, MNTPOINT, DIR_MODE);

	if (tst_path_has_mnt_flags(cleanup, NULL, mount_flags)) {
		const char *fs_type;

		if ((tst_kvercmp(2, 6, 30)) < 0) {
			tst_resm(TCONF,
				"MS_STRICTATIME flags for mount(2) needs kernel 2.6.30 "
				"or higher");
			skip_noatime = 1;
			return;
		}

		fs_type = tst_dev_fs_type();
		device = tst_acquire_device(cleanup);

		if (!device) {
			tst_resm(TINFO, "Failed to obtain block device");
			skip_noatime = 1;
			goto end;
		}

		tst_mkfs(cleanup, device, fs_type, NULL, NULL);

		SAFE_MOUNT(cleanup, device, MNTPOINT, fs_type, MS_STRICTATIME, NULL);
		mount_flag = 1;
	}

end:
	SAFE_FILE_PRINTF(cleanup, TEST_FILE, TEST_FILE);
}
Beispiel #3
0
int main(int argc, char *argv[])
{
	int lc;
	int i;
	int exp_eno;
	char *msg;
	char buf[BUFSIZ];

	msg = parse_opts(argc, argv, NULL, NULL);
	if (msg != NULL)
		tst_brkm(TBROK, tst_exit, "OPTION PARSING ERROR - %s", msg);

	setup();

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

		/*
		 * Before kernel 3.0.0, getxattr(2) will set errno with 'EPERM'
		 * when the file is not a regular file and directory, refer to
		 * commitid 55b23bd
		 */
		if (tst_kvercmp(3, 0, 0) >= 0)
			exp_eno = ENODATA;
		else
			exp_eno = EPERM;

		for (i = 0; i < TST_TOTAL; i++) {
			TEST(getxattr(tc[0], XATTR_TEST_KEY, buf, BUFSIZ));

			if (TEST_RETURN == -1 && TEST_ERRNO == exp_eno)
				tst_resm(TPASS | TTERRNO, "expected behavior");
			else
				tst_resm(TFAIL | TTERRNO, "unexpected behavior"
					 " - expected errno %d - Got", exp_eno);
		}
	}

	cleanup();
	tst_exit();
}
Beispiel #4
0
/* setup() - performs all ONE TIME setup for this test */
void setup(void)
{

	tst_sig(NOFORK, DEF_HANDLER, cleanup);

	tst_require_root(NULL);

	if (tst_kvercmp(2, 5, 48) >= 0)
		tst_brkm(TCONF, NULL, "This test will not work on "
			 "kernels after 2.5.48");

	/* Pause if that option was specified
	 * TEST_PAUSE contains the code to fork the test with the -c option.
	 */
	TEST_PAUSE;

	/* Initialize unique module name for each child process */
	if (sprintf(modname, "%s_%d", BASEMODNAME, getpid()) == -1) {
		tst_brkm(TBROK, NULL, "Failed to initialize module name");
	}
}
Beispiel #5
0
static void setup(void)
{
	if ((tst_kvercmp(3, 15, 0)) < 0) {
		tst_brkm(TCONF, NULL,
			"This test can only run on kernels that are 3.15. and higher");
	}

	tst_tmpdir();

	fs_type = tst_fs_type(cleanup, ".");

	SAFE_MKDIR(cleanup, TEST_DIR, 0700);
	SAFE_MKDIR(cleanup, TEST_DIR2, 0700);

	SAFE_TOUCH(cleanup, TEST_DIR TEST_FILE, 0600, NULL);
	SAFE_TOUCH(cleanup, TEST_DIR2 TEST_FILE2, 0600, NULL);
	SAFE_TOUCH(cleanup, TEST_DIR TEST_FILE3, 0600, NULL);

	olddirfd = SAFE_OPEN(cleanup, TEST_DIR, O_DIRECTORY);
	newdirfd = SAFE_OPEN(cleanup, TEST_DIR2, O_DIRECTORY);
}
Beispiel #6
0
int main(int argc, char *argv[])
{
	int fd, coe;

	if ((tst_kvercmp(2, 6, 27)) < 0) {
		tst_brkm(TCONF, NULL,
		    "This test can only run on kernels that are 2.6.27 and higher");
	}
	setup();

	fd = syscall(__NR_eventfd2, 1, 0);
	if (fd == -1) {
		tst_brkm(TFAIL, cleanup, "eventfd2(0) failed");
	}
	coe = fcntl(fd, F_GETFD);
	if (coe == -1) {
		tst_brkm(TBROK, cleanup, "fcntl failed");
	}
	if (coe & FD_CLOEXEC) {
		tst_brkm(TFAIL, cleanup, "eventfd2(0) set close-on-exec flag");
	}
	close(fd);

	fd = syscall(__NR_eventfd2, 1, EFD_CLOEXEC);
	if (fd == -1) {
		tst_brkm(TFAIL, cleanup, "eventfd2(EFD_CLOEXEC) failed");
	}
	coe = fcntl(fd, F_GETFD);
	if (coe == -1) {
		tst_brkm(TBROK, cleanup, "fcntl failed");
	}
	if ((coe & FD_CLOEXEC) == 0) {
		tst_brkm(TFAIL, cleanup,
			 "eventfd2(EFD_CLOEXEC) does not set close-on-exec flag");
	}
	close(fd);
	tst_resm(TPASS, "eventfd2(EFD_CLOEXEC) Passed");
	cleanup();
	tst_exit();
}
Beispiel #7
0
int main(int argc, char *argv[])
{
	int fd, coe;

	if ((tst_kvercmp(2, 6, 27)) < 0)
		tst_brkm(TCONF, NULL,
			 "This test can only run on kernels that are 2.6.27 and higher");
	setup();

	fd = ltp_syscall(__NR_dup3, 1, 4, 0);
	if (fd == -1) {
		tst_brkm(TFAIL | TERRNO, cleanup, "dup3(0) failed");
	}
	coe = fcntl(fd, F_GETFD);
	if (coe == -1) {
		tst_brkm(TBROK | TERRNO, cleanup, "fcntl failed");
	}
	if (coe & FD_CLOEXEC) {
		tst_brkm(TFAIL, cleanup, "dup3(0) set close-on-exec flag");
	}
	close(fd);

	fd = ltp_syscall(__NR_dup3, 1, 4, O_CLOEXEC);
	if (fd == -1) {
		tst_brkm(TFAIL | TERRNO, cleanup, "dup3(O_CLOEXEC) failed");
	}
	coe = fcntl(fd, F_GETFD);
	if (coe == -1) {
		tst_brkm(TBROK | TERRNO, cleanup, "fcntl failed");
	}
	if ((coe & FD_CLOEXEC) == 0) {
		tst_brkm(TFAIL, cleanup,
			 "dup3(O_CLOEXEC) set close-on-exec flag");
	}
	close(fd);
	tst_resm(TPASS, "dup3(O_CLOEXEC) PASSED");

	cleanup();
	tst_exit();
}
Beispiel #8
0
int main(int ac, char **av)
{
	int lc;
	int i;

	/* Disable test if the version of the kernel is less than 2.6.16 */
	if ((tst_kvercmp(2, 6, 16)) < 0) {
		tst_resm(TWARN, "This test can only run on kernels that are ");
		tst_resm(TWARN, "2.6.16 and higher");
		exit(0);
	}

	tst_parse_opts(ac, av, NULL, NULL);

	setup();

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

		tst_count = 0;

		for (i = 0; i < TST_TOTAL; i++) {
			TEST(myunlinkat(fds[i], filenames[i], flags[i]));

			if (TEST_ERRNO == expected_errno[i]) {
				tst_resm(TPASS,
					 "unlinkat() returned the expected  errno %d: %s",
					 TEST_ERRNO, strerror(TEST_ERRNO));
			} else {
				tst_resm(TFAIL,
					 "unlinkat() Failed, errno=%d : %s",
					 TEST_ERRNO, strerror(TEST_ERRNO));
			}
		}

	}

	cleanup();
	tst_exit();
}
Beispiel #9
0
/*
 * check_config() - check for required configuration
 * @min_nodes: the minimum required NUMA nodes
 *
 * Checks if numa support is availabe, kernel is >= 2.6.18, arch is
 * one of the supported architectures.
 */
void check_config(unsigned int min_nodes)
{
#if HAVE_NUMA_H && HAVE_NUMAIF_H
	int num_allowed_nodes;
	int ret;

	ret = get_allowed_nodes_arr(NH_MEMS, &num_allowed_nodes, NULL);
	if (ret < 0)
		tst_brkm(TBROK | TERRNO, NULL, "get_allowed_nodes(): %d", ret);

	if (numa_available() < 0) {
		tst_brkm(TCONF, NULL, "NUMA support is not available");
	} else if (num_allowed_nodes < min_nodes) {
		tst_brkm(TCONF, NULL, "at least %d allowed NUMA nodes"
			 " are required", min_nodes);
	} else if (tst_kvercmp(2, 6, 18) < 0) {
		tst_brkm(TCONF, NULL, "2.6.18 or greater kernel required");
	}
#else
	tst_brkm(TCONF, NULL, "NUMA support not provided");
#endif
}
Beispiel #10
0
int main(int ac, char **av)
{
	int lc;
	int i;

	/* Disable test if the version of the kernel is less than 2.6.16 */
	if ((tst_kvercmp(2, 6, 16)) < 0)
		tst_brkm(TCONF, NULL, "Test must be run with kernel 2.6.16+");

	tst_parse_opts(ac, av, NULL, NULL);

	setup();

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

		/*
		 * Call faccessat
		 */
		for (i = 0; i < TST_TOTAL; i++) {
			TEST(myfaccessat(fds[i], filenames[i], R_OK));

			/* check return code */
			if (TEST_ERRNO == expected_errno[i]) {
				tst_resm(TPASS,
					 "faccessat() returned the expected  errno %d: %s",
					 TEST_ERRNO,
					 strerror(TEST_ERRNO));
			} else {
				tst_resm(TFAIL,
					 "faccessdat() Failed, errno=%d : %s",
					 TEST_ERRNO, strerror(TEST_ERRNO));
			}
		}
	}

	cleanup();
	tst_exit();
}
Beispiel #11
0
static void test_noatime(void)
{
	char read_buf;
	struct stat old_stat, new_stat;

	if ((tst_kvercmp(2, 6, 8)) < 0) {
		tst_resm(TCONF,
			 "O_NOATIME flags test for open(2) needs kernel 2.6.8 "
			 "or higher");
		return;
	}

	if (skip_noatime) {
		tst_resm(TCONF,
		         "test O_NOATIME flag for open needs filesystems which "
		         "is mounted without noatime and relatime");
		return;
	}

	SAFE_STAT(cleanup, TEST_FILE, &old_stat);

	sleep(1);

	TEST(open(TEST_FILE, O_RDONLY | O_NOATIME, 0777));

	if (TEST_RETURN == -1) {
		tst_resm(TFAIL | TTERRNO, "open failed");
		return;
	}
	SAFE_READ(cleanup, 1, TEST_RETURN, &read_buf, 1);
	SAFE_CLOSE(cleanup, TEST_RETURN);
	SAFE_STAT(cleanup, TEST_FILE, &new_stat);

	if (old_stat.st_atime == new_stat.st_atime)
		tst_resm(TPASS, "test O_NOATIME for open success");
	else
		tst_resm(TFAIL, "test O_NOATIME for open failed");
}
Beispiel #12
0
static void setup(void)
{
	int i;

	if ((tst_kvercmp(2, 6, 17)) < 0) {
		tst_brkm(TCONF, NULL,
		         "The vmsplice is supported 2.6.17 and newer");
	}

	tst_sig(NOFORK, DEF_HANDLER, cleanup);

	tst_tmpdir();

	if (tst_fs_type(cleanup, ".") == TST_NFS_MAGIC) {
		tst_brkm(TCONF, cleanup, "Cannot do splice() "
			 "on a file located on an NFS filesystem");
	}

	for (i = 0; i < TEST_BLOCK_SIZE; i++)
		buffer[i] = i & 0xff;

	TEST_PAUSE;
}
Beispiel #13
0
/*
 * setup() - performs all ONE TIME setup for this test
 */
static void setup(void)
{
	/*
	 * commit 3140a2273009c01c27d316f35ab76a37e105fdd8
	 * Author: Brice Goglin <*****@*****.**>
	 * Date:   Tue Jan 6 14:38:57 2009 -0800
	 *     mm: rework do_pages_move() to work on page_sized chunks
	 *
	 * reworked do_pages_move() to work by page-sized chunks and removed E2BIG
	 */
	if ((tst_kvercmp(2, 6, 29)) >= 0)
		tst_brkm(TCONF, NULL, "move_pages: E2BIG was removed in "
			 "commit 3140a227");

	tst_sig(FORK, DEF_HANDLER, cleanup);

	check_config(TEST_NODES);

	/* Pause if that option was specified
	 * TEST_PAUSE contains the code to fork the test with the -c option.
	 */
	TEST_PAUSE;
}
Beispiel #14
0
/* setup() - performs all ONE TIME setup for this test */
void setup(void)
{
	tst_require_root(NULL);

	tst_sig(NOFORK, DEF_HANDLER, cleanup);

	/*
	 * The value of IO_BITMAP_BITS (include/asm-i386/processor.h) changed
	 * from kernel 2.6.8 to permit 16-bits ioperm
	 *
	 * Ricky Ng-Adam, [email protected]
	 * */
	if (tst_kvercmp(2, 6, 8) < 0) {
		/*get ioperm on 1021, 1022, 1023 */
		io_addr = IO_BITMAP_BITS - NUM_BYTES;
	} else {
		/*get ioperm on 65533, 65534, 65535 */
		io_addr = IO_BITMAP_BITS - NUM_BYTES;
	}

	TEST_PAUSE;

}
int main(int argc, char **argv)
{
	void *handle;
	void *ret;
	char *error;
	if (tst_kvercmp(2, 6, 16) < 0)
		return 1;

	handle = dlopen(NULL, RTLD_LAZY);
	if (!handle) {
		fprintf(stderr, "%s\n", dlerror());
		exit(1);
	}

	dlerror();		/* Clear any existing error */
	ret = dlsym(handle, "unshare");
	if ((error = dlerror()) != NULL) {
		fprintf(stderr, "Error: %s\n", error);
		exit(1);
	}

	dlclose(handle);
	return 0;
}
Beispiel #16
0
/*
 * setup()
 *	performs all ONE TIME setup for this test
 */
void setup(void)
{

	tst_sig(FORK, DEF_HANDLER, cleanup);

	tst_require_root();

	if (tst_kvercmp(2, 5, 48) >= 0)
		tst_brkm(TCONF, NULL, "This test will not work on "
			 "kernels after 2.5.48");

	/* Pause if that option was specified
	 * TEST_PAUSE contains the code to fork the test with the -c option.
	 */
	TEST_PAUSE;

	bad_addr = mmap(0, 1, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
	if (bad_addr == MAP_FAILED) {
		tst_brkm(TBROK, cleanup, "mmap failed");
	}
	tdat[0].modname = bad_addr;
	tdat[2].buf = (void *)bad_addr;

}
int main()
{
	int pid;
	mqd_t mqd;

	if (tst_kvercmp(2, 6, 30) < 0)
		return 1;

	mq_unlink("/checkmqnsenabled");
	mqd =
	    mq_open("/checkmqnsenabled", O_RDWR | O_CREAT | O_EXCL, 0777, NULL);
	if (mqd == -1) {
		perror("mq_open");
		return 3;
	}
	mq_close(mqd);
	mq_unlink("/checkmqnsenabled");

	pid = ltp_clone_quick(CLONE_NEWIPC, dummy, NULL);
	if (pid == -1)
		return 5;

	return 0;
}
Beispiel #18
0
int main(int ac, char **av)
{
	struct stat stat_buf;	/* struct buffer to hold file info. */
	int lc;
	long type;
	time_t modf_time, access_time;
	time_t pres_time;	/* file modification/access/present time */

	tst_parse_opts(ac, av, NULL, NULL);

	setup();

	switch ((type = tst_fs_type(cleanup, "."))) {
	case TST_NFS_MAGIC:
		if (tst_kvercmp(2, 6, 18) < 0)
			tst_brkm(TCONF, cleanup, "Cannot do utime on a file"
				" on %s filesystem before 2.6.18",
				 tst_fs_type_name(type));
		break;
	case TST_V9FS_MAGIC:
		tst_brkm(TCONF, cleanup,
			 "Cannot do utime on a file on %s filesystem",
			 tst_fs_type_name(type));
		break;
	}

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

		tst_count = 0;

		/*
		 * Invoke utime(2) to set TEMP_FILE access and
		 * modification times to the current time.
		 */
		TEST(utime(TEMP_FILE, NULL));

		if (TEST_RETURN == -1) {
			tst_resm(TFAIL|TTERRNO, "utime(%s) failed", TEMP_FILE);
		} else {
			/*
			 * Sleep for a second so that mod time and
			 * access times will be different from the
			 * current time
			 */
			sleep(2);

			/*
			 * Get the current time now, after calling
			 * utime(2)
			 */
			pres_time = time(NULL);

			/*
			 * Get the modification and access times of
			 * temporary file using stat(2).
			 */
			SAFE_STAT(cleanup, TEMP_FILE, &stat_buf);
			modf_time = stat_buf.st_mtime;
			access_time = stat_buf.st_atime;

			/* Now do the actual verification */
			if (modf_time <= curr_time ||
			    modf_time >= pres_time ||
			    access_time <= curr_time ||
			    access_time >= pres_time) {
				tst_resm(TFAIL, "%s access and "
					 "modification times not set",
					 TEMP_FILE);
			} else {
				tst_resm(TPASS, "Functionality of "
					 "utime(%s, NULL) successful",
					 TEMP_FILE);
			}
		}
		tst_count++;
	}

	cleanup();
	tst_exit();
}
Beispiel #19
0
int main(int ac, char **av)
{
	int lc, i;

#if defined (__s390__) || (__s390x__) || (__ia64__)
	/* Disables the test in case the kernel version is lower than 2.6.12 and arch is s390 */
	if ((tst_kvercmp(2, 6, 12)) < 0) {
		tst_resm(TWARN,
			 "This test can only run on kernels that are 2.6.12 and higher");
		exit(0);
	}
#endif

	tst_parse_opts(ac, av, NULL, NULL);

	setup();

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

		tst_count = 0;

		for (i = 0; i < TST_TOTAL; i++) {
			/* do the setup if the test have one */
			if (testcase[i].setupfunc
			    && testcase[i].setupfunc(i) == -1) {
				tst_resm(TWARN,
					 "Failed to setup test %d"
					 " Skipping test", i);
				continue;
			}

			/* run the test */
			TEST(remap_file_pages
			     (testcase[i].start, testcase[i].size,
			      testcase[i].prot, testcase[i].pgoff,
			      testcase[i].flags));

			/* do the cleanup if the test have one */
			if (testcase[i].cleanfunc
			    && testcase[i].cleanfunc(i) == -1) {
				tst_brkm(TBROK, cleanup,
					 "Failed to cleanup test %d,"
					 " quitting the test", i);
			}

			/* verify the return code */
			if ((TEST_RETURN == -1)
			    && (TEST_ERRNO == testcase[i].exp_errno)) {
				tst_resm(TPASS,
					 "remap_file_pages(2) expected failure;"
					 " Got errno - %s : %s",
					 testcase[i].exp_errval,
					 testcase[i].err_desc);
			} else {
				tst_resm(TFAIL,
					 "remap_file_pages(2) failed to produce"
					 " expected error: %d, errno: %s."
					 " because got error %d",
					 testcase[i].exp_errno,
					 testcase[i].exp_errval, TEST_ERRNO);
			}
		}		/* end of test loops */
	}			/* end of  test looping */

	/* clean up and exit */
	cleanup();

	tst_exit();
}
Beispiel #20
0
int main(int ac, char **av)
{
	int lc;
	char *msg;

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

	/*
	 * perform global setup for test
	 */
	setup();

	/*
	 * check looping state if -c option given
	 */
	for (lc = 0; TEST_LOOPING(lc); lc++) {

		Tst_count = 0;

		/*
		 * generate sequence of events
		 */
		if (chmod(".", 0755) < 0) {
			tst_brkm(TBROK|TERRNO, cleanup,
				 "chmod(\".\", 0755) failed");
		}
		event_set[Tst_count].mask = IN_ISDIR | IN_ATTRIB;
		strcpy(event_set[Tst_count].name, "");
		Tst_count++;

		if ((fd = creat(FILE_NAME1, 0755)) == -1) {
			tst_brkm(TBROK|TERRNO, cleanup,
				 "creat(\"%s\", 755) failed",
				 FILE_NAME1);
		}

		event_set[Tst_count].mask = IN_CREATE;
		strcpy(event_set[Tst_count].name, FILE_NAME1);
		Tst_count++;
		event_set[Tst_count].mask = IN_OPEN;
		strcpy(event_set[Tst_count].name, FILE_NAME1);
		Tst_count++;

		if (close(fd) == -1) {
			tst_brkm(TBROK|TERRNO, cleanup,
				 "close(%s) failed", FILE_NAME1);
		}
		event_set[Tst_count].mask = IN_CLOSE_WRITE;
		strcpy(event_set[Tst_count].name, FILE_NAME1);
		Tst_count++;

		if (rename(FILE_NAME1, FILE_NAME2) == -1) {
			tst_brkm(TBROK|TERRNO, cleanup,
				 "rename(%s, %s) failed",
				 FILE_NAME1, FILE_NAME2);
		}
		event_set[Tst_count].mask = IN_MOVED_FROM;
		strcpy(event_set[Tst_count].name, FILE_NAME1);
		Tst_count++;
		event_set[Tst_count].mask = IN_MOVED_TO;
		strcpy(event_set[Tst_count].name, FILE_NAME2);
		Tst_count++;

		if (getcwd(fname1, BUF_SIZE) == NULL) {
			tst_brkm(TBROK|TERRNO, cleanup,
				 "getcwd(%p, %d) failed", fname1,
				 BUF_SIZE);
		}

		snprintf(fname2, BUF_SIZE, "%s.rename1", fname1);
		if (rename(fname1, fname2) == -1) {
			tst_brkm(TBROK|TERRNO, cleanup,
				 "rename(%s, %s) failed", fname1, fname2);
		}
		event_set[Tst_count].mask = IN_MOVE_SELF;
		strcpy(event_set[Tst_count].name, "");
		Tst_count++;

		if (unlink(FILE_NAME2) == -1) {
			tst_brkm(TBROK|TERRNO, cleanup,
				 "unlink(%s) failed", FILE_NAME2);
		}
		event_set[Tst_count].mask = IN_DELETE;
		strcpy(event_set[Tst_count].name, FILE_NAME2);
		Tst_count++;

		/*
		 * test that duplicate events will be coalesced into
		 * a single event. This test case should be last, that
		 * we can correct determine kernel bug which exist before
		 * 2.6.25. See comment below.
		 */
		snprintf(fname3, BUF_SIZE, "%s.rename2", fname1);
		if (rename(fname2, fname3) == -1) {
			tst_brkm(TBROK|TERRNO, cleanup,
				 "rename(%s, %s) failed", fname2, fname3);
		}

		if (rename(fname3, fname1) == -1) {
			tst_brkm(TBROK|TERRNO, cleanup,
				 "rename(%s, %s) failed", fname3, fname1);
		}
		event_set[Tst_count].mask = IN_MOVE_SELF;
		strcpy(event_set[Tst_count].name, "");
		Tst_count++;

		if (Tst_count != TST_TOTAL) {
			tst_brkm(TBROK, cleanup,
				 "Tst_count and TST_TOTAL are not equal");
		}

		Tst_count = 0;

		int len, i = 0, test_num = 0;
		if ((len = read(fd_notify, event_buf, EVENT_BUF_LEN)) == -1) {
			tst_brkm(TBROK|TERRNO, cleanup,
				 "read(%d, buf, %zu) failed",
				 fd_notify, EVENT_BUF_LEN);

		}

		while (i < len) {
			struct inotify_event *event;
			event = (struct inotify_event *)&event_buf[i];
			if (test_num >= TST_TOTAL) {
				if (tst_kvercmp(2, 6, 25) < 0
				    && event_set[TST_TOTAL - 1].mask ==
				    event->mask)
					tst_resm(TWARN,
						 "This may be kernel bug. "
						 "Before kernel 2.6.25, a kernel bug "
						 "meant that the kernel code that was "
						 "intended to coalesce successive identical "
						 "events (i.e., the two most recent "
						 "events could potentially be coalesced "
						 "if the older had not yet been read) "
						 "instead checked if the most recent event "
						 "could be coalesced with the oldest "
						 "unread event. This has been fixed by commit"
						 "1c17d18e3775485bf1e0ce79575eb637a94494a2.");
				tst_resm(TFAIL,
					 "get unnecessary event: "
					 "wd=%d mask=%x cookie=%u len=%u"
					 "name=\"%s\"", event->wd, event->mask,
					 event->cookie, event->len,
					 event->name);

			} else if ((event_set[test_num].mask == event->mask)
				   &&
				   (!strncmp
				    (event_set[test_num].name, event->name,
				     event->len))) {
				tst_resm(TPASS,
					 "get event: wd=%d mask=%x"
					 " cookie=%u len=%u name=\"%s\"",
					 event->wd, event->mask, event->cookie,
					 event->len, event->name);

			} else {
				tst_resm(TFAIL, "get event: wd=%d mask=%x "
					 "(expected %x) cookie=%u len=%u "
					 "name=\"%s\" (expected \"%s\") %d",
					 event->wd, event->mask,
					 event_set[test_num].mask,
					 event->cookie, event->len, event->name,
					 event_set[test_num].name,
					 strcmp(event_set[test_num].name,
						event->name));
			}
			test_num++;
			i += EVENT_SIZE + event->len;
		}

		for (; test_num < TST_TOTAL; test_num++) {
			tst_resm(TFAIL, "didn't get event: mask=%x ",
				 event_set[test_num].mask);
		}
	}

	/* cleanup and exit */
	cleanup();
	tst_exit();
}
Beispiel #21
0
int main(int ac, char **av)
{

	int lc, i;
	const char *msg;
	pid_t child_pid;
	int status;

	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;

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

			/* since Linux 2.6.26, it's allowed to trace init,
			   so just skip this test case */
			if (i == 0 && tst_kvercmp(2, 6, 25) > 0) {
				tst_resm(TCONF,
					 "this kernel allows to trace init");
				continue;
			}

			/* fork() */
			switch (child_pid = FORK_OR_VFORK()) {

			case -1:
				/* fork() failed */
				tst_resm(TFAIL, "fork() failed");
				continue;

			case 0:
				/* Child */

				/* setup for third test case */
				if (i == 2) {
					if ((ptrace(PTRACE_TRACEME, 0,
						    NULL, NULL)) == -1) {
						tst_resm(TWARN, "ptrace()"
							 " falied with errno, %d : %s",
							 errno,
							 strerror(errno));
						exit(0);
					}
				}

				TEST(ptrace(test_cases[i].request,
					    *(test_cases[i].pid), NULL, NULL));
				if ((TEST_RETURN == -1) && (TEST_ERRNO ==
							    test_cases
							    [i].exp_errno)) {
					exit(TEST_ERRNO);
				} else {
					tst_resm(TWARN | TTERRNO,
						 "ptrace() returned %ld",
						 TEST_RETURN);
					exit(TEST_ERRNO);
				}

			default:
				/* Parent */
				if ((waitpid(child_pid, &status, 0)) < 0) {
					tst_resm(TFAIL, "waitpid() failed");
					continue;
				}
				if ((WIFEXITED(status)) &&
				    (WEXITSTATUS(status) ==
				     test_cases[i].exp_errno)) {
					tst_resm(TPASS, "Test Passed");
				} else {
					tst_resm(TFAIL, "Test Failed");
				}
				TEST_ERROR_LOG(WEXITSTATUS(status));
			}
		}
	}

	/* cleanup and exit */
	cleanup();

	tst_exit();

}
Beispiel #22
0
int main(int ac, char **av)
{
	int lc;			/* loop counter */
	char *msg;		/* message returned from parse_opts */
	int i;

	/* Disable test if the version of the kernel is less than 2.6.16 */
	if ((tst_kvercmp(2, 6, 16)) < 0) {
		tst_resm(TWARN, "This test can only run on kernels that are ");
		tst_resm(TWARN, "2.6.16 and higher");
		exit(0);
	}

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

	/***************************************************************
	 * perform global setup for test
	 ***************************************************************/
	setup();

	/***************************************************************
	 * check looping state if -c option given
	 ***************************************************************/
	for (lc = 0; TEST_LOOPING(lc); lc++) {
		setup_every_copy();

		Tst_count = 0;

		/*
		 * Call openat
		 */
		for (i = 0; i < TST_TOTAL; i++) {
			TEST(myopenat
			     (fds[i], filenames[i], O_CREAT | O_WRONLY, 0600));

			/* check return code */
			if (TEST_ERRNO == expected_errno[i]) {

				/***************************************************************
				 * only perform functional verification if flag set (-f not given)
				 ***************************************************************/
				if (STD_FUNCTIONAL_TEST) {
					/* No Verification test, yet... */
					tst_resm(TPASS,
						 "openat() returned the expected errno %d: %s",
						 TEST_ERRNO,
						 strerror(TEST_ERRNO));
				}
			} else {
				TEST_ERROR_LOG(TEST_ERRNO);
				tst_resm(TFAIL,
					 "openat() Failed, errno=%d : %s",
					 TEST_ERRNO, strerror(TEST_ERRNO));
			}
		}

	}

	/***************************************************************
	 * cleanup and exit
	 ***************************************************************/
	cleanup();

	return (0);
}
Beispiel #23
0
int
main(int ac, char **av)
{
	int lc, i;			/* loop counter */
	char *msg;			/* message returned from parse_opts */
	kernel_timer_t timer_id, *temp_id;	/* stores the returned timer_id */
	struct sigevent *temp_ev;	/* used for bad address test case */

	clockid_t clocks[6] = {
		MAX_CLOCKS,
		MAX_CLOCKS + 1,
		CLOCK_REALTIME,
		CLOCK_MONOTONIC,
		CLOCK_PROCESS_CPUTIME_ID,
		CLOCK_THREAD_CPUTIME_ID
	};

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

	TST_TOTAL = sizeof(testcase) / sizeof(testcase[0]);

	/* PROCESS_CPUTIME_ID & THREAD_CPUTIME_ID are not supported on
	 * kernel versions lower than 2.6.12
	 */
	if (tst_kvercmp(2, 6, 12) < 0) {
		testcase[4] = EINVAL;
		testcase[5] = EINVAL;
	} else {
		testcase[4] = EFAULT;
		testcase[5] = EFAULT;
	}

	setup();

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

		Tst_count = 0;

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

			temp_ev = (struct sigevent *) NULL;
			temp_id = &timer_id;

			switch (i) {
			case 2: /* make the timer_id bad address */
				temp_id = (kernel_timer_t *) -1;
				break;
			case 3:
				/* make the event bad address */
				temp_ev = (struct sigevent *) -1;
				break;
			case 4:
				/* Produce an invalid timer_id address. */
				if (tst_kvercmp(2, 6, 12) >= 0)
					temp_id = (kernel_timer_t *) -1;
				break;
			case 5:
				/* Produce an invalid event address. */
				if (tst_kvercmp(2, 6, 12) >= 0)
					temp_ev = (struct sigevent *) -1;
			}

			TEST(syscall(__NR_timer_create, clocks[i], temp_ev,
					temp_id));

			/* check return code */
			if (TEST_RETURN == -1 && TEST_ERRNO == testcase[i]) {
				tst_resm(TPASS | TTERRNO, "failed as expected");
			} else {
				tst_resm(TFAIL | TTERRNO,
					"didn't fail as expected [expected "
					"errno = %d (%s)]",
					testcase[i],
					strerror(testcase[i]));
			} /* end of else */

		}

	}

	cleanup();
	tst_exit();
}
Beispiel #24
0
int
main(int ac, char **av)
{
  int lc,expected_result = -1;		 /* loop counter, expected */ 
					 /* result from system call */ 
    char *msg;		 		 /* message returned from parse_opts */
    int results;                        /* Stores the result of the */
                                         /* kernel comparison test */
    /***************************************************************
     * parse standard options
     ***************************************************************/
    if ( (msg=parse_opts(ac, av, (option_t *) NULL, NULL)) != (char *) NULL )
		 tst_brkm(TBROK, cleanup, "OPTION PARSING ERROR - %s", msg);

    /***************************************************************
     * perform global setup for test
     ***************************************************************/
    setup();

    TEST_EXP_ENOS(exp_enos);

    if( (results=tst_kvercmp(2,6,10)) >= 0)
	  {
	    expected_result = -1;
	  }
    else if( ((results=tst_kvercmp(2,4,0)) >= 0)&&\
	     ((results=tst_kvercmp(2,6,0))< 0) )
      {
	    expected_result = 1;
      }
    else if( ((results=tst_kvercmp(2,6,0)) >= 0)&&\
	 ((results=tst_kvercmp(2,6,10))< 0) )
      {
	    expected_result = 0;
      }
    else
      {
	     expected_result = -1;
      }

    /***************************************************************
     * check looping state if -c option given
     ***************************************************************/
    for (lc=0; TEST_LOOPING(lc); lc++) {

		 /* reset Tst_count in case we are looping. */
		 Tst_count=0;

#ifdef F_SETLEASE
		 /* 
		  * Call fcntl(2) with F_SETLEASE & F_RDLCK argument on fname
		  */
		 TEST(fcntl(fd, F_SETLEASE,F_RDLCK));
		 
		 /* check return code */
		 if ( TEST_RETURN == expected_result ) {
		     TEST_ERROR_LOG(TEST_ERRNO);
                        tst_resm(TPASS,
                                "fcntl(fd, F_SETLEASE,F_RDLCK) succeeded");
                        }
                 else {
                        tst_resm(TFAIL, "fcntl(%s, F_SETLEASE, F_RDLCK)"
                                " failed with errno %d : %s", fname,
                                 TEST_ERRNO, strerror(TEST_ERRNO));
                       }
#endif
    }		 /* End for TEST_LOOPING */

    /***************************************************************
     * cleanup and exit
     ***************************************************************/
    cleanup();

    return 0;
}		 /* End main */
Beispiel #25
0
int main(int ac, char **av)
{
	int lc;
	char *msg;
	int results;

	/* Disable test if the version of the kernel is less than 2.6.17 */
	if (((results = tst_kvercmp(2, 6, 17)) < 0)) {
		tst_resm(TINFO, "This test can only run on kernels that are ");
		tst_resm(TINFO, "2.6.17 and higher");
		exit(0);
	}

	/*
	 * parse standard options
	 */
	if ((msg = parse_opts(ac, av, NULL, NULL)))
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);

	/*
	 * perform global setup for test
	 */
	setup();

	tst_tmpdir();
	if (tst_fs_type(cleanup, ".") == TST_NFS_MAGIC) {
		tst_brkm(TCONF, cleanup,
			 "Cannot do splice on a file on NFS filesystem");
	}
	tst_rmdir();

	/*
	 * check looping state if -c option given
	 */
	for (lc = 0; TEST_LOOPING(lc); lc++) {

		tst_count = 0;

		/*
		 * Call splice_test
		 */
		TEST(splice_test());

		/* check return code */
		if (TEST_RETURN < 0) {
			if (TEST_RETURN != -1) {
				TEST_ERRNO = -TEST_RETURN;
			}
			TEST_ERROR_LOG(TEST_ERRNO);
			tst_resm(TFAIL, "splice() Failed, errno=%d : %s",
				 TEST_ERRNO, strerror(TEST_ERRNO));
		} else {

			/*
			 * only perform functional verification if flag set (-f not given)
			 */
			if (STD_FUNCTIONAL_TEST) {
				/* No Verification test, yet... */
				tst_resm(TPASS, "splice() returned %ld",
					 TEST_RETURN);
			}
		}

	}

	/*
	 * cleanup and exit
	 */
	cleanup();

	return (0);
}
Beispiel #26
0
int main(int ac, char **av)
{

	int lc, i;
	const char *msg;

	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;

		for (i = 0; i < TST_TOTAL; ++i) {
			/*
			 * since Linux 2.6.26, if buf.offset value is outside
			 * the acceptable range, it is simply normalized instead
			 * of letting the syscall fail. so just skip this test
			 * case.
			 */
			if ((i == 3 || i == 4) && tst_kvercmp(2, 6, 25) > 0) {
				tst_resm(TCONF, "this kernel normalizes buf."
					 "offset value if it is outside"
					 " the acceptable range.");
				continue;
			}

			buff = tim_save;
			buff.modes = SET_MODE;
			if ((test_cases[i].setup) && (test_cases[i].setup())) {
				tst_resm(TWARN, "setup() failed, skipping"
					 " this test case");
				continue;
			}

			/* Call adjtimex(2) */
			TEST(adjtimex(test_cases[i].buffp));

			if ((TEST_RETURN == -1) && (TEST_ERRNO ==
						    test_cases[i].exp_errno)) {
				tst_resm(TPASS | TTERRNO,
					 "Test Passed, adjtimex() returned -1");
			} else {
				tst_resm(TFAIL | TTERRNO,
					 "Test Failed, adjtimex() returned %ld",
					 TEST_RETURN);
			}
			TEST_ERROR_LOG(TEST_ERRNO);
			if (test_cases[i].cleanup) {
				test_cases[i].cleanup();
			}
		}
	}

	/* cleanup and exit */
	cleanup();

	tst_exit();

}
Beispiel #27
0
int main(int argc, char **argv)
{
	char *msg;

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

	setup();

#if HAVE_NUMA_MOVE_PAGES
	unsigned int i;
	int lc;
	unsigned int from_node;
	int ret;

	ret = get_allowed_nodes(NH_MEMS, 1, &from_node);
	if (ret < 0)
		tst_brkm(TBROK | TERRNO, cleanup, "get_allowed_nodes: %d", ret);

	/* check for looping state if -i option is given */
	for (lc = 0; TEST_LOOPING(lc); lc++) {
		void *pages[TEST_PAGES] = { 0 };
		int nodes[TEST_PAGES];
		int status[TEST_PAGES];

		/* reset Tst_count in case we are looping */
		Tst_count = 0;

		ret = alloc_pages_on_node(pages, TEST_PAGES, from_node);
		if (ret == -1)
			continue;

		for (i = 0; i < TEST_PAGES; i++)
			nodes[i] = from_node;

		ret = numa_move_pages(0, TEST_PAGES, pages, nodes,
				      status, MPOL_MF_MOVE);
		TEST_ERRNO = errno;

		/*
		 * commit e78bbfa8262424417a29349a8064a535053912b9
		 * Author: Brice Goglin <*****@*****.**>
		 * Date:   Sat Oct 18 20:27:15 2008 -0700
		 *     mm: stop returning -ENOENT from sys_move_pages() if nothing got migrated
		 */
		if ((tst_kvercmp(2, 6, 28)) >= 0) {
			if (ret == 0)
				tst_resm(TPASS, "move_pages succeeded");
			else
				tst_resm(TFAIL | TERRNO, "move_pages");
		} else {
			if (ret == -1 && errno == ENOENT)
				tst_resm(TPASS, "move_pages failed with "
					 "ENOENT as expected");
			else
				tst_resm(TFAIL | TERRNO, "move_pages");
		}

		free_pages(pages, TEST_PAGES);
	}
#else
	tst_resm(TCONF, "move_pages support not found.");
#endif

	cleanup();
	tst_exit();

}
Beispiel #28
0
int
main(int argc, char **argv)
{
	char *msg;
	size_t len;
	int i, test_num;

	i = 0;
	test_num = 0;

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

	setup();

	Tst_count = 0;

	rmdir(TEST_DIR);
	event_set[Tst_count].mask = IN_DELETE_SELF;
	strcpy(event_set[Tst_count].name, "");
	Tst_count++;
	event_set[Tst_count].mask = IN_IGNORED;
	strcpy(event_set[Tst_count].name, "");
	Tst_count++;

	unlink(TEST_FILE);
	/*
	 * When a file is unlinked, the link count is reduced by 1, and when it
	 * hits 0 the file is removed.
	 *
	 * This isn't well documented in inotify(7), but it's intuitive if you
	 * understand how Unix works.
	 */
	if (0 <= tst_kvercmp(2, 6, 25)) {
		event_set[Tst_count].mask = IN_ATTRIB;
		strcpy(event_set[Tst_count].name, "");
		Tst_count++;
		TST_TOTAL++;
	}
	event_set[Tst_count].mask = IN_DELETE_SELF;
	strcpy(event_set[Tst_count].name, TEST_FILE);
	Tst_count++;
	event_set[Tst_count].mask = IN_IGNORED;
	strcpy(event_set[Tst_count].name, "");
	Tst_count++;

	if (Tst_count != TST_TOTAL)
		tst_brkm(TBROK, cleanup,
			 "Tst_count and TST_TOTAL are not equal");

	Tst_count = 0;

	len = read(fd_notify, event_buf, EVENT_BUF_LEN);
	if (len == -1)
		tst_brkm(TBROK|TERRNO, cleanup, "read failed");

	reap_wd_dir = 0;
	reap_wd_file = 0;

	while (i < len) {
		struct inotify_event *event;
		event = (struct inotify_event *)&event_buf[i];
		if (test_num >= TST_TOTAL) {
			if (tst_kvercmp(2, 6, 25) < 0
			    && event_set[TST_TOTAL - 1].mask ==
			    event->mask)
				tst_resm(TWARN,
					 "This may be kernel bug. "
					 "Before kernel 2.6.25, a kernel bug "
					 "meant that the kernel code that was "
					 "intended to coalesce successive identical "
					 "events (i.e., the two most recent "
					 "events could potentially be coalesced "
					 "if the older had not yet been read) "
					 "instead checked if the most recent event "
					 "could be coalesced with the oldest "
					 "unread event. This has been fixed by commit"
					 "1c17d18e3775485bf1e0ce79575eb637a94494a2.");
			tst_resm(TFAIL,
				 "got unnecessary event: "
				 "wd=%d mask=%x cookie=%u len=%u "
				 "name=\"%s\"", event->wd, event->mask,
				 event->cookie, event->len,
				 event->name);

		} else if ((event_set[test_num].mask == event->mask)
			   &&
			   (!strncmp
			    (event_set[test_num].name, event->name,
			     event->len))) {
			tst_resm(TPASS,
				 "got event: wd=%d mask=%x "
				 "cookie=%u len=%u name=\"%s\"",
				 event->wd, event->mask, event->cookie,
				 event->len, event->name);

		} else {
			tst_resm(TFAIL, "got event: wd=%d mask=%x "
				 "(expected %x) cookie=%u len=%u "
				 "name=\"%s\" (expected \"%s\") %d",
				 event->wd, event->mask,
				 event_set[test_num].mask,
				 event->cookie, event->len, event->name,
				 event_set[test_num].name,
				 strcmp(event_set[test_num].name,
					event->name));
		}
		test_num++;
		i += EVENT_SIZE + event->len;
	}

	for (; test_num < TST_TOTAL; test_num++) {
		tst_resm(TFAIL, "didn't get event: mask=%x ",
			 event_set[test_num].mask);
	}

	cleanup();
	tst_exit();
}
Beispiel #29
0
int main(int argc, char *argv[])
{
	int fd[2], i, coe;
	int lc;
	const char *msg;

	msg = parse_opts(argc, argv, NULL, NULL);
	if (msg != NULL) {
		tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg);
		tst_exit();
	}
	if ((tst_kvercmp(2, 6, 27)) < 0) {
		tst_resm(TCONF,
			 "This test can only run on kernels that are 2.6.27 and higher");
		tst_exit();
	}
	setup();

	for (lc = 0; TEST_LOOPING(lc); ++lc) {
		tst_count = 0;
		for (testno = 0; testno < TST_TOTAL; ++testno) {
			if (ltp_syscall(__NR_pipe2, fd, 0) != 0) {
				tst_resm(TFAIL, "pipe2(0) failed");
				cleanup();
				tst_exit();
			}
			for (i = 0; i < 2; ++i) {
				coe = fcntl(fd[i], F_GETFD);
				if (coe == -1) {
					tst_brkm(TBROK, cleanup,
						 "fcntl failed");
					tst_exit();
				}
				if (coe & FD_CLOEXEC) {
					tst_resm(TFAIL,
						 "pipe2(0) set close-on-exit for fd[%d]",
						 i);
					cleanup();
					tst_exit();
				}
			}
			close(fd[0]);
			close(fd[1]);

			if (ltp_syscall(__NR_pipe2, fd, O_CLOEXEC) != 0) {
				tst_resm(TFAIL, "pipe2(O_CLOEXEC) failed");
				cleanup();
				tst_exit();
			}
			for (i = 0; i < 2; ++i) {
				coe = fcntl(fd[i], F_GETFD);
				if (coe == -1) {
					tst_brkm(TBROK, cleanup,
						 "fcntl failed");
					tst_exit();
				}
				if ((coe & FD_CLOEXEC) == 0) {
					tst_resm(TFAIL,
						 "pipe2(O_CLOEXEC) does not set close-on-exit for fd[%d]",
						 i);
					cleanup();
					tst_exit();
				}
			}
			close(fd[0]);
			close(fd[1]);
			tst_resm(TPASS, "pipe2(O_CLOEXEC) PASSED");
			cleanup();
		}
	}
	tst_exit();
}
Beispiel #30
0
int main(int argc, char **argv)
{

	tst_parse_opts(argc, argv, NULL, NULL);

	setup();

#if HAVE_NUMA_MOVE_PAGES
	unsigned int i;
	int lc;
	unsigned int from_node;
	unsigned int to_node;
	int ret, exp_status;

	if ((tst_kvercmp(4, 3, 0)) >= 0)
		exp_status = -EFAULT;
	else
		exp_status = -ENOENT;

	ret = get_allowed_nodes(NH_MEMS, 2, &from_node, &to_node);
	if (ret < 0)
		tst_brkm(TBROK | TERRNO, cleanup, "get_allowed_nodes: %d", ret);

	/* check for looping state if -i option is given */
	for (lc = 0; TEST_LOOPING(lc); lc++) {
		void *pages[TEST_PAGES] = { 0 };
		int nodes[TEST_PAGES];
		int status[TEST_PAGES];
		unsigned long onepage = get_page_size();

		/* reset tst_count in case we are looping */
		tst_count = 0;

		ret = alloc_pages_on_node(pages, TOUCHED_PAGES, from_node);
		if (ret == -1)
			continue;

		/* Allocate page and do not touch it. */
		pages[UNTOUCHED_PAGE] = numa_alloc_onnode(onepage, from_node);
		if (pages[UNTOUCHED_PAGE] == NULL) {
			tst_resm(TBROK, "failed allocating page on node %d",
				 from_node);
			goto err_free_pages;
		}

		for (i = 0; i < TEST_PAGES; i++)
			nodes[i] = to_node;

		ret = numa_move_pages(0, TEST_PAGES, pages, nodes,
				      status, MPOL_MF_MOVE);
		if (ret == -1) {
			tst_resm(TFAIL | TERRNO,
				 "move_pages unexpectedly failed");
			goto err_free_pages;
		}

		if (status[UNTOUCHED_PAGE] == exp_status) {
			tst_resm(TPASS, "status[%d] has expected value",
				 UNTOUCHED_PAGE);
		} else {
			tst_resm(TFAIL, "status[%d] is %s, expected %s",
				UNTOUCHED_PAGE,
				tst_strerrno(-status[UNTOUCHED_PAGE]),
				tst_strerrno(-exp_status));
		}

err_free_pages:
		/* This is capable of freeing both the touched and
		 * untouched pages.
		 */
		free_pages(pages, TEST_PAGES);
	}
#else
	tst_resm(TCONF, "move_pages support not found.");
#endif

	cleanup();
	tst_exit();

}