1#!/bin/sh
2
3#
4# Copyright (c) 2014 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[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
30
31# "ffs_fsync: dirty" seen:
32# http://people.freebsd.org/~pho/stress/log/ffs_sync.txt
33
34. ../default.cfg
35
36here=`pwd`
37cd /tmp
38sed '1,/^EOF/d' < $here/$0 > ffs_sync.c
39mycc -o ffs_sync -Wall -Wextra ffs_sync.c || exit 1
40rm -f ffs_sync.c
41cd $here
42
43mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
44mdconfig -l | grep -q md$mdstart &&  mdconfig -d -u $mdstart
45
46mdconfig -a -t swap -s 4g -u $mdstart || exit 1
47newfs $newfs_flags md$mdstart > /dev/null
48mount /dev/md$mdstart $mntpoint
49chmod 777 $mntpoint
50
51for i in `jot 3`; do
52	su $testuser -c "cd $mntpoint; /tmp/ffs_sync" &
53	sleep 60
54	killall -q ffs_sync
55	killall -q ffs_sync
56done
57
58while mount | grep $mntpoint | grep -q /dev/md; do
59	umount $mntpoint || sleep 1
60done
61rm -f /tmp/ffs_sync
62mdconfig -d -u $mdstart
63exit
64EOF
65#include <sys/param.h>
66#include <err.h>
67#include <errno.h>
68#include <fcntl.h>
69#include <fts.h>
70#include <libutil.h>
71#include <stdint.h>
72#include <stdio.h>
73#include <stdlib.h>
74#include <string.h>
75#include <sys/stat.h>
76#include <sys/wait.h>
77#include <unistd.h>
78
79#define PARALLEL    12
80#define NRW       1000
81#define NFTS     10000
82#define NMKDIR    6000
83#define NSYMLINK 20000
84
85void
86slinktest(void)
87{
88        int i, j;
89        pid_t pid;
90        char file[128];
91
92	setproctitle("slink");
93        pid = getpid();
94        for (j = 0; j < NSYMLINK; j++) {
95                sprintf(file,"p%05d.%05d", pid, j);
96                if (symlink("/tmp/not/there", file) == -1) {
97                        if (errno != EINTR)
98                                warn("symlink(%s). %s.%d", file, __FILE__, __LINE__);
99                }
100        }
101
102        for (i = --j; i >= 0; i--) {
103                sprintf(file,"p%05d.%05d", pid, i);
104                if (unlink(file) == -1)
105                        err(3, "unlink(%s)", file);
106        }
107
108	_exit(0);
109}
110
111void
112mktest(void)
113{
114	int i;
115	char path[80];
116
117	setproctitle("mkdir");
118	sprintf(path, "d%06d", getpid());
119	if (mkdir(path, 0770) == -1)
120		err(1, "mkdir(%s)", path);
121	chdir(path);
122
123	sprintf(path, "d");
124	for (i = 0; i < NMKDIR; i++) {
125		if (mkdir(path, 0770) == -1) {
126			warn("mkdir(%s),  %s:%d", path, __FILE__, __LINE__);
127		} else
128			chdir(path);
129
130	}
131	for (i = 0; i < NMKDIR; i++) {
132		chdir("..");
133		rmdir(path);
134	}
135	chdir("..");
136
137	_exit(0);
138}
139
140void
141rwtest(void)
142{
143	int fd, i, j;
144	char buf[80], file[80];
145
146	setproctitle("rw");
147	for (i = 0; i < NRW; i++) {
148		sprintf(file, "f%06d.%06d", getpid(), i);
149		if ((fd = open(file, O_CREAT | O_EXCL, 0644)) == -1)
150			err(1, "open(%s)", file);
151		for (j = 0; j < 1024; j++)
152			write(fd, buf, sizeof(buf));
153		lseek(fd, 0, SEEK_SET);
154		for (j = 0; j < 1024; j++)
155			read(fd, buf, sizeof(buf));
156		close(fd);
157	}
158	for (i = 0; i < NRW; i++) {
159		sprintf(file, "f%06d.%06d", getpid(), i);
160		if (unlink(file) == -1)
161			warn("unlink(%s)", file);
162	}
163	_exit(0);
164}
165
166void
167slink(void)
168{
169	int i;
170
171	for (i = 0; i < PARALLEL; i++)
172		if (fork() == 0)
173			slinktest();
174}
175
176void
177mk(void)
178{
179	int i;
180
181	for (i = 0; i < PARALLEL; i++)
182		if (fork() == 0)
183			mktest();
184}
185
186void
187rw(void)
188{
189	int i;
190
191	for (i = 0; i < PARALLEL; i++)
192		if (fork() == 0)
193			rwtest();
194}
195
196void
197ftstest(void)
198{
199	FTS *fts;
200	FTSENT *p;
201	int ftsoptions, i;
202	char *args[2];
203
204	setproctitle("fts");
205	ftsoptions = FTS_PHYSICAL;
206	args[0] = ".";
207	args[1] = 0;
208
209	for (i = 0; i < NFTS; i++) {
210		if ((fts = fts_open(args, ftsoptions, NULL)) == NULL)
211			err(1, "fts_open");
212
213		while ((p = fts_read(fts)) != NULL)
214				;
215
216		if (errno != 0 && errno != ENOENT)
217			err(1, "fts_read");
218		if (fts_close(fts) == -1)
219			err(1, "fts_close()");
220	}
221
222	_exit(0);
223}
224
225void
226fts(void)
227{
228	int i;
229
230	for (i = 0; i < PARALLEL; i++)
231		if (fork() == 0)
232			ftstest();
233}
234
235int
236main(void)
237{
238	int i;
239
240	slink();
241	mk();
242	rw();
243	fts();
244
245	for (i = 0; i < PARALLEL; i++) {
246		wait(NULL);
247		wait(NULL);
248		wait(NULL);
249		wait(NULL);
250	}
251
252	return (0);
253}
254