xref: /dflybsd-src/test/stress/stress2/misc/datamove3.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# Threaded variation of datamove.sh
3286d7f5d3SJohn Marino
3386d7f5d3SJohn Marino# Based on a test scenario by ups and suggestions by kib
3486d7f5d3SJohn Marino
3586d7f5d3SJohn Marino[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
3686d7f5d3SJohn Marino
3786d7f5d3SJohn Marinohere=`pwd`
3886d7f5d3SJohn Marinocd /tmp
3986d7f5d3SJohn Marinosed '1,/^EOF/d' < $here/$0 > dl.c
4086d7f5d3SJohn Marinocc -o dl -Wall dl.c -lpthread
4186d7f5d3SJohn Marinorm -f dl.c
4286d7f5d3SJohn Marino
4386d7f5d3SJohn Marinon=5
4486d7f5d3SJohn Marinoold=`sysctl vm.old_msync | awk '{print $NF}'`
4586d7f5d3SJohn Marinosysctl vm.old_msync=1
4686d7f5d3SJohn Marinofor i in `jot $n`; do
4786d7f5d3SJohn Marino	mkdir -p /tmp/dl.dir.$i
4886d7f5d3SJohn Marino	cd /tmp/dl.dir.$i
4986d7f5d3SJohn Marino	/tmp/dl &
5086d7f5d3SJohn Marinodone
5186d7f5d3SJohn Marinocd /tmp
5286d7f5d3SJohn Marinofor i in `jot $n`; do
5386d7f5d3SJohn Marino	wait
5486d7f5d3SJohn Marinodone
5586d7f5d3SJohn Marinofor i in `jot $n`; do
5686d7f5d3SJohn Marino	rm -rf /tmp/dl.dir.$i
5786d7f5d3SJohn Marinodone
5886d7f5d3SJohn Marinosysctl vm.old_msync=$old
5986d7f5d3SJohn Marino
6086d7f5d3SJohn Marinorm -rf /tmp/dl
6186d7f5d3SJohn Marinoexit 0
6286d7f5d3SJohn MarinoEOF
6386d7f5d3SJohn Marino#include <err.h>
6486d7f5d3SJohn Marino#include <fcntl.h>
6586d7f5d3SJohn Marino#include <pthread.h>
6686d7f5d3SJohn Marino#include <stdio.h>
6786d7f5d3SJohn Marino#include <stdio.h>
6886d7f5d3SJohn Marino#include <stdlib.h>
6986d7f5d3SJohn Marino#include <string.h>
7086d7f5d3SJohn Marino#include <sys/mman.h>
7186d7f5d3SJohn Marino#include <sys/stat.h>
7286d7f5d3SJohn Marino#include <sys/types.h>
7386d7f5d3SJohn Marino#include <unistd.h>
7486d7f5d3SJohn Marino
7586d7f5d3SJohn Marinostruct args {
7686d7f5d3SJohn Marino	char *bp;
7786d7f5d3SJohn Marino	int fd1;
7886d7f5d3SJohn Marino	int fd2;
7986d7f5d3SJohn Marino} a[2];
8086d7f5d3SJohn Marino
8186d7f5d3SJohn Marinoint prepareFile(char *, int *);
8286d7f5d3SJohn Marinovoid * mapBuffer(void *);
8386d7f5d3SJohn Marinoint startIO(int, char *);
8486d7f5d3SJohn Marino
8586d7f5d3SJohn Marinoint pagesize;
8686d7f5d3SJohn Marino
8786d7f5d3SJohn Marino#define FILESIZE (32*1024)
8886d7f5d3SJohn Marinochar wbuffer   [FILESIZE];
8986d7f5d3SJohn Marino
9086d7f5d3SJohn Marino/* Create a FILESIZE sized file - then remove file data from the cache */
9186d7f5d3SJohn Marinoint
9286d7f5d3SJohn MarinoprepareFile(char *filename, int *fdp)
9386d7f5d3SJohn Marino{
9486d7f5d3SJohn Marino	int fd;
9586d7f5d3SJohn Marino	int len;
9686d7f5d3SJohn Marino	int status;
9786d7f5d3SJohn Marino	void *addr;
9886d7f5d3SJohn Marino
9986d7f5d3SJohn Marino	fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU);
10086d7f5d3SJohn Marino	if (fd == -1) {
10186d7f5d3SJohn Marino		perror("Creating file");
10286d7f5d3SJohn Marino		return fd;
10386d7f5d3SJohn Marino	}
10486d7f5d3SJohn Marino	len = write(fd, wbuffer, FILESIZE);
10586d7f5d3SJohn Marino	if (len < 0) {
10686d7f5d3SJohn Marino		perror("Write failed");
10786d7f5d3SJohn Marino		return 1;
10886d7f5d3SJohn Marino	}
10986d7f5d3SJohn Marino	status = fsync(fd);
11086d7f5d3SJohn Marino	if (status != 0) {
11186d7f5d3SJohn Marino		perror("fsync failed");
11286d7f5d3SJohn Marino		return 1;
11386d7f5d3SJohn Marino	}
11486d7f5d3SJohn Marino	addr = mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
11586d7f5d3SJohn Marino	if (addr == MAP_FAILED) {
11686d7f5d3SJohn Marino		perror("Mmap failed");
11786d7f5d3SJohn Marino		return 1;
11886d7f5d3SJohn Marino	}
11986d7f5d3SJohn Marino	status = msync(addr, FILESIZE, MS_INVALIDATE | MS_SYNC);
12086d7f5d3SJohn Marino	if (status != 0) {
12186d7f5d3SJohn Marino		perror("Msync failed");
12286d7f5d3SJohn Marino		return 1;
12386d7f5d3SJohn Marino	}
12486d7f5d3SJohn Marino	munmap(addr, FILESIZE);
12586d7f5d3SJohn Marino
12686d7f5d3SJohn Marino	*fdp = fd;
12786d7f5d3SJohn Marino	return 0;
12886d7f5d3SJohn Marino}
12986d7f5d3SJohn Marino
13086d7f5d3SJohn Marino
13186d7f5d3SJohn Marino/* mmap a 2 page buffer - first page is from fd1, second page from fd2 */
13286d7f5d3SJohn Marinovoid *
13386d7f5d3SJohn MarinomapBuffer(void *ar)
13486d7f5d3SJohn Marino{
13586d7f5d3SJohn Marino	void *addr;
13686d7f5d3SJohn Marino	char *buffer;
13786d7f5d3SJohn Marino	int i;
13886d7f5d3SJohn Marino
13986d7f5d3SJohn Marino	i = (int )ar;
14086d7f5d3SJohn Marino	addr = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, a[i].fd1, 0);
14186d7f5d3SJohn Marino	if (addr == MAP_FAILED) {
14286d7f5d3SJohn Marino		err(1, "Mmap failed");
14386d7f5d3SJohn Marino	}
14486d7f5d3SJohn Marino	buffer = addr;
14586d7f5d3SJohn Marino	addr = mmap(buffer + pagesize, pagesize, PROT_READ | PROT_WRITE, MAP_FIXED |
14686d7f5d3SJohn Marino		    MAP_SHARED, a[i].fd2, 0);
14786d7f5d3SJohn Marino
14886d7f5d3SJohn Marino	if (addr == MAP_FAILED) {
14986d7f5d3SJohn Marino		err(1, "Mmap2 failed");
15086d7f5d3SJohn Marino	}
15186d7f5d3SJohn Marino	a[i].bp = buffer;
15286d7f5d3SJohn Marino	sleep(1);
15386d7f5d3SJohn Marino	return (NULL);
15486d7f5d3SJohn Marino}
15586d7f5d3SJohn Marino
15686d7f5d3SJohn Marino
15786d7f5d3SJohn Marinoint
15886d7f5d3SJohn MarinostartIO(int fd, char *buffer)
15986d7f5d3SJohn Marino{
16086d7f5d3SJohn Marino	ssize_t len;
16186d7f5d3SJohn Marino
16286d7f5d3SJohn Marino	len = write(fd, buffer, 2 * pagesize);
16386d7f5d3SJohn Marino	if (len == -1) {
16486d7f5d3SJohn Marino		warn("startIO(%d, %p): write failed", fd, buffer);
16586d7f5d3SJohn Marino		return 1;
16686d7f5d3SJohn Marino	}
16786d7f5d3SJohn Marino	return 0;
16886d7f5d3SJohn Marino}
16986d7f5d3SJohn Marino
17086d7f5d3SJohn Marino
17186d7f5d3SJohn Marino
17286d7f5d3SJohn Marinoint
17386d7f5d3SJohn Marinomain(int argc, char *argv[], char *envp[])
17486d7f5d3SJohn Marino{
17586d7f5d3SJohn Marino
17686d7f5d3SJohn Marino	int fdA, fdB, fdDelayA, fdDelayB;
17786d7f5d3SJohn Marino	int r, status;
17886d7f5d3SJohn Marino	char *bufferA, *bufferB;
17986d7f5d3SJohn Marino	pid_t pid;
18086d7f5d3SJohn Marino	pthread_t threads[2];
18186d7f5d3SJohn Marino
18286d7f5d3SJohn Marino	pagesize = getpagesize();
18386d7f5d3SJohn Marino
18486d7f5d3SJohn Marino	if ((prepareFile("A", &fdA))
18586d7f5d3SJohn Marino	    || (prepareFile("B", &fdB))
18686d7f5d3SJohn Marino	    || (prepareFile("DelayA", &fdDelayA))
18786d7f5d3SJohn Marino	    || (prepareFile("DelayB", &fdDelayB)))
18886d7f5d3SJohn Marino		exit(1);
18986d7f5d3SJohn Marino
19086d7f5d3SJohn Marino	a[0].fd1 = fdDelayA;
19186d7f5d3SJohn Marino	a[0].fd2 = fdB;
19286d7f5d3SJohn Marino
19386d7f5d3SJohn Marino	a[1].fd1 = fdDelayB;
19486d7f5d3SJohn Marino	a[1].fd2 = fdA;
19586d7f5d3SJohn Marino
19686d7f5d3SJohn Marino	if ((r = pthread_create(&threads[0], NULL, mapBuffer, (void *)0)) != 0)
19786d7f5d3SJohn Marino		err(1, "pthread_create(): %s\n", strerror(r));
19886d7f5d3SJohn Marino	if ((r = pthread_create(&threads[1], NULL, mapBuffer, (void *)1)) != 0)
19986d7f5d3SJohn Marino		err(1, "pthread_create(): %s\n", strerror(r));
20086d7f5d3SJohn Marino
20186d7f5d3SJohn Marino	while (a[0].bp == NULL || a[1].bp == NULL)
20286d7f5d3SJohn Marino		pthread_yield();
20386d7f5d3SJohn Marino
20486d7f5d3SJohn Marino	bufferA = a[0].bp;
20586d7f5d3SJohn Marino	bufferB = a[1].bp;
20686d7f5d3SJohn Marino
20786d7f5d3SJohn Marino	pid = fork();
20886d7f5d3SJohn Marino
20986d7f5d3SJohn Marino	if (pid == 0) {
21086d7f5d3SJohn Marino		status = startIO(fdA, bufferA);
21186d7f5d3SJohn Marino		exit(status);
21286d7f5d3SJohn Marino	}
21386d7f5d3SJohn Marino	if (pid == -1) {
21486d7f5d3SJohn Marino		exit(1);
21586d7f5d3SJohn Marino	}
21686d7f5d3SJohn Marino	status = startIO(fdB, bufferB);
21786d7f5d3SJohn Marino	exit(status);
21886d7f5d3SJohn Marino
21986d7f5d3SJohn Marino}
220