1 /* $NetBSD: t_renamerace.c,v 1.18 2011/01/11 09:32:50 pooka Exp $ */ 2 3 /* 4 * Modified for rump and atf from a program supplied 5 * by Nicolas Joly in kern/40948 6 */ 7 8 #include <sys/types.h> 9 #include <sys/mount.h> 10 #include <sys/utsname.h> 11 12 #include <atf-c.h> 13 #include <errno.h> 14 #include <fcntl.h> 15 #include <pthread.h> 16 #include <stdio.h> 17 #include <stdlib.h> 18 #include <string.h> 19 #include <unistd.h> 20 21 #include <rump/rump.h> 22 #include <rump/rump_syscalls.h> 23 24 #include "../common/h_fsmacros.h" 25 #include "../../h_macros.h" 26 27 static volatile int quittingtime; 28 pid_t wrkpid; 29 30 static void * 31 w1(void *arg) 32 { 33 int fd; 34 35 rump_pub_lwproc_newlwp(wrkpid); 36 37 while (!quittingtime) { 38 fd = rump_sys_open("rename.test1", 39 O_WRONLY|O_CREAT|O_TRUNC, 0666); 40 if (fd == -1 && errno != EEXIST) 41 atf_tc_fail_errno("create"); 42 rump_sys_unlink("rename.test1"); 43 rump_sys_close(fd); 44 } 45 46 return NULL; 47 } 48 49 static void * 50 w1_dirs(void *arg) 51 { 52 53 rump_pub_lwproc_newlwp(wrkpid); 54 55 while (!quittingtime) { 56 if (rump_sys_mkdir("rename.test1", 0777) == -1) 57 atf_tc_fail_errno("mkdir"); 58 rump_sys_rmdir("rename.test1"); 59 } 60 61 return NULL; 62 } 63 64 static void * 65 w2(void *arg) 66 { 67 68 rump_pub_lwproc_newlwp(wrkpid); 69 70 while (!quittingtime) { 71 rump_sys_rename("rename.test1", "rename.test2"); 72 } 73 74 return NULL; 75 } 76 77 #define NWRK 8 78 static void 79 renamerace(const atf_tc_t *tc, const char *mp) 80 { 81 pthread_t pt1[NWRK], pt2[NWRK]; 82 int i; 83 84 if (FSTYPE_LFS(tc)) 85 atf_tc_expect_signal(-1, "PR kern/43582"); 86 87 if (FSTYPE_MSDOS(tc)) 88 atf_tc_skip("test fails in some setups, reason unknown"); 89 90 if (FSTYPE_RUMPFS(tc)) 91 atf_tc_skip("rename not supported by fs"); 92 93 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 94 RL(wrkpid = rump_sys_getpid()); 95 96 RL(rump_sys_chdir(mp)); 97 for (i = 0; i < NWRK; i++) 98 pthread_create(&pt1[i], NULL, w1, NULL); 99 100 for (i = 0; i < NWRK; i++) 101 pthread_create(&pt2[i], NULL, w2, NULL); 102 103 sleep(5); 104 quittingtime = 1; 105 106 for (i = 0; i < NWRK; i++) 107 pthread_join(pt1[i], NULL); 108 for (i = 0; i < NWRK; i++) 109 pthread_join(pt2[i], NULL); 110 RL(rump_sys_chdir("/")); 111 112 /* 113 * XXX: does not always fail on LFS, especially for unicpu 114 * configurations. see other ramblings about racy tests. 115 */ 116 if (FSTYPE_LFS(tc)) 117 abort(); 118 } 119 120 static void 121 renamerace_dirs(const atf_tc_t *tc, const char *mp) 122 { 123 pthread_t pt1, pt2; 124 125 if (FSTYPE_SYSVBFS(tc)) 126 atf_tc_skip("directories not supported"); 127 128 if (FSTYPE_RUMPFS(tc)) 129 atf_tc_skip("rename not supported by fs"); 130 131 /* XXX: msdosfs also sometimes hangs */ 132 if (FSTYPE_FFS(tc) || FSTYPE_EXT2FS(tc) || FSTYPE_LFS(tc) || 133 FSTYPE_MSDOS(tc) || FSTYPE_FFSLOG(tc)) 134 atf_tc_expect_signal(-1, "PR kern/43626"); 135 136 /* XXX: unracy execution not caught */ 137 if (FSTYPE_P2K_FFS(tc)) 138 atf_tc_expect_fail("PR kern/44336"); /* child dies */ 139 140 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 141 RL(wrkpid = rump_sys_getpid()); 142 143 RL(rump_sys_chdir(mp)); 144 pthread_create(&pt1, NULL, w1_dirs, NULL); 145 pthread_create(&pt2, NULL, w2, NULL); 146 147 sleep(5); 148 quittingtime = 1; 149 150 pthread_join(pt1, NULL); 151 pthread_join(pt2, NULL); 152 RL(rump_sys_chdir("/")); 153 154 /* 155 * Doesn't always trigger when run on a slow backend 156 * (i.e. not on tmpfs/mfs). So do the usual kludge. 157 */ 158 if (FSTYPE_FFS(tc) || FSTYPE_EXT2FS(tc) || FSTYPE_LFS(tc) || 159 FSTYPE_MSDOS(tc) || FSTYPE_FFSLOG(tc)) 160 abort(); 161 } 162 163 ATF_TC_FSAPPLY(renamerace, "rename(2) race with file unlinked mid-operation"); 164 ATF_TC_FSAPPLY(renamerace_dirs, "rename(2) race with directories"); 165 166 ATF_TP_ADD_TCS(tp) 167 { 168 169 ATF_TP_FSAPPLY(renamerace); /* PR kern/41128 */ 170 ATF_TP_FSAPPLY(renamerace_dirs); 171 172 return atf_no_error(); 173 } 174