xref: /freebsd/tools/test/stress2/misc/cmp.sh (revision fd45b686f9d92f583366c75b22c04c7ee49709c0)
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# Cross mount test of mkdir(2).
30# Page fault seen:
31# http://people.freebsd.org/~pho/stress/log/cmp.txt
32# Fixed by r275347
33
34[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
35
36. ../default.cfg
37
38here=`pwd`
39cd /tmp
40sed '1,/^EOF/d' < $here/$0 > cmp.c
41mycc -o cmp -Wall -Wextra -O2 -g cmp.c || exit 1
42rm -f cmp.c
43
44mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
45[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
46
47mdconfig -a -t swap -s 2g -u $mdstart || exit 1
48# Don't use SU due to bogus "out of inodes" messages.
49newfs md$mdstart > /dev/null
50mount /dev/md$mdstart $mntpoint
51chmod 777 $mntpoint
52
53daemon sh -c "(cd $here/../testcases/swap; ./swap -t 5m -i 20 -h -l 100)" \
54    > /dev/null 2>&1
55sleep 1
56su $testuser -c "/tmp/cmp $mntpoint" &
57
58while kill -0 $! 2>/dev/null; do
59	umount -f $mntpoint &&
60	    mount /dev/md$mdstart $mntpoint
61	chmod 777 $mntpoint
62	sleep .1
63done
64wait
65
66while mount | grep $mntpoint | grep -q /dev/md; do
67	umount $mntpoint || sleep 1
68done
69mdconfig -d -u $mdstart
70[ -d "$mntpoint" ] && (cd $mntpoint && find . -delete)
71
72# tmpfs
73mount -t tmpfs tmpfs $mntpoint
74chmod 777 $mntpoint
75
76su $testuser -c "/tmp/cmp $mntpoint" &
77
78while kill -0 $! 2>/dev/null; do
79	umount -f $mntpoint &&
80	    mount -t tmpfs tmpfs $mntpoint
81	chmod 777 $mntpoint
82	sleep .1
83done
84pkill -9 swap
85wait
86
87while pkill -9 swap; do
88	:
89done > /dev/null 2>&1
90while mount | grep $mntpoint | grep -q tmpfs; do
91	umount $mntpoint || sleep 1
92done
93[ -d "$mntpoint" ] && (cd $mntpoint && find . -delete)
94rm -f /tmp/cmp
95exit 0
96EOF
97#include <sys/param.h>
98#include <sys/stat.h>
99#include <sys/wait.h>
100
101#include <err.h>
102#include <errno.h>
103#include <fcntl.h>
104#include <stdio.h>
105#include <stdlib.h>
106#include <string.h>
107#include <unistd.h>
108
109#define LOOPS 160
110#define PARALLEL 16
111
112int nbc, nbd;
113char *dir;
114
115void
116tmkdir(void)
117{
118	int i, j;
119	char d[MAXPATHLEN + 1], name[MAXPATHLEN + 1];
120
121	setproctitle(__func__);
122
123	i = 0;
124	snprintf(name, sizeof(name), "%s/d1.%05d", dir, getpid());
125	if (mkdir(name, 0755) == -1) {
126		if (errno != ENAMETOOLONG && errno != ENOENT &&
127		    errno != EBUSY && errno != EACCES && errno != EPERM)
128			warn("mkdir(%s)", name);
129		_exit(0);
130	}
131	for (;;) {
132		snprintf(d, sizeof(d), "/%d", i++);
133		strncat(name, d, sizeof(name) - 1);
134		if (mkdir(name, 0755) == -1) {
135			if (errno != ENAMETOOLONG && errno != ENOENT &&
136			    errno != EBUSY && errno != EACCES && errno != EPERM)
137				warn("mkdir(%s)", name);
138			i--;
139			break;
140		}
141		nbc++;
142	}
143
144	while (i >= 0) {
145		snprintf(name, sizeof(name), "%s/d1.%05d", dir, getpid());
146		for (j = 0; j < i; j++) {
147			snprintf(d, sizeof(d), "/%d", j);
148			strncat(name, d, sizeof(name) - 1);
149		}
150		if (rmdir(name) == -1) {
151			if (errno != ENOTEMPTY && errno != ENOENT && errno !=
152			    EBUSY)
153				warn("rmdir(%s)", name);
154		} else
155			nbd++;
156		i--;
157	}
158#if defined(TEST)
159	if (nbc == 0)
160		fprintf(stderr, "FAIL nbc = %d, nbd = %d\n", nbc, nbd);
161#endif
162	_exit(0);
163}
164
165int
166main(int argc, char **argv)
167{
168	int i, j;
169
170	if (argc != 2) {
171		fprintf(stderr, "Usage: %s <full path to dir>", argv[0]);
172		exit(1);
173	}
174	dir = argv[1];
175
176	for (j = 0; j < LOOPS; j++) {
177		for (i = 0; i < PARALLEL; i++) {
178			if (fork() == 0)
179				tmkdir();
180		}
181		for (i = 0; i < PARALLEL; i++)
182			wait(NULL);
183	}
184
185	return(0);
186}
187