xref: /freebsd/contrib/netbsd-tests/fs/tmpfs/t_renamerace.c (revision 57718be8fa0bd5edc11ab9a72e68cc71982939a6)
1*57718be8SEnji Cooper /*	$NetBSD: t_renamerace.c,v 1.13 2011/08/18 21:44:55 riastradh Exp $	*/
2*57718be8SEnji Cooper 
3*57718be8SEnji Cooper /*
4*57718be8SEnji Cooper  * Modified for rump and atf from a program supplied
5*57718be8SEnji Cooper  * by Nicolas Joly in kern/40948
6*57718be8SEnji Cooper  */
7*57718be8SEnji Cooper 
8*57718be8SEnji Cooper #include <sys/types.h>
9*57718be8SEnji Cooper #include <sys/mount.h>
10*57718be8SEnji Cooper #include <sys/utsname.h>
11*57718be8SEnji Cooper 
12*57718be8SEnji Cooper #include <atf-c.h>
13*57718be8SEnji Cooper #include <errno.h>
14*57718be8SEnji Cooper #include <fcntl.h>
15*57718be8SEnji Cooper #include <pthread.h>
16*57718be8SEnji Cooper #include <stdio.h>
17*57718be8SEnji Cooper #include <stdlib.h>
18*57718be8SEnji Cooper #include <string.h>
19*57718be8SEnji Cooper #include <unistd.h>
20*57718be8SEnji Cooper 
21*57718be8SEnji Cooper #include <rump/rump.h>
22*57718be8SEnji Cooper #include <rump/rump_syscalls.h>
23*57718be8SEnji Cooper 
24*57718be8SEnji Cooper #include <fs/tmpfs/tmpfs_args.h>
25*57718be8SEnji Cooper 
26*57718be8SEnji Cooper #include "../../h_macros.h"
27*57718be8SEnji Cooper 
28*57718be8SEnji Cooper ATF_TC(renamerace2);
29*57718be8SEnji Cooper ATF_TC_HEAD(renamerace2, tc)
30*57718be8SEnji Cooper {
31*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "descr", "rename(2) lock order inversion");
32*57718be8SEnji Cooper 	atf_tc_set_md_var(tc, "timeout", "6");
33*57718be8SEnji Cooper }
34*57718be8SEnji Cooper 
35*57718be8SEnji Cooper static volatile int quittingtime = 0;
36*57718be8SEnji Cooper static pid_t wrkpid;
37*57718be8SEnji Cooper 
38*57718be8SEnji Cooper static void *
39*57718be8SEnji Cooper r2w1(void *arg)
40*57718be8SEnji Cooper {
41*57718be8SEnji Cooper 	int fd;
42*57718be8SEnji Cooper 
43*57718be8SEnji Cooper 	rump_pub_lwproc_newlwp(wrkpid);
44*57718be8SEnji Cooper 
45*57718be8SEnji Cooper 	fd = rump_sys_open("/file", O_CREAT | O_RDWR, 0777);
46*57718be8SEnji Cooper 	if (fd == -1)
47*57718be8SEnji Cooper 		atf_tc_fail_errno("creat");
48*57718be8SEnji Cooper 	rump_sys_close(fd);
49*57718be8SEnji Cooper 
50*57718be8SEnji Cooper 	while (!quittingtime) {
51*57718be8SEnji Cooper 		if (rump_sys_rename("/file", "/dir/file") == -1)
52*57718be8SEnji Cooper 			atf_tc_fail_errno("rename 1");
53*57718be8SEnji Cooper 		if (rump_sys_rename("/dir/file", "/file") == -1)
54*57718be8SEnji Cooper 			atf_tc_fail_errno("rename 2");
55*57718be8SEnji Cooper 	}
56*57718be8SEnji Cooper 
57*57718be8SEnji Cooper 	return NULL;
58*57718be8SEnji Cooper }
59*57718be8SEnji Cooper 
60*57718be8SEnji Cooper static void *
61*57718be8SEnji Cooper r2w2(void *arg)
62*57718be8SEnji Cooper {
63*57718be8SEnji Cooper 	int fd;
64*57718be8SEnji Cooper 
65*57718be8SEnji Cooper 	rump_pub_lwproc_newlwp(wrkpid);
66*57718be8SEnji Cooper 
67*57718be8SEnji Cooper 	while (!quittingtime) {
68*57718be8SEnji Cooper 		fd = rump_sys_open("/dir/file1", O_RDWR);
69*57718be8SEnji Cooper 		if (fd != -1)
70*57718be8SEnji Cooper 			rump_sys_close(fd);
71*57718be8SEnji Cooper 	}
72*57718be8SEnji Cooper 
73*57718be8SEnji Cooper 	return NULL;
74*57718be8SEnji Cooper }
75*57718be8SEnji Cooper 
76*57718be8SEnji Cooper ATF_TC_BODY(renamerace2, tc)
77*57718be8SEnji Cooper {
78*57718be8SEnji Cooper 	struct tmpfs_args args;
79*57718be8SEnji Cooper 	pthread_t pt[2];
80*57718be8SEnji Cooper 
81*57718be8SEnji Cooper 	/*
82*57718be8SEnji Cooper 	 * Force SMP regardless of how many host CPUs there are.
83*57718be8SEnji Cooper 	 * Deadlock is highly unlikely to trigger otherwise.
84*57718be8SEnji Cooper 	 */
85*57718be8SEnji Cooper 	setenv("RUMP_NCPU", "2", 1);
86*57718be8SEnji Cooper 
87*57718be8SEnji Cooper 	rump_init();
88*57718be8SEnji Cooper 	memset(&args, 0, sizeof(args));
89*57718be8SEnji Cooper 	args.ta_version = TMPFS_ARGS_VERSION;
90*57718be8SEnji Cooper 	args.ta_root_mode = 0777;
91*57718be8SEnji Cooper 	if (rump_sys_mount(MOUNT_TMPFS, "/", 0, &args, sizeof(args)) == -1)
92*57718be8SEnji Cooper 		atf_tc_fail_errno("could not mount tmpfs");
93*57718be8SEnji Cooper 
94*57718be8SEnji Cooper 	if (rump_sys_mkdir("/dir", 0777) == -1)
95*57718be8SEnji Cooper 		atf_tc_fail_errno("cannot create directory");
96*57718be8SEnji Cooper 
97*57718be8SEnji Cooper 	RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
98*57718be8SEnji Cooper 	RL(wrkpid = rump_sys_getpid());
99*57718be8SEnji Cooper 	pthread_create(&pt[0], NULL, r2w1, NULL);
100*57718be8SEnji Cooper 	pthread_create(&pt[1], NULL, r2w2, NULL);
101*57718be8SEnji Cooper 
102*57718be8SEnji Cooper 	/* usually triggers in <<1s for me */
103*57718be8SEnji Cooper 	sleep(4);
104*57718be8SEnji Cooper 	quittingtime = 1;
105*57718be8SEnji Cooper 
106*57718be8SEnji Cooper 	pthread_join(pt[0], NULL);
107*57718be8SEnji Cooper 	pthread_join(pt[1], NULL);
108*57718be8SEnji Cooper }
109*57718be8SEnji Cooper 
110*57718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
111*57718be8SEnji Cooper {
112*57718be8SEnji Cooper 	ATF_TP_ADD_TC(tp, renamerace2);
113*57718be8SEnji Cooper 
114*57718be8SEnji Cooper 	return atf_no_error();
115*57718be8SEnji Cooper }
116