xref: /freebsd/tools/test/stress2/misc/swapoff5.sh (revision 8a272653d9fbd9fc37691c9aad6a05089b4ecb4d)
1*8a272653SPeter Holm#!/bin/sh
2*8a272653SPeter Holm
3*8a272653SPeter Holm#
4*8a272653SPeter Holm# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
5*8a272653SPeter Holm#
6*8a272653SPeter Holm# Copyright (c) 2020 Mark Johnston
7*8a272653SPeter Holm#
8*8a272653SPeter Holm# Redistribution and use in source and binary forms, with or without
9*8a272653SPeter Holm# modification, are permitted provided that the following conditions
10*8a272653SPeter Holm# are met:
11*8a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright
12*8a272653SPeter Holm#    notice, this list of conditions and the following disclaimer.
13*8a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright
14*8a272653SPeter Holm#    notice, this list of conditions and the following disclaimer in the
15*8a272653SPeter Holm#    documentation and/or other materials provided with the distribution.
16*8a272653SPeter Holm#
17*8a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18*8a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*8a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*8a272653SPeter Holm# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21*8a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*8a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23*8a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24*8a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25*8a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26*8a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27*8a272653SPeter Holm# SUCH DAMAGE.
28*8a272653SPeter Holm#
29*8a272653SPeter Holm
30*8a272653SPeter Holm# Variation of swapoff3.sh
31*8a272653SPeter Holm
32*8a272653SPeter Holm# Deadlock seen:
33*8a272653SPeter Holm# https://people.freebsd.org/~pho/stress/log/log0005.txt
34*8a272653SPeter Holm# This is a "known" low memory deadlocks caused by using md(4) as a swap
35*8a272653SPeter Holm# device.
36*8a272653SPeter Holm
37*8a272653SPeter Holm. ../default.cfg
38*8a272653SPeter Holm[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
39*8a272653SPeter Holmdir=`dirname $diskimage`
40*8a272653SPeter Holm[ `df -k $dir | tail -1 | awk '{print $4}'` -lt \
41*8a272653SPeter Holm    $((20 * 1024 * 1024)) ] &&
42*8a272653SPeter Holm    { echo "Need 20GB on $dir"; exit 0; }
43*8a272653SPeter Holm
44*8a272653SPeter Holmcat > /tmp/swapoff5.c <<EOF
45*8a272653SPeter Holm#include <sys/param.h>
46*8a272653SPeter Holm#include <sys/mman.h>
47*8a272653SPeter Holm#include <sys/sysctl.h>
48*8a272653SPeter Holm
49*8a272653SPeter Holm#include <assert.h>
50*8a272653SPeter Holm#include <err.h>
51*8a272653SPeter Holm#include <stdlib.h>
52*8a272653SPeter Holm#include <unistd.h>
53*8a272653SPeter Holm
54*8a272653SPeter Holmint
55*8a272653SPeter Holmmain(void)
56*8a272653SPeter Holm{
57*8a272653SPeter Holm	char *addr, *naddr, *res;
58*8a272653SPeter Holm	size_t i, len, swap, vsz;
59*8a272653SPeter Holm	u_int free;
60*8a272653SPeter Holm
61*8a272653SPeter Holm	vsz = sizeof(free);
62*8a272653SPeter Holm	if (sysctlbyname("vm.stats.vm.v_free_count", &free, &vsz, NULL, 0) != 0)
63*8a272653SPeter Holm		err(1, "sysctl(vm.stats.vm.v_free_count)");
64*8a272653SPeter Holm	vsz = sizeof(swap);
65*8a272653SPeter Holm	if (sysctlbyname("vm.swap_total", &swap, &vsz, NULL, 0) != 0)
66*8a272653SPeter Holm		err(1, "sysctl(vm.swap_total)");
67*8a272653SPeter Holm
68*8a272653SPeter Holm	len = (size_t)free * PAGE_SIZE + swap / 4;
69*8a272653SPeter Holm	addr = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE,
70*8a272653SPeter Holm	    -1, 0);
71*8a272653SPeter Holm	if (addr == MAP_FAILED)
72*8a272653SPeter Holm		err(1, "mmap");
73*8a272653SPeter Holm
74*8a272653SPeter Holm	res = malloc(howmany(len, PAGE_SIZE));
75*8a272653SPeter Holm	if (res == NULL)
76*8a272653SPeter Holm		err(1, "malloc");
77*8a272653SPeter Holm
78*8a272653SPeter Holm	for (i = 0; i < len; i += PAGE_SIZE)
79*8a272653SPeter Holm		addr[i] = 1;
80*8a272653SPeter Holm
81*8a272653SPeter Holm	for (;;) {
82*8a272653SPeter Holm		if (mincore(addr, len, res) != 0)
83*8a272653SPeter Holm			err(1, "mincore");
84*8a272653SPeter Holm		for (i = 0; i < howmany(len, PAGE_SIZE); i++)
85*8a272653SPeter Holm			if ((res[i] & MINCORE_INCORE) == 0) {
86*8a272653SPeter Holm				naddr = addr + i * PAGE_SIZE;
87*8a272653SPeter Holm				if (munmap(naddr, PAGE_SIZE) != 0)
88*8a272653SPeter Holm					err(1, "munmap");
89*8a272653SPeter Holm				if (mmap(naddr, PAGE_SIZE,
90*8a272653SPeter Holm				    PROT_READ | PROT_WRITE,
91*8a272653SPeter Holm				    MAP_ANON | MAP_PRIVATE | MAP_FIXED,
92*8a272653SPeter Holm				    -1, 0) == MAP_FAILED)
93*8a272653SPeter Holm					err(1, "mmap");
94*8a272653SPeter Holm				assert(*naddr == 0);
95*8a272653SPeter Holm				*naddr = 1;
96*8a272653SPeter Holm			}
97*8a272653SPeter Holm	}
98*8a272653SPeter Holm
99*8a272653SPeter Holm	return (0);
100*8a272653SPeter Holm}
101*8a272653SPeter HolmEOF
102*8a272653SPeter Holmmycc -o /tmp/swapoff5 -Wall -Wextra -O2 -g /tmp/swapoff5.c || exit
103*8a272653SPeter Holm
104*8a272653SPeter Holmcat > /tmp/swapoff5x.c <<EOF
105*8a272653SPeter Holm#include <sys/mman.h>
106*8a272653SPeter Holm
107*8a272653SPeter Holm#include <err.h>
108*8a272653SPeter Holm#include <stdio.h>
109*8a272653SPeter Holm#include <stdlib.h>
110*8a272653SPeter Holm#include <time.h>
111*8a272653SPeter Holm
112*8a272653SPeter Holmint
113*8a272653SPeter Holmmain(int argc, char *argv[])
114*8a272653SPeter Holm{
115*8a272653SPeter Holm	time_t start;
116*8a272653SPeter Holm	int n, r;
117*8a272653SPeter Holm	char off1[80], off2[80], on1[80], on2[80];
118*8a272653SPeter Holm
119*8a272653SPeter Holm	if ( argc != 3) {
120*8a272653SPeter Holm		fprintf(stderr, "Usage: %s <dev1> <dev2>\n", argv[0]);
121*8a272653SPeter Holm		exit(1);
122*8a272653SPeter Holm	}
123*8a272653SPeter Holm
124*8a272653SPeter Holm	snprintf(off1, sizeof(off1), "swapoff %s", argv[1]);
125*8a272653SPeter Holm	snprintf(off2, sizeof(off2), "swapoff %s", argv[2]);
126*8a272653SPeter Holm	snprintf(on1, sizeof(on1), "swapon %s", argv[1]);
127*8a272653SPeter Holm	snprintf(on2, sizeof(on2), "swapon %s", argv[2]);
128*8a272653SPeter Holm
129*8a272653SPeter Holm	start = time(NULL);
130*8a272653SPeter Holm	if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
131*8a272653SPeter Holm		err(1, "mlockall(MCL_CURRENT) | MCL_FUTURE");
132*8a272653SPeter Holm	n = 0;
133*8a272653SPeter Holm	while (time(NULL) - start < 240) {
134*8a272653SPeter Holm		if ((r = system(off1)) != 0)
135*8a272653SPeter Holm			errx(1, "%s failed with %d", off1, r);
136*8a272653SPeter Holm		if ((r = system(on1)) != 0)
137*8a272653SPeter Holm			errx(1, "%s failed with %d", on1, r);
138*8a272653SPeter Holm		if ((r = system(off2)) != 0)
139*8a272653SPeter Holm			errx(1, "%s failed with %d", off2, r);
140*8a272653SPeter Holm		if ((r = system(on2)) != 0)
141*8a272653SPeter Holm			errx(1, "%s failed with %d", on2, r);
142*8a272653SPeter Holm		n++;
143*8a272653SPeter Holm	}
144*8a272653SPeter Holm	if (n < 100)
145*8a272653SPeter Holm		fprintf(stderr, "%d swapoffs\n", n);
146*8a272653SPeter Holm
147*8a272653SPeter Holm	return (0);
148*8a272653SPeter Holm}
149*8a272653SPeter HolmEOF
150*8a272653SPeter Holmmycc -o /tmp/swapoff5x -Wall -Wextra -O2 -g /tmp/swapoff5x.c || exit
151*8a272653SPeter Holm
152*8a272653SPeter Holmset -e
153*8a272653SPeter Holmmd1=$mdstart
154*8a272653SPeter Holmmd2=$((md1 + 1))
155*8a272653SPeter Holm[ `sysctl -n vm.swap_total` -gt 0 ] && { swapoff -a > /dev/null; off=1; }
156*8a272653SPeter Holmtruncate -s 10G $dir/swap1
157*8a272653SPeter Holmmdconfig -a -t vnode -f $dir/swap1 -u $md1
158*8a272653SPeter Holmswapon /dev/md$md1
159*8a272653SPeter Holmtruncate -s 10G $dir/swap2
160*8a272653SPeter Holmmdconfig -a -t vnode -f $dir/swap2 -u $md2
161*8a272653SPeter Holmswapon /dev/md$md2
162*8a272653SPeter Holmset +e
163*8a272653SPeter Holm
164*8a272653SPeter Holmtimeout 4m /tmp/swapoff5 &
165*8a272653SPeter Holmfor i in `jot 60`; do
166*8a272653SPeter Holm	n=`swapinfo | tail -1 | awk '{print $3}'`
167*8a272653SPeter Holm	[ $n -gt 0 ] && break
168*8a272653SPeter Holm	sleep 1
169*8a272653SPeter Holmdone
170*8a272653SPeter Holm
171*8a272653SPeter Holm/tmp/swapoff5x /dev/md$md1 /dev/md$md2
172*8a272653SPeter Holmkill $! > /dev/null 2>&1
173*8a272653SPeter Holmwait
174*8a272653SPeter Holmfor dev in /dev/md$md1 /dev/md$md2; do
175*8a272653SPeter Holm	swapoff $dev
176*8a272653SPeter Holmdone
177*8a272653SPeter Holmmdconfig -d -u $md1
178*8a272653SPeter Holmmdconfig -d -u $md2
179*8a272653SPeter Holmrm -f $dir/swap1 $dir/swap2 /tmp/swapoff5 /tmp/swapoff5.c /tmp/swapoff5x \
180*8a272653SPeter Holm    /tmp/swapoff5x.c
181*8a272653SPeter Holm[ $off ] && swapon -a > /dev/null
182*8a272653SPeter Holmexit $s
183