xref: /freebsd/tools/test/stress2/misc/umountf7.sh (revision 2dd83b3f0507fc7bc64b908fb88f285a3b9663c8)
1#!/bin/sh
2
3#
4# Copyright (c) 2013 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# "panic: handle_written_inodeblock: live inodedep 0xcc731200" seen.
30# http://people.freebsd.org/~pho/stress/log/umountf7.txt
31# https://people.freebsd.org/~pho/stress/log/kostik824.txt
32# Problem only seen with SU+J.
33
34[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
35
36. ../default.cfg
37
38dir=/tmp
39odir=`pwd`
40cd $dir
41sed '1,/^EOF/d' < $odir/$0 > $dir/umountf7.c
42mycc -o umountf7  -Wall -Wextra umountf7.c -lpthread || exit 1
43rm -f umountf7.c
44cd $odir
45
46mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
47mdconfig -l | grep -q md$mdstart &&  mdconfig -d -u $mdstart
48mdconfig -a -t swap -s 3g -u $mdstart || exit 1
49[ "$newfs_flags" = "-U" ] && opt="-j"
50newfs $opt md$mdstart > /dev/null
51mount /dev/md$mdstart $mntpoint
52
53daemon sh -c '(cd ../testcases/swap; ./swap -t 2m -i 4)'
54parallel=4
55for j in `jot $parallel`; do
56	[ -d $mntpoint/$j ] || mkdir $mntpoint/$j
57done
58for j in `jot $parallel`; do
59	(cd $mntpoint/$j; /tmp/umountf7 100000) &
60done
61sleep 30
62umount -f $mntpoint
63pkill umountf7
64wait
65while pkill -9 swap; do
66	:
67done
68find $mntpoint -type f
69
70while mount | grep "on $mntpoint " | grep -q /dev/md; do
71	umount $mntpoint || sleep 1
72done
73mdconfig -d -u $mdstart
74rm -f /tmp/umountf7
75exit
76
77EOF
78#include <err.h>
79#include <fcntl.h>
80#include <pthread.h>
81#include <stdio.h>
82#include <stdlib.h>
83#include <unistd.h>
84
85pid_t pid;
86volatile int n, n2;
87int mx;
88
89void *
90cr(void *arg __unused)
91{
92	char file[80];
93	int fd, i;
94
95	for (i = 0; i < mx; i++) {
96		snprintf(file, sizeof(file), "f%06d.%06d", pid, i);
97		if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0)
98			err(1, "open(%s)", file);
99		close(fd);
100		n++;
101	}
102        return (0);
103
104}
105
106void *
107mv(void *arg __unused)
108{
109	char from[80], to[80];
110	int i;
111
112	for (i = 0; i < mx; i++) {
113		while (n == -1 || i > n)
114			pthread_yield();
115		snprintf(from, sizeof(from), "f%06d.%06d", pid, i);
116		snprintf(to  , sizeof(to  ), "g%06d.%06d", pid, i);
117		if (rename(from, to) == -1)
118			warn("rename(%s, %s)", from, to);
119		n2++;
120	}
121
122        return (0);
123}
124
125void *
126rm(void *arg __unused)
127{
128	char file[80];
129	int i;
130
131	for (i = 0; i < mx; i++) {
132		while (n2 == -1 || i > n2)
133			pthread_yield();
134		snprintf(file, sizeof(file), "g%06d.%06d", pid, i);
135		if (unlink(file) == -1)
136			warn("unlink(%s)", file);
137	}
138
139        return (0);
140}
141
142int
143main(int argc, char **argv)
144{
145        pthread_t rp[3];
146	int e, i;
147
148	if (argc != 2)
149		errx(1, "Usage: %s <number of files>", argv[0]);
150	mx = atoi(argv[1]);
151	n = n2 = -1;
152	pid = getpid();
153
154	if ((e = pthread_create(&rp[0], NULL, cr, NULL)) != 0)
155		errc(1, e, "pthread_create");
156	usleep(arc4random() % 1000);
157	if ((e = pthread_create(&rp[1], NULL, mv, NULL)) != 0)
158		errc(1, e, "pthread_mv");
159	usleep(arc4random() % 1000);
160	if ((e = pthread_create(&rp[2], NULL, rm, NULL)) != 0)
161		errc(1, e, "pthread_rm");
162
163        for (i = 0; i < 3; i++)
164                pthread_join(rp[i], NULL);
165
166	return (0);
167}
168