xref: /freebsd/tools/test/stress2/misc/fifo3.sh (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
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# Demonstrate that fts_read(3) will open a fifo for read.
30# Not seen on a pristine FreeBSD.
31
32# $ while ./fifo.sh; do date; done
33# Wed Oct  1 14:07:41 CEST 2014
34# Wed Oct  1 14:09:58 CEST 2014
35# FAIL
36# $ ps -l19547
37# UID   PID  PPID CPU PRI NI   VSZ  RSS MWCHAN STAT TT     TIME COMMAND
38#   0 19547 19544   0  25  0 12176 3996 fifoor I     0  0:08.19 /tmp/fifo
39# $ gdb /tmp/fifo 19547
40# GNU gdb 6.1.1 [FreeBSD]
41# Copyright 2004 Free Software Foundation, Inc.
42# GDB is free software, covered by the GNU General Public License, and you are
43# welcome to change it and/or distribute copies of it under certain conditions.
44# Type "show copying" to see the conditions.
45# There is absolutely no warranty for GDB.  Type "show warranty" for details.
46# This GDB was configured as "amd64-marcel-freebsd"...
47# Attaching to program: /tmp/fifo, process 19547
48# Reading symbols from /lib/libc.so.7...done.
49# Loaded symbols for /lib/libc.so.7
50# Reading symbols from /libexec/ld-elf.so.1...done.
51# Loaded symbols for /libexec/ld-elf.so.1
52# 0x00000008008a9ab8 in enc_openat () from /lib/libc.so.7
53# (gdb) bt
54# #0  0x00000008008a9ab8 in enc_openat () from /lib/libc.so.7
55# #1  0x00000008008a581b in fts_read () from /lib/libc.so.7
56# #2  0x00000008008a4f24 in fts_read () from /lib/libc.so.7
57# #3  0x0000000000400ee9 in test () at /tmp/fifo.c:86
58# #4  0x0000000000400fd8 in main () at /tmp/fifo.c:108
59# (gdb) f 3
60# #3  0x0000000000400ee9 in test () at /tmp/fifo.c:86
61# 86                      while ((p = fts_read(fts)) != NULL) {
62# Current language:  auto; currently minimal
63# (gdb)
64#
65
66[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
67. ../default.cfg
68
69cat > /tmp/fifo3.c <<EOF
70#include <sys/types.h>
71#include <sys/stat.h>
72#include <sys/wait.h>
73
74#include <err.h>
75#include <errno.h>
76#include <fts.h>
77#include <stdint.h>
78#include <stdio.h>
79#include <stdlib.h>
80#include <unistd.h>
81
82#define LOOPS 50
83#define PARALLEL 4
84
85void
86tmkfifo(void)
87{
88	pid_t pid;
89	int i, j;
90	char name[80];
91
92	setproctitle(__func__);
93	pid = getpid();
94	for (j = 0; j < LOOPS; j++) {
95		for (i = 0; i < 1000; i++) {
96			snprintf(name, sizeof(name), "fifo.%d.%06d", pid, i);
97			if (mkfifo(name, 0644) == -1)
98				err(1, "mkfifo(%s)", name);
99		}
100		for (i = 0; i < 1000; i++) {
101			snprintf(name, sizeof(name), "fifo.%d.%06d", pid, i);
102			if (unlink(name) == -1)
103				err(1, "unlink(%s)", name);
104		}
105	}
106	_exit(0);
107}
108
109void
110tmkdir(void)
111{
112	pid_t pid;
113	int i, j;
114	char name[80];
115
116	setproctitle(__func__);
117	pid = getpid();
118	for (j = 0; j < LOOPS; j++) {
119		for (i = 0; i < 1000; i++) {
120			snprintf(name, sizeof(name), "dir.%d.%06d", pid, i);
121			if (mkdir(name, 0644) == -1)
122				err(1, "mkdir(%s)", name);
123		}
124		for (i = 0; i < 1000; i++) {
125			snprintf(name, sizeof(name), "dir.%d.%06d", pid, i);
126			if (rmdir(name) == -1)
127				err(1, "unlink(%s)", name);
128		}
129	}
130	_exit(0);
131}
132
133void
134test(void)
135{
136	FTS *fts;
137	FTSENT *p;
138	int ftsoptions, i;
139	char *args[2];
140
141	if (fork() == 0)
142		tmkfifo();
143	if (fork() == 0)
144		tmkdir();
145
146	ftsoptions = FTS_PHYSICAL;
147	args[0] = ".";
148	args[1] = 0;
149
150	for (i = 0; i < LOOPS; i++) {
151		if ((fts = fts_open(args, ftsoptions, NULL)) == NULL)
152			err(1, "fts_open");
153
154		while ((p = fts_read(fts)) != NULL) {
155#if defined(TEST)
156			fprintf(stdout, "%s\n", p->fts_path);
157#endif
158		}
159
160		if (errno != 0 && errno != ENOENT)
161			err(1, "fts_read");
162		if (fts_close(fts) == -1)
163			err(1, "fts_close()");
164	}
165	wait(NULL);
166	wait(NULL);
167
168	_exit(0);
169}
170
171int
172main(void)
173{
174	int i;
175
176	for (i = 0; i < PARALLEL; i++)
177		if (fork() == 0)
178			test();
179	for (i = 0; i < PARALLEL; i++)
180		wait(NULL);
181
182	return (0);
183}
184EOF
185mycc -o /tmp/fifo3 -Wall -Wextra -O0 -g /tmp/fifo3.c || exit 1
186
187mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
188[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
189
190mdconfig -a -t swap -s 1g -u $mdstart || exit 1
191newfs md$mdstart > /dev/null
192mount /dev/md$mdstart $mntpoint
193
194(cd $mntpoint; /tmp/fifo3 ) &
195
196while pgrep -q fifo3; do
197	ps -lx | grep -v grep | grep -q fifoor &&
198	    { echo FAIL; exit 1; }
199	sleep 2
200done
201
202wait
203
204while mount | grep $mntpoint | grep -q /dev/md; do
205        umount $mntpoint || sleep 1
206done
207mdconfig -d -u $mdstart
208rm /tmp/fifo3 /tmp/fifo3.c
209