xref: /freebsd/tools/test/stress2/misc/swap8.sh (revision c2b513335f688ac5657abc1bc40f6848988958d7)
1*c2b51333SPeter Holm#!/bin/sh
2*c2b51333SPeter Holm
3*c2b51333SPeter Holm#
4*c2b51333SPeter Holm# Copyright (c) 2026 Peter Holm <pho@FreeBSD.org>
5*c2b51333SPeter Holm#
6*c2b51333SPeter Holm# SPDX-License-Identifier: BSD-2-Clause
7*c2b51333SPeter Holm#
8*c2b51333SPeter Holm
9*c2b51333SPeter Holm# sendfile over tmpfs
10*c2b51333SPeter Holm
11*c2b51333SPeter Holm# "panic: vm_page_assert_busied: page 0xfffffe000015fb88 not busy @ ../../../vm/vm_page.c:5845" seen
12*c2b51333SPeter Holm# Triggered by: 72ddb6de1028 - main - unix: increase net.local.(stream|seqpacket).(recv|send)space to 64 KiB
13*c2b51333SPeter Holm# Fixed by: d198ad51ea73 - main - swap_pager_getpages(): some pages from ma[] might be bogus
14*c2b51333SPeter Holm
15*c2b51333SPeter Holm[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
16*c2b51333SPeter Holm[ `sysctl -n vm.swap_total` -eq 0 ] && exit 0
17*c2b51333SPeter Holm
18*c2b51333SPeter Holm. ../default.cfg
19*c2b51333SPeter Holm
20*c2b51333SPeter Holmprog=$(basename "$0" .sh)
21*c2b51333SPeter Holm
22*c2b51333SPeter Holmcat > /tmp/$prog.c <<EOF
23*c2b51333SPeter Holm#include <sys/types.h>
24*c2b51333SPeter Holm#include <sys/fcntl.h>
25*c2b51333SPeter Holm#include <sys/mman.h>
26*c2b51333SPeter Holm#include <sys/socket.h>
27*c2b51333SPeter Holm#include <sys/stat.h>
28*c2b51333SPeter Holm#include <sys/uio.h>
29*c2b51333SPeter Holm#include <sys/wait.h>
30*c2b51333SPeter Holm
31*c2b51333SPeter Holm#include <err.h>
32*c2b51333SPeter Holm#include <errno.h>
33*c2b51333SPeter Holm#include <stdio.h>
34*c2b51333SPeter Holm#include <stdlib.h>
35*c2b51333SPeter Holm#include <unistd.h>
36*c2b51333SPeter Holm
37*c2b51333SPeter Holmstatic int use_sendfile = 1;
38*c2b51333SPeter Holm
39*c2b51333SPeter Holmint
40*c2b51333SPeter Holmmain(int argc, char *argv[])
41*c2b51333SPeter Holm{
42*c2b51333SPeter Holm	off_t rsize, wsize, pos;
43*c2b51333SPeter Holm	ssize_t n;
44*c2b51333SPeter Holm	struct stat st;
45*c2b51333SPeter Holm	int from, pair[2], pid, status;
46*c2b51333SPeter Holm	const char *from_name;
47*c2b51333SPeter Holm	char *buf, *cp;
48*c2b51333SPeter Holm
49*c2b51333SPeter Holm	if (argc != 2)
50*c2b51333SPeter Holm		errx(1, "Usage: %s from", argv[0]);
51*c2b51333SPeter Holm	from_name = argv[1];
52*c2b51333SPeter Holm
53*c2b51333SPeter Holm	if ((from = open(from_name, O_RDONLY)) == -1)
54*c2b51333SPeter Holm		err(1, "open read %s", from_name);
55*c2b51333SPeter Holm
56*c2b51333SPeter Holm	if (fstat(from, &st) == -1)
57*c2b51333SPeter Holm		err(1, "stat %s", from_name);
58*c2b51333SPeter Holm
59*c2b51333SPeter Holm	if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1)
60*c2b51333SPeter Holm		err(1, "socketpair");
61*c2b51333SPeter Holm
62*c2b51333SPeter Holm	pid = fork();
63*c2b51333SPeter Holm	if (pid == -1)
64*c2b51333SPeter Holm		err(1, "fork");
65*c2b51333SPeter Holm	if (pid == 0) {	/* child */
66*c2b51333SPeter Holm		setproctitle("reader");
67*c2b51333SPeter Holm		close(pair[0]);
68*c2b51333SPeter Holm		buf = malloc(st.st_size);
69*c2b51333SPeter Holm		if (buf == NULL)
70*c2b51333SPeter Holm			err(1, "malloc %jd", st.st_size);
71*c2b51333SPeter Holm		pos = 0;
72*c2b51333SPeter Holm		sleep(1);
73*c2b51333SPeter Holm		for (;;) {
74*c2b51333SPeter Holm			rsize = 413; /* arbitrary small block size */
75*c2b51333SPeter Holm			if (rsize > st.st_size - pos)
76*c2b51333SPeter Holm				rsize = st.st_size - pos;
77*c2b51333SPeter Holm			n = read(pair[1], buf + pos, rsize);
78*c2b51333SPeter Holm			if (n == -1)
79*c2b51333SPeter Holm				err(1, "read()");
80*c2b51333SPeter Holm			else if (n == 0)
81*c2b51333SPeter Holm				errx(1, "Short read: Read %jd bytes out of %jd\n",
82*c2b51333SPeter Holm					(intmax_t)pos, (intmax_t)st.st_size);
83*c2b51333SPeter Holm			pos += n;
84*c2b51333SPeter Holm			if (pos == st.st_size)
85*c2b51333SPeter Holm				break;
86*c2b51333SPeter Holm		}
87*c2b51333SPeter Holm		close(pair[1]);
88*c2b51333SPeter Holm		_exit(0);
89*c2b51333SPeter Holm	}
90*c2b51333SPeter Holm	setproctitle("writer");
91*c2b51333SPeter Holm	close(pair[1]);
92*c2b51333SPeter Holm
93*c2b51333SPeter Holm	if (use_sendfile == 1) {
94*c2b51333SPeter Holm		pos = 0;
95*c2b51333SPeter Holm		for (;;) {
96*c2b51333SPeter Holm			n = sendfile(from, pair[0], pos, st.st_size - pos,
97*c2b51333SPeter Holm			    NULL, &wsize, 0);
98*c2b51333SPeter Holm			if (n == -1) {
99*c2b51333SPeter Holm				if (errno != EAGAIN)
100*c2b51333SPeter Holm					err(1, "sendfile()");
101*c2b51333SPeter Holm			}
102*c2b51333SPeter Holm			if (wsize != st.st_size)
103*c2b51333SPeter Holm				fprintf(stderr, "sendfile() wrote %jd bytes\n", (intmax_t)wsize);
104*c2b51333SPeter Holm			pos += wsize;
105*c2b51333SPeter Holm			if (pos == st.st_size)
106*c2b51333SPeter Holm				break;
107*c2b51333SPeter Holm		}
108*c2b51333SPeter Holm	} else {
109*c2b51333SPeter Holm		fprintf(stderr, "Not using sendfile().\n");
110*c2b51333SPeter Holm		if ((cp = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, from, 0)) == MAP_FAILED)
111*c2b51333SPeter Holm			err(1, "mmap");
112*c2b51333SPeter Holm
113*c2b51333SPeter Holm		if ((n = write(pair[0], cp, st.st_size)) == -1)
114*c2b51333SPeter Holm			err(1, "write()");
115*c2b51333SPeter Holm		if (n != st.st_size)
116*c2b51333SPeter Holm			errx(1, "short write: %jd of %jd\n", (intmax_t)n, (intmax_t)st.st_size);
117*c2b51333SPeter Holm		if (munmap(cp, st.st_size) == -1)
118*c2b51333SPeter Holm			err(1, "munmap()");
119*c2b51333SPeter Holm	}
120*c2b51333SPeter Holm	if (waitpid(pid, &status, 0) != pid)
121*c2b51333SPeter Holm		err(1, "waitpid()");
122*c2b51333SPeter Holm	close(pair[0]);
123*c2b51333SPeter Holm
124*c2b51333SPeter Holm	return (status != 0);
125*c2b51333SPeter Holm}
126*c2b51333SPeter HolmEOF
127*c2b51333SPeter Holmmycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1
128*c2b51333SPeter Holm
129*c2b51333SPeter Holmmount | grep -q "on $mntpoint " && umount -f $mntpoint
130*c2b51333SPeter Holmmount -t tmpfs dummy $mntpoint || exit 1
131*c2b51333SPeter Holmdd if=/dev/zero of=$mntpoint/file bs=1m count=1024 status=none # 1Gb
132*c2b51333SPeter Holm
133*c2b51333SPeter Holm../testcases/swap/swap -t 5m -i 40 > /dev/null 2>&1 &
134*c2b51333SPeter Holmsleep 5
135*c2b51333SPeter Holm/tmp/$prog $mntpoint/file
136*c2b51333SPeter Holmwhile pkill swap; do :; done
137*c2b51333SPeter Holmwait
138*c2b51333SPeter Holm
139*c2b51333SPeter Holmumount $mntpoint
140*c2b51333SPeter Holmrm -f /tmp/$prog /tmp/$prog.c $diskimage
141*c2b51333SPeter Holmexit 0
142