Add a test case for PR kern/36681 demonstrating how easy it is to
get tmpfs rename to "tstile". Note1: triggering this on any non-SMP system is not as easy (because one system call tends to run from start to finish in one go) and therefore I've limited it to i386 and amd64. Incidentally, I'm still waiting for the eternally elusive MI CPU_INFO_FOREACH (or at least something else than a stupid macro) ... Note2: this is a "race condition" test. I tested it on my development host and in qemu and it triggers pretty instantly. But YMMV.
This commit is contained in:
parent
76cbf63f87
commit
d2c2528c3b
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: t_renamerace.c,v 1.6 2009/04/26 15:15:38 pooka Exp $ */
|
||||
/* $NetBSD: t_renamerace.c,v 1.7 2010/07/04 12:43:23 pooka Exp $ */
|
||||
|
||||
/*
|
||||
* Modified for rump and atf from a program supplied
|
||||
|
@ -7,14 +7,16 @@
|
|||
|
||||
#include <sys/types.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <rump/rump.h>
|
||||
#include <rump/rump_syscalls.h>
|
||||
|
@ -73,8 +75,102 @@ ATF_TC_BODY(renamerace, tc)
|
|||
sleep(10);
|
||||
}
|
||||
|
||||
ATF_TC(renamerace2);
|
||||
ATF_TC_HEAD(renamerace2, tc)
|
||||
{
|
||||
atf_tc_set_md_var(tc, "descr", "rename(2) lock order inversion");
|
||||
atf_tc_set_md_var(tc, "timeout", "6");
|
||||
}
|
||||
|
||||
static volatile int quittingtime = 0;
|
||||
|
||||
static void *
|
||||
r2w1(void *arg)
|
||||
{
|
||||
int fd;
|
||||
|
||||
rump_pub_lwp_alloc_and_switch(0, 0);
|
||||
|
||||
fd = rump_sys_open("/file", O_CREAT | O_RDWR, 0777);
|
||||
if (fd == -1)
|
||||
atf_tc_fail_errno("creat");
|
||||
rump_sys_close(fd);
|
||||
|
||||
while (!quittingtime) {
|
||||
if (rump_sys_rename("/file", "/dir/file") == -1)
|
||||
atf_tc_fail_errno("rename 1");
|
||||
if (rump_sys_rename("/dir/file", "/file") == -1)
|
||||
atf_tc_fail_errno("rename 2");
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *
|
||||
r2w2(void *arg)
|
||||
{
|
||||
int fd;
|
||||
|
||||
rump_pub_lwp_alloc_and_switch(0, 0);
|
||||
|
||||
while (!quittingtime) {
|
||||
fd = rump_sys_open("/dir/file1", O_RDWR);
|
||||
if (fd != -1)
|
||||
rump_sys_close(fd);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ATF_TC_BODY(renamerace2, tc)
|
||||
{
|
||||
struct tmpfs_args args;
|
||||
struct utsname un;
|
||||
pthread_t pt[2];
|
||||
|
||||
/*
|
||||
* Check that we are running on an SMP-capable arch. It should
|
||||
* be a rump capability, but after the CPU_INFO_FOREACH is
|
||||
* fixed, it will be every arch (for rump), so don't bother.
|
||||
*/
|
||||
if (uname(&un) == -1)
|
||||
atf_tc_fail_errno("uname");
|
||||
if (strcmp(un.machine, "i386") != 0 && strcmp(un.machine, "amd64") != 0)
|
||||
atf_tc_skip("i386 or amd64 required (have %s)", un.machine);
|
||||
|
||||
/*
|
||||
* Force SMP regardless of how many host CPUs there are.
|
||||
* Deadlock is highly unlikely to trigger otherwise.
|
||||
*/
|
||||
setenv("RUMP_NCPU", "2", 1);
|
||||
|
||||
rump_init();
|
||||
memset(&args, 0, sizeof(args));
|
||||
args.ta_version = TMPFS_ARGS_VERSION;
|
||||
args.ta_root_mode = 0777;
|
||||
if (rump_sys_mount(MOUNT_TMPFS, "/", 0, &args, sizeof(args)) == -1)
|
||||
atf_tc_fail_errno("could not mount tmpfs");
|
||||
|
||||
if (rump_sys_mkdir("/dir", 0777) == -1)
|
||||
atf_tc_fail_errno("cannot create directory");
|
||||
|
||||
pthread_create(&pt[0], NULL, r2w1, NULL);
|
||||
pthread_create(&pt[1], NULL, r2w2, NULL);
|
||||
|
||||
/* usually triggers in <<1s for me */
|
||||
sleep(4);
|
||||
quittingtime = 1;
|
||||
|
||||
atf_tc_expect_timeout("PR kern/36681");
|
||||
|
||||
pthread_join(pt[0], NULL);
|
||||
pthread_join(pt[1], NULL);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, renamerace);
|
||||
return 0; /*XXX?*/
|
||||
ATF_TP_ADD_TC(tp, renamerace2);
|
||||
|
||||
return atf_no_error();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue