1#!/bin/sh 2 3# 4# Copyright (c) 2015 EMC Corp. 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# The core file vnode is unreferenced before notification is sent. 30 31# Problem reported by sbruno@ 32# http://people.freebsd.org/~pho/stress/log/core5.txt 33# Fixed by r279237. 34 35# 20150714 Slowdown seen with core5 waiting in vlruwk. 36# sysctl vfs.vlru_allow_cache_src=1 used to resolve this. 37# For now change MAXVNODES from 1.000 to 4.000. 38 39[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 40. ../default.cfg 41 42here=`pwd` 43cd /tmp 44sed '1,/^EOF/d' < $here/$0 > core5.c 45mycc -o core5 -Wall -Wextra -O0 -g core5.c || exit 1 46rm -f core5.c 47 48cat > core5-dumper.c << EOT 49#include <sys/wait.h> 50 51#include <err.h> 52#include <errno.h> 53#include <signal.h> 54#include <stdio.h> 55#include <time.h> 56#include <unistd.h> 57 58int 59main(int argc __unused, char *argv[]) 60{ 61 time_t start; 62 char core[80]; 63 64 snprintf(core, sizeof(core), "%s.core", argv[0]); 65 66 if (unlink(core) == -1) 67 if (errno != ENOENT) 68 warn("unlink(%s)", core); 69 70 start = time(NULL); 71 while (time(NULL) - start < 600) { 72 if (fork() == 0) 73 raise(SIGSEGV); 74 wait(NULL); 75 } 76 if (unlink(core) == -1) 77 if (errno != ENOENT) 78 warn("unlink(%s)", core); 79 80 return (0); 81} 82EOT 83mycc -o core5-dumper -Wall -Wextra -O0 -g core5-dumper.c || exit 1 84rm -f core5-dumper.c 85for i in `jot 10`; do 86 cp core5-dumper core5-dumper$i 87done 88rm -f core5-dumper 89 90mount | grep -q "on $mntpoint " && umount $mntpoint 91[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart 92 93mdconfig -a -t malloc -s 1g -u $mdstart 94bsdlabel -w md$mdstart auto 95 96newfs -b 4096 -f 512 -i 2048 md${mdstart}$part > /dev/null 97mount -o async /dev/md${mdstart}$part $mntpoint || exit 1 98 99cp /tmp/core5 $mntpoint 100mkdir $mntpoint/dir 101cd $mntpoint 102 103mp2=${mntpoint}2 104[ -d $mp2 ] || mkdir $mp2 105mount | grep -q "on $mp2 " && umount $mp2 106mount -o size=2g -t tmpfs tmpfs $mp2 || exit 1 107for i in `jot 10`; do 108 (cd $mp2; /tmp/core5-dumper$i ) & 109done 110maxvnodes=`sysctl -n kern.maxvnodes` 111trap "sysctl kern.maxvnodes=$maxvnodes > /dev/null" EXIT INT 112$mntpoint/core5 $mntpoint/dir 113wait 114umount $mp2 115 116cd $here 117while mount | grep -q "on $mntpoint "; do 118 umount $mntpoint || sleep 1 119done 120mdconfig -d -u $mdstart 121rm -f /tmp/core5 /tmp/core5-dumper* /tmp/core5-dumper*.core 122exit 0 123EOF 124#include <sys/wait.h> 125#include <sys/sysctl.h> 126 127#include <err.h> 128#include <fcntl.h> 129#include <signal.h> 130#include <stdio.h> 131#include <stdlib.h> 132#include <time.h> 133#include <unistd.h> 134 135#define MAXVNODES 4000 136#define NBFILES 10000 137#define PARALLEL 4 138#define RTIME (10 * 60) 139 140char *path; 141 142void 143test(int n) 144{ 145 int fd, i; 146 char file[80]; 147 148 usleep(arc4random() % 1000); 149 for (i = 0; i < NBFILES; i++) { 150 snprintf(file, sizeof(file), "%s/f%d.%06d", path, n, i); 151 if ((fd = open(file, O_CREAT, 0644)) == -1) { 152 warn("open(%s)", file); 153 break; 154 } 155 close(fd); 156 } 157 for (i = 0; i < NBFILES; i++) { 158 snprintf(file, sizeof(file), "%s/f%d.%06d", path, n, i); 159 if (unlink(file) == -1) 160 err(1, "unlink(%s)", file); 161 } 162 163 _exit(0); 164} 165 166int 167main(int argc, char *argv[]) 168{ 169 size_t len; 170 time_t start; 171 unsigned long nv, maxvnodes; 172 int j; 173 174 if (argc != 2) 175 errx(1, "Usage: %s <path>", argv[0]); 176 path = argv[1]; 177 178 nv = MAXVNODES; 179 len = sizeof(maxvnodes); 180 if (sysctlbyname("kern.maxvnodes", &maxvnodes, &len, &nv, 181 sizeof(nv)) != 0) 182 err(1, "sysctl kern.maxvnodes 1"); 183 184 start = time(NULL); 185 while (time(NULL) - start < RTIME) { 186 for (j = 0; j < PARALLEL; j++) 187 if (fork() == 0) 188 test(j); 189 190 for (j = 0; j < PARALLEL; j++) 191 wait(NULL); 192 } 193 194 if (sysctlbyname("kern.maxvnodes", NULL, NULL, &maxvnodes, 195 sizeof(maxvnodes)) != 0) 196 err(1, "sysctl kern.maxvnodes 2"); 197 198 return (0); 199} 200