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