18a272653SPeter Holm#!/bin/sh 28a272653SPeter Holm 38a272653SPeter Holm# 48a272653SPeter Holm# Copyright (c) 2016 EMC Corp. 58a272653SPeter Holm# All rights reserved. 68a272653SPeter Holm# 78a272653SPeter Holm# Redistribution and use in source and binary forms, with or without 88a272653SPeter Holm# modification, are permitted provided that the following conditions 98a272653SPeter Holm# are met: 108a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright 118a272653SPeter Holm# notice, this list of conditions and the following disclaimer. 128a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright 138a272653SPeter Holm# notice, this list of conditions and the following disclaimer in the 148a272653SPeter Holm# documentation and/or other materials provided with the distribution. 158a272653SPeter Holm# 168a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 178a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 188a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 198a272653SPeter Holm# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 208a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 218a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 228a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 238a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 248a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 258a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 268a272653SPeter Holm# SUCH DAMAGE. 278a272653SPeter Holm# 288a272653SPeter Holm 298a272653SPeter Holm# Hunt for; 308a272653SPeter Holm# Bug 204764 - Filesystem deadlock, process in vodead state 318a272653SPeter Holm# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=204764 328a272653SPeter Holm# No problem seen. 338a272653SPeter Holm 348a272653SPeter Holm. ../default.cfg 358a272653SPeter Holm 368a272653SPeter Holmdir=/tmp 378a272653SPeter Holmodir=`pwd` 388a272653SPeter Holmcd $dir 398a272653SPeter Holmsed '1,/^EOF/d' < $odir/$0 > $dir/lstat.c 408a272653SPeter Holmmycc -o lstat -Wall -Wextra -O0 -g lstat.c || exit 1 418a272653SPeter Holmrm -f lstat.c 428a272653SPeter Holmcd $odir 438a272653SPeter Holm 448a272653SPeter Holmmount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint 458a272653SPeter Holmmdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart 468a272653SPeter Holmmdconfig -a -t swap -s 1g -u $mdstart || exit 1 47*608c97bfSPeter Holmnewfs -n -b 4096 -f 512 -i 1024 md$mdstart > /dev/null 48*608c97bfSPeter Holmmount -o async /dev/md$mdstart $mntpoint || exit 1 498a272653SPeter Holm 508a272653SPeter Holmpath=$mntpoint/a/b/c 518a272653SPeter Holmmkdir -p $path 528a272653SPeter Holm 538a272653SPeter Holm$dir/lstat $path 548a272653SPeter Holm 558a272653SPeter Holmwhile mount | grep "on $mntpoint " | grep -q /dev/md; do 568a272653SPeter Holm umount $mntpoint || sleep 1 578a272653SPeter Holmdone 588a272653SPeter Holmmdconfig -d -u $mdstart 598a272653SPeter Holmrm -rf $dir/lstat $wdir/lstat.tmp.* 608a272653SPeter Holmexit 618a272653SPeter Holm 628a272653SPeter HolmEOF 638a272653SPeter Holm#include <sys/param.h> 648a272653SPeter Holm#include <sys/mman.h> 658a272653SPeter Holm#include <sys/stat.h> 668a272653SPeter Holm#include <sys/wait.h> 678a272653SPeter Holm 688a272653SPeter Holm#include <machine/atomic.h> 698a272653SPeter Holm 708a272653SPeter Holm#include <err.h> 718a272653SPeter Holm#include <errno.h> 728a272653SPeter Holm#include <fcntl.h> 738a272653SPeter Holm#include <fts.h> 748a272653SPeter Holm#include <signal.h> 758a272653SPeter Holm#include <stdio.h> 768a272653SPeter Holm#include <stdlib.h> 778a272653SPeter Holm#include <time.h> 788a272653SPeter Holm#include <unistd.h> 798a272653SPeter Holm 808a272653SPeter Holmstatic volatile u_int *dirs, *share; 818a272653SPeter Holmstatic char *arg; 828a272653SPeter Holm 838a272653SPeter Holm#define R1 0 848a272653SPeter Holm#define R2 1 858a272653SPeter Holm 868a272653SPeter Holm#define MXDIRS 3000 878a272653SPeter Holm#define PARALLEL 2 888a272653SPeter Holm#define RUNTIME 600 898a272653SPeter Holm#define SLPTIME 400 908a272653SPeter Holm 918a272653SPeter Holmstatic void 928a272653SPeter Holmtfts(int idx) 938a272653SPeter Holm{ 948a272653SPeter Holm FTS *fts; 958a272653SPeter Holm FTSENT *p; 968a272653SPeter Holm struct stat sb; 978a272653SPeter Holm int ftsoptions; 988a272653SPeter Holm char *args[2]; 998a272653SPeter Holm 1008a272653SPeter Holm if (idx != 0) 1018a272653SPeter Holm _exit(0); 1028a272653SPeter Holm 1038a272653SPeter Holm ftsoptions = FTS_PHYSICAL; 1048a272653SPeter Holm args[0] = arg, 1058a272653SPeter Holm args[1] = 0; 1068a272653SPeter Holm 1078a272653SPeter Holm setproctitle("fts"); 1088a272653SPeter Holm while (share[R2] == 0) { 1098a272653SPeter Holm if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) 1108a272653SPeter Holm err(1, "fts_open"); 1118a272653SPeter Holm 1128a272653SPeter Holm while ((p = fts_read(fts)) != NULL) { 1138a272653SPeter Holm lstat(fts->fts_path, &sb); 1148a272653SPeter Holm if (share[R2] == 1) 1158a272653SPeter Holm break; 1168a272653SPeter Holm } 1178a272653SPeter Holm 1188a272653SPeter Holm if (fts_close(fts) == -1) 1198a272653SPeter Holm err(1, "fts_close()"); 1208a272653SPeter Holm } 1218a272653SPeter Holm 1228a272653SPeter Holm _exit(0); 1238a272653SPeter Holm} 1248a272653SPeter Holm 1258a272653SPeter Holmstatic int 1268a272653SPeter Holmtest(int idx) 1278a272653SPeter Holm{ 1288a272653SPeter Holm struct stat sb; 1298a272653SPeter Holm pid_t fpid, pd, pid; 1308a272653SPeter Holm size_t len; 1318d72c409SPeter Holm int i, r; 1328a272653SPeter Holm char dir[128], path[128]; 1338a272653SPeter Holm 1348a272653SPeter Holm atomic_add_int(&share[R1], 1); 1358a272653SPeter Holm while (share[R1] != PARALLEL) 1368a272653SPeter Holm ; 1378a272653SPeter Holm 1388a272653SPeter Holm len = PAGE_SIZE; 1398a272653SPeter Holm if ((dirs = mmap(NULL, len, PROT_READ | PROT_WRITE, 1408a272653SPeter Holm MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 1418a272653SPeter Holm err(1, "mmap"); 1428a272653SPeter Holm 1438a272653SPeter Holm if ((fpid = fork()) == 0) 1448a272653SPeter Holm tfts(idx); 1458a272653SPeter Holm 1468a272653SPeter Holm pid = getpid(); 1478a272653SPeter Holm snprintf(dir, sizeof(dir), "%s/dir.%d", arg, pid); 1488a272653SPeter Holm if (mkdir(dir, 0777) == -1) 1498a272653SPeter Holm err(1, "mkdir(%s)", dir); 1508a272653SPeter Holm if (chdir(dir) == -1) 1518a272653SPeter Holm err(1, "chdir(%s)", dir); 1528a272653SPeter Holm if ((pd = fork()) == 0) { 1538a272653SPeter Holm setproctitle("mkdir"); 1548a272653SPeter Holm i = 0; 1558a272653SPeter Holm while (share[R2] == 0) { 1568a272653SPeter Holm snprintf(path, sizeof(path), "%s/d.%d.%d", arg, pid, 1578a272653SPeter Holm i); 1588a272653SPeter Holm while (dirs[0] > MXDIRS && share[R2] == 0) 1598a272653SPeter Holm usleep(SLPTIME); 1608a272653SPeter Holm while ((r = mkdir(path, 0777)) == -1) { 1618a272653SPeter Holm if (errno != EMLINK) 1628a272653SPeter Holm err(1, "mkdir(%s) @ %d", path, 1638a272653SPeter Holm __LINE__); 1648a272653SPeter Holm usleep(SLPTIME); 1658a272653SPeter Holm if (share[2] == 1) 1668a272653SPeter Holm break; 1678a272653SPeter Holm } 1688a272653SPeter Holm if (r == 0) { 1698a272653SPeter Holm atomic_add_int(&dirs[0], 1); 1708a272653SPeter Holm i++; 1718a272653SPeter Holm } 1728a272653SPeter Holm } 1738a272653SPeter Holm 1748a272653SPeter Holm _exit(0); 1758a272653SPeter Holm } 1768a272653SPeter Holm 1778a272653SPeter Holm i = 0; 1788a272653SPeter Holm setproctitle("rmdir"); 1798a272653SPeter Holm while (dirs[0] > 0 || share[R2] == 0) { 1808a272653SPeter Holm if (dirs[0] < MXDIRS / 2) 1818a272653SPeter Holm usleep(SLPTIME); 1828a272653SPeter Holm snprintf(path, sizeof(path), "%s/d.%d.%d", arg, pid, i); 1838a272653SPeter Holm while (lstat(path, &sb) == -1 && share[R2] == 0) { 1848a272653SPeter Holm usleep(SLPTIME); 1858a272653SPeter Holm } 1868a272653SPeter Holm if (rmdir(path) == -1) { 1878a272653SPeter Holm if (errno != ENOENT) 1888a272653SPeter Holm err(1, "rmdir(%s)", path); 1898a272653SPeter Holm } else { 1908a272653SPeter Holm atomic_add_int(&dirs[0], -1); 1918a272653SPeter Holm i++; 1928a272653SPeter Holm } 1938a272653SPeter Holm } 1948a272653SPeter Holm waitpid(pd, NULL, 0); 1958a272653SPeter Holm waitpid(fpid, NULL, 0); 1968a272653SPeter Holm 1978a272653SPeter Holm chdir(".."); 1988a272653SPeter Holm if ((rmdir(dir)) == -1) 1998a272653SPeter Holm err(1, "unlink(%s)", dir); 2008a272653SPeter Holm 2018a272653SPeter Holm _exit(0); 2028a272653SPeter Holm} 2038a272653SPeter Holm 2048a272653SPeter Holmint 2058a272653SPeter Holmmain(int argc, char *argv[]) 2068a272653SPeter Holm{ 2078a272653SPeter Holm size_t len; 2088a272653SPeter Holm int e, i, pids[PARALLEL], status; 2098a272653SPeter Holm 2108a272653SPeter Holm if (argc != 2) 2118a272653SPeter Holm errx(1, "Usage: %s <path>", argv[0]); 2128a272653SPeter Holm arg = argv[1]; 2138a272653SPeter Holm 2148a272653SPeter Holm e = 0; 2158a272653SPeter Holm len = PAGE_SIZE; 2168a272653SPeter Holm if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, 2178a272653SPeter Holm MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 2188a272653SPeter Holm err(1, "mmap"); 2198a272653SPeter Holm 2208a272653SPeter Holm share[R1] = 0; 2218a272653SPeter Holm for (i = 0; i < PARALLEL; i++) { 2228a272653SPeter Holm if ((pids[i] = fork()) == 0) 2238a272653SPeter Holm test(i); 2248a272653SPeter Holm } 2258a272653SPeter Holm sleep(RUNTIME); 2268a272653SPeter Holm share[R2] = 1; 2278a272653SPeter Holm for (i = 0; i < PARALLEL; i++) { 2288a272653SPeter Holm waitpid(pids[i], &status, 0); 2298a272653SPeter Holm e += status == 0 ? 0 : 1; 2308a272653SPeter Holm } 2318a272653SPeter Holm 2328a272653SPeter Holm return (e); 2338a272653SPeter Holm} 234