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