xref: /freebsd/tools/test/stress2/misc/suj23.sh (revision 2008043f386721d58158e37e0d7e50df8095942d)
1#!/bin/sh
2
3#
4# Copyright (c) 2011 Peter Holm <pho@FreeBSD.org>
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
10# 1. Redistributions of source code must retain the above copyright
11#    notice, this list of conditions and the following disclaimer.
12# 2. Redistributions in binary form must reproduce the above copyright
13#    notice, this list of conditions and the following disclaimer in the
14#    documentation and/or other materials provided with the distribution.
15#
16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26# SUCH DAMAGE.
27#
28
29# Scenario from kern/159971
30# bstg0003.c by Kirk Russell <kirk ba23 org>
31
32# panic: ino 0xc84c9b00(0x3C8209) 65554, 32780 != 65570
33# https://people.freebsd.org/~pho/stress/log/suj23.txt
34
35# panic: first_unlinked_inodedep: prev != next. inodedep = 0xcadf9e00
36# https://people.freebsd.org/~pho/stress/log/jeff091.txt
37
38[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
39
40. ../default.cfg
41
42here=`pwd`
43cd /tmp
44sed '1,/^EOF/d' < $here/$0 > suj23.c
45mycc -o suj23 -Wall -Wextra -O2 suj23.c
46rm -f suj23.c
47
48mount | grep "on $mntpoint " | grep -q md$mdstart && umount $mntpoint
49[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
50
51mdconfig -a -t swap -s 1g -u $mdstart
52newfs -j md$mdstart > /dev/null
53mount /dev/md$mdstart $mntpoint
54chmod 777 $mntpoint
55
56su $testuser -c '/tmp/suj23'
57
58while mount | grep -q "on $mntpoint "; do
59	umount $mntpoint || sleep 1
60done
61mdconfig -d -u $mdstart
62rm -f /tmp/suj23
63exit 0
64EOF
65/*
66 * Copyright 2011 Kirk J. Russell
67 *
68 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
69 * use this file except in compliance with the License. You may obtain a copy
70 * of the License at http://www.apache.org/licenses/LICENSE-2.0
71 *
72 * Unless required by applicable law or agreed to in writing, software
73 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
74 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
75 * License for the specific language governing permissions and limitations
76 * under the License.
77 */
78
79#include <unistd.h>
80#include <assert.h>
81#include <err.h>
82#include <fcntl.h>
83#include <signal.h>
84#include <stdio.h>
85#include <stdlib.h>
86#include <string.h>
87#include <time.h>
88#include <sys/stat.h>
89#include <sys/uio.h>
90#include <sys/wait.h>
91
92#define RUNTIME 600
93
94static char *bstg_pathstore[] = {
95	"/mnt/111/z",
96	"/mnt/111/aaaa",
97	"/mnt/111/bbbbb",
98	"/mnt/111/ccccc",
99	"/mnt/111/d",
100	"/mnt/111/e",
101	"/mnt/111/ffffff.fff.f",
102	"/mnt/111/gggggggggggg",
103	"/mnt/111/hhhh",
104	"/mnt/111/iiiii.ii",
105	"/mnt/111/jjjj.jj.jjjjjjjj",
106	"/mnt/111/kkkk.kkkkkkkk",
107	"/mnt/111/lllll",
108	"/mnt/222/z",
109	"/mnt/222/aaaa",
110	"/mnt/222/bbbbb",
111	"/mnt/222/ccccc",
112	"/mnt/222/d",
113	"/mnt/222/e",
114	"/mnt/222/ffffff.fff.f",
115	"/mnt/222/gggggggggggg",
116	"/mnt/222/hhhh",
117	"/mnt/222/iiiii.ii",
118	"/mnt/222/jjjj.jj.jjjjjjjj",
119	"/mnt/222/kkkk.kkkkkkkk",
120	"/mnt/222/lllll",
121	"/mnt/333/z",
122	"/mnt/333/aaaa",
123	"/mnt/333/bbbbb",
124	"/mnt/333/ccccc",
125	"/mnt/333/d",
126	"/mnt/333/e",
127	"/mnt/333/ffffff.fff.f",
128	"/mnt/333/gggggggggggg",
129	"/mnt/333/hhhh",
130	"/mnt/333/iiiii.ii",
131	"/mnt/333/jjjj.jj.jjjjjjjj",
132	"/mnt/333/kkkk.kkkkkkkk",
133	"/mnt/333/lllll",
134	"/mnt/444/z",
135	"/mnt/444/aaaa",
136	"/mnt/444/bbbbb",
137	"/mnt/444/ccccc",
138	"/mnt/444/d",
139	"/mnt/444/e",
140	"/mnt/444/ffffff.fff.f",
141	"/mnt/444/gggggggggggg",
142	"/mnt/444/hhhh",
143	"/mnt/444/iiiii.ii",
144	"/mnt/444/jjjj.jj.jjjjjjjj",
145	"/mnt/444/kkkk.kkkkkkkk",
146	"/mnt/444/lllll",
147	"/mnt/555/z",
148	"/mnt/555/aaaa",
149	"/mnt/555/bbbbb",
150	"/mnt/555/ccccc",
151	"/mnt/555/d",
152	"/mnt/555/e",
153	"/mnt/555/ffffff.fff.f",
154	"/mnt/555/gggggggggggg",
155	"/mnt/555/hhhh",
156	"/mnt/555/iiiii.ii",
157	"/mnt/555/jjjj.jj.jjjjjjjj",
158	"/mnt/555/kkkk.kkkkkkkk",
159	"/mnt/555/lllll",
160	"/mnt/666/z",
161	"/mnt/666/aaaa",
162	"/mnt/666/bbbbb",
163	"/mnt/666/ccccc",
164	"/mnt/666/d",
165	"/mnt/666/e",
166	"/mnt/666/ffffff.fff.f",
167	"/mnt/666/gggggggggggg",
168	"/mnt/666/hhhh",
169	"/mnt/666/iiiii.ii",
170	"/mnt/666/jjjj.jj.jjjjjjjj",
171	"/mnt/666/kkkk.kkkkkkkk",
172	"/mnt/666/lllll",
173	"/mnt/777/z",
174	"/mnt/777/aaaa",
175	"/mnt/777/bbbbb",
176	"/mnt/777/ccccc",
177	"/mnt/777/d",
178	"/mnt/777/e",
179	"/mnt/777/ffffff.fff.f",
180	"/mnt/777/gggggggggggg",
181	"/mnt/777/hhhh",
182	"/mnt/777/iiiii.ii",
183	"/mnt/777/jjjj.jj.jjjjjjjj",
184	"/mnt/777/kkkk.kkkkkkkk",
185	"/mnt/777/lllll",
186	"/mnt/888/z",
187	"/mnt/888/aaaa",
188	"/mnt/888/bbbbb",
189	"/mnt/888/ccccc",
190	"/mnt/888/d",
191	"/mnt/888/e",
192	"/mnt/888/ffffff.fff.f",
193	"/mnt/888/gggggggggggg",
194	"/mnt/888/hhhh",
195	"/mnt/888/iiiii.ii",
196	"/mnt/888/jjjj.jj.jjjjjjjj",
197	"/mnt/888/kkkk.kkkkkkkk",
198	"/mnt/888/lllll",
199	"/mnt/999/z",
200	"/mnt/999/aaaa",
201	"/mnt/999/bbbbb",
202	"/mnt/999/ccccc",
203	"/mnt/999/d",
204	"/mnt/999/e",
205	"/mnt/999/ffffff.fff.f",
206	"/mnt/999/gggggggggggg",
207	"/mnt/999/hhhh",
208	"/mnt/999/iiiii.ii",
209	"/mnt/999/jjjj.jj.jjjjjjjj",
210	"/mnt/999/kkkk.kkkkkkkk",
211	"/mnt/999/lllll",
212	"/mnt/aaa/z",
213	"/mnt/aaa/aaaa",
214	"/mnt/aaa/bbbbb",
215	"/mnt/aaa/ccccc",
216	"/mnt/aaa/d",
217	"/mnt/aaa/e",
218	"/mnt/aaa/ffffff.fff.f",
219	"/mnt/aaa/gggggggggggg",
220	"/mnt/aaa/hhhh",
221	"/mnt/aaa/iiiii.ii",
222	"/mnt/aaa/jjjj.jj.jjjjjjjj",
223	"/mnt/aaa/kkkk.kkkkkkkk",
224	"/mnt/aaa/lllll",
225	"/mnt/bbb/z",
226	"/mnt/bbb/aaaa",
227	"/mnt/bbb/bbbbb",
228	"/mnt/bbb/ccccc",
229	"/mnt/bbb/d",
230	"/mnt/bbb/e",
231	"/mnt/bbb/ffffff.fff.f",
232	"/mnt/bbb/gggggggggggg",
233	"/mnt/bbb/hhhh",
234	"/mnt/bbb/iiiii.ii",
235	"/mnt/bbb/jjjj.jj.jjjjjjjj",
236	"/mnt/bbb/kkkk.kkkkkkkk",
237	"/mnt/bbb/lllll",
238	"/mnt/ccc/z",
239	"/mnt/ccc/aaaa",
240	"/mnt/ccc/bbbbb",
241	"/mnt/ccc/ccccc",
242	"/mnt/ccc/d",
243	"/mnt/ccc/e",
244	"/mnt/ccc/ffffff.fff.f",
245	"/mnt/ccc/gggggggggggg",
246	"/mnt/ccc/hhhh",
247	"/mnt/ccc/iiiii.ii",
248	"/mnt/ccc/jjjj.jj.jjjjjjjj",
249	"/mnt/ccc/kkkk.kkkkkkkk",
250	"/mnt/ccc/lllll",
251	"/mnt/ddd/z",
252	"/mnt/ddd/aaaa",
253	"/mnt/ddd/bbbbb",
254	"/mnt/ddd/ccccc",
255	"/mnt/ddd/d",
256	"/mnt/ddd/e",
257	"/mnt/ddd/ffffff.fff.f",
258	"/mnt/ddd/gggggggggggg",
259	"/mnt/ddd/hhhh",
260	"/mnt/ddd/iiiii.ii",
261	"/mnt/ddd/jjjj.jj.jjjjjjjj",
262	"/mnt/ddd/kkkk.kkkkkkkk",
263	"/mnt/ddd/lllll",
264	"/mnt/eee/z",
265	"/mnt/eee/aaaa",
266	"/mnt/eee/bbbbb",
267	"/mnt/eee/ccccc",
268	"/mnt/eee/d",
269	"/mnt/eee/e",
270	"/mnt/eee/ffffff.fff.f",
271	"/mnt/eee/gggggggggggg",
272	"/mnt/eee/hhhh",
273	"/mnt/eee/iiiii.ii",
274	"/mnt/eee/jjjj.jj.jjjjjjjj",
275	"/mnt/eee/kkkk.kkkkkkkk",
276	"/mnt/eee/lllll",
277	"/mnt/fff/z",
278	"/mnt/fff/aaaa",
279	"/mnt/fff/bbbbb",
280	"/mnt/fff/ccccc",
281	"/mnt/fff/d",
282	"/mnt/fff/e",
283	"/mnt/fff/ffffff.fff.f",
284	"/mnt/fff/gggggggggggg",
285	"/mnt/fff/hhhh",
286	"/mnt/fff/iiiii.ii",
287	"/mnt/fff/jjjj.jj.jjjjjjjj",
288	"/mnt/fff/kkkk.kkkkkkkk",
289	"/mnt/fff/lllll"
290};
291
292char *
293bstg_pathstore_get()
294{
295	return bstg_pathstore[rand() %
296		     ((sizeof(bstg_pathstore) / sizeof(bstg_pathstore[0])))];
297}
298
299void
300dogcore()
301{
302	pid_t sleepchild, gcorechild;
303	extern char **environ;
304
305	/* create a child for the gcore target */
306	if ((sleepchild = fork()) == 0) {
307		sleep(30);
308		_exit(1);
309	} else if (sleepchild > 0) {
310		char *token[] = {NULL, NULL, NULL, NULL, NULL};
311		char buf[64];
312		int status;
313
314		/* use the first process as the target */
315		snprintf(buf, sizeof(buf), "%d", sleepchild);
316		token[0] = "gcore";
317		token[1] = "-c";
318		token[2] = bstg_pathstore_get();
319		token[3] = buf;
320		assert(token[4] == NULL);
321
322		if ((gcorechild = fork()) > 0) {
323			waitpid(gcorechild, &status, 0);
324		} else if (gcorechild == 0) {
325			execve("/usr/bin/gcore", token, environ);
326			_exit(1);
327		}
328		kill(sleepchild, SIGKILL);
329		waitpid(sleepchild, &status, 0);
330	}
331}
332
333void
334dowrite()
335{
336	struct iovec data[] = {
337		{"12", 2},
338		{NULL, 0},
339		{"12345678", 8},
340	};
341	static int fd = -1;
342
343	if (fd == -1) {
344		/* keep existing file open during life of this process */
345		fd = open(bstg_pathstore_get(), O_RDWR | O_NONBLOCK | O_NOCTTY);
346	}
347	data[1].iov_base = bstg_pathstore_get();
348	data[1].iov_len = strlen((char *)data[1].iov_base);
349	ftruncate(fd, 0);
350	pwritev(fd, data, 3, 0);
351}
352
353void
354dounlink()
355{
356	unlink(bstg_pathstore_get());
357}
358
359void
360dolink()
361{
362	link(bstg_pathstore_get(), bstg_pathstore_get());
363}
364
365void
366domkdir()
367{
368	char **pdir;
369	static char *bstg_dirs[] = {
370		"/mnt/111", "/mnt/222", "/mnt/333", "/mnt/444",
371		"/mnt/555", "/mnt/666", "/mnt/777", "/mnt/888",
372		"/mnt/999", "/mnt/aaa", "/mnt/bbb", "/mnt/ccc",
373		"/mnt/ddd", "/mnt/eee", "/mnt/fff", NULL
374	};
375
376	for (pdir = bstg_dirs; *pdir; pdir++) {
377		if (mkdir(*pdir, 0777) == -1)
378			err(1, "mkdir(%s)", *pdir);
379	}
380}
381
382void
383dosync()
384{
385	sync();
386}
387
388int
389main()
390{
391	time_t start;
392	unsigned x;
393	int i, status;
394	void (*funcs[]) () = {
395		dogcore,
396		dowrite,
397		dounlink,
398		dolink,
399		dowrite,
400		dounlink,
401		dolink,
402		dowrite,
403		dosync,
404		dowrite,
405		dounlink,
406		dolink,
407		dowrite,
408		dounlink,
409		dolink,
410		dowrite,
411	};
412
413	/* we only can domkdir() once at startup */
414	domkdir();
415
416	/* create 128 children that loop forever running 4 operations */
417	dosync();
418	for (x = 0; x < 128; x++) {
419		if (fork() == 0) {
420			/* give child a new seed for the pathname selection */
421			srand(x);
422
423			start = time(NULL);
424			for (i = 0; i < 1000; i++) {
425				/* each child will start looping at different
426				 * function */
427				(*funcs[x++ % 16]) ();
428				if (time(NULL) - start > RUNTIME)
429					break;
430			}
431			/* we never expect this code to run */
432			_exit(1);
433		}
434	}
435
436	/* block forever for all our children */
437	while (wait(&status) > 0);
438	return 0;
439}
440