xref: /dflybsd-src/test/stress/stress2/misc/datamove2.sh (revision 86d7f5d305c6adaa56ff4582ece9859d73106103)
186d7f5d3SJohn Marino#!/bin/sh
286d7f5d3SJohn Marino
386d7f5d3SJohn Marino#
486d7f5d3SJohn Marino# Copyright (c) 2009 Peter Holm <pho@FreeBSD.org>
586d7f5d3SJohn Marino# All rights reserved.
686d7f5d3SJohn Marino#
786d7f5d3SJohn Marino# Redistribution and use in source and binary forms, with or without
886d7f5d3SJohn Marino# modification, are permitted provided that the following conditions
986d7f5d3SJohn Marino# are met:
1086d7f5d3SJohn Marino# 1. Redistributions of source code must retain the above copyright
1186d7f5d3SJohn Marino#    notice, this list of conditions and the following disclaimer.
1286d7f5d3SJohn Marino# 2. Redistributions in binary form must reproduce the above copyright
1386d7f5d3SJohn Marino#    notice, this list of conditions and the following disclaimer in the
1486d7f5d3SJohn Marino#    documentation and/or other materials provided with the distribution.
1586d7f5d3SJohn Marino#
1686d7f5d3SJohn Marino# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1786d7f5d3SJohn Marino# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1886d7f5d3SJohn Marino# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1986d7f5d3SJohn Marino# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2086d7f5d3SJohn Marino# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2186d7f5d3SJohn Marino# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2286d7f5d3SJohn Marino# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2386d7f5d3SJohn Marino# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2486d7f5d3SJohn Marino# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2586d7f5d3SJohn Marino# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2686d7f5d3SJohn Marino# SUCH DAMAGE.
2786d7f5d3SJohn Marino#
2886d7f5d3SJohn Marino# $FreeBSD$
2986d7f5d3SJohn Marino#
3086d7f5d3SJohn Marino
3186d7f5d3SJohn Marino# Variation of the datamove.sh scenario by not using "sysctl vm.old_msync=1"
3286d7f5d3SJohn Marino
3386d7f5d3SJohn Marino# Deadlock seen
3486d7f5d3SJohn Marino
3586d7f5d3SJohn Marino# Test scenario by ups
3686d7f5d3SJohn Marino
3786d7f5d3SJohn Marinohere=`pwd`
3886d7f5d3SJohn Marinocd /tmp
3986d7f5d3SJohn Marinosed '1,/^EOF/d' < $here/$0 > dl.c
4086d7f5d3SJohn Marinocc -o dl -Wall dl.c
4186d7f5d3SJohn Marinorm -f dl.c
4286d7f5d3SJohn Marino
4386d7f5d3SJohn Marinofor i in `jot 3`; do
4486d7f5d3SJohn Marino	$here/../testcases/swap/swap -t 10m -i 200 -h &
4586d7f5d3SJohn Marino	/tmp/dl
4686d7f5d3SJohn Marino	ps | grep swap | grep -v swap | awk '{print $1}' | xargs kill
4786d7f5d3SJohn Marinodone
4886d7f5d3SJohn Marinorm -rf /tmp/dl
4986d7f5d3SJohn Marinoexit 0
5086d7f5d3SJohn MarinoEOF
5186d7f5d3SJohn Marino#include <err.h>
5286d7f5d3SJohn Marino#include <fcntl.h>
5386d7f5d3SJohn Marino#include <stdio.h>
5486d7f5d3SJohn Marino#include <stdlib.h>
5586d7f5d3SJohn Marino#include <sys/mman.h>
5686d7f5d3SJohn Marino#include <sys/stat.h>
5786d7f5d3SJohn Marino#include <sys/types.h>
5886d7f5d3SJohn Marino#include <sys/wait.h>
5986d7f5d3SJohn Marino#include <unistd.h>
6086d7f5d3SJohn Marino
6186d7f5d3SJohn Marino
6286d7f5d3SJohn Marinoint	prepareFile(char *filename, int *fdp);
6386d7f5d3SJohn Marinoint	mapBuffer  (char **bufferp, int fd1, int fd2);
6486d7f5d3SJohn Marinoint	startIO    (int fd, char *buffer);
6586d7f5d3SJohn Marino
6686d7f5d3SJohn Marinoint	pagesize;
6786d7f5d3SJohn Marino
6886d7f5d3SJohn Marino#define FILESIZE (32*1024)
6986d7f5d3SJohn Marinochar	wbuffer   [FILESIZE];
7086d7f5d3SJohn Marino
7186d7f5d3SJohn Marino/* Create a FILESIZE sized file - then remove file data from the cache */
7286d7f5d3SJohn Marinoint
7386d7f5d3SJohn MarinoprepareFile(char *filename, int *fdp)
7486d7f5d3SJohn Marino{
7586d7f5d3SJohn Marino	int	fd;
7686d7f5d3SJohn Marino	int	len;
7786d7f5d3SJohn Marino	int	status;
7886d7f5d3SJohn Marino	void	*addr;
7986d7f5d3SJohn Marino
8086d7f5d3SJohn Marino	fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
8186d7f5d3SJohn Marino	if (fd == -1) {
8286d7f5d3SJohn Marino		perror("Creating file");
8386d7f5d3SJohn Marino		return fd;
8486d7f5d3SJohn Marino	}
8586d7f5d3SJohn Marino	len = write(fd, wbuffer, FILESIZE);
8686d7f5d3SJohn Marino	if (len < 0) {
8786d7f5d3SJohn Marino		perror("Write failed");
8886d7f5d3SJohn Marino		return 1;
8986d7f5d3SJohn Marino	}
9086d7f5d3SJohn Marino	status = fsync(fd);
9186d7f5d3SJohn Marino	if (status != 0) {
9286d7f5d3SJohn Marino		perror("fsync failed");
9386d7f5d3SJohn Marino		return 1;
9486d7f5d3SJohn Marino	}
9586d7f5d3SJohn Marino	addr = mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
9686d7f5d3SJohn Marino	if (addr == MAP_FAILED) {
9786d7f5d3SJohn Marino		perror("Mmap failed");
9886d7f5d3SJohn Marino		return 1;
9986d7f5d3SJohn Marino	}
10086d7f5d3SJohn Marino	status = msync(addr, FILESIZE, MS_INVALIDATE | MS_SYNC);
10186d7f5d3SJohn Marino	if (status != 0) {
10286d7f5d3SJohn Marino		perror("Msync failed");
10386d7f5d3SJohn Marino		return 1;
10486d7f5d3SJohn Marino	}
10586d7f5d3SJohn Marino	if (munmap(addr, FILESIZE) == -1) {
10686d7f5d3SJohn Marino		perror("munmap failed");
10786d7f5d3SJohn Marino		return 1;
10886d7f5d3SJohn Marino	}
10986d7f5d3SJohn Marino
11086d7f5d3SJohn Marino	*fdp = fd;
11186d7f5d3SJohn Marino	return 0;
11286d7f5d3SJohn Marino}
11386d7f5d3SJohn Marino
11486d7f5d3SJohn Marino
11586d7f5d3SJohn Marino/* mmap a 2 page buffer - first page is from fd1, second page from fd2 */
11686d7f5d3SJohn Marinoint
11786d7f5d3SJohn MarinomapBuffer(char **bufferp, int fd1, int fd2)
11886d7f5d3SJohn Marino{
11986d7f5d3SJohn Marino	void *addr;
12086d7f5d3SJohn Marino	char *buffer;
12186d7f5d3SJohn Marino
12286d7f5d3SJohn Marino	addr = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd1, 0);
12386d7f5d3SJohn Marino	if (addr == MAP_FAILED) {
12486d7f5d3SJohn Marino		perror("Mmap failed");
12586d7f5d3SJohn Marino		return 1;
12686d7f5d3SJohn Marino	}
12786d7f5d3SJohn Marino	buffer = addr;
12886d7f5d3SJohn Marino	addr = mmap(buffer + pagesize, pagesize, PROT_READ | PROT_WRITE, MAP_FIXED |
12986d7f5d3SJohn Marino		    MAP_SHARED, fd2, 0);
13086d7f5d3SJohn Marino
13186d7f5d3SJohn Marino	if (addr == MAP_FAILED) {
13286d7f5d3SJohn Marino		perror("Mmap2 failed");
13386d7f5d3SJohn Marino		return 1;
13486d7f5d3SJohn Marino	}
13586d7f5d3SJohn Marino	*bufferp = buffer;
13686d7f5d3SJohn Marino	return 0;
13786d7f5d3SJohn Marino}
13886d7f5d3SJohn Marino
13986d7f5d3SJohn Marinovoid
14086d7f5d3SJohn MarinounmapBuffer(char *bufferp)
14186d7f5d3SJohn Marino{
14286d7f5d3SJohn Marino	if (munmap(bufferp, pagesize * 2) == -1)
14386d7f5d3SJohn Marino		err(1, "unmap 1. buffer");
14486d7f5d3SJohn Marino	if (munmap(bufferp + pagesize * 2, pagesize * 2) == -1)
14586d7f5d3SJohn Marino		err(1, "unmap 2. buffer");
14686d7f5d3SJohn Marino}
14786d7f5d3SJohn Marino
14886d7f5d3SJohn Marinoint
14986d7f5d3SJohn MarinostartIO(int fd, char *buffer)
15086d7f5d3SJohn Marino{
15186d7f5d3SJohn Marino	ssize_t	len;
15286d7f5d3SJohn Marino
15386d7f5d3SJohn Marino	len = write(fd, buffer, 2 * pagesize);
15486d7f5d3SJohn Marino	if (len == -1) {
15586d7f5d3SJohn Marino		perror("write failed");
15686d7f5d3SJohn Marino		return 1;
15786d7f5d3SJohn Marino	}
15886d7f5d3SJohn Marino	return 0;
15986d7f5d3SJohn Marino}
16086d7f5d3SJohn Marino
16186d7f5d3SJohn Marino
16286d7f5d3SJohn Marinoint
16386d7f5d3SJohn Marinomain(int argc, char *argv[], char *envp[])
16486d7f5d3SJohn Marino{
16586d7f5d3SJohn Marino
16686d7f5d3SJohn Marino	int	fdA, fdB, fdDelayA, fdDelayB;
16786d7f5d3SJohn Marino	int	status;
16886d7f5d3SJohn Marino	int	i;
16986d7f5d3SJohn Marino	char	*bufferA, *bufferB;
17086d7f5d3SJohn Marino	pid_t	pid;
17186d7f5d3SJohn Marino
17286d7f5d3SJohn Marino	pagesize = getpagesize();
17386d7f5d3SJohn Marino
17486d7f5d3SJohn Marino	for (i = 0; i < 1000; i++) {
17586d7f5d3SJohn Marino		if ((prepareFile("A", &fdA))
17686d7f5d3SJohn Marino		    || (prepareFile("B", &fdB))
17786d7f5d3SJohn Marino		    || (prepareFile("DelayA", &fdDelayA))
17886d7f5d3SJohn Marino		    || (prepareFile("DelayB", &fdDelayB))
17986d7f5d3SJohn Marino		    || (mapBuffer(&bufferA, fdDelayA, fdB))
18086d7f5d3SJohn Marino		    || (mapBuffer(&bufferB, fdDelayB, fdA)))
18186d7f5d3SJohn Marino			exit(1);
18286d7f5d3SJohn Marino
18386d7f5d3SJohn Marino		pid = fork();
18486d7f5d3SJohn Marino
18586d7f5d3SJohn Marino		if (pid == 0) {
18686d7f5d3SJohn Marino			status = startIO(fdA, bufferA);
18786d7f5d3SJohn Marino			exit(status);
18886d7f5d3SJohn Marino		}
18986d7f5d3SJohn Marino		if (pid == -1) {
19086d7f5d3SJohn Marino			perror("fork");
19186d7f5d3SJohn Marino			exit(1);
19286d7f5d3SJohn Marino		}
19386d7f5d3SJohn Marino		status = startIO(fdB, bufferB);
19486d7f5d3SJohn Marino		if (wait(&status) == -1)
19586d7f5d3SJohn Marino			err(1, "wait");
19686d7f5d3SJohn Marino
19786d7f5d3SJohn Marino		close(fdA);
19886d7f5d3SJohn Marino		close(fdB);
19986d7f5d3SJohn Marino		close(fdDelayA);
20086d7f5d3SJohn Marino		close(fdDelayB);
20186d7f5d3SJohn Marino		unmapBuffer(bufferA);
20286d7f5d3SJohn Marino		unmapBuffer(bufferB);
20386d7f5d3SJohn Marino		unlink("A");
20486d7f5d3SJohn Marino		unlink("B");
20586d7f5d3SJohn Marino		unlink("DelayA");
20686d7f5d3SJohn Marino		unlink("DelayB");
20786d7f5d3SJohn Marino	}
20886d7f5d3SJohn Marino	exit(status);
20986d7f5d3SJohn Marino
21086d7f5d3SJohn Marino}
211