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();
}