xref: /freebsd/tools/test/stress2/misc/pageout.sh (revision ec0ea6efa1ad229d75c394c1a9b9cac33af2b1d3)
1#!/bin/sh
2
3#
4# Copyright (c) 2015 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# Trigger the two EDEADLK in vm/vm_pageout.c
30# OOVM deadlock seen
31# https://people.freebsd.org/~pho/stress/log/pageout.txt
32
33# "panic: handle_written_filepage: not started" seen:
34# https://people.freebsd.org/~pho/stress/log/pageout-2.txt
35
36[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
37. ../default.cfg
38
39dir=/tmp
40odir=`pwd`
41cd $dir
42sed '1,/^EOF/d' < $odir/$0 > $dir/pageout.c
43mycc -o pageout -Wall -Wextra -g pageout.c || exit 1
44rm -f pageout.c
45cd $odir
46
47mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
48mdconfig -l | grep -q md$mdstart &&  mdconfig -d -u $mdstart
49
50mdconfig -a -t swap -s 2g -u $mdstart || exit 1
51bsdlabel -w md$mdstart auto
52
53newfs $newfs_flags md${mdstart}$part > /dev/null
54
55mount /dev/md${mdstart}$part $mntpoint
56chmod 777 $mntpoint
57
58f1=$mntpoint/f1
59dd if=/dev/zero of=$f1 bs=1m count=1k status=none
60
61daemon sh -c "(cd ../testcases/swap; ./swap -t 5m -i 20 -l 100 -h)" > /dev/null
62(cd /tmp; /tmp/pageout $f1) &
63sleep .2
64while kill -0 $! 2> /dev/null; do
65	mksnap_ffs $mntpoint $mntpoint/.snap/stress2 &&
66	    rm -f $mntpoint/.snap/stress2
67done
68while pgrep -q swap; do
69	pkill swap
70done
71wait
72
73while mount | grep $mntpoint | grep -q /dev/md; do
74	umount $mntpoint || sleep 1
75done
76mdconfig -d -u $mdstart
77rm -f /tmp/pageout /tmp/pageout.core
78exit
79
80EOF
81#include <sys/param.h>
82#include <sys/fcntl.h>
83#include <sys/mman.h>
84#include <sys/stat.h>
85
86#include <err.h>
87#include <errno.h>
88#include <stdio.h>
89#include <stdlib.h>
90#include <time.h>
91#include <unistd.h>
92
93const char *file;
94
95#define RUNTIME 600
96
97void
98test(void)
99{
100	struct stat st;
101	size_t i, len;
102	time_t start;
103	int error, fd, ps;
104	char *p;
105
106	ps = getpagesize();
107	if ((fd = open(file, O_RDWR)) == -1)
108		err(1, "open(%s)", file);
109	if ((error = fstat(fd, &st)) == -1)
110		err(1, "stat(%s)", file);
111	len = round_page(st.st_size);
112	do {
113		if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
114		    fd, 0)) == MAP_FAILED) {
115			if (errno == ENOMEM)
116				len -= ps;
117			else
118				err(1, "mmap");
119		}
120	} while (p == MAP_FAILED);
121
122	start = time(NULL);
123	/* Touch all pages of the file. */
124	for (i = 0; i < len; i += ps)
125		p[i] = 1;
126	while (time(NULL) - start < RUNTIME)
127		p[arc4random() % len] = 1;
128
129	if (munmap(p, len) == -1)
130		err(1, "unmap()");
131	close(fd);
132}
133
134int
135main(int argc, char *argv[])
136{
137	if (argc != 2)
138		errx(1, "Usage: %s <file>", argv[0]);
139	file = argv[1];
140
141	test();
142
143	return (0);
144}
145