xref: /freebsd/tools/test/stress2/misc/mmap41.sh (revision a90b9d0159070121c221b966469c3e36d912bf82)
1#!/bin/sh
2
3#
4# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
5#
6# SPDX-License-Identifier: BSD-2-Clause
7#
8
9# Based on code from https://syzkaller.appspot.com/text?tag=ReproC&x=15d9baada80000
10# No problems seen
11
12. ../default.cfg
13
14prog=$(basename "$0" .sh)
15odir=`pwd`
16cd /tmp
17sed '1,/^EOF/d' < $odir/$0 > $prog.c
18mycc -o $prog -Wall -Wextra -O0 $prog.c -lpthread || exit 1
19rm -f $prog.c
20
21set -e
22mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
23[ -c /dev/md$mdstart ] &&  mdconfig -d -u $mdstart
24mdconfig -a -t swap -s 2g -u $mdstart
25newfs $newfs_flags md$mdstart > /dev/null
26mount /dev/md$mdstart $mntpoint
27set +e
28
29$odir/../testcases/swap/swap -t 2m -i 10 > /dev/null &
30cd $mntpoint
31/tmp/$prog
32cd $odir
33while pkill swap; do :; done
34wait
35
36for i in `jot 6`; do
37	mount | grep -q "on $mntpoint " || break
38	umount $mntpoint && break || sleep 10
39	[ $i -eq 6 ] &&
40	    { echo FATAL; fstat -mf $mntpoint; exit 1; }
41done
42mdconfig -d -u $mdstart
43rm -f /tmp/$prog
44exit 0
45
46EOF
47#include <sys/param.h>
48#include <sys/mman.h>
49#include <sys/uio.h>
50#include <sys/wait.h>
51
52#include <err.h>
53#include <errno.h>
54#include <fcntl.h>
55#include <pthread.h>
56#include <stdio.h>
57#include <stdlib.h>
58#include <string.h>
59#include <unistd.h>
60
61#define DEBUG 0	/* 1 to enable */
62#define THREADS 2
63
64static volatile int go;
65static int fd;
66static char *p, path[128];
67
68#define ADDR (void *) 0x20000000ul
69#define LEN  0x1000000ul
70
71void *
72thr(void *arg)
73{
74	struct iovec iov;
75	long n, w;
76	char *p1;
77
78	if (*(int *)arg == 0) {
79		while (go == 0)
80			usleep(100);
81		while (go == 1) {
82			if ((p1 = mmap(ADDR, LEN, PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
83				err(1, "mmap() in %s", __func__);
84			usleep(arc4random() % 50);
85			if ((p1 = mmap(ADDR, LEN, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
86				err(1, "mmap() in %s", __func__);
87			usleep(arc4random() % 10000);
88		}
89	} else {
90		while (go == 0)
91			usleep(100);
92		n = w = 0;
93		while (go == 1) {
94			iov.iov_base = p;
95			iov.iov_len = 0x100000;
96			if (pwritev(fd, &iov, 1, 0) != -1)
97				w++;
98			n++;
99		}
100		if (DEBUG == 1)
101			fprintf(stderr, "%ld out of %ld  writes (%ld%%)\n", w, n, w * 100 / n);
102	}
103
104
105	return (0);
106}
107
108void
109test(void)
110{
111	pthread_t threads[THREADS];
112	int nr[THREADS];
113	int i, r;
114
115	sprintf(path, "mmap.%06d", getpid());
116	if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == -1)
117		err(1,"open()");
118
119
120	if ((p = mmap(ADDR, LEN, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
121		err(1, "mmap() in %s", __func__);
122
123	go = 0;
124	for (i = 0; i < THREADS; i++) {
125		nr[i] = i;
126		if ((r = pthread_create(&threads[i], NULL, thr,
127		    (void *)&nr[i])) != 0)
128			errc(1, r, "pthread_create()");
129	}
130
131	go = 1;
132	sleep(60);
133	go = 2;
134
135	for (i = 0; i < THREADS; i++) {
136		if ((r = pthread_join(threads[i], NULL)) != 0)
137			errc(1, r, "pthread_join(%d)", i);
138	}
139	close(fd);
140	if (DEBUG == 0) {
141		if (unlink(path) == -1)
142			err(1, "unlink(%s)", path);
143	}
144
145	_exit(0);
146}
147
148int
149main(void)
150{
151	pid_t pid;
152	int i;
153
154	for (i = 0; i < 2; i++) {
155		if ((pid = fork()) == 0)
156			test();
157		if (waitpid(pid, NULL, 0) != pid)
158			err(1, "waitpid()");
159	}
160}
161