xref: /netbsd-src/tests/fs/tmpfs/t_renamerace.c (revision 55908713e4b89050ab16083b852a73598d855a42)
1*55908713Sjruoho /*	$NetBSD: t_renamerace.c,v 1.15 2020/06/26 07:50:12 jruoho Exp $	*/
2163d880bSpooka 
3163d880bSpooka /*
4163d880bSpooka  * Modified for rump and atf from a program supplied
5*55908713Sjruoho  * by Nicolas Joly in PR kern/40948
6163d880bSpooka  */
7163d880bSpooka 
8163d880bSpooka #include <sys/types.h>
9163d880bSpooka #include <sys/mount.h>
10d2c2528cSpooka #include <sys/utsname.h>
11163d880bSpooka 
12163d880bSpooka #include <atf-c.h>
13163d880bSpooka #include <errno.h>
14163d880bSpooka #include <fcntl.h>
15163d880bSpooka #include <pthread.h>
16163d880bSpooka #include <stdio.h>
17d2c2528cSpooka #include <stdlib.h>
18163d880bSpooka #include <string.h>
19d2c2528cSpooka #include <unistd.h>
20163d880bSpooka 
21163d880bSpooka #include <rump/rump.h>
22163d880bSpooka #include <rump/rump_syscalls.h>
23163d880bSpooka 
24163d880bSpooka #include <fs/tmpfs/tmpfs_args.h>
25163d880bSpooka 
26c54cb811Schristos #include "h_macros.h"
273df59b06Spooka 
28d2c2528cSpooka ATF_TC(renamerace2);
ATF_TC_HEAD(renamerace2,tc)29d2c2528cSpooka ATF_TC_HEAD(renamerace2, tc)
30d2c2528cSpooka {
31d2c2528cSpooka 	atf_tc_set_md_var(tc, "descr", "rename(2) lock order inversion");
32d2c2528cSpooka 	atf_tc_set_md_var(tc, "timeout", "6");
33d2c2528cSpooka }
34d2c2528cSpooka 
35d2c2528cSpooka static volatile int quittingtime = 0;
362a47331eSpooka static pid_t wrkpid;
37d2c2528cSpooka 
38d2c2528cSpooka static void *
r2w1(void * arg)39d2c2528cSpooka r2w1(void *arg)
40d2c2528cSpooka {
41d2c2528cSpooka 	int fd;
42d2c2528cSpooka 
432a47331eSpooka 	rump_pub_lwproc_newlwp(wrkpid);
44d2c2528cSpooka 
45d2c2528cSpooka 	fd = rump_sys_open("/file", O_CREAT | O_RDWR, 0777);
46d2c2528cSpooka 	if (fd == -1)
47d2c2528cSpooka 		atf_tc_fail_errno("creat");
48d2c2528cSpooka 	rump_sys_close(fd);
49d2c2528cSpooka 
50d2c2528cSpooka 	while (!quittingtime) {
51d2c2528cSpooka 		if (rump_sys_rename("/file", "/dir/file") == -1)
52d2c2528cSpooka 			atf_tc_fail_errno("rename 1");
53d2c2528cSpooka 		if (rump_sys_rename("/dir/file", "/file") == -1)
54d2c2528cSpooka 			atf_tc_fail_errno("rename 2");
55d2c2528cSpooka 	}
56d2c2528cSpooka 
57d2c2528cSpooka 	return NULL;
58d2c2528cSpooka }
59d2c2528cSpooka 
60d2c2528cSpooka static void *
r2w2(void * arg)61d2c2528cSpooka r2w2(void *arg)
62d2c2528cSpooka {
63d2c2528cSpooka 	int fd;
64d2c2528cSpooka 
652a47331eSpooka 	rump_pub_lwproc_newlwp(wrkpid);
66d2c2528cSpooka 
67d2c2528cSpooka 	while (!quittingtime) {
68d2c2528cSpooka 		fd = rump_sys_open("/dir/file1", O_RDWR);
69d2c2528cSpooka 		if (fd != -1)
70d2c2528cSpooka 			rump_sys_close(fd);
71d2c2528cSpooka 	}
72d2c2528cSpooka 
73d2c2528cSpooka 	return NULL;
74d2c2528cSpooka }
75d2c2528cSpooka 
ATF_TC_BODY(renamerace2,tc)76d2c2528cSpooka ATF_TC_BODY(renamerace2, tc)
77d2c2528cSpooka {
78d2c2528cSpooka 	struct tmpfs_args args;
79d2c2528cSpooka 	pthread_t pt[2];
80d2c2528cSpooka 
81d2c2528cSpooka 	/*
82d2c2528cSpooka 	 * Force SMP regardless of how many host CPUs there are.
83d2c2528cSpooka 	 * Deadlock is highly unlikely to trigger otherwise.
84d2c2528cSpooka 	 */
85d2c2528cSpooka 	setenv("RUMP_NCPU", "2", 1);
86d2c2528cSpooka 
87d2c2528cSpooka 	rump_init();
88d2c2528cSpooka 	memset(&args, 0, sizeof(args));
89d2c2528cSpooka 	args.ta_version = TMPFS_ARGS_VERSION;
90d2c2528cSpooka 	args.ta_root_mode = 0777;
91d2c2528cSpooka 	if (rump_sys_mount(MOUNT_TMPFS, "/", 0, &args, sizeof(args)) == -1)
92d2c2528cSpooka 		atf_tc_fail_errno("could not mount tmpfs");
93d2c2528cSpooka 
94d2c2528cSpooka 	if (rump_sys_mkdir("/dir", 0777) == -1)
95d2c2528cSpooka 		atf_tc_fail_errno("cannot create directory");
96d2c2528cSpooka 
975c3365ceSpooka 	RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
982a47331eSpooka 	RL(wrkpid = rump_sys_getpid());
99d2c2528cSpooka 	pthread_create(&pt[0], NULL, r2w1, NULL);
100d2c2528cSpooka 	pthread_create(&pt[1], NULL, r2w2, NULL);
101d2c2528cSpooka 
102d2c2528cSpooka 	/* usually triggers in <<1s for me */
103d2c2528cSpooka 	sleep(4);
104d2c2528cSpooka 	quittingtime = 1;
105d2c2528cSpooka 
106d2c2528cSpooka 	pthread_join(pt[0], NULL);
107d2c2528cSpooka 	pthread_join(pt[1], NULL);
108d2c2528cSpooka }
109d2c2528cSpooka 
ATF_TP_ADD_TCS(tp)110163d880bSpooka ATF_TP_ADD_TCS(tp)
111163d880bSpooka {
112d2c2528cSpooka 	ATF_TP_ADD_TC(tp, renamerace2);
113d2c2528cSpooka 
114d2c2528cSpooka 	return atf_no_error();
115163d880bSpooka }
116