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 5.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 94 95newfs -b 4096 -f 512 -i 2048 md$mdstart > /dev/null 96mount -o async /dev/md$mdstart $mntpoint || exit 1 97 98cp /tmp/core5 $mntpoint 99mkdir $mntpoint/dir 100cd $mntpoint 101 102mp2=${mntpoint}2 103[ -d $mp2 ] || mkdir $mp2 104mount | grep -q "on $mp2 " && umount $mp2 105mount -o size=2g -t tmpfs tmpfs $mp2 || exit 1 106for i in `jot 10`; do 107 (cd $mp2; /tmp/core5-dumper$i ) & 108done 109maxvnodes=`sysctl -n kern.maxvnodes` 110trap "sysctl kern.maxvnodes=$maxvnodes > /dev/null" EXIT INT 111$mntpoint/core5 $mntpoint/dir 112wait 113umount $mp2 114 115cd $here 116while mount | grep -q "on $mntpoint "; do 117 umount $mntpoint || sleep 1 118done 119mdconfig -d -u $mdstart 120rm -f /tmp/core5 /tmp/core5-dumper* /tmp/core5-dumper*.core 121exit 0 122EOF 123#include <sys/wait.h> 124#include <sys/sysctl.h> 125 126#include <err.h> 127#include <fcntl.h> 128#include <signal.h> 129#include <stdio.h> 130#include <stdlib.h> 131#include <time.h> 132#include <unistd.h> 133 134#define MAXVNODES 5000 135#define NBFILES 10000 136#define PARALLEL 4 137#define RTIME (10 * 60) 138 139char *path; 140 141void 142test(int n) 143{ 144 int fd, i; 145 char file[80]; 146 147 usleep(arc4random() % 1000); 148 for (i = 0; i < NBFILES; i++) { 149 snprintf(file, sizeof(file), "%s/f%d.%06d", path, n, i); 150 if ((fd = open(file, O_CREAT, 0644)) == -1) { 151 warn("open(%s)", file); 152 break; 153 } 154 close(fd); 155 } 156 for (i = 0; i < NBFILES; i++) { 157 snprintf(file, sizeof(file), "%s/f%d.%06d", path, n, i); 158 if (unlink(file) == -1) 159 err(1, "unlink(%s)", file); 160 } 161 162 _exit(0); 163} 164 165int 166main(int argc, char *argv[]) 167{ 168 size_t len; 169 time_t start; 170 unsigned long nv, maxvnodes; 171 int j; 172 173 if (argc != 2) 174 errx(1, "Usage: %s <path>", argv[0]); 175 path = argv[1]; 176 177 nv = MAXVNODES; 178 len = sizeof(maxvnodes); 179 if (sysctlbyname("kern.maxvnodes", &maxvnodes, &len, &nv, 180 sizeof(nv)) != 0) 181 err(1, "sysctl kern.maxvnodes 1"); 182 183 start = time(NULL); 184 while (time(NULL) - start < RTIME) { 185 for (j = 0; j < PARALLEL; j++) 186 if (fork() == 0) 187 test(j); 188 189 for (j = 0; j < PARALLEL; j++) 190 wait(NULL); 191 } 192 193 if (sysctlbyname("kern.maxvnodes", NULL, NULL, &maxvnodes, 194 sizeof(maxvnodes)) != 0) 195 err(1, "sysctl kern.maxvnodes 2"); 196 197 return (0); 198} 199