xref: /freebsd/tools/test/stress2/misc/rangelocks.sh (revision ef777be98543f7daae90bd123d4fc1ec4a54efc2)
1*ef777be9SPeter Holm#!/bin/sh
2*ef777be9SPeter Holm
3*ef777be9SPeter Holm#
4*ef777be9SPeter Holm# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
5*ef777be9SPeter Holm#
6*ef777be9SPeter Holm# SPDX-License-Identifier: BSD-2-Clause
7*ef777be9SPeter Holm#
8*ef777be9SPeter Holm
9*ef777be9SPeter Holm# Range lock test scenario suggestion by kib@
10*ef777be9SPeter Holm
11*ef777be9SPeter Holm. ../default.cfg
12*ef777be9SPeter Holm
13*ef777be9SPeter Holmset -u
14*ef777be9SPeter Holmprog=$(basename "$0" .sh)
15*ef777be9SPeter Holmdir=/tmp
16*ef777be9SPeter Holmodir=`pwd`
17*ef777be9SPeter Holmcd $dir
18*ef777be9SPeter Holmsed '1,/^EOF/d' < $odir/$0 > $dir/$prog.c
19*ef777be9SPeter Holmmycc -o $prog -Wall -Wextra -O2 -g $prog.c || exit 1
20*ef777be9SPeter Holmrm -f $prog.c
21*ef777be9SPeter Holmcd $odir
22*ef777be9SPeter Holm
23*ef777be9SPeter Holmmdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
24*ef777be9SPeter Holmset -e
25*ef777be9SPeter Holmmdconfig -a -t swap -s 6g -u $mdstart
26*ef777be9SPeter Holmnewfs $newfs_flags -n /dev/md$mdstart > /dev/null
27*ef777be9SPeter Holmmount /dev/md$mdstart $mntpoint
28*ef777be9SPeter Holmset +e
29*ef777be9SPeter Holmwd="$mntpoint/$prog.dir"
30*ef777be9SPeter Holmmkdir -p $wd
31*ef777be9SPeter Holmdd if=/dev/zero of=$wd/file bs=1m count=5k status=none
32*ef777be9SPeter Holm
33*ef777be9SPeter Holm[ `jot -r 1 1 100` -le 25 ] &&
34*ef777be9SPeter Holm    ../testcases/swap/swap -t 10m -i 20 > /dev/null 2>&1 &
35*ef777be9SPeter Holmcd $wd
36*ef777be9SPeter Holm/tmp/$prog $wd/file; s=$?
37*ef777be9SPeter Holmcd $odir
38*ef777be9SPeter Holmwhile pkill swap; do :; done
39*ef777be9SPeter Holmwait
40*ef777be9SPeter Holm
41*ef777be9SPeter Holmumount $mntpoint
42*ef777be9SPeter Holmmdconfig -d -u $mdstart
43*ef777be9SPeter Holmrm -rf /tmp/$prog $wd
44*ef777be9SPeter Holmexit $s
45*ef777be9SPeter Holm
46*ef777be9SPeter HolmEOF
47*ef777be9SPeter Holm#include <sys/param.h>
48*ef777be9SPeter Holm#include <sys/mman.h>
49*ef777be9SPeter Holm#include <sys/stat.h>
50*ef777be9SPeter Holm#include <sys/wait.h>
51*ef777be9SPeter Holm
52*ef777be9SPeter Holm#include <machine/atomic.h>
53*ef777be9SPeter Holm
54*ef777be9SPeter Holm#include <err.h>
55*ef777be9SPeter Holm#include <errno.h>
56*ef777be9SPeter Holm#include <fcntl.h>
57*ef777be9SPeter Holm#include <sched.h>
58*ef777be9SPeter Holm#include <stdio.h>
59*ef777be9SPeter Holm#include <stdlib.h>
60*ef777be9SPeter Holm#include <time.h>
61*ef777be9SPeter Holm#include <unistd.h>
62*ef777be9SPeter Holm
63*ef777be9SPeter Holm#define DONE 1
64*ef777be9SPeter Holm#define MAXBLK 10240
65*ef777be9SPeter Holm//#define MAXPROC 32
66*ef777be9SPeter Holm#define MAXPROC 1024
67*ef777be9SPeter Holm#define MAXSIZ (5LL * 1024 * 1024 *1024)
68*ef777be9SPeter Holm#define RUNTIME (5 * 60)
69*ef777be9SPeter Holm#define SYNC 0
70*ef777be9SPeter Holm
71*ef777be9SPeter Holmstatic volatile u_int *share;
72*ef777be9SPeter Holmstatic int parallel;
73*ef777be9SPeter Holm
74*ef777be9SPeter Holmstatic char *file;
75*ef777be9SPeter Holm
76*ef777be9SPeter Holmstatic off_t
77*ef777be9SPeter Holmnewpos(int lng)
78*ef777be9SPeter Holm{
79*ef777be9SPeter Holm	off_t p;
80*ef777be9SPeter Holm
81*ef777be9SPeter Holm	do {
82*ef777be9SPeter Holm		arc4random_buf(&p, sizeof(p));
83*ef777be9SPeter Holm		p = p & 0xfffffff;
84*ef777be9SPeter Holm	} while (p + lng > MAXSIZ);
85*ef777be9SPeter Holm	return (p);
86*ef777be9SPeter Holm}
87*ef777be9SPeter Holm
88*ef777be9SPeter Holmstatic void
89*ef777be9SPeter Holmtest(int indx, int num)
90*ef777be9SPeter Holm{
91*ef777be9SPeter Holm	off_t pos;
92*ef777be9SPeter Holm	ssize_t i, l, r;
93*ef777be9SPeter Holm	time_t start;
94*ef777be9SPeter Holm	int fd, n;
95*ef777be9SPeter Holm	char *buf;
96*ef777be9SPeter Holm
97*ef777be9SPeter Holm	atomic_add_int(&share[SYNC], 1);
98*ef777be9SPeter Holm	while (share[SYNC] != (unsigned int)parallel)
99*ef777be9SPeter Holm		sched_yield();
100*ef777be9SPeter Holm
101*ef777be9SPeter Holm	if ((buf = malloc(MAXBLK)) == NULL)
102*ef777be9SPeter Holm		err(1, "malloc");
103*ef777be9SPeter Holm	n = 0;
104*ef777be9SPeter Holm	start = time(NULL);
105*ef777be9SPeter Holm	while (share[DONE] != (unsigned int)parallel) {
106*ef777be9SPeter Holm		setproctitle("test(%d) num %d, n %d", indx, num, n);
107*ef777be9SPeter Holm		if ((fd = open(file, O_RDWR)) == -1)
108*ef777be9SPeter Holm			err(1, "open(%s)", file);
109*ef777be9SPeter Holm
110*ef777be9SPeter Holm		for (i = 0; i < arc4random() % 512; i++) {
111*ef777be9SPeter Holm			if (arc4random() % 100 < 50) {
112*ef777be9SPeter Holm				l = arc4random() % MAXBLK + 1;
113*ef777be9SPeter Holm				pos = newpos(l);
114*ef777be9SPeter Holm				if (lseek(fd, pos, SEEK_SET) == -1)
115*ef777be9SPeter Holm					err(1, "lseek");
116*ef777be9SPeter Holm				if ((r = read(fd, buf, l)) != l) {
117*ef777be9SPeter Holm					warn("read %jd @ %jd returned %zd\n", (intmax_t)l, (intmax_t)pos, r);
118*ef777be9SPeter Holm					goto done;
119*ef777be9SPeter Holm				}
120*ef777be9SPeter Holm			}
121*ef777be9SPeter Holm
122*ef777be9SPeter Holm			l = arc4random() % MAXBLK + 1;
123*ef777be9SPeter Holm			pos = newpos(l);
124*ef777be9SPeter Holm			if (lseek(fd, pos, SEEK_SET) == -1)
125*ef777be9SPeter Holm				err(1, "lseek");
126*ef777be9SPeter Holm			if ((r = write(fd, buf, l)) != l) {
127*ef777be9SPeter Holm				warn("write returned %zd\n", r);
128*ef777be9SPeter Holm				goto done;
129*ef777be9SPeter Holm			}
130*ef777be9SPeter Holm		}
131*ef777be9SPeter Holm
132*ef777be9SPeter Holm		close(fd);
133*ef777be9SPeter Holm		if (n++ == 0)
134*ef777be9SPeter Holm			atomic_add_int(&share[DONE], 1);
135*ef777be9SPeter Holm		if (time(NULL) - start >= RUNTIME * 4) {
136*ef777be9SPeter Holm			fprintf(stderr, "test(%d), %d Timed out\n", indx, num);
137*ef777be9SPeter Holm			break;
138*ef777be9SPeter Holm		}
139*ef777be9SPeter Holm	}
140*ef777be9SPeter Holmdone:
141*ef777be9SPeter Holm	if (n++ == 0)
142*ef777be9SPeter Holm		atomic_add_int(&share[DONE], 1);
143*ef777be9SPeter Holm
144*ef777be9SPeter Holm	_exit(0);
145*ef777be9SPeter Holm}
146*ef777be9SPeter Holm
147*ef777be9SPeter Holmvoid
148*ef777be9SPeter Holmsetup(void)
149*ef777be9SPeter Holm{
150*ef777be9SPeter Holm
151*ef777be9SPeter Holm	parallel = arc4random() % MAXPROC + 1;
152*ef777be9SPeter Holm}
153*ef777be9SPeter Holm
154*ef777be9SPeter Holmint
155*ef777be9SPeter Holmmain(int argc, char *argv[])
156*ef777be9SPeter Holm{
157*ef777be9SPeter Holm	size_t len;
158*ef777be9SPeter Holm	time_t start;
159*ef777be9SPeter Holm	int e, i, n, *pids, status;
160*ef777be9SPeter Holm
161*ef777be9SPeter Holm	if (argc != 2) {
162*ef777be9SPeter Holm		fprintf(stderr, "Usage: %s <file>\n", argv[0]);
163*ef777be9SPeter Holm		_exit(1);
164*ef777be9SPeter Holm	}
165*ef777be9SPeter Holm	e = 0;
166*ef777be9SPeter Holm	file = argv[1];
167*ef777be9SPeter Holm	len = PAGE_SIZE;
168*ef777be9SPeter Holm	if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
169*ef777be9SPeter Holm	    MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
170*ef777be9SPeter Holm		err(1, "mmap");
171*ef777be9SPeter Holm
172*ef777be9SPeter Holm	n = 0;
173*ef777be9SPeter Holm	start = time(NULL);
174*ef777be9SPeter Holm	while ((time(NULL) - start) < RUNTIME && e == 0) {
175*ef777be9SPeter Holm		setup();
176*ef777be9SPeter Holm
177*ef777be9SPeter Holm		pids = malloc(sizeof(pid_t) * parallel);
178*ef777be9SPeter Holm		share[SYNC] = share[DONE] = 0;
179*ef777be9SPeter Holm		for (i = 0; i < parallel; i++) {
180*ef777be9SPeter Holm			if ((pids[i] = fork()) == 0)
181*ef777be9SPeter Holm				test(i, n);
182*ef777be9SPeter Holm		}
183*ef777be9SPeter Holm		for (i = 0; i < parallel; i++) {
184*ef777be9SPeter Holm			if (waitpid(pids[i], &status, 0) != pids[i])
185*ef777be9SPeter Holm				err(1, "waitpid %d", pids[i]);
186*ef777be9SPeter Holm			e += status == 0 ? 0 : 1;
187*ef777be9SPeter Holm		}
188*ef777be9SPeter Holm		n++;
189*ef777be9SPeter Holm		n = n % 10;
190*ef777be9SPeter Holm		free(pids);
191*ef777be9SPeter Holm	}
192*ef777be9SPeter Holm
193*ef777be9SPeter Holm	return (e);
194*ef777be9SPeter Holm}
195