Пример #1
0
int chld1_shm(void *arg)
{
	int id, rval = 0;
	char *shmem;

	id = shmget(TESTKEY, SHMSIZE, IPC_CREAT);
	if (id == -1) {
		perror("shmget");
		return 2;
	}

	if ((shmem = shmat(id, NULL, 0)) == (char *) -1) {
		perror("shmat");
		shmctl(id, IPC_RMID, NULL);
		return 2;
	}

	*shmem = 'A';

	TST_SAFE_CHECKPOINT_WAKE_AND_WAIT(NULL, 0);

	/* if child1 shared segment has changed (by child2) report fail */
	if (*shmem != 'A')
		rval = 1;

	/* tell child2 to continue */
	TST_SAFE_CHECKPOINT_WAKE(NULL, 0);

	shmdt(shmem);
	shmctl(id, IPC_RMID, NULL);
	return rval;
}
Пример #2
0
static void test(void)
{
	int status;

	/* unshares the mount ns */
	if (unshare(CLONE_NEWNS) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");
	/* makes sure parent mounts/umounts have no effect on a real system */
	SAFE_MOUNT(cleanup, "none", "/", "none", MS_REC|MS_PRIVATE, NULL);

	/* bind mounts DIRA to itself */
	SAFE_MOUNT(cleanup, DIRA, DIRA, "none", MS_BIND, NULL);

	/* makes mount DIRA shared */
	SAFE_MOUNT(cleanup, "none", DIRA, "none", MS_SHARED, NULL);

	if (do_clone_tests(CLONE_NEWNS, child_func, NULL, NULL, NULL) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "clone failed");

	/* waits for child to make a slave mount */
	TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);

	/* bind mounts DIRB to DIRA making contents of DIRB visible
	 * in DIRA */
	SAFE_MOUNT(cleanup, DIRB, DIRA, "none", MS_BIND, NULL);

	TST_SAFE_CHECKPOINT_WAKE_AND_WAIT(cleanup, 0);

	SAFE_UMOUNT(cleanup, DIRA);

	TST_SAFE_CHECKPOINT_WAKE_AND_WAIT(cleanup, 0);

	/* checks that slave mount doesn't propagate to shared mount */
	if ((access(DIRA"/A", F_OK) == 0) && (access(DIRA"/B", F_OK) == -1))
		tst_resm(TPASS, "propagation from slave mount passed");
	else
		tst_resm(TFAIL, "propagation form slave mount failed");

	TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);


	SAFE_WAIT(cleanup, &status);
	if (WIFEXITED(status)) {
		if (WEXITSTATUS(status) == 0)
			tst_resm(TPASS, "propagation to slave mount passed");
		else
			tst_resm(TFAIL, "propagation to slave mount failed");
	}
	if (WIFSIGNALED(status)) {
		tst_resm(TBROK, "child was killed with signal %s",
			 tst_strsig(WTERMSIG(status)));
		return;
	}

	SAFE_UMOUNT(cleanup, DIRA);
}
Пример #3
0
static void do_child(void)
{
	int fd, offset;
	char buf[FS_BLOCKSIZE];
	char *addr = NULL;

	/*
	 * We have changed SIGBUS' handler in parent process by calling
	 * tst_sig(FORK, DEF_HANDLER, NULL), so here just restore it.
	 */
	if (signal(SIGBUS, SIG_DFL) == SIG_ERR)
		tst_brkm(TBROK | TERRNO, NULL, "signal(SIGBUS) failed");

	memset(buf, 'a', FS_BLOCKSIZE);
	fd = SAFE_OPEN(NULL, "testfilec", O_RDWR);
	SAFE_PWRITE(NULL, 1, fd, buf, FS_BLOCKSIZE, 0);

	/*
	 * In case mremap() may fail because that memory area can not be
	 * expanded at current virtual address(MREMAP_MAYMOVE is not set),
	 * we first do a mmap(page_size * 2) operation to reserve some
	 * free address space.
	 */
	addr = SAFE_MMAP(NULL, NULL, page_size * 2, PROT_WRITE | PROT_READ,
			 MAP_PRIVATE_EXCEPT_UCLINUX | MAP_ANONYMOUS, -1, 0);
	SAFE_MUNMAP(NULL, addr, page_size * 2);

	addr = SAFE_MMAP(NULL, addr, FS_BLOCKSIZE, PROT_WRITE | PROT_READ,
			 MAP_SHARED, fd, 0);

	addr[0] = 'a';

	SAFE_FTRUNCATE(NULL, fd, page_size * 2);
	addr = mremap(addr, FS_BLOCKSIZE, 2 * page_size, 0);
	if (addr == MAP_FAILED)
		tst_brkm(TBROK | TERRNO, NULL, "mremap failed unexpectedly");

	/*
	 * Let parent process consume FS free blocks as many as possible, then
	 * there'll be no free blocks allocated for this new file mmaping for
	 * offset starting at 1024, 2048, or 3072. If this above kernel bug
	 * has been fixed, usually child process will killed by SIGBUS signal,
	 * if not, the data 'A', 'B', 'C' will be silently discarded later when
	 * kernel writepage is called, that means data corruption.
	 */
	TST_SAFE_CHECKPOINT_WAKE(NULL, 0);
	TST_SAFE_CHECKPOINT_WAIT(NULL, 0);

	for (offset = FS_BLOCKSIZE; offset < page_size; offset += FS_BLOCKSIZE)
		addr[offset] = 'a';

	SAFE_MUNMAP(NULL, addr, 2 * page_size);
	SAFE_CLOSE(NULL, fd);
	exit(TFAIL);
}
Пример #4
0
int main(void)
{
	TST_CHECKPOINT_INIT(NULL);

	TST_SAFE_CHECKPOINT_WAKE(NULL, 0);

	for (;;) {
		sleep(1);
	}
	return 0;
}
Пример #5
0
int main(int argc, char *argv[])
{
	int status;
	int lc;
	int childpid;
	int parentuid;
	int parentgid;
	char path[BUFSIZ];
	char content[BUFSIZ];
	int fd;

	tst_parse_opts(argc, argv, NULL, NULL);
	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		tst_count = 0;
		childpid = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD,
			(void *)child_fn1, NULL);

		if (childpid < 0)
			tst_brkm(TFAIL | TERRNO, cleanup, "clone failed");

		parentuid = geteuid();
		parentgid = getegid();
		sprintf(path, "/proc/%d/uid_map", childpid);
		sprintf(content, "100 %d 1", parentuid);
		fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644);
		SAFE_WRITE(cleanup, 1, fd, content, strlen(content));
		SAFE_CLOSE(cleanup, fd);
		sprintf(path, "/proc/%d/gid_map", childpid);
		sprintf(content, "100 %d 1", parentgid);
		fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644);
		SAFE_WRITE(cleanup, 1, fd, content, strlen(content));
		SAFE_CLOSE(cleanup, fd);

		TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);

		if (waitpid(childpid, &status, 0) < 0)
			tst_brkm(TBROK | TERRNO, cleanup, "waitpid failed");

		if (WIFSIGNALED(status)) {
			tst_resm(TFAIL, "child was killed with signal = %d",
				WTERMSIG(status));
		} else if (WIFEXITED(status) && WEXITSTATUS(status) != 0)
			tst_resm(TFAIL, "child exited abnormally");
		else
			tst_resm(TPASS, "the uid and the gid are right inside "
				"the container");
	}
	cleanup();
	tst_exit();
}
Пример #6
0
static void do_child(void)
{
	if (setsid() < 0) {
		printf("CHILD: setsid() failed, errno: %d\n", errno);
		exit(2);
	}

	TST_SAFE_CHECKPOINT_WAKE(NULL, 0);

	TST_SAFE_CHECKPOINT_WAIT(NULL, 0);

	exit(0);
}
Пример #7
0
static void do_test(void)
{
	int fd, ret, status;
	pid_t child;
	char buf[FS_BLOCKSIZE];

	SAFE_TOUCH(cleanup, "testfilep", 0644, NULL);
	SAFE_TOUCH(cleanup, "testfilec", 0644, NULL);

	child = tst_fork();
	switch (child) {
	case -1:
		tst_brkm(TBROK | TERRNO, cleanup, "fork failed");
	case 0:
		do_child();
	default:
		fd = SAFE_OPEN(cleanup, "testfilep", O_RDWR);
		memset(buf, 'a', FS_BLOCKSIZE);

		TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);
		while (1) {
			ret = write(fd, buf, FS_BLOCKSIZE);
			if (ret < 0) {
				if (errno == ENOSPC) {
					break;
				} else {
					tst_brkm(TBROK | TERRNO, cleanup,
						 "write failed unexpectedly");
				}
			}
		}
		SAFE_CLOSE(cleanup, fd);
		TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);
	}

	wait(&status);
	if (WIFEXITED(status) && WEXITSTATUS(status) == 1) {
		bug_reproduced = 1;
	} else {
		/*
		 * If child process was killed by SIGBUS, bug is not reproduced.
		 */
		if (!WIFSIGNALED(status) || WTERMSIG(status) != SIGBUS) {
			tst_brkm(TBROK | TERRNO, cleanup,
				 "child process terminate unexpectedly");
		}
	}

	SAFE_UNLINK(cleanup, "testfilep");
	SAFE_UNLINK(cleanup, "testfilec");
}
Пример #8
0
int main(int argc, char **argv)
{
	int lc, status;

	tst_parse_opts(argc, argv, options, &help);

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

		SAFE_PIPE(cleanup, pipe_fd);

		/* the start of child_init_and_verify and child_write is
		 * already synchronized via pipe */
		pids[0] = fork();
		switch (pids[0]) {
		case -1:
			tst_brkm(TBROK | TERRNO, cleanup, "fork #0");
		case 0:
			child_init_and_verify();
			exit(0);
		default:
			break;
		}

		pids[1] = fork();
		switch (pids[1]) {
		case -1:
			tst_brkm(TBROK | TERRNO, cleanup, "fork #1");
		case 0:
			child_write();
			exit(0);
		}

		/* wait until child_write writes into
		 * child_init_and_verify's VM */
		SAFE_WAITPID(cleanup, pids[1], &status, 0);
		if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
			tst_resm(TFAIL, "child 1 returns %d", status);

		/* signal child_init_and_verify to verify its VM now */
		TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);

		SAFE_WAITPID(cleanup, pids[0], &status, 0);
		if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
			tst_resm(TFAIL, "child 0 returns %d", status);
	}

	cleanup();
	tst_exit();
}
Пример #9
0
int chld2_sem(void *arg)
{
	int id, rval = 0;
	struct sembuf sm;
	union semun su;

	/* wait for child1 to create the semaphore */
	TST_SAFE_CHECKPOINT_WAIT(NULL, 0);

	id = semget(TESTKEY, 1, IPC_CREAT);
	if (id == -1) {
		perror("semget");
		return 2;
	}

	su.val = 1;
	if (semctl(id, 0, SETVAL, su) == -1) {
		perror("semctl");
		semctl(id, 0, IPC_RMID);
		return 2;
	}

	/* tell child1 to continue and wait for it to lock the semaphore */
	TST_SAFE_CHECKPOINT_WAKE_AND_WAIT(NULL, 0);

	sm.sem_num = 0;
	sm.sem_op = -1;
	sm.sem_flg = IPC_NOWAIT;
	if (semop(id, &sm, 1) == -1) {
		if (errno == EAGAIN) {
			rval = 1;
		} else {
			perror("semop");
			semctl(id, 0, IPC_RMID);
			return 2;
		}
	}

	/* tell child1 to continue */
	TST_SAFE_CHECKPOINT_WAKE(NULL, 0);

	sm.sem_op = 1;
	semop(id, &sm, 1);

	semctl(id, 0, IPC_RMID);
	return rval;
}
Пример #10
0
int main(int ac, char **av)
{
	int sig;
	int lc;

	tst_parse_opts(ac, av, NULL, NULL);

#ifdef UCLINUX
	maybe_run_child(&do_child, "");
#endif

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		if ((pid = FORK_OR_VFORK()) < 0) {
			tst_brkm(TBROK | TERRNO, NULL, "fork() failed");
		} else if (pid > 0) {
			TST_SAFE_CHECKPOINT_WAIT(NULL, 0);

			for (sig = 1; sig < NUMSIGS; sig++) {
				if (skip_sig(sig))
					continue;
				SAFE_KILL(NULL, pid, sig);
			}

			TST_SAFE_CHECKPOINT_WAKE(NULL, 0);
			tst_record_childstatus(cleanup, pid);
		} else {

#ifdef UCLINUX
			if (self_exec(av[0], "") < 0) {
				tst_brkm(TBROK | TERRNO, NULL,
					 "self_exec() failed");
			}
#else
			do_child();
#endif
		}
	}

	cleanup();
	tst_exit();
}
Пример #11
0
int main(int ac, char **av)
{
	int lc;
	pid_t pid;
	char *argv[2] = {TEST_APP, NULL};
	char *env[1] = {NULL};

	tst_parse_opts(ac, av, NULL, NULL);

#ifdef UCLINUX
	maybe_run_child(&do_child, "");
#endif

	setup();

	for (lc = 0; TEST_LOOPING(lc); lc++) {
		if ((pid = FORK_OR_VFORK()) == -1) {
			tst_brkm(TBROK, cleanup, "fork failed");
		} else if (pid == 0) {
#ifdef UCLINUX
			if (self_exec(av[0], "") < 0)
				tst_brkm(TBROK, cleanup, "self_exec failed");
#else
			do_child();
#endif
		}

		TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);

		TEST(execve(TEST_APP, argv, env));

		if (TEST_ERRNO != ETXTBSY)
			tst_resm(TFAIL | TTERRNO, "execve succeeded, expected failure");
		else
			tst_resm(TPASS | TTERRNO, "execve failed as expected");

		TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);
		SAFE_WAIT(cleanup, NULL);
	}

	cleanup();
	tst_exit();
}
Пример #12
0
int chld1_msg(void *arg)
{
	int id, n, rval = 0;
	struct sysv_msg m;
	struct sysv_msg rec;

	id = msgget(TESTKEY, IPC_CREAT | 0600);
	if (id == -1) {
		perror("msgget");
		return 2;
	}

	m.mtype = 1;
	m.mtext[0] = 'A';
	if (msgsnd(id, &m, sizeof(struct sysv_msg) - sizeof(long), 0) == -1) {
		perror("msgsnd");
		msgctl(id, IPC_RMID, NULL);
		return 2;
	}

	/* wait for child2 to write into the message queue */
	TST_SAFE_CHECKPOINT_WAIT(NULL, 0);

	/* if child1 message queue has changed (by child2) report fail */
	n = msgrcv(id, &rec, sizeof(struct sysv_msg) - sizeof(long),
		   2, IPC_NOWAIT);
	if (n == -1 && errno != ENOMSG) {
		perror("msgrcv");
		msgctl(id, IPC_RMID, NULL);
		return 2;
	}
	/* if mtype #2 was found in the message queue, it is fail */
	if (n > 0) {
		rval = 1;
	}

	/* tell child2 to continue */
	TST_SAFE_CHECKPOINT_WAKE(NULL, 0);

	msgctl(id, IPC_RMID, NULL);
	return rval;
}
Пример #13
0
static void test(void)
{
	pid_t pid;
	int status;

	/* unshares the network namespace */
	if (unshare(CLONE_NEWNET) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "unshare failed");

	pid = tst_fork();
	if (pid < 0) {
		tst_brkm(TBROK | TERRNO, cleanup, "fork failed");
	}
	if (pid == 0) {
		_exit(child_func());
	}

	/* creates TAP network interface dummy0 */
	if (WEXITSTATUS(system("ip tuntap add dev dummy0 mode tap")) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "system failed");

	/* removes previously created dummy0 device */
	if (WEXITSTATUS(system("ip tuntap del mode tap dummy0")) == -1)
		tst_brkm(TBROK | TERRNO, cleanup, "system failed");

	/* allow child to continue */
	TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);


	SAFE_WAITPID(cleanup, pid, &status, 0);
	if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
		tst_resm(TFAIL, "netlink interface fail");
		return;
	}
	if (WIFSIGNALED(status)) {
		tst_resm(TFAIL, "child was killed with signal %s",
			 tst_strsig(WTERMSIG(status)));
		return;
	}

	tst_resm(TPASS, "netlink interface pass");
}
Пример #14
0
static void doparent(void)
{
	int fd;

	/* Wait for child lock */
	TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);

	fd = SAFE_OPEN(cleanup, filename, O_RDWR | O_NONBLOCK);

	ftruncate_expect_fail(fd, RECLEN, "offset before lock");
	ftruncate_expect_fail(fd, recstart + RECLEN/2, "offset in lock");
	ftruncate_expect_success(fd, recstart + RECLEN, "offset after lock");

	/* wake child and wait for it to exit (to free record lock) */
	TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);
	SAFE_WAIT(NULL, NULL);

	ftruncate_expect_success(fd, recstart + RECLEN/2, "offset in lock");
	ftruncate_expect_success(fd, recstart, "offset before lock");
	ftruncate_expect_success(fd, recstart + RECLEN, "offset after lock");

	SAFE_CLOSE(NULL, fd);
}
Пример #15
0
int main(int ac, char **av)
{
	int child_pid;
	int status;
	int rval;
	int lc;

	tst_parse_opts(ac, av, NULL, NULL);
#ifdef UCLINUX
	maybe_run_child(&do_child, "");
#endif

	setup();

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

		tst_count = 0;

		/* Child is in new session we are not alowed to change pgid */
		if ((child_pid = FORK_OR_VFORK()) == -1)
			tst_brkm(TBROK, cleanup, "fork() failed");

		if (child_pid == 0) {
#ifdef UCLINUX
			if (self_exec(av[0], "") < 0)
				tst_brkm(TBROK, cleanup, "self_exec failed");
#else
			do_child();
#endif
		}

		TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);
		rval = setpgid(child_pid, getppid());
		if (rval == -1 && errno == EPERM) {
			tst_resm(TPASS, "setpgid failed with EPERM");
		} else {
			tst_resm(TFAIL,
				"retval %d, errno %d, expected errno %d",
				rval, errno, EPERM);
		}
		TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);

		if (wait(&status) < 0)
			tst_resm(TFAIL | TERRNO, "wait() for child 1 failed");

		if (!(WIFEXITED(status)) || (WEXITSTATUS(status) != 0))
			tst_resm(TFAIL, "child 1 failed with status %d",
				WEXITSTATUS(status));

		/* Child after exec() we are no longer allowed to set pgid */
		if ((child_pid = FORK_OR_VFORK()) == -1)
			tst_resm(TFAIL, "Fork failed");

		if (child_pid == 0) {
			if (execlp(TEST_APP, TEST_APP, NULL) < 0)
				perror("exec failed");

			exit(127);
		}

		TST_SAFE_CHECKPOINT_WAIT(cleanup, 0);
		rval = setpgid(child_pid, getppid());
		if (rval == -1 && errno == EACCES) {
			tst_resm(TPASS, "setpgid failed with EACCES");
		} else {
			tst_resm(TFAIL,
				"retval %d, errno %d, expected errno %d",
				rval, errno, EACCES);
		}
		TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);

		if (wait(&status) < 0)
			tst_resm(TFAIL | TERRNO, "wait() for child 2 failed");

		if (!(WIFEXITED(status)) || (WEXITSTATUS(status) != 0))
			tst_resm(TFAIL, "child 2 failed with status %d",
				WEXITSTATUS(status));
	}

	cleanup();
	tst_exit();
}
Пример #16
0
/*
 * child_fn2() - Inside a new user namespace
 */
