xref: /freebsd/tools/test/stress2/misc/datamove4.sh (revision 2e3507c25e42292b45a5482e116d278f5515d04d)
1#!/bin/sh
2
3#
4# Copyright (c) 2012 Peter Holm <pho@FreeBSD.org>
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# Variation of the datamove2.sh, using TMPFS
30# Deadlock seen
31# https://people.freebsd.org/~pho/stress/log/datamove4.txt
32
33# panic: elf32_putnote: Note type 10 changed as we read it (2236 > 2220)...
34# https://people.freebsd.org/~pho/stress/log/datamove4-2.txt
35# Fixed by r288944.
36
37[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
38
39. ../default.cfg
40
41here=`pwd`
42cd /tmp
43sed '1,/^EOF/d' < $here/$0 > datamove4.c
44mycc -o datamove4 -Wall -Wextra -O2 -g datamove4.c
45rm -f datamove4.c
46
47mount | grep -q "$mntpoint " && umount $mntpoint
48mount -t tmpfs tmpfs $mntpoint
49chmod 777 $mntpoint
50
51for i in `jot 5`; do
52	su $testuser -c "cd $mntpoint; /tmp/datamove4"
53done
54while mount | grep -q $mntpoint; do
55	umount -f $mntpoint > /dev/null 2>&1
56done
57
58rm -rf /tmp/datamove4
59exit 0
60EOF
61/*-
62 * Copyright (c) 2006, Stephan Uphoff <ups@freebsd.org>
63 * All rights reserved.
64 *
65 * Redistribution and use in source and binary forms, with or without
66 * modification, are permitted provided that the following conditions
67 * are met:
68 * 1. Redistributions of source code must retain the above copyright
69 *    notice unmodified, this list of conditions, and the following
70 *    disclaimer.
71 * 2. Redistributions in binary form must reproduce the above copyright
72 *    notice, this list of conditions and the following disclaimer in the
73 *    documentation and/or other materials provided with the distribution.
74 *
75 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
76 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
77 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
78 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
79 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
80 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
81 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
82 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
83 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
84 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
85 */
86
87#include <err.h>
88#include <fcntl.h>
89#include <stdio.h>
90#include <stdlib.h>
91#include <sys/mman.h>
92#include <sys/stat.h>
93#include <sys/types.h>
94#include <sys/wait.h>
95#include <unistd.h>
96
97int	prepareFile(char *filename, int *fdp);
98int	mapBuffer  (char **bufferp, int fd1, int fd2);
99int	startIO    (int fd, char *buffer);
100
101int	pagesize;
102
103#define FILESIZE (32*1024)
104char	wbuffer   [FILESIZE];
105
106/* Create a FILESIZE sized file - then remove file data from the cache */
107int
108prepareFile(char *filename, int *fdp)
109{
110	int	fd;
111	int	len;
112	int	status;
113	void	*addr;
114
115	fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
116	if (fd == -1) {
117		perror(filename);
118		return fd;
119	}
120	len = write(fd, wbuffer, FILESIZE);
121	if (len < 0) {
122		perror("Write failed");
123		return 1;
124	}
125	status = fsync(fd);
126	if (status != 0) {
127		perror("fsync failed");
128		return 1;
129	}
130	addr = mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
131	if (addr == MAP_FAILED) {
132		perror("Mmap failed");
133		return 1;
134	}
135	status = msync(addr, FILESIZE, MS_INVALIDATE | MS_SYNC);
136	if (status != 0) {
137		perror("Msync failed");
138		return 1;
139	}
140	if (munmap(addr, FILESIZE) == -1) {
141		perror("munmap failed");
142		return 1;
143	}
144
145	*fdp = fd;
146	return 0;
147}
148
149/* mmap a 2 page buffer - first page is from fd1, second page from fd2 */
150int
151mapBuffer(char **bufferp, int fd1, int fd2)
152{
153	void *addr;
154	char *buffer;
155
156	addr = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd1, 0);
157	if (addr == MAP_FAILED) {
158		perror("Mmap failed");
159		return 1;
160	}
161	buffer = addr;
162	addr = mmap(buffer + pagesize, pagesize, PROT_READ | PROT_WRITE, MAP_FIXED |
163		    MAP_SHARED, fd2, 0);
164
165	if (addr == MAP_FAILED) {
166		perror("Mmap2 failed");
167		return 1;
168	}
169	*bufferp = buffer;
170	return 0;
171}
172
173void
174unmapBuffer(char *bufferp)
175{
176	if (munmap(bufferp, pagesize * 2) == -1)
177		err(1, "unmap 1. buffer");
178	/*
179	   The following unmaps something random, which could trigger:
180	   Program received signal SIGSEGV, Segmentation fault.
181	   free (cp=0x28070000) at /usr/src/libexec/rtld-elf/malloc.c:311
182	*/
183
184#if 0
185	if (munmap(bufferp + pagesize * 2, pagesize * 2) == -1)
186		err(1, "unmap 2. buffer");
187#endif
188}
189
190int
191startIO(int fd, char *buffer)
192{
193	ssize_t	len;
194
195	len = write(fd, buffer, 2 * pagesize);
196	if (len == -1) {
197		perror("write failed");
198		return 1;
199	}
200	return 0;
201}
202
203int
204main()
205{
206
207	int	fdA, fdB, fdDelayA, fdDelayB;
208	int	status;
209	int	i;
210	char	*bufferA, *bufferB;
211	pid_t	pid;
212
213	pagesize = getpagesize();
214
215	for (i = 0; i < 1000; i++) {
216		if ((prepareFile("A", &fdA))
217		    || (prepareFile("B", &fdB))
218		    || (prepareFile("DelayA", &fdDelayA))
219		    || (prepareFile("DelayB", &fdDelayB))
220		    || (mapBuffer(&bufferA, fdDelayA, fdB))
221		    || (mapBuffer(&bufferB, fdDelayB, fdA)))
222			exit(1);
223
224		pid = fork();
225
226		if (pid == 0) {
227			status = startIO(fdA, bufferA);
228			exit(status);
229		}
230		if (pid == -1) {
231			perror("fork");
232			exit(1);
233		}
234		status = startIO(fdB, bufferB);
235		if (wait(&status) == -1)
236			err(1, "wait");
237
238		close(fdA);
239		close(fdB);
240		close(fdDelayA);
241		close(fdDelayB);
242		unmapBuffer(bufferA);
243		unmapBuffer(bufferB);
244		unlink("A");
245		unlink("B");
246		unlink("DelayA");
247		unlink("DelayB");
248	}
249	exit(status);
250
251}
252