xref: /freebsd/tools/test/stress2/misc/suj23.sh (revision dd41de95a84d979615a2ef11df6850622bf6184e)
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
52bsdlabel -w md$mdstart auto
53newfs -j md${mdstart}$part > /dev/null
54mount /dev/md${mdstart}$part $mntpoint
55chmod 777 $mntpoint
56
57su $testuser -c '/tmp/suj23'
58
59while mount | grep -q "on $mntpoint "; do
60	umount $mntpoint || sleep 1
61done
62mdconfig -d -u $mdstart
63rm -f /tmp/suj23
64exit 0
65EOF
66/*
67 * Copyright 2011 Kirk J. Russell
68 *
69 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
70 * use this file except in compliance with the License. You may obtain a copy
71 * of the License at http://www.apache.org/licenses/LICENSE-2.0
72 *
73 * Unless required by applicable law or agreed to in writing, software
74 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
75 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
76 * License for the specific language governing permissions and limitations
77 * under the License.
78 */
79
80#include <unistd.h>
81#include <assert.h>
82#include <err.h>
83#include <fcntl.h>
84#include <signal.h>
85#include <stdio.h>
86#include <stdlib.h>
87#include <string.h>
88#include <time.h>
89#include <sys/stat.h>
90#include <sys/uio.h>
91#include <sys/wait.h>
92
93#define RUNTIME 600
94
95static char *bstg_pathstore[] = {
96	"/mnt/111/z",
97	"/mnt/111/aaaa",
98	"/mnt/111/bbbbb",
99	"/mnt/111/ccccc",
100	"/mnt/111/d",
101	"/mnt/111/e",
102	"/mnt/111/ffffff.fff.f",
103	"/mnt/111/gggggggggggg",
104	"/mnt/111/hhhh",
105	"/mnt/111/iiiii.ii",
106	"/mnt/111/jjjj.jj.jjjjjjjj",
107	"/mnt/111/kkkk.kkkkkkkk",
108	"/mnt/111/lllll",
109	"/mnt/222/z",
110	"/mnt/222/aaaa",
111	"/mnt/222/bbbbb",
112	"/mnt/222/ccccc",
113	"/mnt/222/d",
114	"/mnt/222/e",
115	"/mnt/222/ffffff.fff.f",
116	"/mnt/222/gggggggggggg",
117	"/mnt/222/hhhh",
118	"/mnt/222/iiiii.ii",
119	"/mnt/222/jjjj.jj.jjjjjjjj",
120	"/mnt/222/kkkk.kkkkkkkk",
121	"/mnt/222/lllll",
122	"/mnt/333/z",
123	"/mnt/333/aaaa",
124	"/mnt/333/bbbbb",
125	"/mnt/333/ccccc",
126	"/mnt/333/d",
127	"/mnt/333/e",
128	"/mnt/333/ffffff.fff.f",
129	"/mnt/333/gggggggggggg",
130	"/mnt/333/hhhh",
131	"/mnt/333/iiiii.ii",
132	"/mnt/333/jjjj.jj.jjjjjjjj",
133	"/mnt/333/kkkk.kkkkkkkk",
134	"/mnt/333/lllll",
135	"/mnt/444/z",
136	"/mnt/444/aaaa",
137	"/mnt/444/bbbbb",
138	"/mnt/444/ccccc",
139	"/mnt/444/d",
140	"/mnt/444/e",
141	"/mnt/444/ffffff.fff.f",
142	"/mnt/444/gggggggggggg",
143	"/mnt/444/hhhh",
144	"/mnt/444/iiiii.ii",
145	"/mnt/444/jjjj.jj.jjjjjjjj",
146	"/mnt/444/kkkk.kkkkkkkk",
147	"/mnt/444/lllll",
148	"/mnt/555/z",
149	"/mnt/555/aaaa",
150	"/mnt/555/bbbbb",
151	"/mnt/555/ccccc",
152	"/mnt/555/d",
153	"/mnt/555/e",
154	"/mnt/555/ffffff.fff.f",
155	"/mnt/555/gggggggggggg",
156	"/mnt/555/hhhh",
157	"/mnt/555/iiiii.ii",
158	"/mnt/555/jjjj.jj.jjjjjjjj",
159	"/mnt/555/kkkk.kkkkkkkk",
160	"/mnt/555/lllll",
161	"/mnt/666/z",
162	"/mnt/666/aaaa",
163	"/mnt/666/bbbbb",
164	"/mnt/666/ccccc",
165	"/mnt/666/d",
166	"/mnt/666/e",
167	"/mnt/666/ffffff.fff.f",
168	"/mnt/666/gggggggggggg",
169	"/mnt/666/hhhh",
170	"/mnt/666/iiiii.ii",
171	"/mnt/666/jjjj.jj.jjjjjjjj",
172	"/mnt/666/kkkk.kkkkkkkk",
173	"/mnt/666/lllll",
174	"/mnt/777/z",
175	"/mnt/777/aaaa",
176	"/mnt/777/bbbbb",
177	"/mnt/777/ccccc",
178	"/mnt/777/d",
179	"/mnt/777/e",
180	"/mnt/777/ffffff.fff.f",
181	"/mnt/777/gggggggggggg",
182	"/mnt/777/hhhh",
183	"/mnt/777/iiiii.ii",
184	"/mnt/777/jjjj.jj.jjjjjjjj",
185	"/mnt/777/kkkk.kkkkkkkk",
186	"/mnt/777/lllll",
187	"/mnt/888/z",
188	"/mnt/888/aaaa",
189	"/mnt/888/bbbbb",
190	"/mnt/888/ccccc",
191	"/mnt/888/d",
192	"/mnt/888/e",
193	"/mnt/888/ffffff.fff.f",
194	"/mnt/888/gggggggggggg",
195	"/mnt/888/hhhh",
196	"/mnt/888/iiiii.ii",
197	"/mnt/888/jjjj.jj.jjjjjjjj",
198	"/mnt/888/kkkk.kkkkkkkk",
199	"/mnt/888/lllll",
200	"/mnt/999/z",
201	"/mnt/999/aaaa",
202	"/mnt/999/bbbbb",
203	"/mnt/999/ccccc",
204	"/mnt/999/d",
205	"/mnt/999/e",
206	"/mnt/999/ffffff.fff.f",
207	"/mnt/999/gggggggggggg",
208	"/mnt/999/hhhh",
209	"/mnt/999/iiiii.ii",
210	"/mnt/999/jjjj.jj.jjjjjjjj",
211	"/mnt/999/kkkk.kkkkkkkk",
212	"/mnt/999/lllll",
213	"/mnt/aaa/z",
214	"/mnt/aaa/aaaa",
215	"/mnt/aaa/bbbbb",
216	"/mnt/aaa/ccccc",
217	"/mnt/aaa/d",
218	"/mnt/aaa/e",
219	"/mnt/aaa/ffffff.fff.f",
220	"/mnt/aaa/gggggggggggg",
221	"/mnt/aaa/hhhh",
222	"/mnt/aaa/iiiii.ii",
223	"/mnt/aaa/jjjj.jj.jjjjjjjj",
224	"/mnt/aaa/kkkk.kkkkkkkk",
225	"/mnt/aaa/lllll",
226	"/mnt/bbb/z",
227	"/mnt/bbb/aaaa",
228	"/mnt/bbb/bbbbb",
229	"/mnt/bbb/ccccc",
230	"/mnt/bbb/d",
231	"/mnt/bbb/e",
232	"/mnt/bbb/ffffff.fff.f",
233	"/mnt/bbb/gggggggggggg",
234	"/mnt/bbb/hhhh",
235	"/mnt/bbb/iiiii.ii",
236	"/mnt/bbb/jjjj.jj.jjjjjjjj",
237	"/mnt/bbb/kkkk.kkkkkkkk",
238	"/mnt/bbb/lllll",
239	"/mnt/ccc/z",
240	"/mnt/ccc/aaaa",
241	"/mnt/ccc/bbbbb",
242	"/mnt/ccc/ccccc",
243	"/mnt/ccc/d",
244	"/mnt/ccc/e",
245	"/mnt/ccc/ffffff.fff.f",
246	"/mnt/ccc/gggggggggggg",
247	"/mnt/ccc/hhhh",
248	"/mnt/ccc/iiiii.ii",
249	"/mnt/ccc/jjjj.jj.jjjjjjjj",
250	"/mnt/ccc/kkkk.kkkkkkkk",
251	"/mnt/ccc/lllll",
252	"/mnt/ddd/z",
253	"/mnt/ddd/aaaa",
254	"/mnt/ddd/bbbbb",
255	"/mnt/ddd/ccccc",
256	"/mnt/ddd/d",
257	"/mnt/ddd/e",
258	"/mnt/ddd/ffffff.fff.f",
259	"/mnt/ddd/gggggggggggg",
260	"/mnt/ddd/hhhh",
261	"/mnt/ddd/iiiii.ii",
262	"/mnt/ddd/jjjj.jj.jjjjjjjj",
263	"/mnt/ddd/kkkk.kkkkkkkk",
264	"/mnt/ddd/lllll",
265	"/mnt/eee/z",
266	"/mnt/eee/aaaa",
267	"/mnt/eee/bbbbb",
268	"/mnt/eee/ccccc",
269	"/mnt/eee/d",
270	"/mnt/eee/e",
271	"/mnt/eee/ffffff.fff.f",
272	"/mnt/eee/gggggggggggg",
273	"/mnt/eee/hhhh",
274	"/mnt/eee/iiiii.ii",
275	"/mnt/eee/jjjj.jj.jjjjjjjj",
276	"/mnt/eee/kkkk.kkkkkkkk",
277	"/mnt/eee/lllll",
278	"/mnt/fff/z",
279	"/mnt/fff/aaaa",
280	"/mnt/fff/bbbbb",
281	"/mnt/fff/ccccc",
282	"/mnt/fff/d",
283	"/mnt/fff/e",
284	"/mnt/fff/ffffff.fff.f",
285	"/mnt/fff/gggggggggggg",
286	"/mnt/fff/hhhh",
287	"/mnt/fff/iiiii.ii",
288	"/mnt/fff/jjjj.jj.jjjjjjjj",
289	"/mnt/fff/kkkk.kkkkkkkk",
290	"/mnt/fff/lllll"
291};
292
293char *
294bstg_pathstore_get()
295{
296	return bstg_pathstore[rand() %
297		     ((sizeof(bstg_pathstore) / sizeof(bstg_pathstore[0])))];
298}
299
300void
301dogcore()
302{
303	pid_t sleepchild, gcorechild;
304	extern char **environ;
305
306	/* create a child for the gcore target */
307	if ((sleepchild = fork()) == 0) {
308		sleep(30);
309		_exit(1);
310	} else if (sleepchild > 0) {
311		char *token[] = {NULL, NULL, NULL, NULL, NULL};
312		char buf[64];
313		int status;
314
315		/* use the first process as the target */
316		snprintf(buf, sizeof(buf), "%d", sleepchild);
317		token[0] = "gcore";
318		token[1] = "-c";
319		token[2] = bstg_pathstore_get();
320		token[3] = buf;
321		assert(token[4] == NULL);
322
323		if ((gcorechild = fork()) > 0) {
324			waitpid(gcorechild, &status, 0);
325		} else if (gcorechild == 0) {
326			execve("/usr/bin/gcore", token, environ);
327			_exit(1);
328		}
329		kill(sleepchild, SIGKILL);
330		waitpid(sleepchild, &status, 0);
331	}
332}
333
334void
335dowrite()
336{
337	struct iovec data[] = {
338		{"12", 2},
339		{NULL, 0},
340		{"12345678", 8},
341	};
342	static int fd = -1;
343
344	if (fd == -1) {
345		/* keep existing file open during life of this process */
346		fd = open(bstg_pathstore_get(), O_RDWR | O_NONBLOCK | O_NOCTTY);
347	}
348	data[1].iov_base = bstg_pathstore_get();
349	data[1].iov_len = strlen((char *)data[1].iov_base);
350	ftruncate(fd, 0);
351	pwritev(fd, data, 3, 0);
352}
353
354void
355dounlink()
356{
357	unlink(bstg_pathstore_get());
358}
359
360void
361dolink()
362{
363	link(bstg_pathstore_get(), bstg_pathstore_get());
364}
365
366void
367domkdir()
368{
369	char **pdir;
370	static char *bstg_dirs[] = {
371		"/mnt/111", "/mnt/222", "/mnt/333", "/mnt/444",
372		"/mnt/555", "/mnt/666", "/mnt/777", "/mnt/888",
373		"/mnt/999", "/mnt/aaa", "/mnt/bbb", "/mnt/ccc",
374		"/mnt/ddd", "/mnt/eee", "/mnt/fff", NULL
375	};
376
377	for (pdir = bstg_dirs; *pdir; pdir++) {
378		if (mkdir(*pdir, 0777) == -1)
379			err(1, "mkdir(%s)", *pdir);
380	}
381}
382
383void
384dosync()
385{
386	sync();
387}
388
389int
390main()
391{
392	time_t start;
393	unsigned x;
394	int i, status;
395	void (*funcs[]) () = {
396		dogcore,
397		dowrite,
398		dounlink,
399		dolink,
400		dowrite,
401		dounlink,
402		dolink,
403		dowrite,
404		dosync,
405		dowrite,
406		dounlink,
407		dolink,
408		dowrite,
409		dounlink,
410		dolink,
411		dowrite,
412	};
413
414	/* we only can domkdir() once at startup */
415	domkdir();
416
417	/* create 128 children that loop forever running 4 operations */
418	dosync();
419	for (x = 0; x < 128; x++) {
420		if (fork() == 0) {
421			/* give child a new seed for the pathname selection */
422			srand(x);
423
424			start = time(NULL);
425			for (i = 0; i < 1000; i++) {
426				/* each child will start looping at different
427				 * function */
428				(*funcs[x++ % 16]) ();
429				if (time(NULL) - start > RUNTIME)
430					break;
431			}
432			/* we never expect this code to run */
433			_exit(1);
434		}
435	}
436
437	/* block forever for all our children */
438	while (wait(&status) > 0);
439	return 0;
440}
441