static int child_fn2(void)
{
	int exit_val = 0;
	int uid, gid;
	char cpid1uidpath[BUFSIZ];
	char cpid1gidpath[BUFSIZ];
	int idinsidens, idoutsidens, length;

	TST_SAFE_CHECKPOINT_WAIT(NULL, 1);

	uid = geteuid();
	gid = getegid();

	if (uid != CHILD2UID || gid != CHILD2GID) {
		printf("unexpected uid=%d gid=%d\n", uid, gid);
		exit_val = 1;
	}

	/*Get the uid parameters of the child_fn2 process.*/
	SAFE_FILE_SCANF(NULL, "/proc/self/uid_map", "%d %d %d", &idinsidens,
		&idoutsidens, &length);

	/* map file format:ID-inside-ns   ID-outside-ns   length
	If the process opening the file is in the same user namespace as
	the process PID, then ID-outside-ns is defined with respect to the
	 parent user namespace.*/
	if (idinsidens != CHILD2UID || idoutsidens != parentuid) {
		printf("child_fn2 checks /proc/cpid2/uid_map:\n");
		printf("unexpected: idinsidens=%d idoutsidens=%d\n",
			idinsidens, idoutsidens);
		exit_val = 1;
	}

	sprintf(cpid1uidpath, "/proc/%d/uid_map", cpid1);
	SAFE_FILE_SCANF(NULL, cpid1uidpath, "%d %d %d", &idinsidens,
		&idoutsidens, &length);

	/* If the process opening the file is in a different user namespace,
	then ID-outside-ns is defined with respect to the user namespace
	of the process opening the file.*/
	if (idinsidens != CHILD1UID || idoutsidens != CHILD2UID) {
		printf("child_fn2 checks /proc/cpid1/uid_map:\n");
		printf("unexpected: idinsidens=%d idoutsidens=%d\n",
			idinsidens, idoutsidens);
		exit_val = 1;
	}

	sprintf(cpid1gidpath, "/proc/%d/gid_map", cpid1);
	SAFE_FILE_SCANF(NULL, "/proc/self/gid_map", "%d %d %d",
		 &idinsidens, &idoutsidens, &length);

	if (idinsidens != CHILD2GID || idoutsidens != parentgid) {
		printf("child_fn2 checks /proc/cpid2/gid_map:\n");
		printf("unexpected: idinsidens=%d idoutsidens=%d\n",
			idinsidens, idoutsidens);
		exit_val = 1;
	}

	SAFE_FILE_SCANF(NULL, cpid1gidpath, "%d %d %d", &idinsidens,
		&idoutsidens, &length);

	if (idinsidens != CHILD1GID || idoutsidens != CHILD2GID) {
		printf("child_fn1 checks /proc/cpid1/gid_map:\n");
		printf("unexpected: idinsidens=%d idoutsidens=%d\n",
			idinsidens, idoutsidens);
		exit_val = 1;
	}

	TST_SAFE_CHECKPOINT_WAKE(NULL, 0);
	TST_SAFE_CHECKPOINT_WAKE(NULL, 1);
	return exit_val;
}
Пример #17
0
int main(int argc, char **argv)
{
	int lc;
	pid_t pid;
	int status;
	int fd;

	tst_parse_opts(argc, argv, NULL, NULL);

#ifdef UCLINUX
	maybe_run_child(&childfunc_uc, "ds", &fd_uc, FILE_NAME);
#endif

	setup();

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

		fd = open(FILE_NAME, O_RDWR);

		if (fd == -1)
			tst_brkm(TFAIL, cleanup, "parent failed to open the"
				 "file, errno %d", errno);

		pid = FORK_OR_VFORK();

		if (pid == -1)
			tst_brkm(TFAIL, cleanup, "fork() failed, errno %d",
				 errno);
		if (pid == 0) {
#ifdef UCLINUX
			if (self_exec(argv[0], "ds", fd, FILE_NAME) < 0)
				tst_brkm(TFAIL, cleanup, "self_exec failed, "
					 "errno &d", errno);
#else
			childfunc(fd);
#endif
		}

		TEST(flock(fd, LOCK_EX | LOCK_NB));

		if (TEST_RETURN != 0)
			tst_resm(TFAIL,
				 "Parent: Initial attempt to flock() failed, "
				 "errno %d", TEST_ERRNO);
		else
			tst_resm(TPASS,
				 "Parent: Initial attempt to flock() passed");

		TST_SAFE_CHECKPOINT_WAKE(cleanup, 0);

		if ((waitpid(pid, &status, 0)) < 0) {
			tst_resm(TFAIL, "wait() failed");
			continue;
		}
		if ((WIFEXITED(status)) && (WEXITSTATUS(status) == 0))
			tst_resm(TPASS, "flock03 Passed");
		else
			tst_resm(TFAIL, "flock03 Failed");

		close(fd);

	}

	cleanup();
	tst_exit();
}