diff options
Diffstat (limited to 'tools/test/stress2/misc/suj23.sh')
-rwxr-xr-x | tools/test/stress2/misc/suj23.sh | 440 |
1 files changed, 440 insertions, 0 deletions
diff --git a/tools/test/stress2/misc/suj23.sh b/tools/test/stress2/misc/suj23.sh new file mode 100755 index 000000000000..aca810d42485 --- /dev/null +++ b/tools/test/stress2/misc/suj23.sh @@ -0,0 +1,440 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm <pho@FreeBSD.org> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +# Scenario from kern/159971 +# bstg0003.c by Kirk Russell <kirk ba23 org> + +# panic: ino 0xc84c9b00(0x3C8209) 65554, 32780 != 65570 +# https://people.freebsd.org/~pho/stress/log/suj23.txt + +# panic: first_unlinked_inodedep: prev != next. inodedep = 0xcadf9e00 +# https://people.freebsd.org/~pho/stress/log/jeff091.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > suj23.c +mycc -o suj23 -Wall -Wextra -O2 suj23.c +rm -f suj23.c + +mount | grep "on $mntpoint " | grep -q md$mdstart && umount $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs -j md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +su $testuser -c '/tmp/suj23' + +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/suj23 +exit 0 +EOF +/* + * Copyright 2011 Kirk J. Russell + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +#include <unistd.h> +#include <assert.h> +#include <err.h> +#include <fcntl.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <time.h> +#include <sys/stat.h> +#include <sys/uio.h> +#include <sys/wait.h> + +#define RUNTIME 600 + +static char *bstg_pathstore[] = { + "/mnt/111/z", + "/mnt/111/aaaa", + "/mnt/111/bbbbb", + "/mnt/111/ccccc", + "/mnt/111/d", + "/mnt/111/e", + "/mnt/111/ffffff.fff.f", + "/mnt/111/gggggggggggg", + "/mnt/111/hhhh", + "/mnt/111/iiiii.ii", + "/mnt/111/jjjj.jj.jjjjjjjj", + "/mnt/111/kkkk.kkkkkkkk", + "/mnt/111/lllll", + "/mnt/222/z", + "/mnt/222/aaaa", + "/mnt/222/bbbbb", + "/mnt/222/ccccc", + "/mnt/222/d", + "/mnt/222/e", + "/mnt/222/ffffff.fff.f", + "/mnt/222/gggggggggggg", + "/mnt/222/hhhh", + "/mnt/222/iiiii.ii", + "/mnt/222/jjjj.jj.jjjjjjjj", + "/mnt/222/kkkk.kkkkkkkk", + "/mnt/222/lllll", + "/mnt/333/z", + "/mnt/333/aaaa", + "/mnt/333/bbbbb", + "/mnt/333/ccccc", + "/mnt/333/d", + "/mnt/333/e", + "/mnt/333/ffffff.fff.f", + "/mnt/333/gggggggggggg", + "/mnt/333/hhhh", + "/mnt/333/iiiii.ii", + "/mnt/333/jjjj.jj.jjjjjjjj", + "/mnt/333/kkkk.kkkkkkkk", + "/mnt/333/lllll", + "/mnt/444/z", + "/mnt/444/aaaa", + "/mnt/444/bbbbb", + "/mnt/444/ccccc", + "/mnt/444/d", + "/mnt/444/e", + "/mnt/444/ffffff.fff.f", + "/mnt/444/gggggggggggg", + "/mnt/444/hhhh", + "/mnt/444/iiiii.ii", + "/mnt/444/jjjj.jj.jjjjjjjj", + "/mnt/444/kkkk.kkkkkkkk", + "/mnt/444/lllll", + "/mnt/555/z", + "/mnt/555/aaaa", + "/mnt/555/bbbbb", + "/mnt/555/ccccc", + "/mnt/555/d", + "/mnt/555/e", + "/mnt/555/ffffff.fff.f", + "/mnt/555/gggggggggggg", + "/mnt/555/hhhh", + "/mnt/555/iiiii.ii", + "/mnt/555/jjjj.jj.jjjjjjjj", + "/mnt/555/kkkk.kkkkkkkk", + "/mnt/555/lllll", + "/mnt/666/z", + "/mnt/666/aaaa", + "/mnt/666/bbbbb", + "/mnt/666/ccccc", + "/mnt/666/d", + "/mnt/666/e", + "/mnt/666/ffffff.fff.f", + "/mnt/666/gggggggggggg", + "/mnt/666/hhhh", + "/mnt/666/iiiii.ii", + "/mnt/666/jjjj.jj.jjjjjjjj", + "/mnt/666/kkkk.kkkkkkkk", + "/mnt/666/lllll", + "/mnt/777/z", + "/mnt/777/aaaa", + "/mnt/777/bbbbb", + "/mnt/777/ccccc", + "/mnt/777/d", + "/mnt/777/e", + "/mnt/777/ffffff.fff.f", + "/mnt/777/gggggggggggg", + "/mnt/777/hhhh", + "/mnt/777/iiiii.ii", + "/mnt/777/jjjj.jj.jjjjjjjj", + "/mnt/777/kkkk.kkkkkkkk", + "/mnt/777/lllll", + "/mnt/888/z", + "/mnt/888/aaaa", + "/mnt/888/bbbbb", + "/mnt/888/ccccc", + "/mnt/888/d", + "/mnt/888/e", + "/mnt/888/ffffff.fff.f", + "/mnt/888/gggggggggggg", + "/mnt/888/hhhh", + "/mnt/888/iiiii.ii", + "/mnt/888/jjjj.jj.jjjjjjjj", + "/mnt/888/kkkk.kkkkkkkk", + "/mnt/888/lllll", + "/mnt/999/z", + "/mnt/999/aaaa", + "/mnt/999/bbbbb", + "/mnt/999/ccccc", + "/mnt/999/d", + "/mnt/999/e", + "/mnt/999/ffffff.fff.f", + "/mnt/999/gggggggggggg", + "/mnt/999/hhhh", + "/mnt/999/iiiii.ii", + "/mnt/999/jjjj.jj.jjjjjjjj", + "/mnt/999/kkkk.kkkkkkkk", + "/mnt/999/lllll", + "/mnt/aaa/z", + "/mnt/aaa/aaaa", + "/mnt/aaa/bbbbb", + "/mnt/aaa/ccccc", + "/mnt/aaa/d", + "/mnt/aaa/e", + "/mnt/aaa/ffffff.fff.f", + "/mnt/aaa/gggggggggggg", + "/mnt/aaa/hhhh", + "/mnt/aaa/iiiii.ii", + "/mnt/aaa/jjjj.jj.jjjjjjjj", + "/mnt/aaa/kkkk.kkkkkkkk", + "/mnt/aaa/lllll", + "/mnt/bbb/z", + "/mnt/bbb/aaaa", + "/mnt/bbb/bbbbb", + "/mnt/bbb/ccccc", + "/mnt/bbb/d", + "/mnt/bbb/e", + "/mnt/bbb/ffffff.fff.f", + "/mnt/bbb/gggggggggggg", + "/mnt/bbb/hhhh", + "/mnt/bbb/iiiii.ii", + "/mnt/bbb/jjjj.jj.jjjjjjjj", + "/mnt/bbb/kkkk.kkkkkkkk", + "/mnt/bbb/lllll", + "/mnt/ccc/z", + "/mnt/ccc/aaaa", + "/mnt/ccc/bbbbb", + "/mnt/ccc/ccccc", + "/mnt/ccc/d", + "/mnt/ccc/e", + "/mnt/ccc/ffffff.fff.f", + "/mnt/ccc/gggggggggggg", + "/mnt/ccc/hhhh", + "/mnt/ccc/iiiii.ii", + "/mnt/ccc/jjjj.jj.jjjjjjjj", + "/mnt/ccc/kkkk.kkkkkkkk", + "/mnt/ccc/lllll", + "/mnt/ddd/z", + "/mnt/ddd/aaaa", + "/mnt/ddd/bbbbb", + "/mnt/ddd/ccccc", + "/mnt/ddd/d", + "/mnt/ddd/e", + "/mnt/ddd/ffffff.fff.f", + "/mnt/ddd/gggggggggggg", + "/mnt/ddd/hhhh", + "/mnt/ddd/iiiii.ii", + "/mnt/ddd/jjjj.jj.jjjjjjjj", + "/mnt/ddd/kkkk.kkkkkkkk", + "/mnt/ddd/lllll", + "/mnt/eee/z", + "/mnt/eee/aaaa", + "/mnt/eee/bbbbb", + "/mnt/eee/ccccc", + "/mnt/eee/d", + "/mnt/eee/e", + "/mnt/eee/ffffff.fff.f", + "/mnt/eee/gggggggggggg", + "/mnt/eee/hhhh", + "/mnt/eee/iiiii.ii", + "/mnt/eee/jjjj.jj.jjjjjjjj", + "/mnt/eee/kkkk.kkkkkkkk", + "/mnt/eee/lllll", + "/mnt/fff/z", + "/mnt/fff/aaaa", + "/mnt/fff/bbbbb", + "/mnt/fff/ccccc", + "/mnt/fff/d", + "/mnt/fff/e", + "/mnt/fff/ffffff.fff.f", + "/mnt/fff/gggggggggggg", + "/mnt/fff/hhhh", + "/mnt/fff/iiiii.ii", + "/mnt/fff/jjjj.jj.jjjjjjjj", + "/mnt/fff/kkkk.kkkkkkkk", + "/mnt/fff/lllll" +}; + +char * +bstg_pathstore_get() +{ + return bstg_pathstore[rand() % + ((sizeof(bstg_pathstore) / sizeof(bstg_pathstore[0])))]; +} + +void +dogcore() +{ + pid_t sleepchild, gcorechild; + extern char **environ; + + /* create a child for the gcore target */ + if ((sleepchild = fork()) == 0) { + sleep(30); + _exit(1); + } else if (sleepchild > 0) { + char *token[] = {NULL, NULL, NULL, NULL, NULL}; + char buf[64]; + int status; + + /* use the first process as the target */ + snprintf(buf, sizeof(buf), "%d", sleepchild); + token[0] = "gcore"; + token[1] = "-c"; + token[2] = bstg_pathstore_get(); + token[3] = buf; + assert(token[4] == NULL); + + if ((gcorechild = fork()) > 0) { + waitpid(gcorechild, &status, 0); + } else if (gcorechild == 0) { + execve("/usr/bin/gcore", token, environ); + _exit(1); + } + kill(sleepchild, SIGKILL); + waitpid(sleepchild, &status, 0); + } +} + +void +dowrite() +{ + struct iovec data[] = { + {"12", 2}, + {NULL, 0}, + {"12345678", 8}, + }; + static int fd = -1; + + if (fd == -1) { + /* keep existing file open during life of this process */ + fd = open(bstg_pathstore_get(), O_RDWR | O_NONBLOCK | O_NOCTTY); + } + data[1].iov_base = bstg_pathstore_get(); + data[1].iov_len = strlen((char *)data[1].iov_base); + ftruncate(fd, 0); + pwritev(fd, data, 3, 0); +} + +void +dounlink() +{ + unlink(bstg_pathstore_get()); +} + +void +dolink() +{ + link(bstg_pathstore_get(), bstg_pathstore_get()); +} + +void +domkdir() +{ + char **pdir; + static char *bstg_dirs[] = { + "/mnt/111", "/mnt/222", "/mnt/333", "/mnt/444", + "/mnt/555", "/mnt/666", "/mnt/777", "/mnt/888", + "/mnt/999", "/mnt/aaa", "/mnt/bbb", "/mnt/ccc", + "/mnt/ddd", "/mnt/eee", "/mnt/fff", NULL + }; + + for (pdir = bstg_dirs; *pdir; pdir++) { + if (mkdir(*pdir, 0777) == -1) + err(1, "mkdir(%s)", *pdir); + } +} + +void +dosync() +{ + sync(); +} + +int +main() +{ + time_t start; + unsigned x; + int i, status; + void (*funcs[]) () = { + dogcore, + dowrite, + dounlink, + dolink, + dowrite, + dounlink, + dolink, + dowrite, + dosync, + dowrite, + dounlink, + dolink, + dowrite, + dounlink, + dolink, + dowrite, + }; + + /* we only can domkdir() once at startup */ + domkdir(); + + /* create 128 children that loop forever running 4 operations */ + dosync(); + for (x = 0; x < 128; x++) { + if (fork() == 0) { + /* give child a new seed for the pathname selection */ + srand(x); + + start = time(NULL); + for (i = 0; i < 1000; i++) { + /* each child will start looping at different + * function */ + (*funcs[x++ % 16]) (); + if (time(NULL) - start > RUNTIME) + break; + } + /* we never expect this code to run */ + _exit(1); + } + } + + /* block forever for all our children */ + while (wait(&status) > 0); + return 0; +} |