1*63d1fd59SEnji Cooper /* $NetBSD: t_renamerace.c,v 1.14 2017/01/13 21:30:40 christos Exp $ */
257718be8SEnji Cooper
357718be8SEnji Cooper /*
457718be8SEnji Cooper * Modified for rump and atf from a program supplied
557718be8SEnji Cooper * by Nicolas Joly in kern/40948
657718be8SEnji Cooper */
757718be8SEnji Cooper
857718be8SEnji Cooper #include <sys/types.h>
957718be8SEnji Cooper #include <sys/mount.h>
1057718be8SEnji Cooper #include <sys/utsname.h>
1157718be8SEnji Cooper
1257718be8SEnji Cooper #include <atf-c.h>
1357718be8SEnji Cooper #include <errno.h>
1457718be8SEnji Cooper #include <fcntl.h>
1557718be8SEnji Cooper #include <pthread.h>
1657718be8SEnji Cooper #include <stdio.h>
1757718be8SEnji Cooper #include <stdlib.h>
1857718be8SEnji Cooper #include <string.h>
1957718be8SEnji Cooper #include <unistd.h>
2057718be8SEnji Cooper
2157718be8SEnji Cooper #include <rump/rump.h>
2257718be8SEnji Cooper #include <rump/rump_syscalls.h>
2357718be8SEnji Cooper
2457718be8SEnji Cooper #include <fs/tmpfs/tmpfs_args.h>
2557718be8SEnji Cooper
26*63d1fd59SEnji Cooper #include "h_macros.h"
2757718be8SEnji Cooper
2857718be8SEnji Cooper ATF_TC(renamerace2);
ATF_TC_HEAD(renamerace2,tc)2957718be8SEnji Cooper ATF_TC_HEAD(renamerace2, tc)
3057718be8SEnji Cooper {
3157718be8SEnji Cooper atf_tc_set_md_var(tc, "descr", "rename(2) lock order inversion");
3257718be8SEnji Cooper atf_tc_set_md_var(tc, "timeout", "6");
3357718be8SEnji Cooper }
3457718be8SEnji Cooper
3557718be8SEnji Cooper static volatile int quittingtime = 0;
3657718be8SEnji Cooper static pid_t wrkpid;
3757718be8SEnji Cooper
3857718be8SEnji Cooper static void *
r2w1(void * arg)3957718be8SEnji Cooper r2w1(void *arg)
4057718be8SEnji Cooper {
4157718be8SEnji Cooper int fd;
4257718be8SEnji Cooper
4357718be8SEnji Cooper rump_pub_lwproc_newlwp(wrkpid);
4457718be8SEnji Cooper
4557718be8SEnji Cooper fd = rump_sys_open("/file", O_CREAT | O_RDWR, 0777);
4657718be8SEnji Cooper if (fd == -1)
4757718be8SEnji Cooper atf_tc_fail_errno("creat");
4857718be8SEnji Cooper rump_sys_close(fd);
4957718be8SEnji Cooper
5057718be8SEnji Cooper while (!quittingtime) {
5157718be8SEnji Cooper if (rump_sys_rename("/file", "/dir/file") == -1)
5257718be8SEnji Cooper atf_tc_fail_errno("rename 1");
5357718be8SEnji Cooper if (rump_sys_rename("/dir/file", "/file") == -1)
5457718be8SEnji Cooper atf_tc_fail_errno("rename 2");
5557718be8SEnji Cooper }
5657718be8SEnji Cooper
5757718be8SEnji Cooper return NULL;
5857718be8SEnji Cooper }
5957718be8SEnji Cooper
6057718be8SEnji Cooper static void *
r2w2(void * arg)6157718be8SEnji Cooper r2w2(void *arg)
6257718be8SEnji Cooper {
6357718be8SEnji Cooper int fd;
6457718be8SEnji Cooper
6557718be8SEnji Cooper rump_pub_lwproc_newlwp(wrkpid);
6657718be8SEnji Cooper
6757718be8SEnji Cooper while (!quittingtime) {
6857718be8SEnji Cooper fd = rump_sys_open("/dir/file1", O_RDWR);
6957718be8SEnji Cooper if (fd != -1)
7057718be8SEnji Cooper rump_sys_close(fd);
7157718be8SEnji Cooper }
7257718be8SEnji Cooper
7357718be8SEnji Cooper return NULL;
7457718be8SEnji Cooper }
7557718be8SEnji Cooper
ATF_TC_BODY(renamerace2,tc)7657718be8SEnji Cooper ATF_TC_BODY(renamerace2, tc)
7757718be8SEnji Cooper {
7857718be8SEnji Cooper struct tmpfs_args args;
7957718be8SEnji Cooper pthread_t pt[2];
8057718be8SEnji Cooper
8157718be8SEnji Cooper /*
8257718be8SEnji Cooper * Force SMP regardless of how many host CPUs there are.
8357718be8SEnji Cooper * Deadlock is highly unlikely to trigger otherwise.
8457718be8SEnji Cooper */
8557718be8SEnji Cooper setenv("RUMP_NCPU", "2", 1);
8657718be8SEnji Cooper
8757718be8SEnji Cooper rump_init();
8857718be8SEnji Cooper memset(&args, 0, sizeof(args));
8957718be8SEnji Cooper args.ta_version = TMPFS_ARGS_VERSION;
9057718be8SEnji Cooper args.ta_root_mode = 0777;
9157718be8SEnji Cooper if (rump_sys_mount(MOUNT_TMPFS, "/", 0, &args, sizeof(args)) == -1)
9257718be8SEnji Cooper atf_tc_fail_errno("could not mount tmpfs");
9357718be8SEnji Cooper
9457718be8SEnji Cooper if (rump_sys_mkdir("/dir", 0777) == -1)
9557718be8SEnji Cooper atf_tc_fail_errno("cannot create directory");
9657718be8SEnji Cooper
9757718be8SEnji Cooper RZ(rump_pub_lwproc_rfork(RUMP_RFCFDG));
9857718be8SEnji Cooper RL(wrkpid = rump_sys_getpid());
9957718be8SEnji Cooper pthread_create(&pt[0], NULL, r2w1, NULL);
10057718be8SEnji Cooper pthread_create(&pt[1], NULL, r2w2, NULL);
10157718be8SEnji Cooper
10257718be8SEnji Cooper /* usually triggers in <<1s for me */
10357718be8SEnji Cooper sleep(4);
10457718be8SEnji Cooper quittingtime = 1;
10557718be8SEnji Cooper
10657718be8SEnji Cooper pthread_join(pt[0], NULL);
10757718be8SEnji Cooper pthread_join(pt[1], NULL);
10857718be8SEnji Cooper }
10957718be8SEnji Cooper
ATF_TP_ADD_TCS(tp)11057718be8SEnji Cooper ATF_TP_ADD_TCS(tp)
11157718be8SEnji Cooper {
11257718be8SEnji Cooper ATF_TP_ADD_TC(tp, renamerace2);
11357718be8SEnji Cooper
11457718be8SEnji Cooper return atf_no_error();
11557718be8SEnji Cooper }
116