1 /* $NetBSD: t_renamerace.c,v 1.11 2010/08/26 18:06:44 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 29 static void * 30 w1(void *arg) 31 { 32 int fd; 33 34 rump_pub_lwp_alloc_and_switch(0, 10); 35 36 while (!quittingtime) { 37 fd = rump_sys_open("rename.test1", 38 O_WRONLY|O_CREAT|O_TRUNC, 0666); 39 if (fd == -1 && errno != EEXIST) 40 atf_tc_fail_errno("create"); 41 rump_sys_unlink("rename.test1"); 42 rump_sys_close(fd); 43 } 44 45 return NULL; 46 } 47 48 static void * 49 w1_dirs(void *arg) 50 { 51 52 rump_pub_lwp_alloc_and_switch(0, 10); 53 54 while (!quittingtime) { 55 if (rump_sys_mkdir("rename.test1", 0777) == -1) 56 atf_tc_fail_errno("mkdir"); 57 rump_sys_rmdir("rename.test1"); 58 } 59 60 return NULL; 61 } 62 63 static void * 64 w2(void *arg) 65 { 66 67 rump_pub_lwp_alloc_and_switch(0, 11); 68 69 while (!quittingtime) { 70 rump_sys_rename("rename.test1", "rename.test2"); 71 } 72 73 return NULL; 74 } 75 76 #define NWRK 8 77 static void 78 renamerace(const atf_tc_t *tc, const char *mp) 79 { 80 pthread_t pt1[NWRK], pt2[NWRK]; 81 int i; 82 83 if (FSTYPE_LFS(tc)) 84 atf_tc_expect_signal(-1, "PR kern/43582"); 85 86 if (FSTYPE_MSDOS(tc)) 87 atf_tc_skip("test fails in some setups, reason unknown"); 88 89 RL(rump_sys_chdir(mp)); 90 for (i = 0; i < NWRK; i++) 91 pthread_create(&pt1[i], NULL, w1, NULL); 92 93 for (i = 0; i < NWRK; i++) 94 pthread_create(&pt2[i], NULL, w2, NULL); 95 96 sleep(5); 97 quittingtime = 1; 98 99 for (i = 0; i < NWRK; i++) 100 pthread_join(pt1[i], NULL); 101 for (i = 0; i < NWRK; i++) 102 pthread_join(pt2[i], NULL); 103 RL(rump_sys_chdir("/")); 104 105 /* 106 * XXX: does not always fail on LFS, especially for unicpu 107 * configurations. see other ramblings about racy tests. 108 */ 109 if (FSTYPE_LFS(tc)) 110 abort(); 111 } 112 113 static void 114 renamerace_dirs(const atf_tc_t *tc, const char *mp) 115 { 116 pthread_t pt1, pt2; 117 118 if (FSTYPE_SYSVBFS(tc)) 119 atf_tc_skip("directories not supported"); 120 121 /* XXX: msdosfs also sometimes hangs */ 122 if (FSTYPE_FFS(tc) || FSTYPE_EXT2FS(tc) || FSTYPE_LFS(tc) || 123 FSTYPE_MSDOS(tc)) 124 atf_tc_expect_signal(-1, "PR kern/43626"); 125 126 RL(rump_sys_chdir(mp)); 127 pthread_create(&pt1, NULL, w1_dirs, NULL); 128 pthread_create(&pt2, NULL, w2, NULL); 129 130 sleep(5); 131 quittingtime = 1; 132 133 pthread_join(pt1, NULL); 134 pthread_join(pt2, NULL); 135 RL(rump_sys_chdir("/")); 136 137 /* 138 * Doesn't always trigger when run on a slow backend 139 * (i.e. not on tmpfs/mfs). So do the usual kludge. 140 */ 141 if (FSTYPE_FFS(tc) || FSTYPE_EXT2FS(tc) || FSTYPE_LFS(tc) || 142 FSTYPE_MSDOS(tc)) 143 abort(); 144 } 145 146 ATF_TC_FSAPPLY(renamerace, "rename(2) race with file unlinked mid-operation"); 147 ATF_TC_FSAPPLY(renamerace_dirs, "rename(2) race with directories"); 148 149 ATF_TP_ADD_TCS(tp) 150 { 151 152 ATF_TP_FSAPPLY(renamerace); /* PR kern/41128 */ 153 ATF_TP_FSAPPLY(renamerace_dirs); 154 155 return atf_no_error(); 156 } 157