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