1#!/bin/sh 2 3# 4# Copyright (c) 2016 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# Time creating and deleting a number of files once a minute. 30 31. ../default.cfg 32[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 33 34export LANG=C 35dir=/tmp 36runtime=1200 # default 37[ $# -eq 1 ] && runtime=$1 38odir=`pwd` 39cd $dir 40sed '1,/^EOF/d' < $odir/$0 > $dir/burnin.c 41mycc -o burnin -Wall -Wextra -O0 -g burnin.c || exit 1 42rm -f burnin.c 43cd $odir 44 45mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint 46mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart 47mdconfig -a -t swap -s 1g -u $mdstart || exit 1 48newfs -n md$mdstart > /dev/null 49mount /dev/md$mdstart $mntpoint 50d=`date '+%Y%m%dT%H%M%S'` 51log=/tmp/burnin.$d.log 52mode=`pgrep -q cron && echo "Multi-user" || echo "Single-user"` 53echo "# `uname -a` $mode mode `hostname`" > $log 54 55/tmp/burnin -r 10 -d $mntpoint > /dev/null 2>&1 56/tmp/burnin -r $runtime -d $mntpoint >> $log 57 58ministat -A -C 2 -w 72 $log | tail -1 | awk '{if ($NF > .1) exit(1)}' 59s=$? 60[ $s -ne 0 ] && ministat -C 2 -w 72 $log 61 62while mount | grep "on $mntpoint " | grep -q /dev/md; do 63 umount $mntpoint || sleep 1 64done 65mdconfig -d -u $mdstart 66rm -rf /tmp/burnin $log 67exit 0 68EOF 69#include <sys/param.h> 70#include <sys/mman.h> 71#include <sys/stat.h> 72#include <sys/wait.h> 73 74#include <machine/atomic.h> 75 76#include <err.h> 77#include <errno.h> 78#include <fcntl.h> 79#include <stdio.h> 80#include <stdlib.h> 81#include <time.h> 82#include <unistd.h> 83 84#define DELAY 60 85#define SYNC 0 86 87volatile u_int *share; 88int bufsize, files, parallel, runtime; 89char *buf, *dir; 90 91void 92usage(void) 93{ 94 fprintf(stderr, "Usage: %s [-b buf size] [-d directory] [-p parallel] " 95 "[-r runtime]\n", 96 getprogname()); 97 _exit(1); 98} 99 100void 101test(void) 102{ 103 pid_t pid; 104 int fd, i; 105 char path[MAXPATHLEN + 1]; 106 107 atomic_add_int(&share[SYNC], 1); 108 while (share[SYNC] != (volatile u_int)parallel) 109 ; 110 111 pid =getpid(); 112 for (i = 0; i < files; i++) { 113 snprintf(path, sizeof(path), "%s/f%06d.%06d", dir, pid, i); 114 if ((fd = open(path, O_RDWR | O_CREAT | O_TRUNC, DEFFILEMODE)) == 115 -1) 116 err(1, "open(%s)", path); 117 if (write(fd, buf, bufsize) != bufsize) 118 err(1, "write()"); 119 if (close(fd) == -1) 120 err(1, "close(%d)", fd); 121 if (unlink(path) == -1) 122 err(1, "unlink(%s)", path); 123 } 124 125 _exit(0); 126} 127 128int 129main(int argc, char *argv[]) 130{ 131 struct timeval t1, t2, diff; 132 struct tm *tp; 133 size_t len; 134 time_t start, now; 135 int ch, e, i, *pids, status; 136 char help[80]; 137 138 bufsize = 8 * 1024; 139 dir = "/tmp"; 140 files = 5000; 141 parallel = 4; 142 runtime = 1 * 60 * 60 * 24; 143 144 while ((ch = getopt(argc, argv, "b:d:f:r:")) != -1) 145 switch(ch) { 146 case 'b': /* bufsize */ 147 if (sscanf(optarg, "%d", &bufsize) != 1) 148 usage(); 149 break; 150 case 'd': /* dir */ 151 dir = optarg; 152 break; 153 case 'f': /* files */ 154 if (sscanf(optarg, "%d", &files) != 1) 155 usage(); 156 break; 157 case 'p': /* parallel */ 158 if (sscanf(optarg, "%d", ¶llel) != 1) 159 usage(); 160 break; 161 case 'r': /* runtime */ 162 if (sscanf(optarg, "%d", &runtime) != 1) 163 usage(); 164 break; 165 default: 166 usage(); 167 } 168 argc -= optind; 169 argv += optind; 170 171 printf("# Options used: dir=%s, bufsize=%d, files=%d, parallel=%d, " 172 "runtime=%d\n", 173 dir, bufsize, files, parallel, runtime); 174 if ((buf = malloc(bufsize)) == NULL) 175 err(1, "malloc(%d)", bufsize); 176 if ((pids = malloc(sizeof(pid_t) * parallel)) == NULL) 177 err(1, "malloc(%d)", (int)(sizeof(pid_t) * parallel)); 178 e = 0; 179 len = PAGE_SIZE; 180 if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, 181 MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 182 err(1, "mmap"); 183 184 start = time(NULL); 185 while ((time(NULL) - start) < runtime && e == 0) { 186 share[SYNC] = 0; 187 gettimeofday(&t1, NULL); 188 for (i = 0; i < parallel; i++) { 189 if ((pids[i] = fork()) == 0) 190 test(); 191 } 192 for (i = 0; i < parallel; i++) { 193 waitpid(pids[i], &status, 0); 194 e += status == 0 ? 0 : 1; 195 } 196 gettimeofday(&t2, NULL); 197 timersub(&t2, &t1, &diff); 198 now = time(NULL); 199 tp = localtime(&now); 200 strftime(help, sizeof(help), "%Y%m%d%H%M%S", tp); 201 printf("%s %ld.%06ld\n", help, (long)diff.tv_sec, 202 diff.tv_usec); 203 fflush(stdout); 204 if (runtime > DELAY) 205 sleep(DELAY); 206 } 207 208 return (e); 209} 210