xref: /freebsd/tools/test/stress2/misc/bench.sh (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
1#!/bin/sh
2
3#
4# Copyright (c) 2017 Dell EMC Isilon
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# "benchmark" for file system use, using no physical disk.
30
31. ../default.cfg
32[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
33
34export LANG=C
35dir=/tmp
36odir=`pwd`
37cd $dir
38sed '1,/^EOF/d' < $odir/$0 > $dir/bench.c
39mycc -o bench -Wall -Wextra -O0 -g bench.c || exit 1
40rm -f bench.c
41cd $odir
42
43mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
44[ -c /dev/md$mdstart ] &&  mdconfig -d -u $mdstart
45mdconfig -a -t swap -s 1g -u $mdstart || exit 1
46
47log=/tmp/stress2.d/bench.sh.log
48[ -f $log ] && old=`tail -1 $log | awk '{print $2}'`
49tmp=/tmp/bench.sh.tmp
50s=0
51for j in `jot 5`; do
52	newfs -n -b 4096 -f 512 -i 1024 md$mdstart > \
53	    /dev/null
54	mount -o async /dev/md$mdstart $mntpoint
55	/usr/bin/time sh -c "(cd $mntpoint; /tmp/bench)" 2>&1 | \
56	    awk '{print $1}'
57	[ $? -ne 0 ] && s=1
58	umount $mntpoint
59done | ministat -n | tail -1 | awk '{printf "%.3f %.3f\n",$6,$7}' > $tmp
60r=`cat $tmp`
61echo "`date +%Y%m%d%H%M` $r `uname -a`" >> $log
62tail -5 $log | cut -c 1-92
63rm $tmp
64
65if [ $old ]; then
66    awk -v old=$old -v new=$(echo $r | awk '{print $1}') \
67    'BEGIN {if ((new - old) * 100 / old > 5) exit 1; else exit 0}'
68    s=$?
69fi
70
71for i in `jot 6`; do
72	mount | grep -q "on $mntpoint " || break
73	umount $mntpoint && break || sleep 10
74done
75[ $i -eq 6 ] && exit 1
76mdconfig -d -u $mdstart
77rm -rf /tmp/bench
78exit 0
79
80EOF
81#include <sys/param.h>
82#include <sys/mman.h>
83#include <sys/stat.h>
84#include <sys/wait.h>
85
86#include <err.h>
87#include <errno.h>
88#include <fcntl.h>
89#include <stdio.h>
90#include <stdlib.h>
91#include <string.h>
92#include <time.h>
93#include <unistd.h>
94
95#define LOOPS 50000
96#define TESTS 6
97#define TIMEOUT 600
98
99static void (*functions[TESTS])();
100
101static void
102t1(void)
103{
104	int fd, i;
105	char file[128];
106
107	alarm(TIMEOUT);
108	for (i = 0; i < LOOPS; i++) {
109		if (i % 1000 == 0)
110			setproctitle("%s @ %d", __func__, i);
111		snprintf(file, sizeof(file), "t1.%06d.%03d", getpid(), i);
112		if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC,
113		    DEFFILEMODE)) == -1)
114			err(1, "open(%s)", file);
115		close(fd);
116		if (unlink(file) == -1)
117			err(1, "unlink(%s)", file);
118		usleep(100);
119	}
120	_exit(0);
121}
122
123static void
124t2(void)
125{
126	int fd, i;
127	char file[128];
128
129	alarm(TIMEOUT);
130	for (i = 0; i < LOOPS; i++) {
131		if (i % 1000 == 0)
132			setproctitle("%s @ %d", __func__, i);
133		snprintf(file, sizeof(file), "t2.%06d.%03d", getpid(), i);
134		if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC,
135		    DEFFILEMODE)) == -1)
136			err(1, "open(%s)", file);
137		close(fd);
138		usleep(100);
139	}
140	for (i = 0; i < LOOPS; i++) {
141		snprintf(file, sizeof(file), "t2.%06d.%03d", getpid(), i);
142		if (unlink(file) == -1)
143			err(1, "unlink(%s)", file);
144	}
145	_exit(0);
146}
147
148static void
149t3(void)
150{
151	int fd, i;
152	char dir[128], file[128];
153
154	alarm(TIMEOUT);
155	snprintf(dir, sizeof(dir), "t3.%06d.dir", getpid());
156	if (mkdir(dir, 700) == -1)
157		err(1, "mkdir(%s)", dir);
158	for (i = 0; i < LOOPS; i++) {
159		if (i % 1000 == 0)
160			setproctitle("%s @ %d", __func__, i);
161		snprintf(file, sizeof(file), "%s/t3.%06d.%03d", dir,
162		    getpid(), i);
163		if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC,
164		    DEFFILEMODE)) == -1)
165			err(1, "open(%s)", file);
166		close(fd);
167		if (unlink(file) == -1)
168			err(1, "unlink(%s)", file);
169		usleep(100);
170	}
171	if (rmdir(dir) == -1)
172		err(1, "rmdir(%s)", dir);
173
174	_exit(0);
175}
176
177static void
178t4(void)
179{
180	int fd, i;
181	char file[128], new[128];
182
183	alarm(TIMEOUT);
184	for (i = 0; i < LOOPS / 2; i++) {
185		if (i % 1000 == 0)
186			setproctitle("%s @ %d", __func__, i);
187		snprintf(file, sizeof(file), "t4.%06d.%03d", getpid(), i);
188		if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC,
189		    DEFFILEMODE)) == -1)
190			err(1, "open(%s)", file);
191		close(fd);
192		snprintf(new, sizeof(new), "t4.%06d.%03d.new", getpid(), i);
193		if (rename(file, new) == -1)
194			err(1, "rename(%s, %s)", file, new);
195		if (unlink(new) == -1)
196			err(1, "unlink(%s)", new);
197		usleep(100);
198	}
199	_exit(0);
200}
201
202static void
203t5(void)
204{
205	int fd, i;
206	char buf[512], file[128];
207
208	alarm(TIMEOUT);
209	memset(buf, 0, sizeof(buf));
210	for (i = 0; i < LOOPS; i++) {
211		if (i % 1000 == 0)
212			setproctitle("%s @ %d", __func__, i);
213		snprintf(file, sizeof(file), "t5.%06d.%03d", getpid(), i);
214		if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC,
215		    DEFFILEMODE)) == -1)
216			err(1, "open(%s)", file);
217		if (write(fd, buf, sizeof(buf)) != sizeof(buf))
218			err(1, "write(%s)", file);
219		close(fd);
220		if (unlink(file) == -1)
221			err(1, "unlink(%s)", file);
222		usleep(100);
223	}
224	_exit(0);
225}
226
227static void
228t6(void)
229{
230	int fd, i;
231	char buf[512], file[128];
232
233	alarm(TIMEOUT);
234	memset(buf, 0, sizeof(buf));
235	for (i = 0; i < LOOPS / 2; i++) {
236		if (i % 1000 == 0)
237			setproctitle("%s/write @ %d", __func__, i);
238		snprintf(file, sizeof(file), "t6.%06d.%03d", getpid(), i);
239		if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC,
240		    DEFFILEMODE)) == -1)
241			err(1, "open(%s)", file);
242		if (write(fd, buf, sizeof(buf)) != sizeof(buf))
243			err(1, "write(%s)", file);
244		close(fd);
245	}
246	for (i = 0; i < LOOPS / 2; i++) {
247		if (i % 1000 == 0)
248			setproctitle("%s/read @ %d", __func__, i);
249		snprintf(file, sizeof(file), "t6.%06d.%03d", getpid(), i);
250		if ((fd = open(file, O_RDONLY)) == -1)
251			err(1, "open(%s)", file);
252		if (read(fd, buf, sizeof(buf)) != sizeof(buf))
253			err(1, "write(%s)", file);
254		close(fd);
255		usleep(100);
256	}
257	for (i = 0; i < LOOPS / 2; i++) {
258		snprintf(file, sizeof(file), "t6.%06d.%03d", getpid(), i);
259		if (unlink(file) == -1)
260			err(1, "unlink(%s)", file);
261	}
262	_exit(0);
263}
264
265static int
266test(void)
267{
268	pid_t pids[TESTS];
269	int e, i, status;
270
271	e = 0;
272	for (i = 0; i < TESTS; i++)
273		if ((pids[i] = fork()) == 0)
274			functions[i]();
275	for (i = 0; i < TESTS; i++) {
276		if (waitpid(pids[i], &status, 0) != pids[i])
277			err(1, "waitpid(%d)", pids[i]);
278		e += status != 0;
279	}
280
281	return (e);
282}
283
284int
285main(void)
286{
287	int e;
288
289	functions[0] = &t1;
290	functions[1] = &t2;
291	functions[2] = &t3;
292	functions[3] = &t4;
293	functions[4] = &t5;
294	functions[5] = &t6;
295
296	e = test();
297
298	return (e);
299}
300