xref: /freebsd/tools/test/stress2/misc/shm.sh (revision fd45b686f9d92f583366c75b22c04c7ee49709c0)
1#!/bin/sh
2
3#
4# Copyright (c) 2016 Dell EMC Isilon
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# Regression test for r310849. Hang in "vmpfw" was seen.
30
31# Test scenario suggestion by kib.
32
33[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
34
35. ../default.cfg
36
37RUNTIME=60
38old=`sysctl -n kern.ipc.shm_use_phys`
39trap "sysctl kern.ipc.shm_use_phys=$old" EXIT INT
40sysctl kern.ipc.shm_use_phys=1
41
42dir=/tmp
43odir=`pwd`
44cd $dir
45sed '1,/^EOF/d' < $odir/$0 > $dir/shm.c
46mycc -o shm -Wall -Wextra -O0 -g shm.c -pthread || exit 1
47rm -f shm.c
48
49/tmp/shm &
50
51s=0
52sleep $RUNTIME
53if pgrep -q shm; then
54	if pgrep shm | xargs ps -lHp | grep -q vmpfw; then
55		s=1
56		echo FAIL
57		pgrep shm | xargs ps -lHp
58		pkill -9 shm
59	fi
60fi
61wait
62
63rm -rf /tmp/shm
64exit $s
65
66EOF
67#include <sys/param.h>
68#include <sys/ipc.h>
69#include <sys/mman.h>
70#include <sys/shm.h>
71#include <sys/stat.h>
72#include <sys/wait.h>
73
74#include <err.h>
75#include <errno.h>
76#include <fcntl.h>
77#include <pthread.h>
78#include <pthread_np.h>
79#include <stdio.h>
80#include <stdlib.h>
81#include <time.h>
82#include <unistd.h>
83
84static void *shmp;
85static size_t len;
86static int cont, shmid;
87
88#define PAGES 64
89#define RUNTIME (1 * 60)
90#define STOP 1
91#define SYNC 0
92
93static void
94cleanup(void)
95{
96	if (shmp != MAP_FAILED)
97		shmdt(shmp);
98	if (shmid != 0)
99		shmctl(shmid, IPC_RMID, NULL);
100}
101
102static void *
103t1(void *arg __unused)
104{
105	time_t start;
106	char *cp;
107
108	pthread_set_name_np(pthread_self(), __func__);
109	start = time(NULL);
110	while (cont == 1 && (time(NULL) - start) < RUNTIME) {
111		if ((cp = mmap(NULL, len, PROT_READ | PROT_WRITE,
112		    MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
113			err(1, "mmap");
114		usleep(arc4random() % 400);
115		if (munmap(cp, len) == -1)
116			warn("unmap(%p, %zu)", shmp, len);
117	}
118
119	return (NULL);
120}
121
122static void *
123t2(void *arg __unused)
124{
125	key_t shmkey;
126	size_t i;
127	time_t start;
128	char *cp;
129
130	pthread_set_name_np(pthread_self(), __func__);
131	shmkey = ftok("/tmp", getpid());
132	start = time(NULL);
133	atexit(cleanup);
134	while ((time(NULL) - start) < RUNTIME) {
135		if ((shmid = shmget(shmkey, len, IPC_CREAT | IPC_EXCL |
136		    0640)) == -1) {
137			if (errno != ENOSPC && errno != EEXIST)
138				err(1, "shmget (%s:%d)", __FILE__, __LINE__);
139			break;
140		}
141		if ((shmp = shmat(shmid, NULL, 0)) == (void *) -1)
142			break;
143		cp = (char *)(shmp);
144		for (i = 0; i < len; i = i + PAGE_SIZE)
145			cp[i] = 1;
146		if (shmdt(shmp) == -1) {
147			if (errno != EINVAL)
148				warn("shmdt(%p)", shmp);
149		}
150		if (shmctl(shmid, IPC_RMID, NULL) == -1)
151			warn("shmctl IPC_RMID");
152		usleep(50);
153
154		shmp = MAP_FAILED;
155		shmid = 0;
156	}
157	cont = 0;
158
159	return (NULL);
160}
161
162static int
163test(void)
164{
165	pthread_t tid[2];
166	int i, rc;
167
168	shmp = MAP_FAILED;
169
170	cont = 1;
171	if ((rc = pthread_create(&tid[0], NULL, t1, NULL)) != 0)
172		errc(1, rc, "pthread_create()");
173	if ((rc = pthread_create(&tid[1], NULL, t2, NULL)) != 0)
174		errc(1, rc, "pthread_create()");
175
176	for (i = 0; i < 2; i++)
177		if ((rc = pthread_join(tid[i], NULL)) != 0)
178			errc(1, rc, "pthread_join(%d)", i);
179
180	return (0);
181}
182
183int
184main(void)
185{
186	pid_t pid;
187	time_t start;
188
189	len = PAGES * PAGE_SIZE;
190	start = time(NULL);
191	while ((time(NULL) - start) < RUNTIME) {
192		if ((pid = fork()) == 0) {
193			test();
194			exit(0);	/* calls cleanup() */
195		}
196		if (waitpid(pid, NULL,0) != pid)
197			err(1, "waitpid(%d)", pid);
198	}
199
200	return(0);
201}
202