1*11be35a1SLionel Sambuc /* $NetBSD: t_renamerace.c,v 1.29 2013/07/10 18:55:00 reinoud Exp $ */ 2*11be35a1SLionel Sambuc 3*11be35a1SLionel Sambuc /* 4*11be35a1SLionel Sambuc * Modified for rump and atf from a program supplied 5*11be35a1SLionel Sambuc * by Nicolas Joly in kern/40948 6*11be35a1SLionel Sambuc */ 7*11be35a1SLionel Sambuc 8*11be35a1SLionel Sambuc #include <sys/types.h> 9*11be35a1SLionel Sambuc #include <sys/mount.h> 10*11be35a1SLionel Sambuc #include <sys/utsname.h> 11*11be35a1SLionel Sambuc 12*11be35a1SLionel Sambuc #include <atf-c.h> 13*11be35a1SLionel Sambuc #include <errno.h> 14*11be35a1SLionel Sambuc #include <fcntl.h> 15*11be35a1SLionel Sambuc #include <pthread.h> 16*11be35a1SLionel Sambuc #include <stdio.h> 17*11be35a1SLionel Sambuc #include <stdlib.h> 18*11be35a1SLionel Sambuc #include <string.h> 19*11be35a1SLionel Sambuc #include <unistd.h> 20*11be35a1SLionel Sambuc 21*11be35a1SLionel Sambuc #include <rump/rump.h> 22*11be35a1SLionel Sambuc #include <rump/rump_syscalls.h> 23*11be35a1SLionel Sambuc 24*11be35a1SLionel Sambuc /* Bump the size of the test file system image to a larger value. 25*11be35a1SLionel Sambuc * 26*11be35a1SLionel Sambuc * These tests cause a lot of churn in the file system by creating and 27*11be35a1SLionel Sambuc * deleting files/directories in quick succession. A faster CPU will cause 28*11be35a1SLionel Sambuc * more churn because the tests are capped by a run time period in seconds, 29*11be35a1SLionel Sambuc * not number of operations. 30*11be35a1SLionel Sambuc * 31*11be35a1SLionel Sambuc * This is all fine except for LFS, because the lfs_cleanerd cannot keep up 32*11be35a1SLionel Sambuc * with the churn and thus causes the test to fail on fast machines. Hence 33*11be35a1SLionel Sambuc * the reason for this hack. */ 34*11be35a1SLionel Sambuc #define FSTEST_IMGSIZE (50000 * 512) 35*11be35a1SLionel Sambuc 36*11be35a1SLionel Sambuc #include "../common/h_fsmacros.h" 37*11be35a1SLionel Sambuc #include "../../h_macros.h" 38*11be35a1SLionel Sambuc 39*11be35a1SLionel Sambuc static volatile int quittingtime; 40*11be35a1SLionel Sambuc pid_t wrkpid; 41*11be35a1SLionel Sambuc 42*11be35a1SLionel Sambuc static void * 43*11be35a1SLionel Sambuc w1(void *arg) 44*11be35a1SLionel Sambuc { 45*11be35a1SLionel Sambuc int fd; 46*11be35a1SLionel Sambuc 47*11be35a1SLionel Sambuc rump_pub_lwproc_newlwp(wrkpid); 48*11be35a1SLionel Sambuc 49*11be35a1SLionel Sambuc while (!quittingtime) { 50*11be35a1SLionel Sambuc fd = rump_sys_open("rename.test1", 51*11be35a1SLionel Sambuc O_WRONLY|O_CREAT|O_TRUNC, 0666); 52*11be35a1SLionel Sambuc if (fd == -1 && errno != EEXIST) 53*11be35a1SLionel Sambuc atf_tc_fail_errno("create"); 54*11be35a1SLionel Sambuc rump_sys_unlink("rename.test1"); 55*11be35a1SLionel Sambuc rump_sys_close(fd); 56*11be35a1SLionel Sambuc } 57*11be35a1SLionel Sambuc 58*11be35a1SLionel Sambuc return NULL; 59*11be35a1SLionel Sambuc } 60*11be35a1SLionel Sambuc 61*11be35a1SLionel Sambuc static void * 62*11be35a1SLionel Sambuc w1_dirs(void *arg) 63*11be35a1SLionel Sambuc { 64*11be35a1SLionel Sambuc 65*11be35a1SLionel Sambuc rump_pub_lwproc_newlwp(wrkpid); 66*11be35a1SLionel Sambuc 67*11be35a1SLionel Sambuc while (!quittingtime) { 68*11be35a1SLionel Sambuc if (rump_sys_mkdir("rename.test1", 0777) == -1) 69*11be35a1SLionel Sambuc atf_tc_fail_errno("mkdir"); 70*11be35a1SLionel Sambuc rump_sys_rmdir("rename.test1"); 71*11be35a1SLionel Sambuc } 72*11be35a1SLionel Sambuc 73*11be35a1SLionel Sambuc return NULL; 74*11be35a1SLionel Sambuc } 75*11be35a1SLionel Sambuc 76*11be35a1SLionel Sambuc static void * 77*11be35a1SLionel Sambuc w2(void *arg) 78*11be35a1SLionel Sambuc { 79*11be35a1SLionel Sambuc 80*11be35a1SLionel Sambuc rump_pub_lwproc_newlwp(wrkpid); 81*11be35a1SLionel Sambuc 82*11be35a1SLionel Sambuc while (!quittingtime) { 83*11be35a1SLionel Sambuc rump_sys_rename("rename.test1", "rename.test2"); 84*11be35a1SLionel Sambuc } 85*11be35a1SLionel Sambuc 86*11be35a1SLionel Sambuc return NULL; 87*11be35a1SLionel Sambuc } 88*11be35a1SLionel Sambuc 89*11be35a1SLionel Sambuc #define NWRK 8 90*11be35a1SLionel Sambuc static void 91*11be35a1SLionel Sambuc renamerace(const atf_tc_t *tc, const char *mp) 92*11be35a1SLionel Sambuc { 93*11be35a1SLionel Sambuc pthread_t pt1[NWRK], pt2[NWRK]; 94*11be35a1SLionel Sambuc int i; 95*11be35a1SLionel Sambuc 96*11be35a1SLionel Sambuc if (FSTYPE_RUMPFS(tc)) 97*11be35a1SLionel Sambuc atf_tc_skip("rename not supported by file system"); 98*11be35a1SLionel Sambuc 99*11be35a1SLionel Sambuc if (FSTYPE_UDF(tc)) 100*11be35a1SLionel Sambuc atf_tc_expect_fail("Test expected to fail"); 101*11be35a1SLionel Sambuc 102*11be35a1SLionel Sambuc RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 103*11be35a1SLionel Sambuc RL(wrkpid = rump_sys_getpid()); 104*11be35a1SLionel Sambuc 105*11be35a1SLionel Sambuc RL(rump_sys_chdir(mp)); 106*11be35a1SLionel Sambuc for (i = 0; i < NWRK; i++) 107*11be35a1SLionel Sambuc pthread_create(&pt1[i], NULL, w1, NULL); 108*11be35a1SLionel Sambuc 109*11be35a1SLionel Sambuc for (i = 0; i < NWRK; i++) 110*11be35a1SLionel Sambuc pthread_create(&pt2[i], NULL, w2, NULL); 111*11be35a1SLionel Sambuc 112*11be35a1SLionel Sambuc sleep(5); 113*11be35a1SLionel Sambuc quittingtime = 1; 114*11be35a1SLionel Sambuc 115*11be35a1SLionel Sambuc for (i = 0; i < NWRK; i++) 116*11be35a1SLionel Sambuc pthread_join(pt1[i], NULL); 117*11be35a1SLionel Sambuc for (i = 0; i < NWRK; i++) 118*11be35a1SLionel Sambuc pthread_join(pt2[i], NULL); 119*11be35a1SLionel Sambuc RL(rump_sys_chdir("/")); 120*11be35a1SLionel Sambuc 121*11be35a1SLionel Sambuc if (FSTYPE_MSDOS(tc)) { 122*11be35a1SLionel Sambuc atf_tc_expect_fail("PR kern/44661"); 123*11be35a1SLionel Sambuc /* 124*11be35a1SLionel Sambuc * XXX: race does not trigger every time at least 125*11be35a1SLionel Sambuc * on amd64/qemu. 126*11be35a1SLionel Sambuc */ 127*11be35a1SLionel Sambuc if (msdosfs_fstest_unmount(tc, mp, 0) != 0) { 128*11be35a1SLionel Sambuc rump_pub_vfs_mount_print(mp, 1); 129*11be35a1SLionel Sambuc atf_tc_fail_errno("unmount failed"); 130*11be35a1SLionel Sambuc } 131*11be35a1SLionel Sambuc atf_tc_fail("race did not trigger this time"); 132*11be35a1SLionel Sambuc } 133*11be35a1SLionel Sambuc } 134*11be35a1SLionel Sambuc 135*11be35a1SLionel Sambuc static void 136*11be35a1SLionel Sambuc renamerace_dirs(const atf_tc_t *tc, const char *mp) 137*11be35a1SLionel Sambuc { 138*11be35a1SLionel Sambuc pthread_t pt1, pt2; 139*11be35a1SLionel Sambuc 140*11be35a1SLionel Sambuc if (FSTYPE_SYSVBFS(tc)) 141*11be35a1SLionel Sambuc atf_tc_skip("directories not supported by file system"); 142*11be35a1SLionel Sambuc 143*11be35a1SLionel Sambuc if (FSTYPE_RUMPFS(tc)) 144*11be35a1SLionel Sambuc atf_tc_skip("rename not supported by file system"); 145*11be35a1SLionel Sambuc 146*11be35a1SLionel Sambuc if (FSTYPE_UDF(tc)) 147*11be35a1SLionel Sambuc atf_tc_expect_fail("Test expected to fail"); 148*11be35a1SLionel Sambuc 149*11be35a1SLionel Sambuc /* XXX: msdosfs also sometimes hangs */ 150*11be35a1SLionel Sambuc if (FSTYPE_MSDOS(tc)) 151*11be35a1SLionel Sambuc atf_tc_expect_signal(-1, "PR kern/43626"); 152*11be35a1SLionel Sambuc 153*11be35a1SLionel Sambuc RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG)); 154*11be35a1SLionel Sambuc RL(wrkpid = rump_sys_getpid()); 155*11be35a1SLionel Sambuc 156*11be35a1SLionel Sambuc RL(rump_sys_chdir(mp)); 157*11be35a1SLionel Sambuc pthread_create(&pt1, NULL, w1_dirs, NULL); 158*11be35a1SLionel Sambuc pthread_create(&pt2, NULL, w2, NULL); 159*11be35a1SLionel Sambuc 160*11be35a1SLionel Sambuc sleep(5); 161*11be35a1SLionel Sambuc quittingtime = 1; 162*11be35a1SLionel Sambuc 163*11be35a1SLionel Sambuc pthread_join(pt1, NULL); 164*11be35a1SLionel Sambuc pthread_join(pt2, NULL); 165*11be35a1SLionel Sambuc RL(rump_sys_chdir("/")); 166*11be35a1SLionel Sambuc 167*11be35a1SLionel Sambuc /* 168*11be35a1SLionel Sambuc * Doesn't always trigger when run on a slow backend 169*11be35a1SLionel Sambuc * (i.e. not on tmpfs/mfs). So do the usual kludge. 170*11be35a1SLionel Sambuc */ 171*11be35a1SLionel Sambuc if (FSTYPE_MSDOS(tc)) 172*11be35a1SLionel Sambuc abort(); 173*11be35a1SLionel Sambuc } 174*11be35a1SLionel Sambuc 175*11be35a1SLionel Sambuc ATF_TC_FSAPPLY(renamerace, "rename(2) race with file unlinked mid-operation"); 176*11be35a1SLionel Sambuc ATF_TC_FSAPPLY(renamerace_dirs, "rename(2) race with directories"); 177*11be35a1SLionel Sambuc 178*11be35a1SLionel Sambuc ATF_TP_ADD_TCS(tp) 179*11be35a1SLionel Sambuc { 180*11be35a1SLionel Sambuc 181*11be35a1SLionel Sambuc ATF_TP_FSAPPLY(renamerace); /* PR kern/41128 */ 182*11be35a1SLionel Sambuc ATF_TP_FSAPPLY(renamerace_dirs); 183*11be35a1SLionel Sambuc 184*11be35a1SLionel Sambuc return atf_no_error(); 185*11be35a1SLionel Sambuc } 186