xref: /freebsd/contrib/netbsd-tests/fs/tmpfs/t_renamerace.c (revision 1a36faad54665288ed4eb839d2a4699ae2ead45e)
1*63d1fd59SEnji Cooper /*	$NetBSD: t_renamerace.c,v 1.14 2017/01/13 21:30:40 christos Exp $	*/
257718be8SEnji Cooper 
357718be8SEnji Cooper /*
457718be8SEnji Cooper  * Modified for rump and atf from a program supplied
557718be8SEnji Cooper  * by Nicolas Joly in kern/40948
657718be8SEnji Cooper  */
757718be8SEnji Cooper 
857718be8SEnji Cooper #include <sys/types.h>
957718be8SEnji Cooper #include <sys/mount.h>
1057718be8SEnji Cooper #include <sys/utsname.h>
1157718be8SEnji Cooper 
1257718be8SEnji Cooper #include <atf-c.h>
1357718be8SEnji Cooper #include <errno.h>
1457718be8SEnji Cooper #include <fcntl.h>
1557718be8SEnji Cooper #include <pthread.h>
1657718be8SEnji Cooper #include <stdio.h>
1757718be8SEnji Cooper #include <stdlib.h>
1857718be8SEnji Cooper #include <string.h>
1957718be8SEnji Cooper #include <unistd.h>
2057718be8SEnji Cooper 
2157718be8SEnji Cooper #include <rump/rump.h>
2257718be8SEnji Cooper #include <rump/rump_syscalls.h>
2357718be8SEnji Cooper 
2457718be8SEnji Cooper #include <fs/tmpfs/tmpfs_args.h>
2557718be8SEnji Cooper 
26*63d1fd59SEnji Cooper #include "h_macros.h"
2757718be8SEnji Cooper 
2857718be8SEnji Cooper ATF_TC(renamerace2);
ATF_TC_HEAD(renamerace2,tc)2957718be8SEnji Cooper ATF_TC_HEAD(renamerace2, tc)
3057718be8SEnji Cooper {
3157718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "rename(2) lock order inversion");
3257718be8SEnji Cooper 	atf_tc_set_md_var(tc, "timeout", "6");
3357718be8SEnji Cooper }
3457718be8SEnji Cooper 
3557718be8SEnji Cooper static volatile int quittingtime = 0;
3657718be8SEnji Cooper static pid_t wrkpid;
3757718be8SEnji Cooper 
3857718be8SEnji Cooper static void *
r2w1(void * arg)3957718be8SEnji Cooper r2w1(void *arg)
4057718be8SEnji Cooper {
4157718be8SEnji Cooper 	int fd;
4257718be8SEnji Cooper 
4357718be8SEnji Cooper 	rump_pub_lwproc_newlwp(wrkpid);
4457718be8SEnji Cooper 
4557718be8SEnji Cooper 	fd = rump_sys_open("/file", O_CREAT | O_RDWR, 0777);
4657718be8SEnji Cooper 	if (fd == -1)
4757718be8SEnji Cooper 		atf_tc_fail_errno("creat");
4857718be8SEnji Cooper 	rump_sys_close(fd);
4957718be8SEnji Cooper 
5057718be8SEnji Cooper 	while (!quittingtime) {
5157718be8SEnji Cooper 		if (rump_sys_rename("/file", "/dir/file") == -1)
5257718be8SEnji Cooper 			atf_tc_fail_errno("rename 1");
5357718be8SEnji Cooper 		if (rump_sys_rename("/dir/file", "/file") == -1)
5457718be8SEnji Cooper 			atf_tc_fail_errno("rename 2");
5557718be8SEnji Cooper 	}
5657718be8SEnji Cooper 
5757718be8SEnji Cooper 	return NULL;
5857718be8SEnji Cooper }
5957718be8SEnji Cooper 
6057718be8SEnji Cooper static void *
r2w2(void * arg)6157718be8SEnji Cooper r2w2(void *arg)
6257718be8SEnji Cooper {
6357718be8SEnji Cooper 	int fd;
6457718be8SEnji Cooper 
6557718be8SEnji Cooper 	rump_pub_lwproc_newlwp(wrkpid);
6657718be8SEnji Cooper 
6757718be8SEnji Cooper 	while (!quittingtime) {
6857718be8SEnji Cooper 		fd = rump_sys_open("/dir/file1", O_RDWR);
6957718be8SEnji Cooper 		if (fd != -1)
7057718be8SEnji Cooper 			rump_sys_close(fd);
7157718be8SEnji Cooper 	}
7257718be8SEnji Cooper 
7357718be8SEnji Cooper 	return NULL;
7457718be8SEnji Cooper }
7557718be8SEnji Cooper 
ATF_TC_BODY(renamerace2,tc)7657718be8SEnji Cooper ATF_TC_BODY(renamerace2, tc)
7757718be8SEnji Cooper {
7857718be8SEnji Cooper 	struct tmpfs_args args;
7957718be8SEnji Cooper 	pthread_t pt[2];
8057718be8SEnji Cooper 
8157718be8SEnji Cooper 	/*
8257718be8SEnji Cooper 	 * Force SMP regardless of how many host CPUs there are.
8357718be8SEnji Cooper 	 * Deadlock is highly unlikely to trigger otherwise.
8457718be8SEnji Cooper 	 */
8557718be8SEnji Cooper 	setenv("RUMP_NCPU", "2", 1);
8657718be8SEnji Cooper 
8757718be8SEnji Cooper 	rump_init();
8857718be8SEnji Cooper 	memset(&args, 0, sizeof(args));
8957718be8SEnji Cooper 	args.ta_version = TMPFS_ARGS_VERSION;
9057718be8SEnji Cooper 	args.ta_root_mode = 0777;
9157718be8SEnji Cooper 	if (rump_sys_mount(MOUNT_TMPFS, "/", 0, &args, sizeof(args)) == -1)
9257718be8SEnji Cooper 		atf_tc_fail_errno("could not mount tmpfs");
9357718be8SEnji Cooper 
9457718be8SEnji Cooper 	if (rump_sys_mkdir("/dir", 0777) == -1)
9557718be8SEnji Cooper 		atf_tc_fail_errno("cannot create directory");
9657718be8SEnji Cooper 
9757718be8SEnji Cooper 	RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
9857718be8SEnji Cooper 	RL(wrkpid = rump_sys_getpid());
9957718be8SEnji Cooper 	pthread_create(&pt[0], NULL, r2w1, NULL);
10057718be8SEnji Cooper 	pthread_create(&pt[1], NULL, r2w2, NULL);
10157718be8SEnji Cooper 
10257718be8SEnji Cooper 	/* usually triggers in <<1s for me */
10357718be8SEnji Cooper 	sleep(4);
10457718be8SEnji Cooper 	quittingtime = 1;
10557718be8SEnji Cooper 
10657718be8SEnji Cooper 	pthread_join(pt[0], NULL);
10757718be8SEnji Cooper 	pthread_join(pt[1], NULL);
10857718be8SEnji Cooper }
10957718be8SEnji Cooper 
ATF_TP_ADD_TCS(tp)11057718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
11157718be8SEnji Cooper {
11257718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, renamerace2);
11357718be8SEnji Cooper 
11457718be8SEnji Cooper 	return atf_no_error();
11557718be8SEnji Cooper }
116