1#!/bin/sh 2 3# 4# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org> 5# 6# SPDX-License-Identifier: BSD-2-Clause 7# 8 9# No problems observed 10 11[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 12 13. ../default.cfg 14 15set -u 16prog=$(basename "$0" .sh) 17mount | grep -q "on $mntpoint " && umount $mntpoint 18[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart 19 20mdconfig -a -t swap -s 1g -u $mdstart 21gpart create -s bsd md$mdstart > /dev/null 22gpart add -t freebsd-ufs md$mdstart > /dev/null 23part=a 24newfs_msdos -F 32 -b 8192 /dev/md${mdstart}$part > /dev/null || exit 1 25mount -t msdosfs /dev/md${mdstart}$part $mntpoint 26 27here=`pwd` 28cd /tmp 29cat > $prog.c <<EOF 30#include <sys/param.h> 31#include <sys/mman.h> 32#include <sys/stat.h> 33#include <sys/wait.h> 34 35#include <machine/atomic.h> 36 37#include <err.h> 38#include <errno.h> 39#include <fcntl.h> 40#include <stdio.h> 41#include <stdlib.h> 42#include <unistd.h> 43 44static volatile u_int *share; 45static char file1[80], file2[80]; 46 47#define SYNC 0 48#define STOP 1 49 50static void 51test0(void) 52{ 53 struct stat sb; 54 55 while (share[STOP] == 0) { 56 while (share[SYNC] != 0) 57 usleep(100); 58 if (rename(file1, file2) == -1) 59 err(1, "rename(%s, %s)", file1, file2); 60 if (stat(file1, &sb) == 0) 61 err(1, "stat(%s)", file1); 62 atomic_add_int(&share[SYNC], 1); 63 } 64 65 _exit(0); 66} 67 68static void 69test1(void) 70{ 71 struct stat sb; 72 73 while (share[STOP] == 0) { 74 while (share[SYNC] != 1) 75 usleep(100); 76 if (rename(file2, file1) == -1) 77 err(1, "rename(%s, %s)", file2, file1); 78 if (stat(file2, &sb) == 0) 79 err(1, "stat(%s)", file2); 80 atomic_add_int(&share[SYNC], -1); 81 } 82 83 _exit(0); 84} 85 86int 87main(void) 88{ 89 pid_t pids[2]; 90 size_t len; 91 int fd; 92 char cwd[80]; 93 94 len = PAGE_SIZE; 95 if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, 96 MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 97 err(1, "mmap"); 98 99 if (getcwd(cwd, sizeof(cwd)) == NULL) 100 err(1, "getcwd()"); 101 snprintf(file1, sizeof(file1), "%s/a.%06d", cwd, getpid()); 102 snprintf(file2, sizeof(file2), "%s/b.%06d", cwd, getpid()); 103 if ((fd = open(file1, O_CREAT, 0640)) == -1) 104 err(1, "open(%s)", file1); 105 close(fd); 106 107 if ((pids[0] = fork()) == 0) 108 test0(); 109 if ((pids[1] = fork()) == 0) 110 test1(); 111 112 sleep(120); 113 share[STOP] = 1; 114 115 if (waitpid(pids[0], NULL, 0) == -1) 116 err(1, "waitpid(%d)", pids[0]); 117 if (waitpid(pids[1], NULL, 0) == -1) 118 err(1, "waitpid(%d)", pids[1]); 119 unlink(file1); 120 unlink(file2); 121} 122EOF 123mycc -o $prog -Wall $prog.c || exit 1 124rm -f $prog.c 125cd $here 126 127(cd ../testcases/swap; ./swap -t 5m -i 20 -l 100) & 128cd $mntpoint 129pids="" 130for i in `jot 30`; do 131 /tmp/$prog & 132 pids="$pids $!" 133done 134for pid in $pids; do 135 wait $pid 136done 137cd $here 138while pkill swap; do :; done 139wait 140 141umount $mntpoint 142mdconfig -d -u $mdstart 143rm -f /tmp/$prog 144exit 0 145