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