Module Name:    src
Committed By:   riastradh
Date:           Sat Sep  5 02:45:23 UTC 2020

Modified Files:
        src/tests/fs/vfs: t_renamerace.c

Log Message:
tests/fs/vfs/t_renamerace: Test a screw case hannken@ found.


To generate a diff of this commit:
cvs rdiff -u -r1.36 -r1.37 src/tests/fs/vfs/t_renamerace.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/tests/fs/vfs/t_renamerace.c
diff -u src/tests/fs/vfs/t_renamerace.c:1.36 src/tests/fs/vfs/t_renamerace.c:1.37
--- src/tests/fs/vfs/t_renamerace.c:1.36	Sat Aug 17 09:44:01 2019
+++ src/tests/fs/vfs/t_renamerace.c	Sat Sep  5 02:45:22 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: t_renamerace.c,v 1.36 2019/08/17 09:44:01 gson Exp $	*/
+/*	$NetBSD: t_renamerace.c,v 1.37 2020/09/05 02:45:22 riastradh Exp $	*/
 
 /*
  * Modified for rump and atf from a program supplied
@@ -86,6 +86,64 @@ w2(void *arg)
 	return NULL;
 }
 
+static void
+w3_mkdir(void)
+{
+
+	if (rump_sys_mkdir("c", 0777) == -1)
+		ATF_CHECK_MSG(errno == ENOENT || errno == EEXIST,
+		    "mkdir: %s (errno=%d)\n", strerror(errno), errno);
+	if (rump_sys_mkdir("c/d", 0777) == -1)
+		ATF_CHECK_MSG(errno == ENOENT || errno == EEXIST,
+		    "mkdir: %s (errno=%d)\n", strerror(errno), errno);
+	if (rump_sys_mkdir("c/d/e", 0777) == -1)
+		ATF_CHECK_MSG(errno == ENOENT || errno == EEXIST,
+		    "mkdir: %s (errno=%d)\n", strerror(errno), errno);
+}
+
+static void *
+w3_rmdir(void *arg)
+{
+
+	rump_pub_lwproc_newlwp(wrkpid);
+
+	while (!quittingtime) {
+		w3_mkdir();
+		rump_sys_rmdir("c/d/e");
+		rump_sys_rmdir("c/d");
+	}
+
+	return NULL;
+}
+
+static void *
+w3_rename1(void *arg)
+{
+
+	rump_pub_lwproc_newlwp(wrkpid);
+
+	while (!quittingtime) {
+		w3_mkdir();
+		rump_sys_rename("c", "c/d/e");
+	}
+
+	return NULL;
+}
+
+static void *
+w3_rename2(void *arg)
+{
+
+	rump_pub_lwproc_newlwp(wrkpid);
+
+	while (!quittingtime) {
+		w3_mkdir();
+		rump_sys_rename("c/d/e", "c");
+	}
+
+	return NULL;
+}
+
 #define NWRK 8
 static void
 renamerace(const atf_tc_t *tc, const char *mp)
@@ -181,14 +239,70 @@ renamerace_dirs(const atf_tc_t *tc, cons
 		abort();
 }
 
+static void
+renamerace_cycle(const atf_tc_t *tc, const char *mp)
+{
+	pthread_t pt_rmdir, pt_rename1, pt_rename2;
+
+	if (FSTYPE_SYSVBFS(tc))
+		atf_tc_skip("directories not supported by file system");
+	if (FSTYPE_RUMPFS(tc))
+		atf_tc_skip("rename not supported by file system");
+	if (FSTYPE_P2K_FFS(tc))
+		atf_tc_expect_fail("assertion \"vp->v_size == ip->i_size\" failed");
+	if (FSTYPE_PUFFS(tc))
+		atf_tc_expect_fail("assertion \"dfd\" failed");
+	if (FSTYPE_NFS(tc))
+		atf_tc_expect_fail("mkdir fails with ESTALE");
+
+	/* XXX: msdosfs also sometimes hangs */
+	if (FSTYPE_MSDOS(tc))
+		atf_tc_expect_signal(-1, "PR kern/43626");
+
+	RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
+	RL(wrkpid = rump_sys_getpid());
+
+	RL(rump_sys_chdir(mp));
+	pthread_create(&pt_rmdir, NULL, w3_rmdir, NULL);
+	pthread_create(&pt_rename1, NULL, w3_rename1, NULL);
+	pthread_create(&pt_rename2, NULL, w3_rename2, NULL);
+
+	sleep(10);
+	quittingtime = 1;
+
+	if (FSTYPE_EXT2FS(tc) ||
+	    FSTYPE_FFS(tc) ||
+	    FSTYPE_FFSLOG(tc) ||
+	    FSTYPE_LFS(tc) ||
+	    FSTYPE_TMPFS(tc) ||
+	    FSTYPE_UDF(tc))
+		atf_tc_expect_signal(SIGALRM, "genfs_rename is busted");
+
+	alarm(1);
+	pthread_join(pt_rmdir, NULL);
+	pthread_join(pt_rename1, NULL);
+	pthread_join(pt_rename2, NULL);
+	alarm(0);
+	RL(rump_sys_chdir("/"));
+
+	/*
+	 * Doesn't always trigger when run on a slow backend
+	 * (i.e. not on tmpfs/mfs).  So do the usual kludge.
+	 */
+	if (FSTYPE_MSDOS(tc))
+		abort();
+}
+
 ATF_TC_FSAPPLY(renamerace, "rename(2) race with file unlinked mid-operation");
 ATF_TC_FSAPPLY(renamerace_dirs, "rename(2) race with directories");
+ATF_TC_FSAPPLY(renamerace_cycle, "rename(2) race making directory cycles");
 
 ATF_TP_ADD_TCS(tp)
 {
 
 	ATF_TP_FSAPPLY(renamerace); /* PR kern/41128 */
 	ATF_TP_FSAPPLY(renamerace_dirs);
+	ATF_TP_FSAPPLY(renamerace_cycle);
 
 	return atf_no_error();
 }

Reply via email to