2 * Copyright (c) 2000-2001 Silicon Graphics, Inc.
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it would be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write the Free Software Foundation,
16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * This is mostly a "crash & burn" test. -v turns on verbosity
21 * and -c actually fails on errors - but expected errors aren't
34 static int dirstress(char *dirname, int dirnum, int nfiles, int keep, int nprocs_per_dir);
35 static int create_entries(int nfiles);
36 static int scramble_entries(int nfiles);
37 static int remove_entries(int nfiles);
66 while ((c = getopt(argc, argv, "d:p:f:s:n:kvc")) != EOF) {
69 nprocs = atoi(optarg);
72 nfiles = atoi(optarg);
75 nprocs_per_dir = atoi(optarg);
81 seed = strtol(optarg, NULL, 0);
97 if (errflg || (dirname == NULL)) {
98 printf("Usage: dirstress [-d dir] [-p nprocs] [-f nfiles] [-n procs per dir]\n"
99 " [-v] [-s seed] [-k] [-c]\n");
103 printf("** [%d] Using seed %ld\n", pid, seed);
106 for (i = 0; i < nprocs; i++) {
107 if (verbose) fprintf(stderr,"** [%d] fork\n", pid);
110 perror("Fork failed");
118 if (verbose) fprintf(stderr,"** [%d] forked\n", pid);
119 r=dirstress(dirname, i / nprocs_per_dir, nfiles, keep, nprocs_per_dir);
120 if (verbose) fprintf(stderr,"** [%d] exit %d\n", pid, r);
124 if (verbose) fprintf(stderr,"** [%d] wait\n", pid);
127 /* wait & reap children, accumulating error results */
128 while (wait(&status) != -1)
131 printf("INFO: Dirstress complete\n");
132 if (verbose) fprintf(stderr,"** [%d] parent exit %d\n", pid, istatus);
150 sprintf(buf, "%s/stressdir", dirname);
151 if (verbose) fprintf(stderr,"** [%d] mkdir %s 0777\n", pid, buf);
152 error = mkdir(buf, 0777);
153 if (error && (errno != EEXIST)) {
154 perror("Create stressdir directory failed");
158 if (verbose) fprintf(stderr,"** [%d] chdir %s\n", pid, buf);
161 perror("Cannot chdir to main directory");
165 sprintf(buf, "stress.%d", dirnum);
166 if (verbose) fprintf(stderr,"** [%d] mkdir %s 0777\n", pid, buf);
167 error = mkdir(buf, 0777);
168 if (error && (errno != EEXIST)) {
169 perror("Create pid directory failed");
173 if (verbose) fprintf(stderr,"** [%d] chdir %s\n", pid, buf);
176 perror("Cannot chdir to dirnum directory");
180 r=1; /* assume failure */
181 if (verbose) fprintf(stderr,"** [%d] create entries\n", pid);
182 if (create_entries(nfiles)) {
183 printf("!! [%d] create failed\n", pid);
185 if (verbose) fprintf(stderr,"** [%d] scramble entries\n", pid);
186 if (scramble_entries(nfiles)) {
187 printf("!! [%d] scramble failed\n", pid);
190 if (verbose) fprintf(stderr,"** [%d] keep entries\n", pid);
193 if (verbose) fprintf(stderr,"** [%d] remove entries\n", pid);
194 if (remove_entries(nfiles)) {
195 printf("!! [%d] remove failed\n", pid);
203 if (verbose) fprintf(stderr,"** [%d] chdir ..\n", pid);
206 /* If this is multithreaded, then expecting a ENOENT here is fine,
207 * and ESTALE is normal in the NFS case. */
208 if (nprocs_per_dir > 1 && (errno == ENOENT || errno == ESTALE)) {
212 perror("Cannot chdir out of pid directory");
217 sprintf(buf, "stress.%d", dirnum);
218 if (verbose) fprintf(stderr,"** [%d] rmdir %s\n", pid, buf);
221 if (checkflag) return 1;
225 if (verbose) fprintf(stderr,"** [%d] chdir ..\n", pid);
228 /* If this is multithreaded, then expecting a ENOENT here is fine,
229 * and ESTALE is normal in the NFS case. */
230 if (nprocs_per_dir > 1 && (errno == ENOENT || errno == ESTALE)) {
234 perror("Cannot chdir out of working directory");
239 if (verbose) fprintf(stderr,"** [%d] rmdir stressdir\n", pid);
240 if (rmdir("stressdir")) {
242 if (checkflag) return 1;
257 for (i = 0; i < nfiles; i++) {
258 sprintf(buf, "XXXXXXXXXXXX.%d", i);
264 if (verbose) fprintf(stderr,"** [%d] creat %s\n", pid, buf);
265 fd = creat(buf, 0666);
267 if (verbose) fprintf(stderr,"** [%d] close %s\n", pid, buf);
270 fprintf(stderr,"!! [%d] close %s failed\n", pid, buf);
272 if (checkflag) return 1;
280 if (verbose) fprintf(stderr,"** [%d] mkdir %s 0777\n", pid, buf);
281 if (mkdir(buf, 0777)) {
282 fprintf(stderr,"!! [%d] mkdir %s 0777 failed\n", pid, buf);
284 if (checkflag) return 1;
292 if (verbose) fprintf(stderr,"** [%d] symlink %s %s\n", pid, buf, buf);
293 if (symlink(buf, buf)) {
294 fprintf(stderr,"!! [%d] symlink %s %s failed\n", pid, buf, buf);
296 if (checkflag) return 1;
304 if (verbose) fprintf(stderr,"** [%d] mknod %s 0x%x\n", pid, buf, MKNOD_DEV);
305 if (mknod(buf, S_IFCHR | 0666, MKNOD_DEV)) {
306 fprintf(stderr,"!! [%d] mknod %s 0x%x failed\n", pid, buf, MKNOD_DEV);
308 if (checkflag) return 1;
330 for (i = 0; i < nfiles * 2; i++) {
334 * rename two random entries
336 r = random() % nfiles;
337 sprintf(buf, "XXXXXXXXXXXX.%ld", r);
338 r = random() % nfiles;
339 sprintf(buf1, "XXXXXXXXXXXX.%ld", r);
341 if (verbose) fprintf(stderr,"** [%d] rename %s %s\n", pid, buf, buf1);
342 if (rename(buf, buf1)) {
344 if (checkflag) return 1;
349 * unlink a random entry
351 r = random() % nfiles;
352 sprintf(buf, "XXXXXXXXXXXX.%ld", r);
353 if (verbose) fprintf(stderr,"** [%d] unlink %s\n", pid, buf);
355 fprintf(stderr,"!! [%d] unlink %s failed\n", pid, buf);
357 if (checkflag) return 1;
362 * rmdir a random entry
364 r = random() % nfiles;
365 sprintf(buf, "XXXXXXXXXXXX.%ld", r);
366 if (verbose) fprintf(stderr,"** [%d] rmdir %s\n", pid, buf);
368 fprintf(stderr,"!! [%d] rmdir %s failed\n", pid, buf);
370 if (checkflag) return 1;
375 * create a random entry
377 r = random() % nfiles;
378 sprintf(buf, "XXXXXXXXXXXX.%ld", r);
380 if (verbose) fprintf(stderr,"** [%d] creat %s 0666\n", pid, buf);
381 fd = creat(buf, 0666);
383 if (verbose) fprintf(stderr,"** [%d] close %s\n", pid, buf);
385 fprintf(stderr,"!! [%d] close %s failed\n", pid, buf);
387 if (checkflag) return 1;
390 fprintf(stderr,"!! [%d] creat %s 0666 failed\n", pid, buf);
392 if (checkflag) return 1;
397 * mkdir a random entry
399 r = random() % nfiles;
400 sprintf(buf, "XXXXXXXXXXXX.%ld", r);
401 if (verbose) fprintf(stderr,"** [%d] mkdir %s\n", pid, buf);
402 if (mkdir(buf, 0777)) {
403 fprintf(stderr,"!! [%d] mkdir %s failed\n", pid, buf);
405 if (checkflag) return 1;
424 for (i = 0; i < nfiles; i++) {
425 sprintf(buf, "XXXXXXXXXXXX.%d", i);
426 error = lstat(buf, &statb);
428 /* ignore this one */
431 if (S_ISDIR(statb.st_mode)) {
432 if (verbose) fprintf(stderr,"** [%d] rmdir %s\n", pid, buf);
434 fprintf(stderr,"!! [%d] rmdir %s failed\n", pid, buf);
436 if (checkflag) return 1;
439 if (verbose) fprintf(stderr,"** [%d] unlink %s\n", pid, buf);
441 fprintf(stderr,"!! [%d] unlink %s failed\n", pid, buf);
443 if (checkflag) return 1;