xref: /freebsd/tools/test/stress2/misc/suj30.sh (revision a25818eb2869ccc56bd711eca14cd7bbbaddd676)
18a272653SPeter Holm#!/bin/sh
28a272653SPeter Holm
38a272653SPeter Holm#
48a272653SPeter Holm# Copyright (c) 2012 Peter Holm <pho@FreeBSD.org>
58a272653SPeter Holm# All rights reserved.
68a272653SPeter Holm#
78a272653SPeter Holm# Redistribution and use in source and binary forms, with or without
88a272653SPeter Holm# modification, are permitted provided that the following conditions
98a272653SPeter Holm# are met:
108a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright
118a272653SPeter Holm#    notice, this list of conditions and the following disclaimer.
128a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright
138a272653SPeter Holm#    notice, this list of conditions and the following disclaimer in the
148a272653SPeter Holm#    documentation and/or other materials provided with the distribution.
158a272653SPeter Holm#
168a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
178a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
188a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
198a272653SPeter Holm# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
208a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
218a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
228a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
238a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
248a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
258a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
268a272653SPeter Holm# SUCH DAMAGE.
278a272653SPeter Holm#
288a272653SPeter Holm
298a272653SPeter Holm# SUJ rename test scenario by Andrey Zonov <zont@FreeBSD.org>
308a272653SPeter Holm# "panic: flush_pagedep_deps: MKDIR_PARENT" seen:
318a272653SPeter Holm# http://people.freebsd.org/~pho/stress/log/suj30.txt
328a272653SPeter Holm
33*a25818ebSPeter Holm# Hang seen: https://people.freebsd.org/~pho/stress/log/log0337.txt
34*a25818ebSPeter Holm
358a272653SPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
368a272653SPeter Holm
378a272653SPeter Holm. ../default.cfg
388a272653SPeter Holm
398a272653SPeter Holmhere=`pwd`
408a272653SPeter Holmcd /tmp
418a272653SPeter Holmsed '1,/^EOF/d' < $here/$0 > suj30.c
428a272653SPeter Holmmycc -o suj30 -Wall -Wextra -O2 suj30.c -lpthread
438a272653SPeter Holmrm -f suj30.c
448a272653SPeter Holm
458a272653SPeter Holmmount | grep "on $mntpoint " | grep -q md$mdstart && umount $mntpoint
468a272653SPeter Holmmdconfig -l | grep -q md$mdstart &&  mdconfig -d -u $mdstart
478a272653SPeter Holm
488a272653SPeter Holmmdconfig -a -t swap -s 4g -u $mdstart
49608c97bfSPeter Holmnewfs -j md$mdstart > /dev/null
50608c97bfSPeter Holmmount /dev/md$mdstart $mntpoint
518a272653SPeter Holmchmod 777 $mntpoint
528a272653SPeter Holm
538a272653SPeter Holmfor i in `jot 10`; do
548a272653SPeter Holm	/tmp/suj30 $mntpoint/test-$i 100000 &
558a272653SPeter Holmdone
568a272653SPeter Holmwait
578a272653SPeter Holm
588a272653SPeter Holmwhile mount | grep -q $mntpoint; do
598a272653SPeter Holm	umount $mntpoint || sleep 1
608a272653SPeter Holmdone
618a272653SPeter Holmmdconfig -d -u $mdstart
628a272653SPeter Holmrm -f /tmp/suj30
638a272653SPeter Holmexit 0
648a272653SPeter HolmEOF
658a272653SPeter Holm/*
668a272653SPeter Holm * Andrey Zonov (c) 2012
678a272653SPeter Holm *
688a272653SPeter Holm * compile as `cc -o rename rename.c -lpthread'
698a272653SPeter Holm */
708a272653SPeter Holm
718a272653SPeter Holm#include <sys/types.h>
728a272653SPeter Holm#include <sys/stat.h>
738a272653SPeter Holm#include <sys/time.h>
748a272653SPeter Holm#include <sys/queue.h>
758a272653SPeter Holm#include <err.h>
768a272653SPeter Holm#include <errno.h>
778a272653SPeter Holm#include <fcntl.h>
788a272653SPeter Holm#include <pthread.h>
798a272653SPeter Holm#ifdef __FreeBSD__
808a272653SPeter Holm#include <pthread_np.h>
818a272653SPeter Holm#define	__NP__
828a272653SPeter Holm#endif
838a272653SPeter Holm#include <sched.h>
848a272653SPeter Holm#include <stdio.h>
858a272653SPeter Holm#include <stdlib.h>
868a272653SPeter Holm#include <string.h>
878a272653SPeter Holm#include <time.h>
888a272653SPeter Holm#include <unistd.h>
898a272653SPeter Holm
908a272653SPeter Holm#define	LOCK(x)		pthread_mutex_lock(&x.mtx)
918a272653SPeter Holm#define	UNLOCK(x)	pthread_mutex_unlock(&x.mtx)
928a272653SPeter Holm#define	SIGNAL(x)	pthread_cond_signal(&x.wait)
938a272653SPeter Holm#define	WAIT(x)		pthread_cond_wait(&x.wait, &x.mtx)
948a272653SPeter Holm
958a272653SPeter Holmint max;
968a272653SPeter Holmint exited;
978a272653SPeter Holmchar *dirname1;
988a272653SPeter Holmchar *dirname2;
998a272653SPeter Holm
1008a272653SPeter Holmstruct file {
1018a272653SPeter Holm	char *name;
1028a272653SPeter Holm	STAILQ_ENTRY(file) next;
1038a272653SPeter Holm};
1048a272653SPeter Holm
1058a272653SPeter Holmstruct files {
1068a272653SPeter Holm	pthread_mutex_t mtx;
1078a272653SPeter Holm	pthread_cond_t wait;
1088a272653SPeter Holm	STAILQ_HEAD(, file) list;
1098a272653SPeter Holm};
1108a272653SPeter Holm
1118a272653SPeter Holmstatic struct files newfiles;
1128a272653SPeter Holmstatic struct files renamedfiles;
1138a272653SPeter Holm
1148a272653SPeter Holmvoid *loop_create(void *arg __unused);
1158a272653SPeter Holmvoid *loop_rename(void *arg __unused);
1168a272653SPeter Holmvoid *loop_unlink(void *arg __unused);
1178a272653SPeter Holm
1188a272653SPeter Holmint
1198a272653SPeter Holmmain(int argc, char **argv)
1208a272653SPeter Holm{
1218a272653SPeter Holm	int i;
1228a272653SPeter Holm	int rc;
1238a272653SPeter Holm	pthread_t tid[3];
1248a272653SPeter Holm
1258a272653SPeter Holm	if (argc != 3)
1268a272653SPeter Holm		errx(1, "usage: pthread_count <dirname> <max>");
1278a272653SPeter Holm
1288a272653SPeter Holm	asprintf(&dirname1, "%s.1", argv[1]);
1298a272653SPeter Holm	asprintf(&dirname2, "%s.2", argv[1]);
1308a272653SPeter Holm	if (mkdir(dirname1, 0755) == -1)
1318a272653SPeter Holm		err(1, "mkdir(%s)", dirname1);
1328a272653SPeter Holm	if (mkdir(dirname2, 0755) == -1)
1338a272653SPeter Holm		err(1, "mkdir(%s)", dirname2);
1348a272653SPeter Holm	max = atoi(argv[2]);
1358a272653SPeter Holm
1368a272653SPeter Holm	STAILQ_INIT(&newfiles.list);
1378a272653SPeter Holm	STAILQ_INIT(&renamedfiles.list);
1388a272653SPeter Holm
1398a272653SPeter Holm	rc = pthread_mutex_init(&newfiles.mtx, NULL);
1408a272653SPeter Holm	if (rc != 0)
1418a272653SPeter Holm		errc(1, rc, "pthread_mutex_init()");
1428a272653SPeter Holm	rc = pthread_cond_init(&newfiles.wait, NULL);
1438a272653SPeter Holm	if (rc != 0)
1448a272653SPeter Holm		errc(1, rc, "pthread_cond_init()");
1458a272653SPeter Holm	rc = pthread_mutex_init(&renamedfiles.mtx, NULL);
1468a272653SPeter Holm	if (rc != 0)
1478a272653SPeter Holm		errc(1, rc, "pthread_mutex_init()");
1488a272653SPeter Holm	rc = pthread_cond_init(&renamedfiles.wait, NULL);
1498a272653SPeter Holm	if (rc != 0)
1508a272653SPeter Holm		errc(1, rc, "pthread_cond_init()");
1518a272653SPeter Holm
1528a272653SPeter Holm	rc = pthread_create(&tid[0], NULL, loop_create, NULL);
1538a272653SPeter Holm	if (rc != 0)
1548a272653SPeter Holm		errc(1, rc, "pthread_create()");
1558a272653SPeter Holm	rc = pthread_create(&tid[1], NULL, loop_rename, NULL);
1568a272653SPeter Holm	if (rc != 0)
1578a272653SPeter Holm		errc(1, rc, "pthread_create()");
1588a272653SPeter Holm	rc = pthread_create(&tid[2], NULL, loop_unlink, NULL);
1598a272653SPeter Holm	if (rc != 0)
1608a272653SPeter Holm		errc(1, rc, "pthread_create()");
1618a272653SPeter Holm
1628a272653SPeter Holm	for (i = 0; i < 3; i++) {
1638a272653SPeter Holm		rc = pthread_join(tid[i], NULL);
1648a272653SPeter Holm		if (rc != 0)
1658a272653SPeter Holm			errc(1, rc, "pthread_join(%d)", i);
1668a272653SPeter Holm	}
1678a272653SPeter Holm
1688a272653SPeter Holm	rc = pthread_mutex_destroy(&newfiles.mtx);
1698a272653SPeter Holm	if (rc != 0)
1708a272653SPeter Holm		errc(1, rc, "pthread_mutex_destroy(newfiles)");
1718a272653SPeter Holm	rc = pthread_cond_destroy(&newfiles.wait);
1728a272653SPeter Holm	if (rc != 0)
1738a272653SPeter Holm		errc(1, rc, "pthread_cond_destroy(newfiles)");
1748a272653SPeter Holm	rc = pthread_mutex_destroy(&renamedfiles.mtx);
1758a272653SPeter Holm	if (rc != 0)
1768a272653SPeter Holm		errc(1, rc, "pthread_mutex_destroy(renamedfiles)");
1778a272653SPeter Holm	rc = pthread_cond_destroy(&renamedfiles.wait);
1788a272653SPeter Holm	if (rc != 0)
1798a272653SPeter Holm		errc(1, rc, "pthread_cond_destroy(renamedfiles)");
1808a272653SPeter Holm	rmdir(dirname1);
1818a272653SPeter Holm	rmdir(dirname2);
1828a272653SPeter Holm	free(dirname1);
1838a272653SPeter Holm	free(dirname2);
1848a272653SPeter Holm
1858a272653SPeter Holm	exit(0);
1868a272653SPeter Holm}
1878a272653SPeter Holm
1888a272653SPeter Holmvoid *
1898a272653SPeter Holmloop_create(void *arg __unused)
1908a272653SPeter Holm{
1918a272653SPeter Holm	int i;
1928a272653SPeter Holm	struct file *file;
1938a272653SPeter Holm
1948a272653SPeter Holm#ifdef __NP__
1958a272653SPeter Holm	pthread_set_name_np(pthread_self(), __func__);
1968a272653SPeter Holm#endif
1978a272653SPeter Holm
1988a272653SPeter Holm	for (i = 0; i < max; i++) {
1998a272653SPeter Holm		file = malloc(sizeof(*file));
2008a272653SPeter Holm		asprintf(&file->name, "%s/filename_too-long:%d", dirname1, i);
2018a272653SPeter Holm		if (mkdir(file->name, 0666) == -1) {
2028a272653SPeter Holm			warn("mkdir(%s)", file->name);
2038a272653SPeter Holm			free(file->name);
2048a272653SPeter Holm			free(file);
2058a272653SPeter Holm			break;
2068a272653SPeter Holm		}
2078a272653SPeter Holm		LOCK(newfiles);
2088a272653SPeter Holm		STAILQ_INSERT_TAIL(&newfiles.list, file, next);
2098a272653SPeter Holm		UNLOCK(newfiles);
2108a272653SPeter Holm		SIGNAL(newfiles);
2118a272653SPeter Holm	}
2128a272653SPeter Holm	exited = 1;
2138a272653SPeter Holm	SIGNAL(newfiles);
2148a272653SPeter Holm	pthread_exit(NULL);
2158a272653SPeter Holm}
2168a272653SPeter Holm
2178a272653SPeter Holmvoid *
2188a272653SPeter Holmloop_rename(void *arg __unused)
2198a272653SPeter Holm{
2208a272653SPeter Holm	char *filename, *newname;
2218a272653SPeter Holm	struct file *file;
2228a272653SPeter Holm
2238a272653SPeter Holm#ifdef	__NP__
2248a272653SPeter Holm	pthread_set_name_np(pthread_self(), __func__);
2258a272653SPeter Holm#endif
2268a272653SPeter Holm
2278a272653SPeter Holm	for ( ;; ) {
2288a272653SPeter Holm		LOCK(newfiles);
2298a272653SPeter Holm		while (STAILQ_EMPTY(&newfiles.list) && exited < 1)
2308a272653SPeter Holm			WAIT(newfiles);
2318a272653SPeter Holm		if (STAILQ_EMPTY(&newfiles.list) && exited == 1) {
2328a272653SPeter Holm			UNLOCK(newfiles);
2338a272653SPeter Holm			break;
2348a272653SPeter Holm		}
2358a272653SPeter Holm		file = STAILQ_FIRST(&newfiles.list);
2368a272653SPeter Holm		STAILQ_REMOVE_HEAD(&newfiles.list, next);
2378a272653SPeter Holm		UNLOCK(newfiles);
2388a272653SPeter Holm		filename = strrchr(file->name, '/');
2398a272653SPeter Holm		asprintf(&newname, "%s/%s", dirname2, filename);
2408a272653SPeter Holm		if (rename(file->name, newname) == -1)
2418a272653SPeter Holm			err(1, "rename(%s, %s)", file->name, newname);
2428a272653SPeter Holm		free(file->name);
2438a272653SPeter Holm		file->name = newname;
2448a272653SPeter Holm		LOCK(renamedfiles);
2458a272653SPeter Holm		STAILQ_INSERT_TAIL(&renamedfiles.list, file, next);
2468a272653SPeter Holm		UNLOCK(renamedfiles);
2478a272653SPeter Holm		SIGNAL(renamedfiles);
2488a272653SPeter Holm	}
2498a272653SPeter Holm	exited = 2;
2508a272653SPeter Holm	SIGNAL(renamedfiles);
2518a272653SPeter Holm	pthread_exit(NULL);
2528a272653SPeter Holm}
2538a272653SPeter Holm
2548a272653SPeter Holmvoid *
2558a272653SPeter Holmloop_unlink(void *arg __unused)
2568a272653SPeter Holm{
2578a272653SPeter Holm	struct file *file;
2588a272653SPeter Holm
2598a272653SPeter Holm#ifdef	__NP__
2608a272653SPeter Holm	pthread_set_name_np(pthread_self(), __func__);
2618a272653SPeter Holm#endif
2628a272653SPeter Holm
2638a272653SPeter Holm	for ( ;; ) {
2648a272653SPeter Holm		LOCK(renamedfiles);
2658a272653SPeter Holm		while (STAILQ_EMPTY(&renamedfiles.list) && exited < 2)
2668a272653SPeter Holm			WAIT(renamedfiles);
2678a272653SPeter Holm		if (STAILQ_EMPTY(&renamedfiles.list) && exited == 2) {
2688a272653SPeter Holm			UNLOCK(renamedfiles);
2698a272653SPeter Holm			break;
2708a272653SPeter Holm		}
2718a272653SPeter Holm		file = STAILQ_FIRST(&renamedfiles.list);
2728a272653SPeter Holm		STAILQ_REMOVE_HEAD(&renamedfiles.list, next);
2738a272653SPeter Holm		UNLOCK(renamedfiles);
2748a272653SPeter Holm		rmdir(file->name);
2758a272653SPeter Holm		free(file->name);
2768a272653SPeter Holm		free(file);
2778a272653SPeter Holm	}
2788a272653SPeter Holm	pthread_exit(NULL);
2798a272653SPeter Holm}
280