xref: /freebsd/tools/test/stress2/misc/rename16.sh (revision ef777be98543f7daae90bd123d4fc1ec4a54efc2)
1#!/bin/sh
2
3# Copy of suj30.sh but with SU instead of SUJ
4
5# Rename test scenario by Andrey Zonov <zont@FreeBSD.org>
6
7[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
8
9. ../default.cfg
10
11set -u
12prog=$(basename "$0" .sh)
13here=`pwd`
14log=/tmp/$prog.sh.log
15cd /tmp
16sed '1,/^EOF/d' < $here/$0 > $prog.c
17mycc -o $prog -Wall -Wextra -O2 $prog.c -lpthread
18rm -f $prog.c
19
20mount | grep "on $mntpoint " | grep -q md$mdstart && umount $mntpoint
21mdconfig -l | grep -q md$mdstart &&  mdconfig -d -u $mdstart
22
23mdconfig -a -t swap -s 8g -u $mdstart
24newfs -U md$mdstart > /dev/null
25mount /dev/md$mdstart $mntpoint
26chmod 777 $mntpoint
27
28t=`date +%s`
29/tmp/$prog $mntpoint/test-0 100000
30t=$((`date +%s` - t))
31[ $t -gt 60 ] && n=20000 || n=100000
32
33for i in `jot 10`; do
34	/tmp/$prog $mntpoint/test-$i $n &
35done
36wait
37
38while mount | grep -q $mntpoint; do
39	umount $mntpoint || sleep 1
40done
41fsck -fy /dev/md$mdstart > $log
42grep -q "WAS MODIFIED" $log && s=1 || s=0
43mdconfig -d -u $mdstart
44rm -f /tmp/$prog $log
45exit $s
46EOF
47/*
48 * Andrey Zonov (c) 2012
49 *
50 * compile as `cc -o rename rename.c -lpthread'
51 */
52
53#include <sys/types.h>
54#include <sys/stat.h>
55#include <sys/time.h>
56#include <sys/queue.h>
57#include <err.h>
58#include <errno.h>
59#include <fcntl.h>
60#include <pthread.h>
61#ifdef __FreeBSD__
62#include <pthread_np.h>
63#define	__NP__
64#endif
65#include <sched.h>
66#include <stdio.h>
67#include <stdlib.h>
68#include <string.h>
69#include <time.h>
70#include <unistd.h>
71
72#define	LOCK(x)		pthread_mutex_lock(&x.mtx)
73#define	UNLOCK(x)	pthread_mutex_unlock(&x.mtx)
74#define	SIGNAL(x)	pthread_cond_signal(&x.wait)
75#define	WAIT(x)		pthread_cond_wait(&x.wait, &x.mtx)
76
77int max;
78int exited;
79char *dirname1;
80char *dirname2;
81
82struct file {
83	char *name;
84	STAILQ_ENTRY(file) next;
85};
86
87struct files {
88	pthread_mutex_t mtx;
89	pthread_cond_t wait;
90	STAILQ_HEAD(, file) list;
91};
92
93static struct files newfiles;
94static struct files renamedfiles;
95
96void *loop_create(void *arg __unused);
97void *loop_rename(void *arg __unused);
98void *loop_unlink(void *arg __unused);
99
100int
101main(int argc, char **argv)
102{
103	int i;
104	int rc;
105	pthread_t tid[3];
106
107	if (argc != 3)
108		errx(1, "usage: pthread_count <dirname> <max>");
109
110	asprintf(&dirname1, "%s.1", argv[1]);
111	asprintf(&dirname2, "%s.2", argv[1]);
112	if (mkdir(dirname1, 0755) == -1)
113		err(1, "mkdir(%s)", dirname1);
114	if (mkdir(dirname2, 0755) == -1)
115		err(1, "mkdir(%s)", dirname2);
116	max = atoi(argv[2]);
117
118	STAILQ_INIT(&newfiles.list);
119	STAILQ_INIT(&renamedfiles.list);
120
121	rc = pthread_mutex_init(&newfiles.mtx, NULL);
122	if (rc != 0)
123		errc(1, rc, "pthread_mutex_init()");
124	rc = pthread_cond_init(&newfiles.wait, NULL);
125	if (rc != 0)
126		errc(1, rc, "pthread_cond_init()");
127	rc = pthread_mutex_init(&renamedfiles.mtx, NULL);
128	if (rc != 0)
129		errc(1, rc, "pthread_mutex_init()");
130	rc = pthread_cond_init(&renamedfiles.wait, NULL);
131	if (rc != 0)
132		errc(1, rc, "pthread_cond_init()");
133
134	rc = pthread_create(&tid[0], NULL, loop_create, NULL);
135	if (rc != 0)
136		errc(1, rc, "pthread_create()");
137	rc = pthread_create(&tid[1], NULL, loop_rename, NULL);
138	if (rc != 0)
139		errc(1, rc, "pthread_create()");
140	rc = pthread_create(&tid[2], NULL, loop_unlink, NULL);
141	if (rc != 0)
142		errc(1, rc, "pthread_create()");
143
144	for (i = 0; i < 3; i++) {
145		rc = pthread_join(tid[i], NULL);
146		if (rc != 0)
147			errc(1, rc, "pthread_join(%d)", i);
148	}
149
150	rc = pthread_mutex_destroy(&newfiles.mtx);
151	if (rc != 0)
152		errc(1, rc, "pthread_mutex_destroy(newfiles)");
153	rc = pthread_cond_destroy(&newfiles.wait);
154	if (rc != 0)
155		errc(1, rc, "pthread_cond_destroy(newfiles)");
156	rc = pthread_mutex_destroy(&renamedfiles.mtx);
157	if (rc != 0)
158		errc(1, rc, "pthread_mutex_destroy(renamedfiles)");
159	rc = pthread_cond_destroy(&renamedfiles.wait);
160	if (rc != 0)
161		errc(1, rc, "pthread_cond_destroy(renamedfiles)");
162	rmdir(dirname1);
163	rmdir(dirname2);
164	free(dirname1);
165	free(dirname2);
166
167	exit(0);
168}
169
170void *
171loop_create(void *arg __unused)
172{
173	int i;
174	struct file *file;
175
176#ifdef __NP__
177	pthread_set_name_np(pthread_self(), __func__);
178#endif
179
180	for (i = 0; i < max; i++) {
181		file = malloc(sizeof(*file));
182		asprintf(&file->name, "%s/filename_too-long:%d", dirname1, i);
183		if (mkdir(file->name, 0666) == -1) {
184			warn("mkdir(%s)", file->name);
185			free(file->name);
186			free(file);
187			break;
188		}
189		LOCK(newfiles);
190		STAILQ_INSERT_TAIL(&newfiles.list, file, next);
191		UNLOCK(newfiles);
192		SIGNAL(newfiles);
193	}
194	exited = 1;
195	SIGNAL(newfiles);
196	pthread_exit(NULL);
197}
198
199void *
200loop_rename(void *arg __unused)
201{
202	char *filename, *newname;
203	struct file *file;
204
205#ifdef	__NP__
206	pthread_set_name_np(pthread_self(), __func__);
207#endif
208
209	for ( ;; ) {
210		LOCK(newfiles);
211		while (STAILQ_EMPTY(&newfiles.list) && exited < 1)
212			WAIT(newfiles);
213		if (STAILQ_EMPTY(&newfiles.list) && exited == 1) {
214			UNLOCK(newfiles);
215			break;
216		}
217		file = STAILQ_FIRST(&newfiles.list);
218		STAILQ_REMOVE_HEAD(&newfiles.list, next);
219		UNLOCK(newfiles);
220		filename = strrchr(file->name, '/');
221		asprintf(&newname, "%s/%s", dirname2, filename);
222		if (rename(file->name, newname) == -1)
223			err(1, "rename(%s, %s)", file->name, newname);
224		free(file->name);
225		file->name = newname;
226		LOCK(renamedfiles);
227		STAILQ_INSERT_TAIL(&renamedfiles.list, file, next);
228		UNLOCK(renamedfiles);
229		SIGNAL(renamedfiles);
230	}
231	exited = 2;
232	SIGNAL(renamedfiles);
233	pthread_exit(NULL);
234}
235
236void *
237loop_unlink(void *arg __unused)
238{
239	struct file *file;
240
241#ifdef	__NP__
242	pthread_set_name_np(pthread_self(), __func__);
243#endif
244
245	for ( ;; ) {
246		LOCK(renamedfiles);
247		while (STAILQ_EMPTY(&renamedfiles.list) && exited < 2)
248			WAIT(renamedfiles);
249		if (STAILQ_EMPTY(&renamedfiles.list) && exited == 2) {
250			UNLOCK(renamedfiles);
251			break;
252		}
253		file = STAILQ_FIRST(&renamedfiles.list);
254		STAILQ_REMOVE_HEAD(&renamedfiles.list, next);
255		UNLOCK(renamedfiles);
256		rmdir(file->name);
257		free(file->name);
258		free(file);
259	}
260	pthread_exit(NULL);
261}
262