1 /* $NetBSD: t_renamerace.c,v 1.22 2011/03/14 19:05:19 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_RUMPFS(tc)) 88 atf_tc_skip("rename not supported by fs"); 89 90 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 91 RL(wrkpid = rump_sys_getpid()); 92 93 RL(rump_sys_chdir(mp)); 94 for (i = 0; i < NWRK; i++) 95 pthread_create(&pt1[i], NULL, w1, NULL); 96 97 for (i = 0; i < NWRK; i++) 98 pthread_create(&pt2[i], NULL, w2, NULL); 99 100 sleep(5); 101 quittingtime = 1; 102 103 for (i = 0; i < NWRK; i++) 104 pthread_join(pt1[i], NULL); 105 for (i = 0; i < NWRK; i++) 106 pthread_join(pt2[i], NULL); 107 RL(rump_sys_chdir("/")); 108 109 /* 110 * XXX: does not always fail on LFS, especially for unicpu 111 * configurations. see other ramblings about racy tests. 112 */ 113 if (FSTYPE_LFS(tc)) 114 abort(); 115 116 if (FSTYPE_MSDOS(tc)) { 117 atf_tc_expect_fail("PR kern/44661"); 118 /* 119 * XXX: race does not trigger every time at least 120 * on amd64/qemu. 121 */ 122 if (msdosfs_fstest_unmount(tc, mp, 0) != 0) { 123 rump_pub_vfs_mount_print(mp, 1); 124 atf_tc_fail_errno("unmount failed"); 125 } 126 atf_tc_fail("race did not trigger this time"); 127 } 128 } 129 130 static void 131 renamerace_dirs(const atf_tc_t *tc, const char *mp) 132 { 133 pthread_t pt1, pt2; 134 135 if (FSTYPE_SYSVBFS(tc)) 136 atf_tc_skip("directories not supported"); 137 138 if (FSTYPE_RUMPFS(tc)) 139 atf_tc_skip("rename not supported by fs"); 140 141 /* XXX: msdosfs also sometimes hangs */ 142 if (FSTYPE_FFS(tc) || FSTYPE_EXT2FS(tc) || FSTYPE_LFS(tc) || 143 FSTYPE_MSDOS(tc) || FSTYPE_FFSLOG(tc)) 144 atf_tc_expect_signal(-1, "PR kern/43626"); 145 146 /* XXX: unracy execution not caught */ 147 if (FSTYPE_P2K_FFS(tc)) 148 atf_tc_expect_fail("PR kern/44336"); /* child dies */ 149 150 RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 151 RL(wrkpid = rump_sys_getpid()); 152 153 RL(rump_sys_chdir(mp)); 154 pthread_create(&pt1, NULL, w1_dirs, NULL); 155 pthread_create(&pt2, NULL, w2, NULL); 156 157 sleep(5); 158 quittingtime = 1; 159 160 pthread_join(pt1, NULL); 161 pthread_join(pt2, NULL); 162 RL(rump_sys_chdir("/")); 163 164 /* 165 * Doesn't always trigger when run on a slow backend 166 * (i.e. not on tmpfs/mfs). So do the usual kludge. 167 */ 168 if (FSTYPE_FFS(tc) || FSTYPE_EXT2FS(tc) || FSTYPE_LFS(tc) || 169 FSTYPE_MSDOS(tc) || FSTYPE_FFSLOG(tc)) 170 abort(); 171 172 if (FSTYPE_P2K_FFS(tc)) { 173 /* XXX: some races may hang test run if we don't unmount */ 174 puffs_fstest_unmount(tc, mp, MNT_FORCE); 175 atf_tc_fail("problem did not trigger"); 176 } 177 } 178 179 ATF_TC_FSAPPLY(renamerace, "rename(2) race with file unlinked mid-operation"); 180 ATF_TC_FSAPPLY(renamerace_dirs, "rename(2) race with directories"); 181 182 ATF_TP_ADD_TCS(tp) 183 { 184 185 ATF_TP_FSAPPLY(renamerace); /* PR kern/41128 */ 186 ATF_TP_FSAPPLY(renamerace_dirs); 187 188 return atf_no_error(); 189 } 190