xref: /freebsd/tools/test/stress2/misc/fsync2.sh (revision e0c4386e)
1#!/bin/sh
2
3#
4# SPDX-License-Identifier: BSD-2-Clause
5#
6# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions
10# are met:
11# 1. Redistributions of source code must retain the above copyright
12#    notice, this list of conditions and the following disclaimer.
13# 2. Redistributions in binary form must reproduce the above copyright
14#    notice, this list of conditions and the following disclaimer in the
15#    documentation and/or other materials provided with the distribution.
16#
17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27# SUCH DAMAGE.
28#
29
30# Deadlock seen: https://people.freebsd.org/~pho/stress/log/mark169.txt
31# Test scenario based on the syzkaller reproducer syzkaller21.sh and comments
32# by markj@.
33
34. ../default.cfg
35[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
36
37dir=/tmp
38odir=`pwd`
39cd $dir
40sed '1,/^EOF/d' < $odir/$0 > $dir/fsync2.c
41mycc -o fsync2 -Wall -Wextra -O0 -g fsync2.c -lpthread || exit 1
42rm -f fsync2.c
43cd $odir
44
45set -e
46mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
47[ -c /dev/md$mdstart ] &&  mdconfig -d -u $mdstart
48mdconfig -a -t swap -s 2g -u $mdstart
49newfs $newfs_flags md$mdstart > /dev/null
50mount /dev/md$mdstart $mntpoint
51set +e
52
53(cd $mntpoint; $dir/fsync2)
54
55for i in `jot 6`; do
56	mount | grep -q "on $mntpoint " || break
57	umount $mntpoint && break || sleep 10
58	[ $i -eq 6 ] &&
59	    { echo FATAL; fstat -mf $mntpoint; exit 1; }
60done
61mdconfig -d -u $mdstart
62rm -rf $dir/fsync2
63exit 0
64EOF
65#include <sys/types.h>
66#include <sys/stat.h>
67
68#include <err.h>
69#include <fcntl.h>
70#include <pthread.h>
71#include <signal.h>
72#include <stdio.h>
73#include <stdlib.h>
74#include <string.h>
75#include <unistd.h>
76
77#define RUNTIME 60
78
79static time_t start;
80static volatile int fd;
81
82static void *
83t1(void *data __unused)
84{
85	char cwd[1024];
86
87	if (getcwd(cwd, sizeof(cwd)) == NULL)
88		err(1, "getcwd()");
89	while (time(NULL) - start < RUNTIME) {
90		if (mkdir("./file0", 0740) == -1)
91			err(1, "mkdir(file0)");
92		if (mkdir("./file1", 0740) == -1)
93			err(1, "mkdir(file2)");
94		if (rename("./file1", "./file0/file0") == -1)
95			err(1, "rename()");
96		if ((fd = open("./file0/file0", O_RDONLY)) == -1)
97			err(1, "open()");
98		if (chdir("./file0/file0") == -1)
99			err(1, "chdir()");
100		if (chdir(cwd) == -1)
101			err(1, "chdir(HOME)");
102		close(fd);
103		rmdir("./file0/file0");
104		rmdir("./file0");
105	}
106
107	return (NULL);
108}
109
110static void *
111t2(void *data __unused)
112{
113	while (time(NULL) - start < RUNTIME) {
114		fsync(fd);
115	}
116
117	return (NULL);
118}
119
120int
121main(void)
122{
123	pthread_t tid[2];
124	int r;
125
126	start = time(NULL);
127	if ((r = pthread_create(&tid[0], NULL, t1, NULL)) != 0)
128		errc(1, r, "pthread_create");
129	if ((r = pthread_create(&tid[1], NULL, t2, NULL)) != 0)
130		errc(1, r, "pthread_create");
131
132	if ((r = pthread_join(tid[0], NULL)) != 0)
133		errc(1, r, "pthread_join");
134	if ((r = pthread_join(tid[1], NULL)) != 0)
135		errc(1, r, "pthread_join");
136
137	return (0);
138}
139