aboutsummaryrefslogtreecommitdiff
path: root/tools/test/stress2
diff options
context:
space:
mode:
Diffstat (limited to 'tools/test/stress2')
-rw-r--r--tools/test/stress2/default.cfg1
-rw-r--r--tools/test/stress2/lib/resources.c2
-rwxr-xr-xtools/test/stress2/misc/1st.sh2
-rwxr-xr-xtools/test/stress2/misc/aesni.sh7
-rw-r--r--tools/test/stress2/misc/all.debug.inc3
-rw-r--r--tools/test/stress2/misc/all.exclude66
-rwxr-xr-xtools/test/stress2/misc/all.sh16
-rwxr-xr-xtools/test/stress2/misc/arp.sh2
-rwxr-xr-xtools/test/stress2/misc/aslr.sh2
-rwxr-xr-xtools/test/stress2/misc/badcode2.sh2
-rwxr-xr-xtools/test/stress2/misc/badcode3.sh9
-rwxr-xr-xtools/test/stress2/misc/beneath.sh2
-rwxr-xr-xtools/test/stress2/misc/beneath2.sh2
-rwxr-xr-xtools/test/stress2/misc/beneath3.sh2
-rwxr-xr-xtools/test/stress2/misc/beneath4.sh2
-rwxr-xr-xtools/test/stress2/misc/buildkernel.sh3
-rwxr-xr-xtools/test/stress2/misc/buildworld.sh1
-rwxr-xr-xtools/test/stress2/misc/buildworld2.sh1
-rwxr-xr-xtools/test/stress2/misc/buildworld3.sh3
-rwxr-xr-xtools/test/stress2/misc/buildworld4.sh3
-rwxr-xr-xtools/test/stress2/misc/chain.sh2
-rwxr-xr-xtools/test/stress2/misc/chroot.sh2
-rwxr-xr-xtools/test/stress2/misc/compare.sh2
-rwxr-xr-xtools/test/stress2/misc/contigmalloc.sh10
-rwxr-xr-xtools/test/stress2/misc/contigmalloc2.sh11
-rwxr-xr-xtools/test/stress2/misc/contigmalloc3.sh10
-rwxr-xr-xtools/test/stress2/misc/core5.sh4
-rwxr-xr-xtools/test/stress2/misc/cpuset.sh2
-rwxr-xr-xtools/test/stress2/misc/creat.sh84
-rwxr-xr-xtools/test/stress2/misc/crossmp.sh3
-rwxr-xr-xtools/test/stress2/misc/crossmp2.sh3
-rwxr-xr-xtools/test/stress2/misc/crossmp3.sh1
-rwxr-xr-xtools/test/stress2/misc/crossmp4.sh1
-rwxr-xr-xtools/test/stress2/misc/crossmp5.sh6
-rwxr-xr-xtools/test/stress2/misc/crossmp6.sh3
-rwxr-xr-xtools/test/stress2/misc/crossmp7.sh3
-rwxr-xr-xtools/test/stress2/misc/crossmp8.sh1
-rwxr-xr-xtools/test/stress2/misc/datagram.sh2
-rwxr-xr-xtools/test/stress2/misc/datagram2.sh2
-rwxr-xr-xtools/test/stress2/misc/datagram3.sh2
-rwxr-xr-xtools/test/stress2/misc/datamove.sh2
-rwxr-xr-xtools/test/stress2/misc/datamove2.sh2
-rwxr-xr-xtools/test/stress2/misc/datamove3.sh2
-rwxr-xr-xtools/test/stress2/misc/datamove6.sh50
-rwxr-xr-xtools/test/stress2/misc/devfs4.sh2
-rwxr-xr-xtools/test/stress2/misc/devfs5.sh4
-rwxr-xr-xtools/test/stress2/misc/dtrace_fault.sh2
-rwxr-xr-xtools/test/stress2/misc/dup.sh2
-rwxr-xr-xtools/test/stress2/misc/elf.sh2
-rwxr-xr-xtools/test/stress2/misc/execpath.sh2
-rwxr-xr-xtools/test/stress2/misc/exlock2.sh19
-rwxr-xr-xtools/test/stress2/misc/ext2fs.sh2
-rwxr-xr-xtools/test/stress2/misc/ext2fs2.sh2
-rwxr-xr-xtools/test/stress2/misc/ext2fs3.sh4
-rwxr-xr-xtools/test/stress2/misc/ext3fs.sh4
-rwxr-xr-xtools/test/stress2/misc/ext4fs.sh4
-rwxr-xr-xtools/test/stress2/misc/extattr2.sh2
-rwxr-xr-xtools/test/stress2/misc/extattr3.sh2
-rwxr-xr-xtools/test/stress2/misc/fcntl.sh21
-rwxr-xr-xtools/test/stress2/misc/fcntl2.sh4
-rwxr-xr-xtools/test/stress2/misc/fcntl3.sh2
-rwxr-xr-xtools/test/stress2/misc/fexecve.sh2
-rwxr-xr-xtools/test/stress2/misc/fifo2.sh8
-rwxr-xr-xtools/test/stress2/misc/fifo4.sh4
-rwxr-xr-xtools/test/stress2/misc/flock_open_close.sh7
-rwxr-xr-xtools/test/stress2/misc/force.sh2
-rwxr-xr-xtools/test/stress2/misc/force10.sh92
-rwxr-xr-xtools/test/stress2/misc/force11.sh100
-rwxr-xr-xtools/test/stress2/misc/force12.sh83
-rwxr-xr-xtools/test/stress2/misc/force13.sh129
-rwxr-xr-xtools/test/stress2/misc/force14.sh119
-rwxr-xr-xtools/test/stress2/misc/force15.sh113
-rwxr-xr-xtools/test/stress2/misc/force2.sh2
-rwxr-xr-xtools/test/stress2/misc/force3.sh2
-rwxr-xr-xtools/test/stress2/misc/force4.sh2
-rwxr-xr-xtools/test/stress2/misc/force5.sh2
-rwxr-xr-xtools/test/stress2/misc/force6.sh2
-rwxr-xr-xtools/test/stress2/misc/force7.sh2
-rwxr-xr-xtools/test/stress2/misc/force8.sh2
-rwxr-xr-xtools/test/stress2/misc/force9.sh25
-rwxr-xr-xtools/test/stress2/misc/fork2.sh134
-rwxr-xr-xtools/test/stress2/misc/forkbomb.sh5
-rwxr-xr-xtools/test/stress2/misc/fsck.sh22
-rwxr-xr-xtools/test/stress2/misc/fsck10.sh172
-rwxr-xr-xtools/test/stress2/misc/fsck11.sh171
-rwxr-xr-xtools/test/stress2/misc/fsck12.sh175
-rwxr-xr-xtools/test/stress2/misc/fsck13.sh153
-rwxr-xr-xtools/test/stress2/misc/fsck14.sh119
-rwxr-xr-xtools/test/stress2/misc/fsck2.sh2
-rwxr-xr-xtools/test/stress2/misc/fsck3.sh2
-rwxr-xr-xtools/test/stress2/misc/fsck4.sh2
-rwxr-xr-xtools/test/stress2/misc/fsck5.sh2
-rwxr-xr-xtools/test/stress2/misc/fsck6.sh2
-rwxr-xr-xtools/test/stress2/misc/fsck7.sh2
-rwxr-xr-xtools/test/stress2/misc/fsck8.sh179
-rwxr-xr-xtools/test/stress2/misc/fsck9.sh168
-rwxr-xr-xtools/test/stress2/misc/fstat.sh2
-rwxr-xr-xtools/test/stress2/misc/fsync2.sh2
-rwxr-xr-xtools/test/stress2/misc/fsync3.sh156
-rwxr-xr-xtools/test/stress2/misc/fsync4.sh146
-rwxr-xr-xtools/test/stress2/misc/ftruncate3.sh96
-rwxr-xr-xtools/test/stress2/misc/geomleak2.sh2
-rwxr-xr-xtools/test/stress2/misc/getrandom.sh2
-rwxr-xr-xtools/test/stress2/misc/getrandom2.sh2
-rwxr-xr-xtools/test/stress2/misc/gnop10.sh6
-rwxr-xr-xtools/test/stress2/misc/gnop11.sh2
-rwxr-xr-xtools/test/stress2/misc/gnop12.sh2
-rwxr-xr-xtools/test/stress2/misc/gnop13.sh138
-rwxr-xr-xtools/test/stress2/misc/gnop2.sh2
-rwxr-xr-xtools/test/stress2/misc/gnop4.sh3
-rwxr-xr-xtools/test/stress2/misc/gnop6.sh2
-rwxr-xr-xtools/test/stress2/misc/gnop7.sh2
-rwxr-xr-xtools/test/stress2/misc/gnop8.sh2
-rwxr-xr-xtools/test/stress2/misc/gnop9.sh2
-rwxr-xr-xtools/test/stress2/misc/gpt.sh2
-rwxr-xr-xtools/test/stress2/misc/growfs2.sh65
-rwxr-xr-xtools/test/stress2/misc/growfs3.sh41
-rwxr-xr-xtools/test/stress2/misc/gunion.sh9
-rwxr-xr-xtools/test/stress2/misc/gunion2.sh9
-rwxr-xr-xtools/test/stress2/misc/holdcnt05.sh2
-rwxr-xr-xtools/test/stress2/misc/ifconfig.sh2
-rwxr-xr-xtools/test/stress2/misc/ifconfig2.sh2
-rwxr-xr-xtools/test/stress2/misc/indir.sh2
-rwxr-xr-xtools/test/stress2/misc/indir_trunc.sh2
-rwxr-xr-xtools/test/stress2/misc/jexec.sh2
-rwxr-xr-xtools/test/stress2/misc/jumbo.sh2
-rwxr-xr-xtools/test/stress2/misc/kcmp.sh67
-rwxr-xr-xtools/test/stress2/misc/kern_umtx_inf_loop.sh1
-rwxr-xr-xtools/test/stress2/misc/kevent10.sh2
-rwxr-xr-xtools/test/stress2/misc/kevent12.sh2
-rwxr-xr-xtools/test/stress2/misc/kevent13.sh2
-rwxr-xr-xtools/test/stress2/misc/kevent14.sh2
-rwxr-xr-xtools/test/stress2/misc/kevent15.sh2
-rwxr-xr-xtools/test/stress2/misc/killpg2.sh197
-rwxr-xr-xtools/test/stress2/misc/killpg3.sh192
-rwxr-xr-xtools/test/stress2/misc/killpg4.sh114
-rwxr-xr-xtools/test/stress2/misc/kpti.sh2
-rwxr-xr-xtools/test/stress2/misc/largepage.sh2
-rwxr-xr-xtools/test/stress2/misc/ldt.sh1
-rwxr-xr-xtools/test/stress2/misc/linux.sh2
-rwxr-xr-xtools/test/stress2/misc/mapwrite.sh189
-rwxr-xr-xtools/test/stress2/misc/marcus6.sh2
-rwxr-xr-xtools/test/stress2/misc/marcus7.sh2
-rwxr-xr-xtools/test/stress2/misc/marcus8.sh41
-rwxr-xr-xtools/test/stress2/misc/mdconfig3.sh2
-rwxr-xr-xtools/test/stress2/misc/mdconfig4.sh2
-rwxr-xr-xtools/test/stress2/misc/mdconfig5.sh2
-rwxr-xr-xtools/test/stress2/misc/midi.sh2
-rwxr-xr-xtools/test/stress2/misc/midi2.sh2
-rwxr-xr-xtools/test/stress2/misc/mincore.sh2
-rwxr-xr-xtools/test/stress2/misc/minherit.sh2
-rwxr-xr-xtools/test/stress2/misc/mkdir.sh81
-rwxr-xr-xtools/test/stress2/misc/mkfifo5.sh2
-rwxr-xr-xtools/test/stress2/misc/mkfifo6.sh2
-rwxr-xr-xtools/test/stress2/misc/mkfifo7.sh2
-rwxr-xr-xtools/test/stress2/misc/mkfifo8.sh2
-rwxr-xr-xtools/test/stress2/misc/mlockall4.sh2
-rwxr-xr-xtools/test/stress2/misc/mlockall6.sh5
-rwxr-xr-xtools/test/stress2/misc/mmap10.sh21
-rwxr-xr-xtools/test/stress2/misc/mmap18.sh13
-rwxr-xr-xtools/test/stress2/misc/mmap32.sh5
-rwxr-xr-xtools/test/stress2/misc/mmap33.sh2
-rwxr-xr-xtools/test/stress2/misc/mmap34.sh2
-rwxr-xr-xtools/test/stress2/misc/mmap35.sh2
-rwxr-xr-xtools/test/stress2/misc/mmap36.sh2
-rwxr-xr-xtools/test/stress2/misc/mmap37.sh2
-rwxr-xr-xtools/test/stress2/misc/mmap38.sh2
-rwxr-xr-xtools/test/stress2/misc/mmap39.sh2
-rwxr-xr-xtools/test/stress2/misc/mmap40.sh13
-rwxr-xr-xtools/test/stress2/misc/mmap41.sh160
-rwxr-xr-xtools/test/stress2/misc/mmap42.sh101
-rwxr-xr-xtools/test/stress2/misc/mmap43.sh182
-rwxr-xr-xtools/test/stress2/misc/mmap44.sh255
-rwxr-xr-xtools/test/stress2/misc/mmap45.sh230
-rwxr-xr-xtools/test/stress2/misc/mmap46.sh233
-rwxr-xr-xtools/test/stress2/misc/mmap47.sh237
-rwxr-xr-xtools/test/stress2/misc/mmap48.sh289
-rwxr-xr-xtools/test/stress2/misc/mmap5.sh14
-rwxr-xr-xtools/test/stress2/misc/mount7.sh (renamed from tools/test/stress2/misc/vmstat2.sh)46
-rwxr-xr-xtools/test/stress2/misc/mountro4.sh2
-rwxr-xr-xtools/test/stress2/misc/mountro5.sh2
-rwxr-xr-xtools/test/stress2/misc/mountro6.sh2
-rwxr-xr-xtools/test/stress2/misc/mountu.sh2
-rwxr-xr-xtools/test/stress2/misc/mprotect.sh2
-rwxr-xr-xtools/test/stress2/misc/mprotect2.sh2
-rwxr-xr-xtools/test/stress2/misc/mprotect3.sh70
-rwxr-xr-xtools/test/stress2/misc/mprotect4.sh109
-rwxr-xr-xtools/test/stress2/misc/mprotect5.sh118
-rwxr-xr-xtools/test/stress2/misc/mprotect6.sh146
-rwxr-xr-xtools/test/stress2/misc/msdos11.sh2
-rwxr-xr-xtools/test/stress2/misc/msdos12.sh2
-rwxr-xr-xtools/test/stress2/misc/msdos13.sh2
-rwxr-xr-xtools/test/stress2/misc/msdos14.sh4
-rwxr-xr-xtools/test/stress2/misc/msdos15.sh2
-rwxr-xr-xtools/test/stress2/misc/msdos16.sh2
-rwxr-xr-xtools/test/stress2/misc/msdos17.sh144
-rwxr-xr-xtools/test/stress2/misc/msdos18.sh250
-rwxr-xr-xtools/test/stress2/misc/msdos20.sh87
-rwxr-xr-xtools/test/stress2/misc/msdos21.sh25
-rwxr-xr-xtools/test/stress2/misc/namecache2.sh2
-rwxr-xr-xtools/test/stress2/misc/newfs.sh4
-rwxr-xr-xtools/test/stress2/misc/newfs6.sh (renamed from tools/test/stress2/misc/md4.sh)50
-rwxr-xr-xtools/test/stress2/misc/newfs7.sh (renamed from tools/test/stress2/misc/gbde.sh)48
-rwxr-xr-xtools/test/stress2/misc/newfs8.sh69
-rwxr-xr-xtools/test/stress2/misc/nfs17.sh2
-rwxr-xr-xtools/test/stress2/misc/nfs18.sh2
-rwxr-xr-xtools/test/stress2/misc/nfs_halfpage.sh2
-rwxr-xr-xtools/test/stress2/misc/nfs_halfpage2.sh2
-rwxr-xr-xtools/test/stress2/misc/nfsrename.sh4
-rwxr-xr-xtools/test/stress2/misc/nlink.sh2
-rwxr-xr-xtools/test/stress2/misc/nlink2.sh2
-rwxr-xr-xtools/test/stress2/misc/nlink3.sh4
-rwxr-xr-xtools/test/stress2/misc/nlink4.sh4
-rwxr-xr-xtools/test/stress2/misc/nlink5.sh9
-rwxr-xr-xtools/test/stress2/misc/nullfs18.sh3
-rwxr-xr-xtools/test/stress2/misc/nullfs25.sh2
-rwxr-xr-xtools/test/stress2/misc/nullfs26.sh2
-rwxr-xr-xtools/test/stress2/misc/nullfs27.sh2
-rwxr-xr-xtools/test/stress2/misc/nullfs28.sh2
-rwxr-xr-xtools/test/stress2/misc/nullfs30.sh112
-rwxr-xr-xtools/test/stress2/misc/nullfs31.sh75
-rwxr-xr-xtools/test/stress2/misc/nullfs32.sh43
-rwxr-xr-xtools/test/stress2/misc/numa.sh2
-rwxr-xr-xtools/test/stress2/misc/open2.sh2
-rwxr-xr-xtools/test/stress2/misc/overflow3.sh2
-rwxr-xr-xtools/test/stress2/misc/pageout.sh10
-rwxr-xr-xtools/test/stress2/misc/pager_read_error.sh36
-rwxr-xr-xtools/test/stress2/misc/perf.sh3
-rwxr-xr-xtools/test/stress2/misc/ping.sh2
-rwxr-xr-xtools/test/stress2/misc/pipe3.sh2
-rwxr-xr-xtools/test/stress2/misc/pipe_enomem.sh2
-rwxr-xr-xtools/test/stress2/misc/pkru.sh2
-rwxr-xr-xtools/test/stress2/misc/pmc6.sh2
-rwxr-xr-xtools/test/stress2/misc/poll2.sh6
-rwxr-xr-xtools/test/stress2/misc/pread.sh10
-rwxr-xr-xtools/test/stress2/misc/proccontrol.sh2
-rwxr-xr-xtools/test/stress2/misc/procfs.sh3
-rwxr-xr-xtools/test/stress2/misc/procfs3.sh2
-rwxr-xr-xtools/test/stress2/misc/procfs4.sh7
-rwxr-xr-xtools/test/stress2/misc/procfs6.sh2
-rwxr-xr-xtools/test/stress2/misc/procstat.sh2
-rwxr-xr-xtools/test/stress2/misc/procstat2.sh2
-rwxr-xr-xtools/test/stress2/misc/pthread10.sh106
-rwxr-xr-xtools/test/stress2/misc/ptrace10.sh2
-rwxr-xr-xtools/test/stress2/misc/ptrace11.sh2
-rwxr-xr-xtools/test/stress2/misc/ptrace12.sh2
-rwxr-xr-xtools/test/stress2/misc/ptrace9.sh2
-rwxr-xr-xtools/test/stress2/misc/pts2.sh4
-rwxr-xr-xtools/test/stress2/misc/pts3.sh2
-rwxr-xr-xtools/test/stress2/misc/quota12.sh2
-rwxr-xr-xtools/test/stress2/misc/quota5.sh2
-rwxr-xr-xtools/test/stress2/misc/r335171.sh2
-rwxr-xr-xtools/test/stress2/misc/radix.sh6
-rwxr-xr-xtools/test/stress2/misc/random.sh2
-rwxr-xr-xtools/test/stress2/misc/rangelocks.sh194
-rwxr-xr-xtools/test/stress2/misc/rangelocks2.sh178
-rwxr-xr-xtools/test/stress2/misc/rdgsbase.sh2
-rwxr-xr-xtools/test/stress2/misc/rdwr.sh50
-rwxr-xr-xtools/test/stress2/misc/readdir.sh8
-rwxr-xr-xtools/test/stress2/misc/reaper.sh2
-rwxr-xr-xtools/test/stress2/misc/reaper2.sh10
-rwxr-xr-xtools/test/stress2/misc/reaper3.sh13
-rwxr-xr-xtools/test/stress2/misc/reaper4.sh13
-rwxr-xr-xtools/test/stress2/misc/reaper5.sh2
-rwxr-xr-xtools/test/stress2/misc/rename14.sh5
-rwxr-xr-xtools/test/stress2/misc/rename15.sh2
-rwxr-xr-xtools/test/stress2/misc/rename16.sh261
-rwxr-xr-xtools/test/stress2/misc/rename3.sh3
-rwxr-xr-xtools/test/stress2/misc/rename7.sh6
-rwxr-xr-xtools/test/stress2/misc/rmdir.sh119
-rwxr-xr-xtools/test/stress2/misc/rsync.sh49
-rwxr-xr-xtools/test/stress2/misc/rsync2.sh17
-rwxr-xr-xtools/test/stress2/misc/rsync3.sh43
-rwxr-xr-xtools/test/stress2/misc/seekhole.sh77
-rwxr-xr-xtools/test/stress2/misc/seekhole2.sh65
-rwxr-xr-xtools/test/stress2/misc/segnp.sh2
-rwxr-xr-xtools/test/stress2/misc/segregs.sh2
-rwxr-xr-xtools/test/stress2/misc/sem_post.sh2
-rwxr-xr-xtools/test/stress2/misc/sem_timedwait.sh2
-rwxr-xr-xtools/test/stress2/misc/sem_wait.sh2
-rwxr-xr-xtools/test/stress2/misc/sendfile15.sh2
-rwxr-xr-xtools/test/stress2/misc/sendfile17.sh2
-rwxr-xr-xtools/test/stress2/misc/sendfile18.sh2
-rwxr-xr-xtools/test/stress2/misc/sendfile19.sh2
-rwxr-xr-xtools/test/stress2/misc/sendfile20.sh2
-rwxr-xr-xtools/test/stress2/misc/sendfile21.sh2
-rwxr-xr-xtools/test/stress2/misc/sendfile22.sh2
-rwxr-xr-xtools/test/stress2/misc/sendfile23.sh2
-rwxr-xr-xtools/test/stress2/misc/sendfile24.sh2
-rwxr-xr-xtools/test/stress2/misc/sendfile25.sh6
-rwxr-xr-xtools/test/stress2/misc/sendfile26.sh2
-rwxr-xr-xtools/test/stress2/misc/sendfile5.sh4
-rwxr-xr-xtools/test/stress2/misc/setrlimit.sh193
-rwxr-xr-xtools/test/stress2/misc/setrlimit2.sh118
-rwxr-xr-xtools/test/stress2/misc/setsockopt.sh2
-rwxr-xr-xtools/test/stress2/misc/setsockopt2.sh5
-rwxr-xr-xtools/test/stress2/misc/shm2.sh2
-rwxr-xr-xtools/test/stress2/misc/shm_super.sh2
-rwxr-xr-xtools/test/stress2/misc/sigfastblock.sh2
-rwxr-xr-xtools/test/stress2/misc/sigfastblock2.sh2
-rwxr-xr-xtools/test/stress2/misc/signal2.sh53
-rwxr-xr-xtools/test/stress2/misc/sigreturn2.sh69
-rwxr-xr-xtools/test/stress2/misc/sigreturn3.sh181
-rwxr-xr-xtools/test/stress2/misc/sigreturn4.sh207
-rwxr-xr-xtools/test/stress2/misc/sigstop2.sh2
-rwxr-xr-xtools/test/stress2/misc/smrstress.sh2
-rwxr-xr-xtools/test/stress2/misc/smrstress2.sh2
-rwxr-xr-xtools/test/stress2/misc/snap12.sh2
-rwxr-xr-xtools/test/stress2/misc/snap13.sh70
-rwxr-xr-xtools/test/stress2/misc/socketpair4.sh2
-rwxr-xr-xtools/test/stress2/misc/softupdate.sh1
-rwxr-xr-xtools/test/stress2/misc/sort2.sh2
-rwxr-xr-xtools/test/stress2/misc/split.sh2
-rwxr-xr-xtools/test/stress2/misc/su.sh2
-rwxr-xr-xtools/test/stress2/misc/suj11.sh2
-rwxr-xr-xtools/test/stress2/misc/suj12.sh3
-rwxr-xr-xtools/test/stress2/misc/suj15.sh2
-rwxr-xr-xtools/test/stress2/misc/suj16.sh2
-rwxr-xr-xtools/test/stress2/misc/suj26.sh2
-rwxr-xr-xtools/test/stress2/misc/suj27.sh2
-rwxr-xr-xtools/test/stress2/misc/suj36.sh84
-rwxr-xr-xtools/test/stress2/misc/suj4.sh2
-rwxr-xr-xtools/test/stress2/misc/suj5.sh3
-rwxr-xr-xtools/test/stress2/misc/swap5.sh2
-rwxr-xr-xtools/test/stress2/misc/swap6.sh4
-rwxr-xr-xtools/test/stress2/misc/swapoff3.sh2
-rwxr-xr-xtools/test/stress2/misc/swapoff4.sh2
-rwxr-xr-xtools/test/stress2/misc/swapoff5.sh2
-rwxr-xr-xtools/test/stress2/misc/swapoff6.sh42
-rwxr-xr-xtools/test/stress2/misc/symlink.sh1
-rwxr-xr-xtools/test/stress2/misc/symlink2.sh1
-rwxr-xr-xtools/test/stress2/misc/symlink5.sh3
-rwxr-xr-xtools/test/stress2/misc/syscall4.sh2
-rwxr-xr-xtools/test/stress2/misc/systrace.sh2
-rwxr-xr-xtools/test/stress2/misc/systrace2.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller11.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller12.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller14.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller15.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller16.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller19.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller24.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller26.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller27.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller28.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller29.sh4
-rwxr-xr-xtools/test/stress2/misc/syzkaller30.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller31.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller32.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller33.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller34.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller4.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller42.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller43.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller50.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller51.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller53.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller54.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller55.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller58.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller59.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller61.sh319
-rwxr-xr-xtools/test/stress2/misc/syzkaller62.sh83
-rwxr-xr-xtools/test/stress2/misc/syzkaller63.sh75
-rwxr-xr-xtools/test/stress2/misc/syzkaller64.sh328
-rwxr-xr-xtools/test/stress2/misc/syzkaller65.sh82
-rwxr-xr-xtools/test/stress2/misc/syzkaller66.sh156
-rwxr-xr-xtools/test/stress2/misc/syzkaller67.sh99
-rwxr-xr-xtools/test/stress2/misc/syzkaller68.sh235
-rwxr-xr-xtools/test/stress2/misc/syzkaller69.sh494
-rwxr-xr-xtools/test/stress2/misc/syzkaller7.sh2
-rwxr-xr-xtools/test/stress2/misc/syzkaller70.sh302
-rwxr-xr-xtools/test/stress2/misc/syzkaller71.sh171
-rwxr-xr-xtools/test/stress2/misc/syzkaller72.sh70
-rwxr-xr-xtools/test/stress2/misc/syzkaller73.sh537
-rwxr-xr-xtools/test/stress2/misc/syzkaller74.sh469
-rwxr-xr-xtools/test/stress2/misc/syzkaller75.sh377
-rwxr-xr-xtools/test/stress2/misc/syzkaller76.sh235
-rwxr-xr-xtools/test/stress2/misc/syzkaller77.sh290
-rwxr-xr-xtools/test/stress2/misc/syzkaller78.sh282
-rwxr-xr-xtools/test/stress2/misc/syzkaller79.sh82
-rwxr-xr-xtools/test/stress2/misc/tcp4.sh2
-rwxr-xr-xtools/test/stress2/misc/timeout.sh2
-rwxr-xr-xtools/test/stress2/misc/tmpfs10.sh2
-rwxr-xr-xtools/test/stress2/misc/tmpfs11.sh2
-rwxr-xr-xtools/test/stress2/misc/tmpfs13.sh1
-rwxr-xr-xtools/test/stress2/misc/tmpfs17.sh2
-rwxr-xr-xtools/test/stress2/misc/tmpfs19.sh2
-rwxr-xr-xtools/test/stress2/misc/tmpfs2.sh6
-rwxr-xr-xtools/test/stress2/misc/tmpfs20.sh2
-rwxr-xr-xtools/test/stress2/misc/tmpfs21.sh2
-rwxr-xr-xtools/test/stress2/misc/tmpfs22.sh2
-rwxr-xr-xtools/test/stress2/misc/tmpfs23.sh2
-rwxr-xr-xtools/test/stress2/misc/tmpfs24.sh71
-rwxr-xr-xtools/test/stress2/misc/tmpfs25.sh86
-rwxr-xr-xtools/test/stress2/misc/tmpfs26.sh179
-rwxr-xr-xtools/test/stress2/misc/tmpfs27.sh49
-rwxr-xr-xtools/test/stress2/misc/tmpfs28.sh61
-rwxr-xr-xtools/test/stress2/misc/tmpfs8.sh2
-rwxr-xr-xtools/test/stress2/misc/trim8.sh2
-rwxr-xr-xtools/test/stress2/misc/truncate8.sh2
-rwxr-xr-xtools/test/stress2/misc/truncate9.sh2
-rwxr-xr-xtools/test/stress2/misc/truss2.sh2
-rwxr-xr-xtools/test/stress2/misc/udp2.sh2
-rwxr-xr-xtools/test/stress2/misc/ufsbench.sh2
-rwxr-xr-xtools/test/stress2/misc/umount3.sh2
-rwxr-xr-xtools/test/stress2/misc/umount4.sh2
-rwxr-xr-xtools/test/stress2/misc/umountf11.sh2
-rwxr-xr-xtools/test/stress2/misc/umountf12.sh2
-rwxr-xr-xtools/test/stress2/misc/umountf4.sh6
-rwxr-xr-xtools/test/stress2/misc/umountf6.sh6
-rwxr-xr-xtools/test/stress2/misc/unionfs13.sh2
-rwxr-xr-xtools/test/stress2/misc/unionfs14.sh2
-rwxr-xr-xtools/test/stress2/misc/unionfs15.sh86
-rwxr-xr-xtools/test/stress2/misc/unionfs16.sh65
-rwxr-xr-xtools/test/stress2/misc/unionfs17.sh73
-rwxr-xr-xtools/test/stress2/misc/unionfs18.sh73
-rwxr-xr-xtools/test/stress2/misc/unionfs19.sh74
-rwxr-xr-xtools/test/stress2/misc/unionfs4.sh4
-rwxr-xr-xtools/test/stress2/misc/unionfs5.sh13
-rwxr-xr-xtools/test/stress2/misc/unionfs6.sh8
-rwxr-xr-xtools/test/stress2/misc/unionfs7.sh8
-rwxr-xr-xtools/test/stress2/misc/unionfs8.sh12
-rwxr-xr-xtools/test/stress2/misc/unionfs9.sh3
-rwxr-xr-xtools/test/stress2/misc/unix_socket.sh2
-rwxr-xr-xtools/test/stress2/misc/unix_socket_detach.sh2
-rwxr-xr-xtools/test/stress2/misc/vfork.sh36
-rwxr-xr-xtools/test/stress2/misc/vm_map.sh2
-rwxr-xr-xtools/test/stress2/misc/vunref.sh3
-rwxr-xr-xtools/test/stress2/misc/write2.sh2
-rwxr-xr-xtools/test/stress2/misc/zfs10.sh2
-rwxr-xr-xtools/test/stress2/misc/zfs11.sh2
-rwxr-xr-xtools/test/stress2/misc/zfs12.sh2
-rwxr-xr-xtools/test/stress2/misc/zfs13.sh2
-rwxr-xr-xtools/test/stress2/misc/zfs14.sh2
-rwxr-xr-xtools/test/stress2/misc/zfs15.sh88
-rwxr-xr-xtools/test/stress2/misc/zfs16.sh105
-rwxr-xr-xtools/test/stress2/misc/zfs17.sh74
-rwxr-xr-xtools/test/stress2/misc/zfs18.sh134
-rwxr-xr-xtools/test/stress2/misc/zfs19.sh72
-rwxr-xr-xtools/test/stress2/misc/zfs8.sh2
-rwxr-xr-xtools/test/stress2/misc/zfs9.sh2
-rwxr-xr-xtools/test/stress2/misc/zz-combo01.sh2
-rwxr-xr-xtools/test/stress2/misc/zz-combo02.sh2
-rwxr-xr-xtools/test/stress2/misc/zz-combo03.sh2
-rwxr-xr-xtools/test/stress2/misc/zz-combo04.sh2
-rwxr-xr-xtools/test/stress2/misc/zzbuildworld.sh3
-rw-r--r--tools/test/stress2/testcases/swap/swap.c6
-rw-r--r--tools/test/stress2/tools/bench.c2
-rwxr-xr-xtools/test/stress2/tools/fail.sh2
-rwxr-xr-xtools/test/stress2/tools/fast.sh2
-rw-r--r--tools/test/stress2/tools/flip.c29
-rw-r--r--tools/test/stress2/tools/lsholes.c61
-rwxr-xr-xtools/test/stress2/tools/ministat.sh2
-rwxr-xr-xtools/test/stress2/tools/ps.sh2
-rw-r--r--tools/test/stress2/tools/serial.c44
-rw-r--r--tools/test/stress2/tools/swap.c2
-rwxr-xr-xtools/test/stress2/tools/vmstat.sh31
458 files changed, 15523 insertions, 666 deletions
diff --git a/tools/test/stress2/default.cfg b/tools/test/stress2/default.cfg
index f7748b55fa04..bff7f3f168a9 100644
--- a/tools/test/stress2/default.cfg
+++ b/tools/test/stress2/default.cfg
@@ -88,6 +88,7 @@ checkfs () {
# BMODE=1 ./all.sh -on `grep -lw mycc *.sh`
# BMODE=2 STRESS2BIN=/home/pho/stress2/bin.i386.r276368 ./all.sh
+BMODE=${BMODE:-0}
CC=${CC:-cc}
top=`dirname $(pwd)` # cwd for the all.sh script
STRESS2BIN=${STRESS2BIN:-$top/bin}
diff --git a/tools/test/stress2/lib/resources.c b/tools/test/stress2/lib/resources.c
index 935a085a58de..1888d1fba87f 100644
--- a/tools/test/stress2/lib/resources.c
+++ b/tools/test/stress2/lib/resources.c
@@ -149,7 +149,7 @@ usermem(void)
}
static void
-cleanupdf()
+cleanupdf(void)
{
unlink(dfpath);
}
diff --git a/tools/test/stress2/misc/1st.sh b/tools/test/stress2/misc/1st.sh
index 00602d67e803..59edb7957bfb 100755
--- a/tools/test/stress2/misc/1st.sh
+++ b/tools/test/stress2/misc/1st.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/aesni.sh b/tools/test/stress2/misc/aesni.sh
index c25694fa002a..0fe7390d2fbd 100755
--- a/tools/test/stress2/misc/aesni.sh
+++ b/tools/test/stress2/misc/aesni.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
@@ -29,6 +29,11 @@
# Simple AESNI(4) test.
+if [ $(uname -m) != "amd64" -a $(uname -m) != "i386" ]; then
+ echo "This test requires an x86 system."
+ exit 0
+fi
+
kldstat -v | grep -qw aesni || { kldload aesni.ko; loaded=1; }
../misc/geli.sh
diff --git a/tools/test/stress2/misc/all.debug.inc b/tools/test/stress2/misc/all.debug.inc
index ea0f2d6a5c58..4042ca1f7718 100644
--- a/tools/test/stress2/misc/all.debug.inc
+++ b/tools/test/stress2/misc/all.debug.inc
@@ -1,5 +1,5 @@
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
@@ -24,7 +24,6 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
-# $FreeBSD$
#
# Example debug include file for misc/all.sh
diff --git a/tools/test/stress2/misc/all.exclude b/tools/test/stress2/misc/all.exclude
index 029a77b9b094..f8a5ea4a91f1 100644
--- a/tools/test/stress2/misc/all.exclude
+++ b/tools/test/stress2/misc/all.exclude
@@ -1,40 +1,44 @@
-# List of tests not to run, unless the '-a' option is used with run.sh
+# List of tests not to run, unless the '-a' option is used with all.sh
# Exclude names must start in column 1
backingstore.sh g_vfs_done():md6a[WRITE(offset=...)]error = 28 20111220
backingstore2.sh panic: 43 vncache entries remaining 20111220
backingstore3.sh g_vfs_done():md6a[WRITE(offset=...)]error = 28 20111230
dd.sh CAM stuck in vmwait 20200116
+force13.sh https://people.freebsd.org/~pho/stress/log/log0376.txt 20221113
+force14.sh Waiting for fix 20230319
+force15.sh Waiting for fix 20230319
force4.sh https://people.freebsd.org/~pho/stress/log/log0082.txt 20210328
force7.sh https://people.freebsd.org/~pho/stress/log/log0266.txt 20220207
+fsck10.sh Waiting for fix 20230319
+fsck11.sh Waiting for fix 20230319
+fsck12.sh Waiting for fix 20230319
fsync.sh panic: Journal overflow 20190208
-fuse.sh Memory corruption seen in log file kostik734.txt 20141114
-fuse2.sh Deadlock seen 20121129
-fuse3.sh Deadlock seen 20141120
+fuse.sh https://people.freebsd.org/~pho/stress/log/log0546.txt 20240828
+fuse2.sh https://people.freebsd.org/~pho/stress/log/log0547.txt 20240828
getrandom.sh Known DoS issue 20201107
getrandom2.sh Known DoS issue 20200302
gjournal.sh panic: Journal overflow 20190626
gjournal2.sh panic: Journal overflow 20180125
gjournal3.sh panic: Bio not on queue 20171225
gjournal4.sh CAM stuck in vmwait 20180517
+gnop10.sh Waiting for fix 20230319
+gnop13.sh https://people.freebsd.org/~pho/stress/log/log0386.txt 20221113
gnop7.sh Waiting for patch commit 20190820
gnop8.sh Waiting for patch commit 20201214
gnop9.sh Waiting for patch commit 20201214
graid1_8.sh Known issue 20170909
graid1_9.sh panic: Bad effnlink 20180212
-gunion.sh Waiting for fix 20220308
-gunion2.sh Waiting for fix 20220308
-ifconfig.sh Bug 253824 20210322
-ifconfig2.sh https://people.freebsd.org/~pho/stress/log/log0051.txt 20210210
lockf5.sh Spinning threads seen 20160718
maxvnodes2.sh https://people.freebsd.org/~pho/stress/log/log0083.txt 20210329
memguard.sh https://people.freebsd.org/~pho/stress/log/log0088.txt 20210402
memguard2.sh Waiting for fix commit
memguard3.sh Waiting for fix commit
mlockall2.sh Unrecoverable OOM killing seen 20190203
+mlockall6.sh https://people.freebsd.org/~pho/stress/log/log0430.txt 20230403
mlockall7.sh Needs further investigation 20210123
-msetdomain.sh May change policy for random threads to to domainset_fixed 20210104
-newfs4.sh watchdog fired. newbuf 20190225
+msetdomain.sh May change policy for random threads to domainset_fixed 20210104
+newfs4.sh watchdog fired. newbuf (still seen 20240729) 20190225
nfs10.sh Double fault 20151013
nfs13.sh mount_nfs hangs in mntref 20191007
nfs15lockd.sh panic: Assertion td->td_realucred == td->td_ucred failed ... 20210211
@@ -42,53 +46,41 @@ nfs16.sh panic: Failed to register NFS lock locally - error=11 20160608
nullfs28.sh Hang in "mount drain" seen 20220111
oom2.sh Hang in pfault 20180324
overcommit2.sh CAM stuck in vmwait seen 20200112
-pageout.sh panic: handle_written_filepage: not started 20190218
pmc8.sh panic: [pmc,2749] (ri21, rc1) waiting too long for pmc to ... 20210621
-rename14.sh https://people.freebsd.org/~pho/stress/log/log0279.txt 20220415
+rename14.sh https://people.freebsd.org/~pho/stress/log/log0433.txt 20230409
sctp2.sh panic: Queues are not empty when handling SHUTDOWN-COMPLETE 20210211
sctp3.sh panic: Queues are not empty when handling SHUTDOWN-COMPLETE 20210211
-sendfile25.sh WiP 20200611
signal.sh Timing issues. Needs fixing 20171116
snap8.sh https://people.freebsd.org/~pho/stress/log/log0123.txt 20211008
+suj12.sh Waiting for fix 20230319
+suj19.sh https://people.freebsd.org/~pho/stress/log/log0378.txt 20221113
+suj27.sh https://people.freebsd.org/~pho/stress/log/log0387.txt 20221113
+suj36.sh https://people.freebsd.org/~pho/stress/log/log0392.txt 20221114
+swap3.sh https://people.freebsd.org/~pho/stress/log/log0543.txt 20240719
swapoff2.sh swap_pager_force_pagein: read from swap failed 20171223
swapoff3.sh Excessive OOM killing 20220403
swapoff5.sh log0005.txt, known issue 20210111
+swapoff6.sh https://people.freebsd.org/~pho/stress/log/log0540.txt 20240716
systrace.sh WiP 20200227
systrace2.sh WiP 20200227
-syzkaller15.sh WiP 20200712
-syzkaller16.sh WiP 20210722
-syzkaller25.sh WiP 20201116
-syzkaller27.sh watchdogd fires 20220512
-syzkaller28.sh WiP 20201120
-syzkaller50.sh panic: Assertion done != job_total_nbytes failed at ... 20220405
-syzkaller54.sh panic: td 0xfffffe014f7193a0 is not suspended 20220527
-syzkaller55.sh panic: Counter goes negative 20220525
+syzkaller16.sh zonelimit issue 20210722
+syzkaller28.sh panic: About to free ctl:0x... so:0x... and its in 1 20201120
+syzkaller31.sh panic: Bad tailq NEXT(0xfffffe01a0899430->tqh_last) != NULL 20220420
+syzkaller55.sh https://people.freebsd.org/~pho/stress/log/log0533.txt 20240702
syzkaller59.sh Page fault 20220625
+syzkaller65.sh panic: in_pcblookup_hash_locked: invalid local address 20230318
+syzkaller66.sh panic: in_pcbconnect: inp is already connected 20230621
+syzkaller67.sh panic: ASan: Invalid access, 8-byte read at ... 20230621
+quota6.sh https://people.freebsd.org/~pho/stress/log/log0456.txt 20240707
truss3.sh WiP 20200915
-unionfs14.sh WiP 20220111
-unionfs9.sh https://people.freebsd.org/~pho/stress/log/log0226.txt 20220111
# Test not to run for other reasons:
-fuzz.sh A know issue
marcus3.sh OK, but runs for a long time
statfs.sh Not very interesting
vunref.sh No problems ever seen
vunref2.sh No problems ever seen
-# Snapshots has been disabled on SU+J
-suj15.sh
-suj16.sh
-suj19.sh
-suj20.sh
-suj21.sh
-suj22.sh
-suj24.sh
-suj25.sh
-suj26.sh
-suj27.sh
-suj28.sh
-
# Exclude NFS loopback tests
nfs2.sh panic: wrong diroffset 20140219
nfs5.sh
diff --git a/tools/test/stress2/misc/all.sh b/tools/test/stress2/misc/all.sh
index 58bf3a630294..86d986099dbb 100755
--- a/tools/test/stress2/misc/all.sh
+++ b/tools/test/stress2/misc/all.sh
@@ -42,14 +42,15 @@ alloutput=$sdir/output # Output from current test
allexcess=$sdir/excessive # Tests with excessive runtime
allelapsed=$sdir/elapsed # Test runtime
alllocal=$sdir/all.exclude # Local exclude list
+exitonerror=0 # -e option
loops=0 # Times to run the tests
# Get kernel config + revision
rev=`uname -a | awk '{print $7}' | sed 's/://'`
rev="`uname -a | sed 's#.*/compile/##; s/ .*//'` $rev"
-args=`getopt acl:m:no "$@"`
+args=`getopt acel:m:no "$@"`
[ $? -ne 0 ] &&
- echo "Usage $0 [-a] [-c] [-l <val>] [-m <min.>] [-n] [-o] [<tests>]" &&
+ echo "Usage $0 [-a] [-c] [-e] [-l <val>] [-m <min.>] [-n] [-o] [<tests>]" &&
exit 1
set -- $args
for i; do
@@ -62,6 +63,9 @@ for i; do
rm -f $alllist
shift
;;
+ -e) exitonerror=1
+ shift
+ ;;
-l) loops=$2 # Number of time to run
shift; shift
;;
@@ -160,6 +164,7 @@ trap intr INT
[ -f all.debug.inc ] && . all.debug.inc
s1=`date +%s`
+touch $sdir/starttime
while true; do
exclude=`cat all.exclude $alllocal 2>/dev/null | sed '/^#/d' |
grep "^[a-zA-Z].*\.sh" | awk '{print $1}'`
@@ -226,6 +231,7 @@ while true; do
[ $e -ne 0 ] &&
echo "FAIL $i exit code $e"
) 2>&1 | tee $alloutput
+ grep -qw FAIL $alloutput && e=1 || e=0
ts=`date '+%Y%m%d %T'`
grep -qw FAIL $alloutput &&
echo "$ts $rev $i" >> $allfaillog &&
@@ -237,9 +243,8 @@ while true; do
[ -f ../tools/ministat.sh ] &&
../tools/ministat.sh $allelapsed $i
[ $((`date '+%s'` - start)) -gt 1980 ] &&
- printf "$ts *** Excessive run time: %s %d min\r\n" $i, \
- $(((`date '+%s'` - start) / 60)) |
- tee $console >> $allexcess
+ printf "$ts $rev $i %d min\n" \
+ $(((`date '+%s'` - start) / 60)) >> $allexcess
while pgrep -q "^swap$"; do
echo "swap still running"
sleep 2
@@ -248,6 +253,7 @@ while true; do
[ $all_debug ] && post_debug
[ $minutes ] && [ $((`date +%s` - s1)) -ge $minutes ] &&
break 2
+ [ $exitonerror -eq 1 -a $e -ne 0 ] && break 2
done
[ $((loops -= 1)) -eq 0 ] && break
done
diff --git a/tools/test/stress2/misc/arp.sh b/tools/test/stress2/misc/arp.sh
index ef66ce351e24..5c4d997ba975 100755
--- a/tools/test/stress2/misc/arp.sh
+++ b/tools/test/stress2/misc/arp.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/aslr.sh b/tools/test/stress2/misc/aslr.sh
index 6261fae4546b..686b2b414030 100755
--- a/tools/test/stress2/misc/aslr.sh
+++ b/tools/test/stress2/misc/aslr.sh
@@ -1,7 +1,7 @@
#/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/badcode2.sh b/tools/test/stress2/misc/badcode2.sh
index 8e47a74a87d1..dbf2cadbc4cd 100755
--- a/tools/test/stress2/misc/badcode2.sh
+++ b/tools/test/stress2/misc/badcode2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Peter Holm
#
diff --git a/tools/test/stress2/misc/badcode3.sh b/tools/test/stress2/misc/badcode3.sh
index e0a10d0074a4..da4f811bff6d 100755
--- a/tools/test/stress2/misc/badcode3.sh
+++ b/tools/test/stress2/misc/badcode3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Peter Holm
#
@@ -39,13 +39,18 @@ mdconfig -a -t swap -s 1g -u $mdstart
newfs $newfs_flags md$mdstart > /dev/null
mount /dev/md$mdstart $mntpoint
chmod 777 $mntpoint
+export badcodeLOAD=100
+export RUNDIR=$mntpoint/stressX
+mkdir -p $RUNDIR
+chmod 0777 $RUNDIR
here=`pwd`
cd $mntpoint
(cd $here/../testcases/swap; ./swap -t 5m -i 20) &
sleep 2
while pgrep -q swap; do
- timeout 1m limits -c 0 $here/../testcases/badcode/badcode -t 1m -i 20
+ su $testuser -c \
+ "timeout 1m limits -c 0 $here/../testcases/badcode/badcode -t 1m -i 20"
done
wait
cd $here
diff --git a/tools/test/stress2/misc/beneath.sh b/tools/test/stress2/misc/beneath.sh
index 5f61dbd5e383..29c7ce967197 100755
--- a/tools/test/stress2/misc/beneath.sh
+++ b/tools/test/stress2/misc/beneath.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Konstantin Belousov <kib@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/beneath2.sh b/tools/test/stress2/misc/beneath2.sh
index ad1f5c538258..5cbe3c160e00 100755
--- a/tools/test/stress2/misc/beneath2.sh
+++ b/tools/test/stress2/misc/beneath2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/beneath3.sh b/tools/test/stress2/misc/beneath3.sh
index 9e7493a2322c..aac7079e284b 100755
--- a/tools/test/stress2/misc/beneath3.sh
+++ b/tools/test/stress2/misc/beneath3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/beneath4.sh b/tools/test/stress2/misc/beneath4.sh
index 0f51980cb75a..48458f088a96 100755
--- a/tools/test/stress2/misc/beneath4.sh
+++ b/tools/test/stress2/misc/beneath4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/buildkernel.sh b/tools/test/stress2/misc/buildkernel.sh
index fe8d530dfab7..e0aa85617f9b 100755
--- a/tools/test/stress2/misc/buildkernel.sh
+++ b/tools/test/stress2/misc/buildkernel.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
@@ -49,6 +49,7 @@ chmod 0777 $TMPDIR
log=$mntpoint/log
p=$((`sysctl -n hw.ncpu`+ 1))
+[ $p -gt 32 ] && p=32 # Arbitrary cap
p=`jot -r 1 1 $p`
echo "make -j $p buildkernel KERNCONF=GENERIC DESTDIR=$mntpoint" \
"TARGET=amd64 TARGET_ARCH=amd64"
diff --git a/tools/test/stress2/misc/buildworld.sh b/tools/test/stress2/misc/buildworld.sh
index 595b387c90ae..3b362ec7041a 100755
--- a/tools/test/stress2/misc/buildworld.sh
+++ b/tools/test/stress2/misc/buildworld.sh
@@ -55,6 +55,7 @@ mkdir $TMPDIR
chmod 0777 $TMPDIR
p=$((`sysctl -n hw.ncpu`+ 1))
+[ $p -gt 32 ] && p=32 # Arbitrary cap
timeout 20m make -i -j $p buildworld DESTDIR=$mntpoint TARGET=amd64 \
TARGET_ARCH=amd64 > /dev/null
diff --git a/tools/test/stress2/misc/buildworld2.sh b/tools/test/stress2/misc/buildworld2.sh
index 9c1eed97b7ea..3653cb1db5b4 100755
--- a/tools/test/stress2/misc/buildworld2.sh
+++ b/tools/test/stress2/misc/buildworld2.sh
@@ -46,6 +46,7 @@ mkdir $TMPDIR
chmod 0777 $TMPDIR
p=$((`sysctl -n hw.ncpu`+ 1))
+[ $p -gt 32 ] && p=32 # Arbitrary cap
make -j $p buildworld DESTDIR=$mntpoint TARGET=amd64 TARGET_ARCH=amd64 \
> /dev/null &
sleep $((20 * 60))
diff --git a/tools/test/stress2/misc/buildworld3.sh b/tools/test/stress2/misc/buildworld3.sh
index a5dc642ce876..e3bce2764c0c 100755
--- a/tools/test/stress2/misc/buildworld3.sh
+++ b/tools/test/stress2/misc/buildworld3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
@@ -62,6 +62,7 @@ mkdir $TMPDIR $MAKEOBJDIRPREFIX
chmod 0777 $TMPDIR $MAKEOBJDIRPREFIX
p=$((`sysctl -n hw.ncpu`+ 1))
+[ $p -gt 32 ] && p=32 # Arbitrary cap
su $testuser -c \
"make -i -j $p buildworld DESTDIR=$mntpoint TARGET=amd64 \
TARGET_ARCH=amd64 > /dev/null" &
diff --git a/tools/test/stress2/misc/buildworld4.sh b/tools/test/stress2/misc/buildworld4.sh
index 98d4904ec4bd..d1d162120952 100755
--- a/tools/test/stress2/misc/buildworld4.sh
+++ b/tools/test/stress2/misc/buildworld4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
@@ -50,6 +50,7 @@ mkdir $TMPDIR
chmod 0777 $TMPDIR
p=$((`sysctl -n hw.ncpu`+ 1))
+[ $p -gt 16 ] && p=16 # Arbitrary cap
[ `sysctl -n vm.swap_total` -gt 0 ] && p=$((p * 4))
p=`jot -r 1 1 $p`
echo "make -i -j $p buildworld DESTDIR=$mntpoint TARGET=amd64 "\
diff --git a/tools/test/stress2/misc/chain.sh b/tools/test/stress2/misc/chain.sh
index 46d2f32cd7c4..ebc3f118e1bf 100755
--- a/tools/test/stress2/misc/chain.sh
+++ b/tools/test/stress2/misc/chain.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Jeremy <peterj@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/chroot.sh b/tools/test/stress2/misc/chroot.sh
index 176b249312f0..35e2d2f11e0e 100755
--- a/tools/test/stress2/misc/chroot.sh
+++ b/tools/test/stress2/misc/chroot.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/compare.sh b/tools/test/stress2/misc/compare.sh
index c983046384b5..9ca6542d1af5 100755
--- a/tools/test/stress2/misc/compare.sh
+++ b/tools/test/stress2/misc/compare.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/contigmalloc.sh b/tools/test/stress2/misc/contigmalloc.sh
index 92bf6ff40905..abaa2c3cad53 100755
--- a/tools/test/stress2/misc/contigmalloc.sh
+++ b/tools/test/stress2/misc/contigmalloc.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# contigmalloc(9) / contigfree(9) test scenario.
+# contigmalloc(9) / free(9) test scenario.
# malloc() a random number of buffers with random size and then free them.
# A malloc pattern might look like this:
@@ -116,7 +116,7 @@ test(int argc, char *argv[])
if (p[i] != NULL) {
res = syscall(no, TFREE, &p[i], &size[i]);
#if defined(TEST)
- fprintf(stderr, "contigfree(%lu pages)\n",
+ fprintf(stderr, "free(%lu pages)\n",
size[i] / ps);
#endif
p[i] = NULL;
@@ -197,10 +197,8 @@ cmalloc(struct thread *td, struct cmalloc_args *uap)
switch (uap->a_op) {
case TFREE:
error = copyin(uap->a_ptr, &p, sizeof(p));
- if (error == 0) {
- if (p != NULL)
- contigfree(p, size, M_TEMP);
- }
+ if (error == 0)
+ free(p, M_TEMP);
return (error);
case TALLOC:
diff --git a/tools/test/stress2/misc/contigmalloc2.sh b/tools/test/stress2/misc/contigmalloc2.sh
index e3ec5bf3a358..dd4bbd751fd4 100755
--- a/tools/test/stress2/misc/contigmalloc2.sh
+++ b/tools/test/stress2/misc/contigmalloc2.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# contigmalloc(9) / contigfree(9) test scenario.
+# contigmalloc(9) / free(9) test scenario.
# Regression test for allocations >= 2 GiB.
# "panic: vm_page_insert_after: mpred doesn't precede pindex" seen.
# Fixed by r284207.
@@ -87,8 +87,7 @@ test(int argc, char *argv[])
#endif
res = syscall(no, TFREE, &p, &size);
#if defined(TEST)
- fprintf(stderr, "contigfree(%lu pages)\n",
- size);
+ fprintf(stderr, "free(%lu pages)\n", size);
#endif
}
size /= 2;
@@ -165,10 +164,8 @@ cmalloc(struct thread *td, struct cmalloc_args *uap)
switch (uap->a_op) {
case TFREE:
error = copyin(uap->a_ptr, &p, sizeof(p));
- if (error == 0) {
- if (p != NULL)
- contigfree(p, size, M_TEMP);
- }
+ if (error == 0)
+ free(p, M_TEMP);
return (error);
case TALLOC:
diff --git a/tools/test/stress2/misc/contigmalloc3.sh b/tools/test/stress2/misc/contigmalloc3.sh
index 9baf7c129688..28d5c17e0566 100755
--- a/tools/test/stress2/misc/contigmalloc3.sh
+++ b/tools/test/stress2/misc/contigmalloc3.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# contigmalloc(9) / contigfree(9) test scenario.
+# contigmalloc(9) / free(9) test scenario.
# Test allocation with 1GB
# "panic: Bad link elm 0x6766fbc next->prev != elm" seen:
@@ -91,7 +91,7 @@ test(int argc, char *argv[])
res = syscall(no, TFREE, &cp, &size);
#if defined(TEST)
- fprintf(stderr, "contigfree(%lu pages) %luMB\n",
+ fprintf(stderr, "free(%lu pages) %luMB\n",
size / ps, size / 1024 / 1024);
#endif
}
@@ -166,10 +166,8 @@ cmalloc(struct thread *td, struct cmalloc_args *uap)
switch (uap->a_op) {
case TFREE:
error = copyin(uap->a_ptr, &p, sizeof(p));
- if (error == 0) {
- if (p != NULL)
- contigfree(p, size, M_TEMP);
- }
+ if (error == 0)
+ free(p, M_TEMP);
return (error);
case TALLOC:
diff --git a/tools/test/stress2/misc/core5.sh b/tools/test/stress2/misc/core5.sh
index 856b01608f2e..c7928a7cf1dc 100755
--- a/tools/test/stress2/misc/core5.sh
+++ b/tools/test/stress2/misc/core5.sh
@@ -34,7 +34,7 @@
# 20150714 Slowdown seen with core5 waiting in vlruwk.
# sysctl vfs.vlru_allow_cache_src=1 used to resolve this.
-# For now change MAXVNODES from 1.000 to 4.000.
+# For now change MAXVNODES from 1.000 to 5.000.
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
. ../default.cfg
@@ -131,7 +131,7 @@ EOF
#include <time.h>
#include <unistd.h>
-#define MAXVNODES 4000
+#define MAXVNODES 5000
#define NBFILES 10000
#define PARALLEL 4
#define RTIME (10 * 60)
diff --git a/tools/test/stress2/misc/cpuset.sh b/tools/test/stress2/misc/cpuset.sh
index ad9f8569f386..359974a4bd87 100755
--- a/tools/test/stress2/misc/cpuset.sh
+++ b/tools/test/stress2/misc/cpuset.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/creat.sh b/tools/test/stress2/misc/creat.sh
new file mode 100755
index 000000000000..1abab774ed7f
--- /dev/null
+++ b/tools/test/stress2/misc/creat.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Demonstrate incorrect "out of inodes" message with SU enabled.
+# No issue seen with SU+J
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+set -eu
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+s=0
+mount | grep -q "on $mntpoint " && umount $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+
+mdconfig -a -t swap -s 100m -u $mdstart
+[ $# -eq 1 ] && flags="$@" || flags="-Un"
+echo "newfs $flags /dev/md$mdstart"
+newfs $flags /dev/md$mdstart > /dev/null
+[ "$flags" = "" ] && tunefs -n disable md$mdstart
+mount /dev/md$mdstart $mntpoint
+set +e
+
+ifree1=`df -i $mntpoint | tail -1 | awk '{print $7}'`
+before=`df -i $mntpoint`
+n=$(((ifree1 - 5) / 10))
+jot 10 | xargs -I% mkdir $mntpoint/%
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 60 ]; do
+ for j in `jot 10`; do
+ (
+ jot $n | xargs -P0 -I% touch $mntpoint/$j/%
+ jot $n | xargs -P0 -I% rm $mntpoint/$j/%
+ ) &
+ done
+ wait
+done 2>&1 | tee $log | head -5
+[ -s $log ] && s=3
+jot 10 | xargs -I% rmdir $mntpoint/%
+umount $mntpoint; mount /dev/md$mdstart $mntpoint
+
+ifree2=`df -i $mntpoint | tail -1 | awk '{print $7}'`
+after=`df -i $mntpoint | tail -1`
+if [ $ifree1 -ne $ifree2 ]; then
+ echo "$before"
+ echo "$after"
+ s=1
+ ls -alsrt $mntpoint | head -20
+fi
+
+umount $mntpoint
+fsck -fy /dev/md$mdstart > $log 2>&1
+grep -Eq "WAS MODIFIED" $log && { s=2; cat $log; }
+
+mdconfig -d -u $mdstart
+rm -f $log
+exit $s
diff --git a/tools/test/stress2/misc/crossmp.sh b/tools/test/stress2/misc/crossmp.sh
index 0bd07cea2aaf..b61506dcc477 100755
--- a/tools/test/stress2/misc/crossmp.sh
+++ b/tools/test/stress2/misc/crossmp.sh
@@ -74,7 +74,8 @@ else
else
# The test: Parallel mount and unmounts
- for i in `jot 1024`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
m=$1
mount /dev/md${m} ${mntpoint}$m
while mount | grep -q "on ${mntpoint}$m "; do
diff --git a/tools/test/stress2/misc/crossmp2.sh b/tools/test/stress2/misc/crossmp2.sh
index 03cd04e077c1..1f2f1a921e10 100755
--- a/tools/test/stress2/misc/crossmp2.sh
+++ b/tools/test/stress2/misc/crossmp2.sh
@@ -67,7 +67,8 @@ else
else
# The test: Parallel mount and unmounts
- for i in `jot 128`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
m=$1
mount -t nfs -o tcp -o nfsv3 -o retrycnt=3 \
-o intr,soft -o rw $nfs_export ${mntpoint}$m
diff --git a/tools/test/stress2/misc/crossmp3.sh b/tools/test/stress2/misc/crossmp3.sh
index 5eecb936e900..32c625a1e4ad 100755
--- a/tools/test/stress2/misc/crossmp3.sh
+++ b/tools/test/stress2/misc/crossmp3.sh
@@ -41,6 +41,7 @@
CONT=/tmp/crossmp3.continue
if [ $# -eq 0 ]; then
N=`sysctl -n hw.ncpu`
+ [ $N -gt 32 ] && N=32 # Arbitrary cap
usermem=`sysctl -n hw.usermem`
[ `sysctl -n vm.swap_total` -eq 0 ] && usermem=$((usermem / 2))
size=$((usermem / 1024 / 1024 / N))
diff --git a/tools/test/stress2/misc/crossmp4.sh b/tools/test/stress2/misc/crossmp4.sh
index e22f969b72bb..21d22bee69e5 100755
--- a/tools/test/stress2/misc/crossmp4.sh
+++ b/tools/test/stress2/misc/crossmp4.sh
@@ -40,6 +40,7 @@
. ../default.cfg
N=`sysctl -n hw.ncpu`
+[ $N -gt 32 ] && N=32 # Arbitrary cap
usermem=`sysctl -n hw.usermem`
[ `swapinfo | wc -l` -eq 1 ] && usermem=$((usermem/100*80))
size=$((usermem / 1024 / 1024 - 2))
diff --git a/tools/test/stress2/misc/crossmp5.sh b/tools/test/stress2/misc/crossmp5.sh
index b5a8304f2dcb..6e504d9f20ad 100755
--- a/tools/test/stress2/misc/crossmp5.sh
+++ b/tools/test/stress2/misc/crossmp5.sh
@@ -33,6 +33,7 @@
. ../default.cfg
N=`sysctl -n hw.ncpu`
+[ $N -gt 32 ] && N=32 # Arbitrary cap
usermem=`sysctl -n hw.usermem`
[ `swapinfo | wc -l` -eq 1 ] && usermem=$((usermem/100*80))
size=$((usermem / 1024 / 1024 / N))
@@ -74,8 +75,10 @@ else
done
else
# The test: Parallel mount and unmount
+ i=0
m=$1
- for i in `jot 200`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
mount /dev/md${m} ${mntpoint}$m
chmod 777 ${mntpoint}$m
l=`jot -r 1 65535`
@@ -88,6 +91,7 @@ else
echo "-f")
umount $opt ${mntpoint}$m > /dev/null 2>&1
done
+ i=$((i + 1))
done
rm -f /tmp/crossmp.continue
fi
diff --git a/tools/test/stress2/misc/crossmp6.sh b/tools/test/stress2/misc/crossmp6.sh
index 92ca0abcba27..d5abd27f99f1 100755
--- a/tools/test/stress2/misc/crossmp6.sh
+++ b/tools/test/stress2/misc/crossmp6.sh
@@ -72,7 +72,8 @@ if [ $# -eq 0 ]; then
exit 0
else
if [ $1 = find ]; then
- for i in `jot 128`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
find ${mntpoint}* -maxdepth 1 -type f > \
/dev/null 2>&1
(lockf -t 10 ${mntpoint}$2/$0.$$.$i sleep 1 &) > \
diff --git a/tools/test/stress2/misc/crossmp7.sh b/tools/test/stress2/misc/crossmp7.sh
index c2c2752f38e7..f4f12e64c35f 100755
--- a/tools/test/stress2/misc/crossmp7.sh
+++ b/tools/test/stress2/misc/crossmp7.sh
@@ -91,7 +91,8 @@ else
else
# The test: Parallel mount and unmounts
m=$1
- for i in `jot 1024`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
zfs mount stress2_tank/test$m
zfs umount -f stress2_tank/test$m
done 2>/dev/null
diff --git a/tools/test/stress2/misc/crossmp8.sh b/tools/test/stress2/misc/crossmp8.sh
index e877dfaf6d1c..eec5ba9bc7c1 100755
--- a/tools/test/stress2/misc/crossmp8.sh
+++ b/tools/test/stress2/misc/crossmp8.sh
@@ -41,6 +41,7 @@
CONT=/tmp/crossmp8.continue
N=`sysctl -n hw.ncpu`
+[ $N -gt 32 ] && N=32 # Arbitrary cap
usermem=`sysctl -n hw.usermem`
[ `swapinfo | wc -l` -eq 1 ] && usermem=$((usermem/100*80))
size=$((usermem / 1024 / 1024 / N))
diff --git a/tools/test/stress2/misc/datagram.sh b/tools/test/stress2/misc/datagram.sh
index 5a5715886a88..0eec052823b7 100755
--- a/tools/test/stress2/misc/datagram.sh
+++ b/tools/test/stress2/misc/datagram.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/datagram2.sh b/tools/test/stress2/misc/datagram2.sh
index 66cfd44711c2..746ea33cb734 100755
--- a/tools/test/stress2/misc/datagram2.sh
+++ b/tools/test/stress2/misc/datagram2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/datagram3.sh b/tools/test/stress2/misc/datagram3.sh
index ca54377befcc..a5e141702139 100755
--- a/tools/test/stress2/misc/datagram3.sh
+++ b/tools/test/stress2/misc/datagram3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/datamove.sh b/tools/test/stress2/misc/datamove.sh
index a27a53e5e31b..67de998f3816 100755
--- a/tools/test/stress2/misc/datamove.sh
+++ b/tools/test/stress2/misc/datamove.sh
@@ -194,7 +194,7 @@ int startIO(int fd,char *buffer)
return 0;
}
-int main(int argc,char *argv[],char *envp[])
+int main(void)
{
int fdA,fdB,fdDelayA,fdDelayB;
diff --git a/tools/test/stress2/misc/datamove2.sh b/tools/test/stress2/misc/datamove2.sh
index 1b4c964a1f12..e503edf152a4 100755
--- a/tools/test/stress2/misc/datamove2.sh
+++ b/tools/test/stress2/misc/datamove2.sh
@@ -194,7 +194,7 @@ startIO(int fd, char *buffer)
}
int
-main(int argc, char *argv[], char *envp[])
+main(void)
{
int fdA, fdB, fdDelayA, fdDelayB;
diff --git a/tools/test/stress2/misc/datamove3.sh b/tools/test/stress2/misc/datamove3.sh
index 19beffc00655..0cdd4b5c0c3c 100755
--- a/tools/test/stress2/misc/datamove3.sh
+++ b/tools/test/stress2/misc/datamove3.sh
@@ -192,7 +192,7 @@ startIO(int fd, char *buffer)
}
int
-main(int argc, char *argv[], char *envp[])
+main(void)
{
int fdA, fdB, fdDelayA, fdDelayB;
diff --git a/tools/test/stress2/misc/datamove6.sh b/tools/test/stress2/misc/datamove6.sh
new file mode 100755
index 000000000000..88bfea425bdc
--- /dev/null
+++ b/tools/test/stress2/misc/datamove6.sh
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Variation of the datamove.sh, using MSDOSFS
+
+# No problems seen
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+here=`pwd`
+prog=$(basename "$0" .sh)
+cd /tmp
+sed '1,/^EOF/d' < $here/datamove.sh > $prog.c
+mycc -o $prog -Wall -Wextra -O2 -g $prog.c
+rm -f $prog.c
+
+set -eu
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 2g -u $mdstart
+newfs_msdos -F 32 -b 8192 /dev/md$mdstart 2> /dev/null
+#mount -t msdosfs /dev/md$mdstart $mntpoint
+mount_msdosfs -m 777 /dev/md$mdstart $mntpoint
+set +e
+
+$here/../testcases/swap/swap -t 5m -i 100 -h &
+for i in `jot 5`; do
+ su $testuser -c "cd $mntpoint; /tmp/$prog"
+done
+mv /tmp/$prog $mntpoint
+for i in `jot 5`; do
+ mkdir -p $mntpoint/datamove.dir.$i
+ cd $mntpoint/datamove.dir.$i
+ $mntpoint/$prog &
+done
+pkill swap
+wait
+while mount | grep -q $mntpoint; do
+ umount -f $mntpoint > /dev/null 2>&1
+done
+mdconfig -d -u $mdstart
+
+exit 0
diff --git a/tools/test/stress2/misc/devfs4.sh b/tools/test/stress2/misc/devfs4.sh
index 3ca8f44eb036..03a9f8cc8ca3 100755
--- a/tools/test/stress2/misc/devfs4.sh
+++ b/tools/test/stress2/misc/devfs4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/devfs5.sh b/tools/test/stress2/misc/devfs5.sh
index b0b1d98fc83e..5a72d7db9efb 100755
--- a/tools/test/stress2/misc/devfs5.sh
+++ b/tools/test/stress2/misc/devfs5.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
@@ -30,7 +30,7 @@
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
# Test scenario for https://reviews.freebsd.org/D20411
-# Add devfs(5) support for VOP_MKDIR(9) and VOP_RMDIR(9)
+# Add devfs(4) support for VOP_MKDIR(9) and VOP_RMDIR(9)
. ../default.cfg
diff --git a/tools/test/stress2/misc/dtrace_fault.sh b/tools/test/stress2/misc/dtrace_fault.sh
index 508cfc48cd59..6de6c058a998 100755
--- a/tools/test/stress2/misc/dtrace_fault.sh
+++ b/tools/test/stress2/misc/dtrace_fault.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Konstantin Belousov <kib@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/dup.sh b/tools/test/stress2/misc/dup.sh
index 7223709d09c4..89b4e637a737 100755
--- a/tools/test/stress2/misc/dup.sh
+++ b/tools/test/stress2/misc/dup.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/elf.sh b/tools/test/stress2/misc/elf.sh
index eb6650c9c088..5d7cbaaf9952 100755
--- a/tools/test/stress2/misc/elf.sh
+++ b/tools/test/stress2/misc/elf.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
diff --git a/tools/test/stress2/misc/execpath.sh b/tools/test/stress2/misc/execpath.sh
index 22613a948e6b..0e88472ae356 100755
--- a/tools/test/stress2/misc/execpath.sh
+++ b/tools/test/stress2/misc/execpath.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/exlock2.sh b/tools/test/stress2/misc/exlock2.sh
index 94e3f88f48e3..811fd96f502c 100755
--- a/tools/test/stress2/misc/exlock2.sh
+++ b/tools/test/stress2/misc/exlock2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
@@ -68,6 +68,7 @@ EOF
#include <unistd.h>
static _Atomic(int) *share;
+static int debug; /* Set to "1" for debug output */
static int quit;
static char file[80];
@@ -101,9 +102,8 @@ test1(void)
; /* wait for test2 to signal "done" */
close(fd);
}
-#if defined(DEBUG)
- fprintf(stderr, "%s: n = %d\n", __func__, n);
-#endif
+ if (debug != 0)
+ fprintf(stderr, "%s: n = %d\n", __func__, n);
_exit(0);
}
@@ -114,17 +114,15 @@ test2(void)
struct flock fl;
struct stat st;
time_t start;
- int e, fd, n;
+ int e, fd;
e = 0;
fd = 0;
- n = 0;
start = time(NULL);
while (time(NULL) - start < RUNTIME) {
share[SYNC] = 1;
if ((fd = open(file, O_RDWR)) == -1)
goto out;
- n++;
memset(&fl, 0, sizeof(fl));
fl.l_start = 0;
fl.l_len = 0;
@@ -151,12 +149,9 @@ out:
share[SYNC] = 0;
usleep(100);
}
-#if defined(DEBUG)
- if (e != 0) {
- system("ps -Uroot | grep -v grep | grep /tmp/exlock2 | "\
+ if (debug != 0 && e != 0)
+ system("ps -x | grep -v grep | grep /tmp/exlock2 | "\
"awk '{print $1}' | xargs procstat -f");
- }
-#endif
share[SYNC] = 0;
_exit(e);
diff --git a/tools/test/stress2/misc/ext2fs.sh b/tools/test/stress2/misc/ext2fs.sh
index f4d33116faed..e93da12419b0 100755
--- a/tools/test/stress2/misc/ext2fs.sh
+++ b/tools/test/stress2/misc/ext2fs.sh
@@ -32,7 +32,7 @@
. ../default.cfg
-# Uses mke2fs from sysutils/e2fsprogs
+# Uses mke2fs from filesystems/e2fsprogs
[ -z "`type mke2fs 2>/dev/null`" ] &&
echo "Skipping test as mke2fs not installed" && exit 0
diff --git a/tools/test/stress2/misc/ext2fs2.sh b/tools/test/stress2/misc/ext2fs2.sh
index 748e45a33ffa..07ff5d5058fb 100755
--- a/tools/test/stress2/misc/ext2fs2.sh
+++ b/tools/test/stress2/misc/ext2fs2.sh
@@ -33,7 +33,7 @@
. ../default.cfg
-# Uses mke2fs from sysutils/e2fsprogs
+# Uses mke2fs from filesystems/e2fsprogs
[ -x /usr/local/sbin/mke2fs ] || exit 0
mount | grep "$mntpoint" | grep -q md$mdstart && umount -f $mntpoint
mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart
diff --git a/tools/test/stress2/misc/ext2fs3.sh b/tools/test/stress2/misc/ext2fs3.sh
index f33b4cc73547..5c904d218a5f 100755
--- a/tools/test/stress2/misc/ext2fs3.sh
+++ b/tools/test/stress2/misc/ext2fs3.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# ext2fs(5) test scenario with a 1k block size
+# ext2fs(4) test scenario with a 1k block size
# "panic: ext2_reallocblks: alloc mismatch" seen.
# "Fatal trap 12: page fault while in kernel mode" seen.
@@ -35,7 +35,7 @@
. ../default.cfg
-# Uses mke2fs from sysutils/e2fsprogs
+# Uses mke2fs from filesystems/e2fsprogs
[ -z "`type mke2fs 2>/dev/null`" ] &&
echo "Skipping test as mke2fs not installed" && exit 0
diff --git a/tools/test/stress2/misc/ext3fs.sh b/tools/test/stress2/misc/ext3fs.sh
index 826317857f85..210008ce3942 100755
--- a/tools/test/stress2/misc/ext3fs.sh
+++ b/tools/test/stress2/misc/ext3fs.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
@@ -33,7 +33,7 @@
. ../default.cfg
-# Uses mke2fs from sysutils/e2fsprogs
+# Uses mke2fs from filesystems/e2fsprogs
[ -z "`type mke2fs 2>/dev/null`" ] &&
echo "Skipping test as mke2fs not installed" && exit 0
diff --git a/tools/test/stress2/misc/ext4fs.sh b/tools/test/stress2/misc/ext4fs.sh
index 610351352501..2e2ac8d77440 100755
--- a/tools/test/stress2/misc/ext4fs.sh
+++ b/tools/test/stress2/misc/ext4fs.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
@@ -36,7 +36,7 @@
. ../default.cfg
-# Uses mke2fs from sysutils/e2fsprogs
+# Uses mke2fs from filesystems/e2fsprogs
[ -z "`type mke2fs 2>/dev/null`" ] &&
echo "Skipping test as mke2fs not installed" && exit 0
diff --git a/tools/test/stress2/misc/extattr2.sh b/tools/test/stress2/misc/extattr2.sh
index 3ce10dfbc894..64cd73dcce47 100755
--- a/tools/test/stress2/misc/extattr2.sh
+++ b/tools/test/stress2/misc/extattr2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/extattr3.sh b/tools/test/stress2/misc/extattr3.sh
index 84b5e1821473..82d404400b7d 100755
--- a/tools/test/stress2/misc/extattr3.sh
+++ b/tools/test/stress2/misc/extattr3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/fcntl.sh b/tools/test/stress2/misc/fcntl.sh
index 39f7f87dc005..237cacdf6de8 100755
--- a/tools/test/stress2/misc/fcntl.sh
+++ b/tools/test/stress2/misc/fcntl.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# fcntl(2) locking scenario. No problems seen.
+# fcntl(2) locking scenario.
. ../default.cfg
@@ -45,6 +45,8 @@ rm -f /tmp/fcntl
exit $status
EOF
#include <sys/types.h>
+#include <sys/wait.h>
+
#include <err.h>
#include <errno.h>
#include <fcntl.h>
@@ -52,7 +54,6 @@ EOF
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/wait.h>
#include <unistd.h>
#define PARALLEL 16
@@ -80,9 +81,10 @@ add(int n, int increment)
{
struct flock fl;
off_t pos;
- long val, oval __unused;
- int r;
+ long val, oval;
+ int debug, r;
+ debug = 0; /* set to "1" for debug output. */
pos = n * sizeof(val);
memset(&fl, 0, sizeof(fl));
fl.l_start = pos;
@@ -107,10 +109,9 @@ add(int n, int increment)
}
oval = val;
val = val + increment;
-#if defined(DEBUG)
- fprintf(stderr, "add(%d, %d) @ pos %ld: %ld = %ld + %d\n",
- n, increment, (long)pos, val, oval, increment);
-#endif
+ if (debug != 0)
+ fprintf(stderr, "add(%d, %d) @ pos %ld: %ld = %ld + %d\n",
+ n, increment, (long)pos, val, oval, increment);
if (lseek(fd, pos, SEEK_SET) == -1)
err(1, "lseek");
while ((r = write(fd, &val, sizeof(val)) != sizeof(val))) {
@@ -178,9 +179,9 @@ down(void)
int
main(void)
{
- int flags, i;
- long val, sum;
off_t len;
+ long val, sum;
+ int flags, i;
signal(SIGHUP, handler);
signal(SIGALRM, ahandler);
diff --git a/tools/test/stress2/misc/fcntl2.sh b/tools/test/stress2/misc/fcntl2.sh
index 5f276ae81ccc..acb161fd0523 100755
--- a/tools/test/stress2/misc/fcntl2.sh
+++ b/tools/test/stress2/misc/fcntl2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
@@ -150,6 +150,8 @@ test(void)
}
close(fd);
unlink(file);
+ if (success == 0)
+ fprintf(stderr, "No calls to fcntl() succeeded.\n");
_exit(0);
}
diff --git a/tools/test/stress2/misc/fcntl3.sh b/tools/test/stress2/misc/fcntl3.sh
index 8892a9d5670b..650619b43762 100755
--- a/tools/test/stress2/misc/fcntl3.sh
+++ b/tools/test/stress2/misc/fcntl3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Mark Johnston <markj@freebsd.org>
#
diff --git a/tools/test/stress2/misc/fexecve.sh b/tools/test/stress2/misc/fexecve.sh
index 01ff0b723134..432945061c64 100755
--- a/tools/test/stress2/misc/fexecve.sh
+++ b/tools/test/stress2/misc/fexecve.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/fifo2.sh b/tools/test/stress2/misc/fifo2.sh
index 9e4a7e632e9d..4a7b986931d9 100755
--- a/tools/test/stress2/misc/fifo2.sh
+++ b/tools/test/stress2/misc/fifo2.sh
@@ -96,6 +96,7 @@ EOF
#include <unistd.h>
#define N (128 * 1024 / (int)sizeof(u_int32_t))
+static int debug; /* Set to 1 for debug output */
u_int32_t r[N];
static void
@@ -143,11 +144,10 @@ calls(void *arg __unused)
arg6 = makearg();
arg7 = makearg();
-#if 0
- fprintf(stderr, "%2d : syscall(%3d, %lx, %lx, %lx, %lx, %lx, %lx, %lx)\n",
- i, SYS_open, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
+ if (debug != 0)
+ fprintf(stderr, "%2d : syscall(%3d, %lx, %lx, %lx, %lx, %lx, %lx, %lx)\n",
+ i, SYS_open, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
usleep(100000);
-#endif
alarm(1);
syscall(SYS_open, arg1, arg2, arg3, arg4, arg5, arg6, arg7);
}
diff --git a/tools/test/stress2/misc/fifo4.sh b/tools/test/stress2/misc/fifo4.sh
index 7f46f8537dc6..1578b8786d43 100755
--- a/tools/test/stress2/misc/fifo4.sh
+++ b/tools/test/stress2/misc/fifo4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
@@ -27,7 +27,7 @@
# SUCH DAMAGE.
#
-# tmpfs(5) version of fifo2.sh
+# tmpfs(4) version of fifo2.sh
# No problems seen on HEAD.
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
diff --git a/tools/test/stress2/misc/flock_open_close.sh b/tools/test/stress2/misc/flock_open_close.sh
index 01e376319abe..39b894da8a63 100755
--- a/tools/test/stress2/misc/flock_open_close.sh
+++ b/tools/test/stress2/misc/flock_open_close.sh
@@ -87,6 +87,7 @@ EOF
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
+#include <time.h>
#include <unistd.h>
static void
@@ -135,7 +136,8 @@ main(int ac, char **av)
{
struct stat sb;
pid_t pid;
- int e, i, status;
+ time_t start;
+ int e, status;
if (ac < 2)
usage();
@@ -150,7 +152,8 @@ main(int ac, char **av)
if (pid == 0)
child(av[1]);
e = 0;
- for (i = 0; i < 200000; i++) {
+ start = time(NULL);
+ while (time(NULL) - start < 150) {
pid = fork();
if (pid < 0)
err(1, "vfork");
diff --git a/tools/test/stress2/misc/force.sh b/tools/test/stress2/misc/force.sh
index 4c5cd6c255f6..61f15b0d5b8b 100755
--- a/tools/test/stress2/misc/force.sh
+++ b/tools/test/stress2/misc/force.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/force10.sh b/tools/test/stress2/misc/force10.sh
new file mode 100755
index 000000000000..d0ff36ae2ef9
--- /dev/null
+++ b/tools/test/stress2/misc/force10.sh
@@ -0,0 +1,92 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# "mdconfig -o force" test scenario. Simplification of force7.sh
+
+# panic: buf_alloc: BUF_LOCK on free buf 0xfffffe0038652410: 16.
+# https://people.freebsd.org/~pho/stress/log/log0270.txt
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+set -u
+log=/tmp/force10.sh.log
+mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+truncate -s 1g $diskimage
+mdconfig -a -t vnode -f $diskimage -s 1g -u $mdstart
+flags=$newfs_flags
+echo "newfs $flags md$mdstart"
+newfs $flags md$mdstart > /dev/null 2>&1
+
+#export TESTPROGS=`cd ..; find testcases/ -perm -1 -type f | \
+# egrep -Ev "/run/|/badcode/|/pty/|/shm/|/socket/|sysctl|tcp|thr|udp"`
+export TESTPROGS='
+testcases/creat/creat
+testcases/swap/swap
+'
+export runRUNTIME=3m
+export RUNDIR=$mntpoint/stressX
+s=0
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 300 ]; do
+ mount /dev/md$mdstart $mntpoint
+ rm -fr $mntpoint/lost+found
+ chmod 777 $mntpoint
+
+ su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > \
+ /dev/null 2>&1 &
+
+ sleep `jot -r 1 5 9`
+ while mdconfig -l | grep -q md$mdstart; do
+ mdconfig -d -u $mdstart -o force || sleep 1
+ done
+ sleep 1
+ ../tools/killall.sh
+ wait
+ n=0
+ while mount | grep $mntpoint | grep -q /dev/md; do
+ umount $mntpoint || sleep 1
+ [ $((n += 1)) -gt 300 ] && { echo FAIL; exit 1; }
+ done
+ mdconfig -a -t vnode -f $diskimage -s 1g -u $mdstart
+ for i in `jot 10`; do
+ fsck_ffs -fy /dev/md$mdstart > $log 2>&1
+ grep -Eq "FILE SYSTEM WAS MODIFIED" $log || break
+ done
+ [ $i -gt 2 ] && echo "Ran fsck $i times"
+ [ $i -eq 10 ] && { s=1; break; }
+done
+if [ $s -eq 0 ]; then
+ mdconfig -d -u $mdstart
+ rm -f $diskimage $log
+else
+ cat $log
+fi
+exit $s
diff --git a/tools/test/stress2/misc/force11.sh b/tools/test/stress2/misc/force11.sh
new file mode 100755
index 000000000000..229a83ce69fe
--- /dev/null
+++ b/tools/test/stress2/misc/force11.sh
@@ -0,0 +1,100 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+set -u
+backup=`dirname $diskimage`/force11.sh.diskimage.`date +%Y%m%dT%H%M%S`
+log=/tmp/force11.sh.log
+mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+truncate -s 10g $diskimage
+mdconfig -a -t vnode -f $diskimage -u $mdstart
+flags=$newfs_flags
+[ `jot -r 1 0 1` -eq 1 ] && flags="-j"
+echo "newfs $flags md$mdstart"
+newfs $flags md$mdstart > /dev/null 2>&1
+
+export TESTPROGS=`cd ..; find testcases/ -perm -1 -type f | \
+ egrep -Ev "/run/|/badcode/|/pty/|/shm/|/socket/|sysctl|tcp|thr|udp|rename"`
+export runRUNTIME=3m
+export RUNDIR=$mntpoint/stressX
+export CTRLDIR=$mntpoint/stressX.control
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt $((15 * 60)) ]; do
+ mount /dev/md$mdstart $mntpoint
+ rm -fr $mntpoint/lost+found
+ chmod 777 $mntpoint
+
+ su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > \
+ /dev/null 2>&1 &
+
+ sleep `jot -r 1 30 60`
+ while mdconfig -l | grep -q md$mdstart; do
+ mdconfig -d -u $mdstart -o force || sleep 1
+ done
+ sleep 1
+ ../tools/killall.sh
+ wait
+ dd if=$diskimage of=$backup bs=1m conv=sparse,sync status=none
+ sync; sleep .5; sync; sleep .5; sync
+ n=0
+ while mount | grep $mntpoint | grep -q /dev/md; do
+ umount $mntpoint || sleep 1
+ [ $((n += 1)) -gt 300 ] && { echo FAIL; exit 1; }
+ done
+ mdconfig -a -t vnode -f $diskimage -u $mdstart
+ c=0
+ for i in `jot 5`; do
+ fsck_ffs -fyR /dev/md$mdstart > $log 2>&1; s=$?
+ grep -q CLEAN $log && grep -q "MODIFIED" $log && c=$((c+=1))
+ grep -Eq "FILE SYSTEM WAS MODIFIED" $log || break
+ done
+ [ $c -gt 1 ] &&
+ { echo "Note: FS marked clean+modified $c times out of $i fsck runs"; s=101; }
+ [ $s -ne 0 ] && break
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log || { s=100; break; }
+ break # For now, only once
+done
+if [ $s -eq 0 ]; then
+ mount /dev/md$mdstart $mntpoint
+ cp -R /usr/include $mntpoint || s=1
+ dd if=/dev/zero of=$mntpoint/big bs=1m count=10 status=none || s=2
+ ls -lR $mntpoint > /dev/null || s=3
+ find $mntpoint/* -delete || s=4
+ umount $mntpoint
+ [ $s -eq 0 ] &&
+ rm -f $diskimage $log $backup
+else
+ tail -10 $log
+fi
+mdconfig -d -u $mdstart
+[ -f $backup ] && xz -T0 $backup
+exit $s
diff --git a/tools/test/stress2/misc/force12.sh b/tools/test/stress2/misc/force12.sh
new file mode 100755
index 000000000000..c030adb16d86
--- /dev/null
+++ b/tools/test/stress2/misc/force12.sh
@@ -0,0 +1,83 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# rename() livelock seen with a forced unmount of a FS
+# https://people.freebsd.org/~pho/stress/log/log0375.txt
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+echo "Known issue. Skipping ..."; exit 0
+
+set -u
+log=/tmp/force12.sh.log
+mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 4g -u $mdstart
+flags=$newfs_flags
+[ `jot -r 1 0 1` -eq 1 ] && flags="-j"
+echo "newfs $flags md$mdstart"
+newfs $flags md$mdstart > /dev/null 2>&1
+
+export TESTPROGS='
+testcases/dirnprename/dirnprename
+testcases/dirrename/dirrename
+testcases/fts/fts
+testcases/mkdir/mkdir
+testcases/rename/rename
+testcases/rw/rw
+testcases/swap/swap
+'
+
+export runRUNTIME=3m
+export RUNDIR=$mntpoint/stressX
+export CTRLDIR=$mntpoint/stressX.control
+
+mount /dev/md$mdstart $mntpoint
+chmod 777 $mntpoint
+export dirnprenameLOAD=100
+export dirrenameLOAD=100
+
+su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > \
+ /dev/null 2>&1 &
+
+sleep `jot -r 1 60 180`
+while mdconfig -l | grep -q md$mdstart; do
+ mdconfig -d -u $mdstart -o force || sleep 1
+done
+sleep 1
+../tools/killall.sh
+wait
+n=0
+while mount | grep $mntpoint | grep -q /dev/md; do
+ umount $mntpoint || sleep 1
+ [ $((n += 1)) -gt 30 ] && { echo FAIL; exit 1; }
+done
+mdconfig -d -u $mdstart > /dev/null 2>&1
+rm -f $log
+exit 0
diff --git a/tools/test/stress2/misc/force13.sh b/tools/test/stress2/misc/force13.sh
new file mode 100755
index 000000000000..ac32ee90e38c
--- /dev/null
+++ b/tools/test/stress2/misc/force13.sh
@@ -0,0 +1,129 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Snapshot test
+
+# "panic: flush_pagedep_deps: failed to flush inodedep 0xfff..." seen:
+# https://people.freebsd.org/~pho/stress/log/log0376.txt
+
+# watchdog fired:
+# https://people.freebsd.org/~pho/stress/log/log0377.txt
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+set -u
+log=/tmp/force13.sh.log
+mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+truncate -s 10g $diskimage
+mdconfig -a -t vnode -f $diskimage -u $mdstart
+flags=$newfs_flags
+[ `jot -r 1 0 1` -eq 1 ] && flags="-j"
+
+echo "newfs $flags md$mdstart"
+newfs $flags md$mdstart > /dev/null 2>&1
+
+# Exclude rename for now due to log0374.txt
+export TESTPROGS=`cd ..; find testcases/ -perm -1 -type f | \
+ egrep -Ev "/run/|/badcode/|/pty/|/shm/|/socket/|sysctl|tcp|thr|udp|rename"`
+export runRUNTIME=3m
+export RUNDIR=$mntpoint/stressX
+export CTRLDIR=$mntpoint/stressX.control
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt $((15 * 60)) ]; do
+ mount /dev/md$mdstart $mntpoint
+ rm -fr $mntpoint/lost+found
+ chmod 777 $mntpoint
+
+ su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > \
+ /dev/null 2>&1 &
+
+ t=`jot -r 1 60 180`
+ start=`date +%s`
+ mkdir -p $mntpoint/.snap
+ for i in `jot 10`; do
+ rm -f $mntpoint/.snap/$i
+ mksnap_ffs $mntpoint $mntpoint/.snap/$i ||
+ { ../tools/killall.sh; break; }
+ sleep `jot -r 1 1 5`
+ [ $((`date +%s` - start)) -ge $t ] && break
+ done &
+ sleep `jot -r 1 60 180`
+ while mdconfig -l | grep -q md$mdstart; do
+ mdconfig -d -u $mdstart -o force || sleep 1
+ done
+ sleep 1
+ ../tools/killall.sh
+ wait
+ n=0
+ while mount | grep -q "on $mntpoint "; do
+ umount $mntpoint || sleep 1
+ [ $((n += 1)) -gt 300 ] && { echo FAIL; exit 1; }
+ done
+ mdconfig -a -t vnode -f $diskimage -u $mdstart
+ c=0
+ # Run fsck minimum two times
+ for i in `jot 5`; do
+ fsck_ffs -fy /dev/md$mdstart > $log 2>&1; s=$?
+ grep -q CLEAN $log && grep -q "MODIFIED" $log && c=$((c+=1))
+ grep -Eq "FILE SYSTEM WAS MODIFIED" $log || break
+ done
+ [ $c -gt 1 ] &&
+ { echo "Note: FS marked clean+modified $c times out of $i fsck runs"; s=101; }
+ [ $s -ne 0 ] && break
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log || { s=102; break; }
+done
+[ $s -eq 101 ] && s=0 # Ignore CLEANish problem for now
+if [ $s -eq 0 ]; then
+ mount /dev/md$mdstart $mntpoint
+ cp -R /usr/include $mntpoint
+ dd if=/dev/zero of=$mntpoint/big bs=1m count=10 status=none
+ find $mntpoint/* -delete
+
+ # Check the snapshots
+ for f in $mntpoint/.snap/*; do
+ c=0
+ for i in `jot 5`; do
+ echo "fsck_ffs -fy $f"
+ fsck_ffs -fy $f > $log 2>&1; s=$?
+ grep -q CLEAN $log && grep -q "MODIFIED" $log && c=$((c+=1))
+ grep -Eq "FILE SYSTEM WAS MODIFIED" $log || break
+ done
+ [ $c -gt 1 ] &&
+ { echo "Note: snapshot $i marked clean+modified $c times out of $i fsck runs"; s=201; }
+ [ $s -ne 0 ] && break
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log ||
+ { s=202; tail -10 $log; break; }
+ done
+ umount $mntpoint
+ mdconfig -d -u $mdstart
+ rm -f $diskimage $log
+fi
+exit $s
diff --git a/tools/test/stress2/misc/force14.sh b/tools/test/stress2/misc/force14.sh
new file mode 100755
index 000000000000..eec850c50891
--- /dev/null
+++ b/tools/test/stress2/misc/force14.sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# SU+J Snapshot test with a 50G file system
+
+# "panic: handle_jwork: Unknown type jnewblk" seen:
+# https://people.freebsd.org/~pho/stress/log/log0422.txt
+
+# "panic: flush_pagedep_deps: failed to flush inodedep..." seen:
+# https://people.freebsd.org/~pho/stress/log/log0423.txt
+
+# "panic: softdep_deallocate_dependencies: dangling deps" seen:
+# https://people.freebsd.org/~pho/stress/log/log0424.txt
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+set -u
+log=/tmp/force14.sh.log
+mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+truncate -s 50g $diskimage
+mdconfig -a -t vnode -f $diskimage -u $mdstart
+flags="-j"
+
+newfs $flags md$mdstart > /dev/null 2>&1
+
+# Exclude rename for now due to log0374.txt
+export TESTPROGS=`cd ..; find testcases/ -perm -1 -type f | \
+ egrep -Ev "/run/|/badcode/|/pty/|/shm/|/socket/|sysctl|tcp|thr|udp|rename"`
+export runRUNTIME=3m
+export RUNDIR=$mntpoint/stressX
+export CTRLDIR=$mntpoint/stressX.control
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt $((15 * 60)) ]; do
+ mount /dev/md$mdstart $mntpoint
+ rm -fr $mntpoint/lost+found
+ chmod 777 $mntpoint
+
+ su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > \
+ /dev/null 2>&1 &
+
+ t=`jot -r 1 60 180`
+ st=`date +%s`
+ mkdir -p $mntpoint/.snap
+ for i in `jot 10`; do
+ rm -f $mntpoint/.snap/$i
+ mksnap_ffs $mntpoint $mntpoint/.snap/$i ||
+ { ../tools/killall.sh; break; }
+ sleep `jot -r 1 1 5`
+ [ $((`date +%s` - st)) -ge $t ] && break
+ done &
+ sleep `jot -r 1 60 180`
+ while mdconfig -l | grep -q md$mdstart; do
+ mdconfig -d -u $mdstart -o force || sleep 1
+ done
+ sleep 1
+ ../tools/killall.sh
+ wait
+ n=0
+ while mount | grep -q "on $mntpoint "; do
+ umount $mntpoint || sleep 1
+ [ $((n += 1)) -gt 300 ] && { echo FAIL; exit 1; }
+ done
+ mdconfig -a -t vnode -f $diskimage -u $mdstart
+ c=0
+ # Process the journal
+ fsck_ffs -fy /dev/md$mdstart > $log 2>&1; s=$?
+ grep 'INTERNAL ERROR: GOT TO reply' $log
+ for i in `jot 4`; do
+ [ $i -ne 1 ] &&
+ echo "fsck_ffs -fy /dev/md$mdstart"
+ fsck_ffs -fy /dev/md$mdstart > $log 2>&1; s=$?
+ grep 'INTERNAL ERROR: GOT TO reply' $log
+ grep -q CLEAN $log && c=$((c+=1))
+ grep -Eq "WAS MODIFIED" $log || break
+ done
+ [ $c -gt 1 ] &&
+ { echo "Note: FS marked clean+modified $c times out of $i fsck runs"; s=101; }
+ [ $s -ne 0 ] && break
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log || { s=102; break; }
+done
+if [ $s -eq 0 ]; then
+ mount /dev/md$mdstart $mntpoint
+ cp -R /usr/include $mntpoint
+ dd if=/dev/zero of=$mntpoint/big bs=1m count=10 status=none
+ find $mntpoint/* -delete
+
+ umount $mntpoint
+ mdconfig -d -u $mdstart
+ rm -f $diskimage $log
+fi
+exit $s
diff --git a/tools/test/stress2/misc/force15.sh b/tools/test/stress2/misc/force15.sh
new file mode 100755
index 000000000000..955025cd98c6
--- /dev/null
+++ b/tools/test/stress2/misc/force15.sh
@@ -0,0 +1,113 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# FFS+SU with snapshots and forced unmounts
+
+# "panic: flush_pagedep_deps: failed to flush inodedep ..." seen
+# https://people.freebsd.org/~pho/stress/log/log0427.txt
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+prog=$(basename "$0" .sh)
+diskimage=/tmp/diskimage
+log=/tmp/$prog.log
+mdstart=10
+mntpoint=/mnt
+newfs_flags="-U"
+
+set -u
+mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+dd if=/dev/zero of=$diskimage bs=1m count=1k status=none
+mdconfig -a -t vnode -f $diskimage -u $mdstart
+flags="-U"
+
+newfs $flags md$mdstart > /dev/null 2>&1
+
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt $((5 * 60)) ]; do
+ mount /dev/md$mdstart $mntpoint
+ rm -fr $mntpoint/lost+found
+
+ jot 10 | xargs -I% mkdir -p $mntpoint/%
+ n=5000
+ for j in `jot 10`; do
+ (
+ jot $n | xargs -P0 -I% touch $mntpoint/$j/%
+ jot $n | xargs -P0 -I% rm $mntpoint/$j/%
+ ) > /dev/null 2>&1 &
+ done
+
+ sleep `jot -r 1 5 20`
+ t=`jot -r 1 60 180`
+ st=`date +%s`
+ mkdir -p $mntpoint/.snap
+ for i in `jot 10`; do
+ rm -f $mntpoint/.snap/$i
+ mksnap_ffs $mntpoint $mntpoint/.snap/$i > /dev/null 2>&1 || break
+ sleep `jot -r 1 1 5`
+ [ $((`date +%s` - st)) -ge $t ] && break
+ done &
+ sleep `jot -r 1 2 5`
+ while mdconfig -l | grep -q md$mdstart; do
+ mdconfig -d -u $mdstart -o force || sleep 1
+ done
+ sleep 1
+ wait
+ n=0
+ while mount | grep -q "on $mntpoint "; do
+ umount $mntpoint || sleep 1
+ [ $((n += 1)) -gt 300 ] && { echo FAIL; exit 1; }
+ done
+ mdconfig -a -t vnode -f $diskimage -u $mdstart
+ c=0
+ for i in `jot 5`; do
+ [ $i -ne 1 ] &&
+ echo "$i: fsck_ffs -fy /dev/md$mdstart"
+ fsck_ffs -fy /dev/md$mdstart > $log 2>&1; s=$?
+ grep 'INTERNAL ERROR: GOT TO reply' $log
+ grep -q CLEAN $log && grep -q MODIFIED && c=$((c+=1))
+ grep -Eq "WAS MODIFIED" $log || break
+ done
+ [ $c -gt 1 ] &&
+ { echo "Note: FS marked clean+modified $c times out of $i fsck runs"; s=101; }
+ [ $s -ne 0 ] && break
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log || { s=102; break; }
+done
+if [ $s -eq 0 ]; then
+ mount /dev/md$mdstart $mntpoint
+ cp -R /usr/include $mntpoint
+ dd if=/dev/zero of=$mntpoint/big bs=1m count=10 status=none
+ find $mntpoint/* -delete
+
+ umount $mntpoint
+ mdconfig -d -u $mdstart
+ rm -f $diskimage $log
+fi
+exit $s
diff --git a/tools/test/stress2/misc/force2.sh b/tools/test/stress2/misc/force2.sh
index 35e448afbbba..cd947ef7d13d 100755
--- a/tools/test/stress2/misc/force2.sh
+++ b/tools/test/stress2/misc/force2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/force3.sh b/tools/test/stress2/misc/force3.sh
index 4bfb0011cbef..2fc947bb0af6 100755
--- a/tools/test/stress2/misc/force3.sh
+++ b/tools/test/stress2/misc/force3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/force4.sh b/tools/test/stress2/misc/force4.sh
index 72932aec1fe6..69bbb7f4c978 100755
--- a/tools/test/stress2/misc/force4.sh
+++ b/tools/test/stress2/misc/force4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/force5.sh b/tools/test/stress2/misc/force5.sh
index c0aa6436fc1f..263761211148 100755
--- a/tools/test/stress2/misc/force5.sh
+++ b/tools/test/stress2/misc/force5.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/force6.sh b/tools/test/stress2/misc/force6.sh
index 5c7d508241ec..22b362d51573 100755
--- a/tools/test/stress2/misc/force6.sh
+++ b/tools/test/stress2/misc/force6.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/force7.sh b/tools/test/stress2/misc/force7.sh
index 0f2e6e9a0e9e..e828b0090f7b 100755
--- a/tools/test/stress2/misc/force7.sh
+++ b/tools/test/stress2/misc/force7.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/force8.sh b/tools/test/stress2/misc/force8.sh
index 77a8e6fd97bf..26361890f02f 100755
--- a/tools/test/stress2/misc/force8.sh
+++ b/tools/test/stress2/misc/force8.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
diff --git a/tools/test/stress2/misc/force9.sh b/tools/test/stress2/misc/force9.sh
index a62e00242a67..54a17f20e036 100755
--- a/tools/test/stress2/misc/force9.sh
+++ b/tools/test/stress2/misc/force9.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
@@ -34,9 +34,12 @@
# "panic: softdep_update_inodeblock inconsistent ip ..." seen:
# https://people.freebsd.org/~pho/stress/log/log0184.txt
+# Watchdog fired: https://people.freebsd.org/~pho/stress/log/log0374.txt
+
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
. ../default.cfg
+set -u
log=/tmp/force7.sh.log
mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
@@ -46,22 +49,22 @@ flags=$newfs_flags
echo "newfs $flags md$mdstart"
newfs $flags md$mdstart > /dev/null 2>&1
+# Exclude rename for now due to log0374.txt
export TESTPROGS=`cd ..; find testcases/ -perm -1 -type f | \
- egrep -Ev "/run/|/badcode/|/pty/|/shm/|/socket/|sysctl|tcp|thr|udp"`
+ egrep -Ev "/run/|/badcode/|/pty/|/shm/|/socket/|sysctl|tcp|thr|udp|rename"`
export runRUNTIME=3m
export RUNDIR=$mntpoint/stressX
+export CTRLDIR=$mntpoint/stressX.control
start=`date +%s`
while [ $((`date +%s` - start)) -lt $((15 * 60)) ]; do
mount /dev/md$mdstart $mntpoint
rm -fr $mntpoint/lost+found
chmod 777 $mntpoint
- echo "Start tests"
su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > \
/dev/null 2>&1 &
sleep `jot -r 1 60 180`
- echo "Force destroy MD disk"
while mdconfig -l | grep -q md$mdstart; do
mdconfig -d -u $mdstart -o force || sleep 1
done
@@ -74,9 +77,17 @@ while [ $((`date +%s` - start)) -lt $((15 * 60)) ]; do
[ $((n += 1)) -gt 300 ] && { echo FAIL; exit 1; }
done
mdconfig -a -t vnode -f $diskimage -u $mdstart
- fsck_ffs -fyR /dev/md$mdstart > $log 2>&1; s=$?
+ c=0
+ # Run fsck minimum two times
+ for i in `jot 5`; do
+ fsck_ffs -fy /dev/md$mdstart > $log 2>&1; s=$?
+ grep -q CLEAN $log && grep -q "MODIFIED" $log && c=$((c+=1))
+ grep -Eq "FILE SYSTEM WAS MODIFIED" $log || break
+ done
+ [ $c -gt 1 ] &&
+ { echo "Note: FS marked clean+modified $c times out of $i fsck runs"; s=101; }
[ $s -ne 0 ] && break
- grep -Eq "IS CLEAN|MARKED CLEAN" $log || { s=100; break; }
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log || { s=102; break; }
done
if [ $s -eq 0 ]; then
mount /dev/md$mdstart $mntpoint
@@ -87,6 +98,6 @@ if [ $s -eq 0 ]; then
mdconfig -d -u $mdstart
rm -f $diskimage $log
else
- cat $log
+ tail -10 $log
fi
exit $s
diff --git a/tools/test/stress2/misc/fork2.sh b/tools/test/stress2/misc/fork2.sh
new file mode 100755
index 000000000000..4dbe2de3f6d1
--- /dev/null
+++ b/tools/test/stress2/misc/fork2.sh
@@ -0,0 +1,134 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Regression test for D36069
+# thread_create(): call cpu_copy_thread() after td_pflags is zeroed
+
+# Seen before fix:
+# cc: error: unable to execute command: Segmentation fault (core dumped)
+# cc: error: linker command failed due to signal (use -v to see invocation)
+# Aug 9 18:27:47 freebsd-vm kernel: pid 32094 (ld.lld), jid 0, uid 0: exited on signal 11 (core dumped)
+
+. ../default.cfg
+[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
+
+dir=/tmp
+odir=`pwd`
+cd $dir
+sed '1,/^EOF/d' < $odir/$0 > $dir/fork2.c
+mycc -o fork2 -Wall -Wextra -O0 -g fork2.c || exit 1
+cd $odir
+
+set -e
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 2g -u $mdstart
+newfs $newfs_flags md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+set +e
+
+cd $mntpoint
+$dir/fork2
+s=$?
+pkill fork2
+[ -f fork2.core -a $s -eq 0 ] &&
+ { ls -l fork2.core; mv fork2.core $dir; s=1; }
+cd $odir
+
+for i in `jot 6`; do
+ mount | grep -q "on $mntpoint " || break
+ umount $mntpoint && break || sleep 10
+ [ $i -eq 6 ] &&
+ { echo FATAL; fstat -mf $mntpoint; exit 1; }
+done
+mdconfig -d -u $mdstart
+cd $dir
+mycc -o $dir/fork2 -Wall -Wextra -O0 -g $dir/fork2.c; s=$?
+rm -rf $dir/fork2 $dir/fork2.c
+exit $s
+
+EOF
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <machine/atomic.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+static volatile u_int *share;
+
+#define MX 5000
+#define RUNTIME (1 * 60)
+#define SYNC 0
+
+int
+main(void)
+{
+ pid_t pid;
+ size_t len;
+ time_t start;
+ int n;
+
+ len = PAGE_SIZE;
+ if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
+ err(1, "mmap");
+
+ n = 0;
+ signal(SIGCHLD, SIG_IGN);
+ start = time(NULL);
+ while ((time(NULL) - start) < RUNTIME) {
+ while ((atomic_load_int(&share[SYNC])) > MX)
+ usleep(100);
+ n++;
+ pid = fork();
+ if (pid == -1)
+ err(1, "fork)");
+ if (pid == 0) {
+ atomic_add_int(&share[SYNC], 1);
+ while (atomic_load_int(&share[SYNC]) <= MX)
+ usleep(10000);
+ usleep(arc4random() % 1000);
+ atomic_add_int(&share[SYNC], -1);
+ raise(SIGHUP);
+ _exit(0);
+ }
+ }
+ atomic_add_int(&share[SYNC], MX * 2);
+ fprintf(stderr, "%d fork() calls\n", n);
+}
diff --git a/tools/test/stress2/misc/forkbomb.sh b/tools/test/stress2/misc/forkbomb.sh
index 73a3c5f37fe2..caaaa27db281 100755
--- a/tools/test/stress2/misc/forkbomb.sh
+++ b/tools/test/stress2/misc/forkbomb.sh
@@ -81,7 +81,7 @@ volatile u_int *share;
#define R4 4 /* fork failed */
//#define DEBUG
-#define MXFAIL 100
+#define MXFAIL 2
#define MAXPROC 40000 /* Arbitrary cap */
#define PARALLEL 200
@@ -93,7 +93,7 @@ test(void)
alarm(1200);
atomic_add_int(&share[R1], 1);
while (share[R1] != PARALLEL)
- ;
+ usleep(100);
atomic_add_int(&share[R2], 1);
for (;;) {
@@ -103,6 +103,7 @@ test(void)
if ((r = fork()) == -1) {
atomic_add_int(&share[R4], 1);
atomic_add_int(&share[R2], -1);
+ usleep(arc4random() % 100000);
break;
}
}
diff --git a/tools/test/stress2/misc/fsck.sh b/tools/test/stress2/misc/fsck.sh
index 826c31f733c3..4af41df037e9 100755
--- a/tools/test/stress2/misc/fsck.sh
+++ b/tools/test/stress2/misc/fsck.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
@@ -49,9 +49,12 @@ u2=$((mdstart + 1))
mp1=${mntpoint}$u1
mp2=${mntpoint}$u2
mkdir -p $mp1 $mp2
-log=$mp1/fsck.sh.log
-diskimage=$mp1/fsck.sh.diskimage
+
backup=/tmp/fsck.sh.diskimage.`date +%Y%m%dT%H%M%S`.gz
+core=/tmp/fsck.sh.core.`date +%Y%m%dT%H%M%S`
+diskimage=$mp1/fsck.sh.diskimage
+log=$mp1/fsck.sh.log
+
asbs=0
cleans=0
reruns=0
@@ -71,6 +74,7 @@ mount /dev/md$u1 $mp1
[ -c /dev/md$u2 ] && mdconfig -d -u $u2
dd if=/dev/zero of=$diskimage bs=$max count=1 status=none
mdconfig -a -t vnode -f $diskimage -u $u2
+[ "$newfs_flags" = "-U" ] && [ `jot -r 1 0 1` -eq 1 ] && newfs_flags="-j"
backups=`newfs -N $newfs_flags md$u2 | grep -A1 "super-block backups" | \
tail -1 | sed 's/,//g'`
newfs $newfs_flags md$u2 > /dev/null
@@ -86,13 +90,13 @@ chk() {
waccess=0
fsck_ffs -fy $1 > $log 2>&1
r=$?
- if grep -qE "Cannot find file system superblock|Superblock check-hash failed" $log; then
+ if grep -qiE "super-?block.*failed" $log; then
for b in $backups; do
echo "Using alternate SB $b"
asbs=$((asbs + 1))
fsck_ffs -b $b -fy $1 > $log 2>&1
r=$?
- grep -qE "Cannot find file system superblock|Superblock check-hash failed" $log ||
+ grep -qiE "super-?block.*failed" $log ||
break
done
usedasb=1
@@ -144,7 +148,8 @@ while [ $((`date +%s` - start)) -lt 60 ]; do
break
done
mount | grep -q "on $mp2 " && umount $mp2
-mdconfig -d -u $u2 || exit 1
+mdconfig -l | grep -q "md$u2" &&
+ mdconfig -d -u $u2
echo "$cleans cleans, $reruns reruns, $asbs alternate SBs."
if [ $clean -ne 1 ]; then
@@ -153,8 +158,9 @@ if [ $clean -ne 1 ]; then
cp -v $log /tmp
[ $s -eq 0 ] && s=106
fi
-echo * | grep -q core && { ls -l *.core; cp $log /tmp; exit 106; } ||
- rm -f $backup
+[ -f fsck_ffs.core ] &&
+ mv fsck_ffs.core $core
+[ $s -eq 0 ] && rm -f $backup
cd /tmp
umount $mp1
mdconfig -d -u $u1
diff --git a/tools/test/stress2/misc/fsck10.sh b/tools/test/stress2/misc/fsck10.sh
new file mode 100755
index 000000000000..33ad35f65f11
--- /dev/null
+++ b/tools/test/stress2/misc/fsck10.sh
@@ -0,0 +1,172 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Variation of fsck9.sh with smaller disk size and newfs options '', 'U' and 'O1'
+# fsck_ffs core dump seen
+
+. ../default.cfg
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+cc -o /tmp/flip -Wall -Wextra -O2 ../tools/flip.c || exit 1
+
+set -e
+prog=$(basename "$0" .sh)
+u1=$mdstart
+u2=$((mdstart + 1))
+mp1=${mntpoint}$u1
+mp2=${mntpoint}$u2
+mkdir -p $mp1 $mp2
+log=$mp1/$prog.sh.log
+diskimage=$mp1/$prog.sh.diskimage
+backup=/tmp/$prog.sh.diskimage.`date +%Y%m%dT%H%M%S`.gz
+cleans=0
+reruns=0
+
+# Pick a random newfs flag
+newfs_flags=$(echo "" "-U" "-O1" | awk -v N=`jot -r 1 1 3` '{print $N}')
+[ $# -eq 1 ] && newfs_flags="$1" # or use script argument
+max=$((512 * 1024))
+
+mount | grep "on $mp1 " | grep -q /dev/md && umount -f $mp1
+[ -c /dev/md$u1 ] && mdconfig -d -u $u1
+mdconfig -a -t swap -s 1g -u $u1
+newfs $newfs_flags -n /dev/md$u1 > /dev/null
+mount /dev/md$u1 $mp1
+
+[ -c /dev/md$u2 ] && mdconfig -d -u $u2
+dd if=/dev/zero of=$diskimage bs=$max count=1 status=none
+mdconfig -a -t vnode -f $diskimage -u $u2
+backups=`newfs -N $newfs_flags md$u2 | grep -A1 "super-block backups" | \
+ tail -1 | sed 's/,//g'`
+echo "newfs $newfs_flags -n md$u2"
+newfs $newfs_flags -n md$u2 > /dev/null
+[ "$newfs_flags" = "" ] && tunefs -n disable md$u2
+set +e
+
+chk() {
+ local i
+
+ clean=0
+ rerun=0
+ fsck_ffs -fy $1 > $log 2>&1
+ r=$?
+ if grep -qiE "super-?block.*failed" $log; then
+ for b in $backups; do
+ echo "fsck_ffs -b $b -fy $1"
+ fsck_ffs -b $b -fy $1 > $log 2>&1
+ r=$?
+ grep -qiE "super-?block.*failed" $log ||
+ break
+ echo "Checking next SB"
+ done
+ usedasb=1
+ else
+ usedasb=0
+ fi
+ LANG=C egrep -q "[A-Z][A-Z]" $log && clean=0
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log && clean=1
+ grep -q RERUN $log && rerun=1
+ [ $r -ne 0 -a $clean -eq 1 ] && echo "Exit code $r w/ clean == 1"
+}
+
+cd $mp1
+clean=0
+errors=0
+s=0
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 300 ]; do
+ mount /dev/md$u2 $mp2 || break
+ if ! ls -lR $mp2 > /dev/null; then
+ s=102
+ echo "ls failed"; grep "core dumped" /var/log/messages | tail -1
+ break
+ fi
+ rm -f $mp2/????????
+ touch $mp2/`jot -rc 8 a z | tr -d '\n'`
+ mkdir -p $mp2/dir/dir/dir/dir
+ echo "abc" > $mp2/dir/dir/dir/dir/f
+ while mount | grep -q "on $mp2 "; do umount $mp2; done
+ echo * | grep -q core && break
+ mdconfig -d -u $u2
+
+ # Introduce 5 random single bit errors to the file system image
+ /tmp/flip -n 5 $diskimage
+
+ sync; sleep .1
+ if [ `stat -f%z $diskimage` -gt $max ]; then
+ ls -lh $diskimage
+ truncate -s $max $diskimage
+ else
+ gzip < $diskimage > $backup
+ fi
+ fsync $backup
+ sync; sleep .1
+
+ for i in `jot 5`; do
+ [ $i -gt 2 ] && echo "fsck run #$i"
+ chk $diskimage
+ [ $rerun -eq 1 ] && { reruns=$((reruns + 1)); continue; }
+ [ $clean -eq 1 ] && { cleans=$((cleans + 1)); break; }
+ if [ -f fsck_ffs.core ]; then
+ tstamp=`date +%Y%m%dT%H%M%S`
+ gzip < $backup > /tmp/fsck_ffs.core.diskimage.$tstamp
+ gzip < fsck_ffs.core > /tmp/fsck_ffs.core.$tstamp
+ break 2
+ fi
+ done
+ if [ $clean -eq 1 ]; then
+ fsck_ffs -fy $diskimage > $log 2>&1
+ if grep -q MODIFIED $log; then
+ echo "*** fsck of \"clean\" FS found more issues:"
+ cat $log
+ errors=$((errors + 1))
+ s=1
+ break
+ fi
+ fi
+ [ $clean -ne 1 ] && break
+ mdconfig -a -t vnode -f $diskimage -u $u2
+done
+for i in `jot 5`; do
+ mount | grep -q "on $mp2 " || break
+ umount $mp2 && break
+ sleep 2
+done
+mdconfig -l | grep -q $u2 && mdconfig -d -u $u2
+
+[ $s -eq 0 ] && rm -f $backup || echo "Preserved $backup due to status code $s"
+cd /tmp
+for i in `jot 5`; do
+ umount $mp1 && break
+ sleep 2
+done
+mdconfig -d -u $u1
+rm -f /tmp/flip
+exit $s
diff --git a/tools/test/stress2/misc/fsck11.sh b/tools/test/stress2/misc/fsck11.sh
new file mode 100755
index 000000000000..de4cf2536dad
--- /dev/null
+++ b/tools/test/stress2/misc/fsck11.sh
@@ -0,0 +1,171 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Demonstrate how the "CLEAN" message and the exit code can be misleading
+
+# "panic: softdep_update_inodeblock inconsistent ip ..." seen:
+# https://people.freebsd.org/~pho/stress/log/log0421.txt
+# https://people.freebsd.org/~pho/fsck11.sh.diskimage.20230228T064402.gz
+
+. ../default.cfg
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+cc -o /tmp/flip -Wall -Wextra -O2 ../tools/flip.c || exit 1
+
+set -e
+prog=$(basename "$0" .sh)
+u1=$mdstart
+u2=$((mdstart + 1))
+mp1=${mntpoint}$u1
+mp2=${mntpoint}$u2
+mkdir -p $mp1 $mp2
+log=$mp1/$prog.sh.log
+diskimage=$mp1/$prog.sh.diskimage
+backup=/tmp/$prog.sh.diskimage.`date +%Y%m%dT%H%M%S`.gz
+cleans=0
+reruns=0
+
+# Pick a random newfs flag
+newfs_flags=$(echo "" "-U" "-O1" | awk -v N=`jot -r 1 1 3` '{print $N}')
+[ $# -eq 1 ] && newfs_flags="$1" # or use script argument
+max=$((2 * 1024 * 1024))
+[ "$newfs_flags" = "-j" ] && max=$((20 * 1024 * 1024)) # Make room for the journal file
+
+mount | grep "on $mp1 " | grep -q /dev/md && umount -f $mp1
+[ -c /dev/md$u1 ] && mdconfig -d -u $u1
+mdconfig -a -t swap -s 1g -u $u1
+newfs $newfs_flags -n /dev/md$u1 > /dev/null
+mount /dev/md$u1 $mp1
+
+[ -c /dev/md$u2 ] && mdconfig -d -u $u2
+dd if=/dev/zero of=$diskimage bs=$max count=1 status=none
+mdconfig -a -t vnode -f $diskimage -u $u2
+backups=`newfs -N $newfs_flags md$u2 | grep -A1 "super-block backups" | \
+ tail -1 | sed 's/,//g'`
+echo "newfs $newfs_flags -n md$u2"
+newfs $newfs_flags -n md$u2 > /dev/null
+[ "$newfs_flags" = "" ] && tunefs -n disable md$u2
+set +e
+
+chk() {
+ local i
+
+ clean=0
+ rerun=0
+ fsck_ffs -fy $1 > $log 2>&1
+ r=$?
+ if grep -qiE "super-?block.*failed" $log; then
+ for b in $backups; do
+ echo "fsck_ffs -b $b -fy $1"
+ fsck_ffs -b $b -fy $1 > $log 2>&1
+ r=$?
+ grep -qiE "super-?block.*failed" $log ||
+ break
+ echo "Checking next SB"
+ done
+ usedasb=1
+ else
+ usedasb=0
+ fi
+ LANG=C egrep -q "[A-Z][A-Z]" $log && clean=0
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log && clean=1
+ grep -q RERUN $log && rerun=1
+ [ $r -ne 0 -a $clean -eq 1 ] && echo "Exit code $r w/ clean == 1"
+}
+
+cd $mp1
+clean=0
+errors=0
+s=0
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 300 ]; do
+ mount /dev/md$u2 $mp2 || break
+ if ! ls -lR $mp2 > /dev/null; then
+ s=102
+ echo "ls failed"; grep "core dumped" /var/log/messages | tail -1
+ break
+ fi
+
+ find $mp2 -type f | xargs cat > /dev/null
+ for j in `jot 9`; do
+ rm -rf $mp2/$j
+ mkdir $mp2/$j
+ jot 10 | xargs -P0 -I% cp /etc/group $mp2/$j/%
+ done 2>/dev/null
+
+ while mount | grep -q "on $mp2 "; do umount $mp2; done
+ echo * | grep -q core && break
+ mdconfig -d -u $u2
+
+ # Introduce 5 random single bit errors to the file system image
+ /tmp/flip -n 5 $diskimage
+
+ if [ `stat -f%z $diskimage` -gt $max ]; then
+ ls -lh $diskimage
+ truncate -s $max $diskimage
+ else
+ gzip < $diskimage > $backup
+ fi
+ fsync $backup
+ sync; sleep 1
+
+ [ "$newfs_flags" = "-j" ] &&
+ fsck -fy $diskimage > $log 2>&1 # process the journal file
+ for i in `jot 5`; do
+ [ $i -gt 2 ] && echo "fsck run #$i"
+ chk $diskimage
+ [ $rerun -eq 1 ] && { reruns=$((reruns + 1)); continue; }
+ [ $clean -eq 1 ] && { cleans=$((cleans + 1)); break; }
+ if [ -f fsck_ffs.core ]; then
+ tstamp=`date +%Y%m%dT%H%M%S`
+ gzip < $backup > /tmp/fsck_ffs.core.diskimage.$tstamp
+ gzip < fsck_ffs.core > /tmp/fsck_ffs.core.$tstamp
+ break 2
+ fi
+ done
+ [ $clean -ne 1 ] && { s=99; break; } # broken image?
+ mdconfig -a -t vnode -f $diskimage -u $u2
+done
+for i in `jot 5`; do
+ mount | grep -q "on $mp2 " || break
+ umount $mp2 && break
+ sleep 2
+done
+mdconfig -l | grep -q $u2 && mdconfig -d -u $u2
+
+[ $s -eq 0 ] && rm -f $backup || echo "Preserved $backup due to status code $s"
+cd /tmp
+for i in `jot 5`; do
+ umount $mp1 && break
+ sleep 2
+done
+mdconfig -d -u $u1
+rm -f /tmp/flip
+exit $s
diff --git a/tools/test/stress2/misc/fsck12.sh b/tools/test/stress2/misc/fsck12.sh
new file mode 100755
index 000000000000..da4629991705
--- /dev/null
+++ b/tools/test/stress2/misc/fsck12.sh
@@ -0,0 +1,175 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# "panic: ffs_copyonwrite: bad copy block" seen:
+# Hunt for fsck_ffs's INTERNAL ERROR message
+
+# https://people.freebsd.org/~pho/stress/log/log0426.txt
+
+. ../default.cfg
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+cc -o /tmp/flip -Wall -Wextra -O2 ../tools/flip.c || exit 1
+
+set -e
+prog=$(basename "$0" .sh)
+u1=$mdstart
+u2=$((mdstart + 1))
+mp1=${mntpoint}$u1
+mp2=${mntpoint}$u2
+mkdir -p $mp1 $mp2
+log=$mp1/$prog.sh.log
+diskimage=$mp1/$prog.sh.diskimage
+backup=/tmp/$prog.sh.diskimage.`date +%Y%m%dT%H%M%S`.gz
+cleans=0
+reruns=0
+
+mount | grep "on $mp1 " | grep -q /dev/md && umount -f $mp1
+[ -c /dev/md$u1 ] && mdconfig -d -u $u1
+mdconfig -a -t swap -s 1g -u $u1
+newfs $newfs_flags -n /dev/md$u1 > /dev/null
+mount /dev/md$u1 $mp1
+
+newfs_flags='-j'
+[ $# -eq 1 ] && newfs_flags="$1" # or use script argument
+max=$((2 * 1024 * 1024))
+[ "$newfs_flags" = "-j" ] && max=$((20 * 1024 * 1024)) # Make room for the journal file
+
+[ -c /dev/md$u2 ] && mdconfig -d -u $u2
+dd if=/dev/zero of=$diskimage bs=$max count=1 status=none
+mdconfig -a -t vnode -f $diskimage -u $u2
+backups=`newfs -N $newfs_flags md$u2 | grep -A1 "super-block backups" | \
+ tail -1 | sed 's/,//g'`
+echo "newfs $newfs_flags md$u2"
+newfs $newfs_flags md$u2 > /dev/null
+set +e
+
+chk() {
+ local i
+
+ clean=0
+ rerun=0
+ fsck_ffs -fy $1 > $log 2>&1
+ r=$?
+ grep "GOT TO reply" $log && exit 1
+ if grep -qiE "super-?block.*failed" $log; then
+ for b in $backups; do
+ echo "fsck_ffs -b $b -fy $1"
+ fsck_ffs -b $b -fy $1 > $log 2>&1
+ r=$?
+ grep "GOT TO reply" $log && exit 1
+ grep -qiE "super-?block.*failed" $log ||
+ break
+ echo "Checking next SB"
+ done
+ usedasb=1
+ else
+ usedasb=0
+ fi
+ LANG=C egrep -q "[A-Z][A-Z]" $log && clean=0
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log && clean=1
+ grep -q RERUN $log && rerun=1
+ [ $r -ne 0 -a $clean -eq 1 ] && echo "Exit code $r w/ clean == 1"
+}
+
+cd $mp1
+clean=0
+errors=0
+s=0
+sno=0
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 300 ]; do
+ mount /dev/md$u2 $mp2 || break
+ if ! ls -lR $mp2 > /dev/null; then
+ s=102
+ echo "ls failed"; grep "core dumped" /var/log/messages | tail -1
+ break
+ fi
+ mkdir -p $mp2/d/d/d/d/d
+ cp /etc/group $mp2/d/d/d/d/d/f
+ for i in `jot 20`; do
+ cp -r $mp2/d $i
+ done
+
+ rm -f $mp2/.snap/$sno
+ mksnap_ffs $mp2 $mp2/.snap/$sno &
+ sno=$(((sno + 1) % 10))
+
+ sleep 1
+ rm -rf $mp/?
+ wait
+ while mount | grep -q "on $mp2 "; do umount $mp2; done
+ echo * | grep -q core && break
+ mdconfig -d -u $u2
+
+ # Introduce 5 random single bit errors to the file system image
+ /tmp/flip -n 5 $diskimage
+
+ if [ `stat -f%z $diskimage` -gt $max ]; then
+ ls -lh $diskimage
+ truncate -s $max $diskimage
+ else
+ gzip < $diskimage > $backup
+ fi
+ fsync $backup
+ sync; sleep 1
+
+ [ $newfs_flags = "-j" ] &&
+ fsck -fy $diskimage > $log 2>&1 # process the journal file
+ for i in `jot 5`; do
+ [ $i -gt 2 ] && echo "fsck run #$i"
+ chk $diskimage
+ [ $rerun -eq 1 ] && { reruns=$((reruns + 1)); continue; }
+ grep -q "MODIFIED" $log && continue # For now, do not trust CLEAN
+ [ $clean -eq 1 ] && { cleans=$((cleans + 1)); break; }
+ if [ -f fsck_ffs.core ]; then
+ s=1
+ break 2
+ fi
+ done
+ [ $clean -ne 1 ] && { s=99; break; } # broken image?
+ mdconfig -a -t vnode -f $diskimage -u $u2
+done
+for i in `jot 5`; do
+ mount | grep -q "on $mp2 " || break
+ umount $mp2 && break
+ sleep 2
+done
+mdconfig -l | grep -q $u2 && mdconfig -d -u $u2
+
+[ $s -eq 0 ] && rm -f $backup || echo "Preserved $backup due to status code $s"
+cd /tmp
+for i in `jot 5`; do
+ umount $mp1 && break
+ sleep 2
+done
+mdconfig -d -u $u1
+rm -f /tmp/flip
+exit $s
diff --git a/tools/test/stress2/misc/fsck13.sh b/tools/test/stress2/misc/fsck13.sh
new file mode 100755
index 000000000000..3b8dc64d12b9
--- /dev/null
+++ b/tools/test/stress2/misc/fsck13.sh
@@ -0,0 +1,153 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# fsck_ffs(8) disk image fuzz test.
+# Test without mount(8) and umount(8)
+
+. ../default.cfg
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+cc -o /tmp/flip -Wall -Wextra -O2 ../tools/flip.c || exit 1
+
+# Disable the calls to sync(2) in fsck_ffs(8) to speed up the test
+echo 'int sync(void) { return (0); }' > /tmp/fsck_preload.c
+mycc -o /tmp/fsck_preload.so -shared -fpic /tmp/fsck_preload.c || exit 1
+rm /tmp/fsck_preload.c
+
+set -eu
+u1=$mdstart
+u2=$((mdstart + 1))
+mp1=${mntpoint}$u1
+prog=$(basename "$0" .sh)
+mkdir -p $mp1
+
+max=$((2 * 1024 * 1024)) # Two alternate super blocks @ 192 and 2240
+i=`jot -r 1 1 3`
+[ $i -eq 1 ] && flags="-O2"
+[ $i -eq 2 ] && flags="-U"
+[ $i -eq 3 ] && { flags="-j"; max=$((8 * 1024 * 1024)); }
+
+backup=$mp1/$prog.diskimage.$flags.`date +%Y%m%dT%H%M%S`
+core=/tmp/$prog.core.`date +%Y%m%dT%H%M%S`
+diskimage=$mp1/$prog.diskimage
+log=$mp1/$prog.log
+
+asbs=0
+cleans=0
+reruns=0
+waccess=0
+
+set +e
+mount | grep "on $mp1 " | grep -q /dev/md && umount -f $mp1
+[ -c /dev/md$u1 ] && mdconfig -d -u $u1
+mdconfig -a -t swap -s 10g -u $u1
+newfs $newfs_flags /dev/md$u1 > /dev/null
+mount /dev/md$u1 $mp1
+
+[ -c /dev/md$u2 ] && mdconfig -d -u $u2
+dd if=/dev/zero of=$diskimage bs=$max count=1 status=none
+mdconfig -a -t vnode -f $diskimage -u $u2
+backups=`newfs -N $flags md$u2 | grep -A1 "super-block backups" | \
+ tail -1 | sed 's/,//g'`
+echo "newfs $flags /dev/md$u2"
+newfs $flags md$u2 > /dev/null
+[ "$newfs_flags" = "" ] && tunefs -n disable md$u2
+mdconfig -d -u $u2
+
+chk() {
+ local i
+
+ clean=0
+ rerun=0
+ waccess=0
+ LD_PRELOAD=/tmp/fsck_preload.so \
+ timeout 2m fsck_ffs -fy $1 > $log 2>&1
+ r=$?
+ if grep -qiE "super-?block.*failed" $log; then
+ for b in $backups; do
+ asbs=$((asbs + 1))
+ LD_PRELOAD=/tmp/fsck_preload.so \
+ timeout 2m fsck_ffs -b $b -fy $1 > $log 2>&1
+ r=$?
+ grep -qiE "super-?block.*failed" $log ||
+ break
+ done
+ usedasb=1
+ else
+ usedasb=0
+ fi
+ LANG=C egrep -q "[A-Z][A-Z]" $log && clean=0
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log && clean=1
+ # For now regard a "was modified" as a cause for a rerun,
+ # disregarding "clean" claim.
+ grep -Eq "WAS MODIFIED" $log && rerun=1
+ grep -q RERUN $log && rerun=1
+ grep -q "NO WRITE ACCESS" $log && waccess=1
+ [ $r -ne 0 -a $clean -eq 1 ] && echo "Exit code $r w/ clean == 1"
+}
+
+cd $mp1
+s=0
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 60 ]; do
+ /tmp/flip -n 50 $diskimage
+
+ cp $diskimage $backup
+
+ for i in `jot 10`; do
+ chk $diskimage
+ [ $i -eq 1 -a "$flags" = "-j" ] && continue # First run processes the journal
+ [ $rerun -eq 1 ] && { reruns=$((reruns + 1)); continue; }
+ [ $clean -eq 1 ] && { cleans=$((cleans + 1)); break; }
+ [ -f fsck_ffs.core ] && { s=1; break 2; }
+ [ $r -eq 124 ] && { s=2; break 2; } # timeout
+ done
+ [ $clean -ne 1 ] && break
+ [ $r -ne 0 -a $clean -eq 1 ] &&
+ { echo "CLEAN && non zero exit code"; break; }
+ [ $clean -eq 1 ] && continue
+ [ $usedasb -eq 1 ] && { echo "Alt. SB failed"; s=104; }
+ [ $waccess -eq 1 ] && { echo "No write access"; s=105; }
+ break
+done
+
+echo "$cleans cleans, $reruns reruns, $asbs alternate SBs."
+if [ $clean -ne 1 ]; then
+ echo "FS still not clean. Last fsck_ffs exit code was $r."
+ [ $s -eq 0 ] && s=106
+fi
+grep -q "Superblock check-hash failed" $log && s=0 # Ignore for now
+grep -q "is not a file system superblock" $log && s=0 # Ignore for now
+[ $s -ne 0 ] && { gzip $backup; cp -v $backup.gz /tmp; }
+cd /tmp
+umount $mp1
+mdconfig -d -u $u1
+rm -f /tmp/flip /tmp/fsck_preload.so
+exit $s
diff --git a/tools/test/stress2/misc/fsck14.sh b/tools/test/stress2/misc/fsck14.sh
new file mode 100755
index 000000000000..ddeb45a83e96
--- /dev/null
+++ b/tools/test/stress2/misc/fsck14.sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# fsck -B test scenario with SUJ. -B implies "preen mode".
+
+# 'panic: ffs_blkfree_cg: bad size' seen:
+# https://people.freebsd.org/~pho/stress/log/log0465.txt
+# Fixed by: 220427da0e9b - Set UFS/FFS file type to snapshot before changing
+# its block pointers.
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+mycc -o /tmp/flip -Wall -Wextra ../tools/flip.c || exit 2
+
+set -e
+md=/dev/md$mdstart
+prog=$(basename "$0" .sh)
+backup=/tmp/$prog.sh.diskimage.`date +%Y%m%dT%H%M%S`.gz
+log=/tmp/$prog.sh.log
+[ -c $md ] && mdconfig -d -u $mdstart
+dd if=/dev/zero of=$diskimage bs=128m count=1 status=none
+mdconfig -a -t vnode -f $diskimage -u $mdstart
+backups=`newfs -N $j $md | grep -A1 "super-block backups" | \
+ tail -1 | sed 's/,//g'`
+newfs -j $md > /dev/null 2>&1
+mount $md $mntpoint
+set +e
+
+jot 5000 | xargs -P0 -I% touch $mntpoint/a%
+while ! umount $mntpoint; do :; done
+/tmp/flip -n 10 $diskimage
+gzip < $diskimage > $backup
+fsync $diskimage $backup
+
+mount -f $md $mntpoint
+
+if ! fsck_ffs -B $md > $log 2>&1; then
+ grep MANUALLY $log
+ umount $mntpoint
+ fsck_ffs -fy $md > $log 2>&1; s=$?
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log || {
+ cat $log
+ echo "fsck_ffs -f failed with exit code $s"
+ umount $mntpoint; mdconfig -d -u $mdstart
+ rm -f $log /tmp/flip $diskimage $backup
+ exit 1
+ }
+ mount $md $mntpoint
+fi
+
+jot 5000 | xargs -P0 -I% rm $mntpoint/a%
+jot 5000 | xargs -P0 -I% touch $mntpoint/b%
+
+ls -lR $mntpoint > /dev/null || {
+ echo "ls -lR $mntpoint failed after fsck -B"
+ umount $mntpoint; mdconfig -d -u $mdstart
+ rm -f $log /tmp/flip $diskimage $backup
+ exit 0 # For now, ignore non fatal errors
+}
+
+jot 5000 | xargs -P0 -I% rm $mntpoint/b% || {
+ echo "clean failed"
+ umount $mntpoint; mdconfig -d -u $mdstart
+ rm -f $log /tmp/flip $diskimage $backup
+ exit 0 # For now, ignore non fatal errors
+}
+umount $mntpoint
+
+r=0
+for i in `jot 4`; do
+ fsck_ffs -fy $diskimage > $log 2>&1; r=$?
+ if grep -qiE "super-?block.*failed" $log; then
+ for b in $backups; do
+ echo "fsck_ffs -b $b -fy $diskimage"
+ fsck_ffs -b $b -fy $diskimage > $log 2>&1
+ r=$?
+ grep -qiE "super-?block.*failed" $log ||
+ break
+ echo "Checking next SB"
+ done
+ fi
+ [ $r -ne 0 ] && continue
+ grep -Eq "WAS MODIFIED" $log && continue
+ grep -Eq "CLEAN" $log && break
+done
+mount $md $mntpoint || exit 3
+ls -lR $mntpoint > /dev/null || { umount $mntpoint; mdconfig -d -u mdstart; echo "exit 4"; exit 4; }
+umount $mntpoint
+fsck_ffs -fy $md > $log 2>&1
+grep -Eq 'IS CLEAN|MARKED CLEAN' $log && s=0 || { s=1; cat $log; }
+mdconfig -d -u $mdstart
+rm -f $log /tmp/flip $diskimage $backup
+exit $s
diff --git a/tools/test/stress2/misc/fsck2.sh b/tools/test/stress2/misc/fsck2.sh
index 313efec490d1..3287e240d338 100755
--- a/tools/test/stress2/misc/fsck2.sh
+++ b/tools/test/stress2/misc/fsck2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/fsck3.sh b/tools/test/stress2/misc/fsck3.sh
index f9bd29017e35..39ebd112fccf 100755
--- a/tools/test/stress2/misc/fsck3.sh
+++ b/tools/test/stress2/misc/fsck3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/fsck4.sh b/tools/test/stress2/misc/fsck4.sh
index 3e97f7b54340..feb955ac3231 100755
--- a/tools/test/stress2/misc/fsck4.sh
+++ b/tools/test/stress2/misc/fsck4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/fsck5.sh b/tools/test/stress2/misc/fsck5.sh
index 35381c8c55e7..5ffded87d95e 100755
--- a/tools/test/stress2/misc/fsck5.sh
+++ b/tools/test/stress2/misc/fsck5.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/fsck6.sh b/tools/test/stress2/misc/fsck6.sh
index e1c5a4f36559..5d86b9d59ed2 100755
--- a/tools/test/stress2/misc/fsck6.sh
+++ b/tools/test/stress2/misc/fsck6.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/fsck7.sh b/tools/test/stress2/misc/fsck7.sh
index ab83f6ad0166..9662393e1df6 100755
--- a/tools/test/stress2/misc/fsck7.sh
+++ b/tools/test/stress2/misc/fsck7.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/fsck8.sh b/tools/test/stress2/misc/fsck8.sh
new file mode 100755
index 000000000000..9613fe72173e
--- /dev/null
+++ b/tools/test/stress2/misc/fsck8.sh
@@ -0,0 +1,179 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# fsck_ffs(8) disk image fuzz test. SB focus.
+
+# panic: wrong length 4098 for sectorsize 512
+# FreeBSD 14.0-CURRENT #0 main-n255602-51adf913e8815: Fri May 13 07:55:32 CEST 2022
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO
+
+. ../default.cfg
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+cc -o /tmp/flip -Wall -Wextra -O2 ../tools/flip.c || exit 1
+
+set -e
+u1=$mdstart
+u2=$((mdstart + 1))
+mp1=${mntpoint}$u1
+mp2=${mntpoint}$u2
+mkdir -p $mp1 $mp2
+log=$mp1/fsck8.sh.log
+diskimage=$mp1/fsck8.sh.diskimage
+backup=/tmp/fsck8.sh.diskimage.`date +%Y%m%dT%H%M%S`.gz
+asbs=0
+cleans=0
+reruns=0
+waccess=0
+
+max=$((10 * 1024 * 1024))
+# UFS1 or UFS2 SU:
+[ `jot -r 1 0 1` -eq 0 ] && newfs_flags='-O 1' || newfs_flags='-O 2 -U'
+
+mount | grep "on $mp1 " | grep -q /dev/md && umount -f $mp1
+[ -c /dev/md$u1 ] && mdconfig -d -u $u1
+mdconfig -a -t swap -s 1g -u $u1
+newfs $newfs_flags -n /dev/md$u1 > /dev/null
+mount /dev/md$u1 $mp1
+
+[ -c /dev/md$u2 ] && mdconfig -d -u $u2
+dd if=/dev/zero of=$diskimage bs=$max count=1 status=none
+mdconfig -a -t vnode -f $diskimage -u $u2
+backups=`newfs -N $newfs_flags md$u2 | grep -A1 "super-block backups" | \
+ tail -1 | sed 's/,//g'`
+newfs $newfs_flags -n md$u2 > /dev/null
+mount /dev/md$u2 $mp2
+[ -d /usr/include/sys ] && cp -r /usr/include/sys $mp2
+umount $mp2
+set +e
+
+chk() {
+ local i
+
+ clean=0
+ rerun=0
+ waccess=0
+ timeout 5m fsck_ffs -fy $1 > $log 2>&1
+ r=$?
+ if grep -qiE "super-?block.*failed" $log; then
+ for b in $backups; do
+ echo "Using alternate SB $b"
+ asbs=$((asbs + 1))
+ fsck_ffs -b $b -fy $1 > $log 2>&1
+ r=$?
+ grep -qiE "super-?block.*failed" $log ||
+ break
+ done
+ usedasb=1
+ else
+ usedasb=0
+ fi
+ LANG=C egrep -q "[A-Z][A-Z]" $log && clean=0
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log && clean=1
+ # For now regard a "was modified" as a cause for a rerun,
+ # disregarding the "clean" claim.
+ grep -Eq "WAS MODIFIED" $log && rerun=1
+ grep -q RERUN $log && rerun=1
+ grep -q "NO WRITE ACCESS" $log && waccess=1
+ [ $r -ne 0 -a $clean -eq 1 ] && echo "Exit code $r w/ clean == 1"
+}
+
+cd $mp1
+clean=0
+s=0
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 300 ]; do
+ mount /dev/md$u2 $mp2 || break
+ ls -lR $mp2 > /dev/null || { s=102; echo "ls failed"; break; }
+ touch $mp2/`jot -rc 8 a z | tr -d '\n'`
+ while mount | grep -q "on $mp2 "; do umount $mp2; done
+ echo * | grep -q core && break
+ sync
+ mdconfig -d -u $u2
+ # SBLOCK = 64k, SBLOCKSIZE = 8k
+ /tmp/flip -n 5 -s $(((64 + 8) * 1024)) $diskimage
+
+ sync
+ if [ `stat -f%z $diskimage` -gt $max ]; then
+ ls -lh $diskimage
+ truncate -s $max $diskimage
+ else
+ gzip < $diskimage > $backup
+ fi
+ fsync $backup
+ sync
+
+ for i in `jot 5`; do
+ [ $i -gt 2 ] && echo "fsck run #$i"
+ chk $diskimage
+ [ $rerun -eq 1 ] && { reruns=$((reruns + 1)); continue; }
+ [ $clean -eq 1 ] && { cleans=$((cleans + 1)); break; }
+ [ -f fsck_ffs.core ] &&
+ { cp -v $diskimage \
+ /tmp/fsck_ffs.core.diskimage.`date +%Y%m%dT%H%M%S`; break 2; }
+ done
+ [ $clean -ne 1 ] && break
+ mdconfig -a -t vnode -f $diskimage -u $u2
+ [ $r -ne 0 -a $clean -eq 1 ] &&
+ { echo "CLEAN && non zero exit code"; break; }
+ [ $clean -eq 1 ] && continue
+ [ $usedasb -eq 1 ] && { echo "Alt. SB failed"; s=104; }
+ [ $waccess -eq 1 ] && { echo "No write access"; s=105; }
+ break
+done
+sleep 2 # Wait for /dev to catch up
+[ -c /dev/md$u2 ] && r1=1 || r1=0
+for i in `jot 5`; do
+ mount | grep -q "on $mp2 " || break
+ umount $mp2 && break
+ sleep 2
+done
+mdconfig -d -u $u2 2>/dev/null # XXX when mount fails
+
+echo "$cleans cleans, $reruns reruns, $asbs alternate SBs."
+if [ $clean -ne 1 ]; then
+ echo "FS still not clean. Last fsck_ffs exit code was $r."
+ echo =================
+ cat $log
+ echo =================
+ cp -v $log /tmp
+ [ $s -eq 0 ] && s=106
+fi
+echo * | grep -q core && { ls -l *.core; cp -v $log /tmp; exit 106; } ||
+ rm -f $backup
+[ $s -eq 101 ] && rm -f $backup # mount error breakout
+cd /tmp
+for i in `jot 5`; do
+ umount $mp1 && break
+ sleep 2
+done
+mdconfig -d -u $u1
+rm -f /tmp/flip
+exit $s
diff --git a/tools/test/stress2/misc/fsck9.sh b/tools/test/stress2/misc/fsck9.sh
new file mode 100755
index 000000000000..bbb10609ea67
--- /dev/null
+++ b/tools/test/stress2/misc/fsck9.sh
@@ -0,0 +1,168 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# fsck_ffs(8) false CLEAN claim scenario
+
+# https://people.freebsd.org/~pho/fsck9.sh.diskimage.20220716T150359.txt
+# https://people.freebsd.org/~pho/fsck9.sh.diskimage.20220716T150359.gz
+
+# https://people.freebsd.org/~pho/fsck9.sh.diskimage.20220716T172428.txt
+# https://people.freebsd.org/~pho/fsck9.sh.diskimage.20220716T172428.gz
+
+. ../default.cfg
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+cc -o /tmp/flip -Wall -Wextra -O2 ../tools/flip.c || exit 1
+
+set -e
+u1=$mdstart
+u2=$((mdstart + 1))
+mp1=${mntpoint}$u1
+mp2=${mntpoint}$u2
+mkdir -p $mp1 $mp2
+log=$mp1/fsck9.sh.log
+diskimage=$mp1/fsck9.sh.diskimage
+backup=/tmp/fsck9.sh.diskimage.`date +%Y%m%dT%H%M%S`.gz
+cleans=0
+reruns=0
+
+max=$((10 * 1024 * 1024))
+newfs_flags='-U'
+
+mount | grep "on $mp1 " | grep -q /dev/md && umount -f $mp1
+[ -c /dev/md$u1 ] && mdconfig -d -u $u1
+mdconfig -a -t swap -s 1g -u $u1
+newfs $newfs_flags -n /dev/md$u1 > /dev/null
+mount /dev/md$u1 $mp1
+
+[ -c /dev/md$u2 ] && mdconfig -d -u $u2
+dd if=/dev/zero of=$diskimage bs=$max count=1 status=none
+mdconfig -a -t vnode -f $diskimage -u $u2
+backups=`newfs -N $newfs_flags md$u2 | grep -A1 "super-block backups" | \
+ tail -1 | sed 's/,//g'`
+newfs $newfs_flags -n md$u2 > /dev/null
+mount /dev/md$u2 $mp2
+[ -d /usr/include/sys ] && cp -r /usr/include/sys $mp2
+umount $mp2
+set +e
+
+chk() {
+ local i
+
+ clean=0
+ rerun=0
+ fsck_ffs -fy $1 > $log 2>&1
+ r=$?
+ if grep -qiE "super-?block.*failed" $log; then
+ for b in $backups; do
+ echo "fsck_ffs -b $b -fy $1"
+ fsck_ffs -b $b -fy $1 > $log 2>&1
+ r=$?
+ grep -qiE "super-?block.*failed" $log ||
+ break
+ echo "Checking next SB"
+ done
+ usedasb=1
+ else
+ usedasb=0
+ fi
+ LANG=C egrep -q "[A-Z][A-Z]" $log && clean=0
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log && clean=1
+ grep -q RERUN $log && rerun=1
+ [ $r -ne 0 -a $clean -eq 1 ] && echo "Exit code $r w/ clean == 1"
+}
+
+cd $mp1
+clean=0
+s=0
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 300 ]; do
+ mount /dev/md$u2 $mp2 || break
+ if ! ls -lR $mp2 > /dev/null; then
+ s=102
+ echo "ls failed"; grep "core dumped" /var/log/messages | tail -1
+ break
+ fi
+ touch $mp2/`jot -rc 8 a z | tr -d '\n'`
+ while mount | grep -q "on $mp2 "; do umount $mp2; done
+ echo * | grep -q core && break
+ sync
+ mdconfig -d -u $u2
+ /tmp/flip -n 5 $diskimage
+
+ sync
+ if [ `stat -f%z $diskimage` -gt $max ]; then
+ ls -lh $diskimage
+ truncate -s $max $diskimage
+ else
+ gzip < $diskimage > $backup
+ fi
+ fsync $backup
+ sync
+
+ for i in `jot 5`; do
+ [ $i -gt 2 ] && echo "fsck run #$i"
+ chk $diskimage
+ [ $rerun -eq 1 ] && { reruns=$((reruns + 1)); continue; }
+ [ $clean -eq 1 ] && { cleans=$((cleans + 1)); break; }
+ [ -f fsck_ffs.core ] &&
+ { cp -v $diskimage \
+ /tmp/fsck_ffs.core.diskimage.`date +%Y%m%dT%H%M%S`; break 2; }
+ done
+ if [ $clean -eq 1 ]; then
+ fsck_ffs -fy $diskimage > $log 2>&1
+ if grep -q MODIFIED $log; then
+ echo "*** fsck of \"clean\" FS found more issues:"
+ cat $log
+ s=1
+ break
+ fi
+ fi
+ [ $clean -ne 1 ] && break
+ mdconfig -a -t vnode -f $diskimage -u $u2
+done
+sleep 2 # Wait for /dev to catch up
+[ -c /dev/md$u2 ] && r1=1 || r1=0
+for i in `jot 5`; do
+ mount | grep -q "on $mp2 " || break
+ umount $mp2 && break
+ sleep 2
+done
+mdconfig -d -u $u2 2>/dev/null # XXX when mount fails
+
+[ $s -eq 0 ] && rm -f $backup || echo "Preserved $backup due to status code $s"
+cd /tmp
+for i in `jot 5`; do
+ umount $mp1 && break
+ sleep 2
+done
+mdconfig -d -u $u1
+rm -f /tmp/flip
+exit $s
diff --git a/tools/test/stress2/misc/fstat.sh b/tools/test/stress2/misc/fstat.sh
index 441065f8e769..72e90d631e6d 100755
--- a/tools/test/stress2/misc/fstat.sh
+++ b/tools/test/stress2/misc/fstat.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/fsync2.sh b/tools/test/stress2/misc/fsync2.sh
index f2e846c4aa20..009fe9542f07 100755
--- a/tools/test/stress2/misc/fsync2.sh
+++ b/tools/test/stress2/misc/fsync2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/fsync3.sh b/tools/test/stress2/misc/fsync3.sh
new file mode 100755
index 000000000000..f220d19b8c24
--- /dev/null
+++ b/tools/test/stress2/misc/fsync3.sh
@@ -0,0 +1,156 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Regression test for D37997: ffs_syncvnode(): avoid a LoR for SU
+# https://people.freebsd.org/~pho/stress/log/log0402.txt
+# Fixed by 6e1eabadcb1d - main - ffs_syncvnode(): avoid a LoR for SU
+
+# Test scenario based on report by jkim
+
+. ../default.cfg
+[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
+
+dir=/tmp
+odir=`pwd`
+prog=$(basename "$0" .sh)
+cd $dir
+sed '1,/^EOF/d' < $odir/$0 > $dir/$prog.c
+mycc -o $prog -Wall -Wextra -O0 -g $prog.c -lpthread || exit 1
+rm -f $prog.c
+cd $odir
+
+set -eu
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 1g -u $mdstart
+newfs -U md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+set +e
+
+cd $odir
+../testcases/swap/swap -t 1m -i 20 -l 100 > /dev/null &
+sleep .5
+cd $mntpoint
+mkdir -p d1/d2/d3/d4/d5
+for i in `jot 8`; do
+ $dir/$prog $i &
+done
+cd $odir
+wait
+
+for i in `jot 6`; do
+ mount | grep -q "on $mntpoint " || break
+ umount $mntpoint && break || sleep 10
+ [ $i -eq 6 ] &&
+ { echo FATAL; fstat -mf $mntpoint; exit 1; }
+done
+mdconfig -d -u $mdstart
+rm -rf $dir/$prog
+exit 0
+EOF
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define RUNTIME 60
+
+static time_t start;
+static volatile int fd, n;
+static char buf[4096];
+
+static void *
+t1(void *data __unused)
+{
+ char *path = "d1/d2/d3/d4/d5";
+ char d1[1024], d2[1024], file[1024];
+
+ pthread_set_name_np(pthread_self(), __func__);
+ snprintf(d1, sizeof(d1), "%s/dir.%d", path, getpid());
+ snprintf(d2, sizeof(d2), "%s/new.%d", path, getpid());
+ snprintf(file, sizeof(file), "%s/../file.%d", path, getpid());
+ while (time(NULL) - start < RUNTIME) {
+ if (mkdir(d1, 0740) == -1)
+ err(1, "mkdir(%s)", d1);
+ if (rename(d1, d2) == -1)
+ err(1, "rename(%s, %s)", d1, d2);
+ if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) == -1)
+ err(1, "open%s()", file);
+ if (write(fd, buf, sizeof(buf)) != sizeof(buf))
+ err(1, "write()");
+ close(fd);
+ if (rename(d2, d1) == -1)
+ err(1, "rename(%s, %s)", d2, d1);
+ if (rmdir(d1) == -1)
+ err(1, "rmdir(%s)", d1);
+ }
+
+ return (NULL);
+}
+
+static void *
+t2(void *data __unused)
+{
+ pthread_set_name_np(pthread_self(), __func__);
+ while (time(NULL) - start < RUNTIME) {
+ fsync(fd);
+ usleep(arc4random() % 500);
+ }
+
+ return (NULL);
+}
+
+int
+main(int argc __unused, char *argv[])
+{
+ pthread_t tid[2];
+ int r;
+
+ n = atoi(argv[1]);
+ start = time(NULL);
+ if ((r = pthread_create(&tid[0], NULL, t1, NULL)) != 0)
+ errc(1, r, "pthread_create");
+ if ((r = pthread_create(&tid[1], NULL, t2, NULL)) != 0)
+ errc(1, r, "pthread_create");
+
+ if ((r = pthread_join(tid[0], NULL)) != 0)
+ errc(1, r, "pthread_join");
+ if ((r = pthread_join(tid[1], NULL)) != 0)
+ errc(1, r, "pthread_join");
+
+ return (0);
+}
diff --git a/tools/test/stress2/misc/fsync4.sh b/tools/test/stress2/misc/fsync4.sh
new file mode 100755
index 000000000000..ac08dd6dff49
--- /dev/null
+++ b/tools/test/stress2/misc/fsync4.sh
@@ -0,0 +1,146 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Regression test for D38114: Handle ERELOOKUP from VOP_FSYNC()
+
+# "fsync4: msync(0x82d3cc000), file d1/d2/d3/d4/d5/../file.92660:
+# Input/output error" seen
+
+# Fixed by: 6189672e6008 - main - Handle ERELOOKUP from VOP_FSYNC() in
+# several other places
+
+. ../default.cfg
+[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
+
+dir=/tmp
+odir=`pwd`
+pids=""
+prog=$(basename "$0" .sh)
+s=0
+cd $dir
+sed '1,/^EOF/d' < $odir/$0 > $dir/$prog.c
+mycc -o $prog -Wall -Wextra -O0 -g $prog.c || exit 1
+rm -f $prog.c
+cd $odir
+
+set -eu
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 1g -u $mdstart
+newfs -U md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+set +e
+
+cd $odir
+../testcases/swap/swap -t 1m -i 20 -l 100 > /dev/null &
+sleep .5
+cd $mntpoint
+mkdir -p d1/d2/d3/d4/d5
+for i in `jot 8`; do
+ $dir/$prog $i &
+ pids="$pids $!"
+done
+cd $odir
+for pid in $pids; do
+ wait $pid
+ [ $? -ne 0 ] && s=1
+done
+
+for i in `jot 6`; do
+ mount | grep -q "on $mntpoint " || break
+ umount $mntpoint && break || sleep 10
+ [ $i -eq 6 ] &&
+ { echo FATAL; fstat -mf $mntpoint; exit 1; }
+done
+mdconfig -d -u $mdstart
+rm -rf $dir/$prog
+exit $s
+EOF
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define RUNTIME 60
+#define SIZ (1024 * 1024)
+
+static time_t start;
+
+int
+main(void)
+{
+ size_t len;
+ int fd, i, ps;
+ char *cp;
+ char *path = "d1/d2/d3/d4/d5";
+ char d1[1024], d2[1024], file[1024];
+
+ snprintf(d1, sizeof(d1), "%s/dir.%d", path, getpid());
+ snprintf(d2, sizeof(d2), "%s/new.%d", path, getpid());
+ snprintf(file, sizeof(file), "%s/../file.%d", path, getpid());
+
+ start = time(NULL);
+ while (time(NULL) - start < RUNTIME) {
+ if (mkdir(d1, 0740) == -1)
+ err(1, "mkdir(%s)", d1);
+ if (rename(d1, d2) == -1)
+ err(1, "rename(%s, %s)", d1, d2);
+ if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) == -1)
+ err(1, "open%s()", file);
+ len = SIZ;
+ if (ftruncate(fd, len) == -1)
+ err(1, "ftruncate");
+ cp = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0);
+ if (cp == MAP_FAILED)
+ err(1, "mmap()");
+ ps = getpagesize();
+ for (i = 0; i < SIZ; i += ps)
+ cp[i] = 1;
+ if (msync(cp, 0, MS_SYNC) == -1)
+ err(1, "msync(%p), file %s", cp, file);
+ if (munmap(cp, len) == -1)
+ err(1, "unmap()");
+ close(fd);
+ if (rename(d2, d1) == -1)
+ err(1, "rename(%s, %s)", d2, d1);
+ if (rmdir(d1) == -1)
+ err(1, "rmdir(%s)", d1);
+ }
+
+ return (0);
+}
diff --git a/tools/test/stress2/misc/ftruncate3.sh b/tools/test/stress2/misc/ftruncate3.sh
new file mode 100755
index 000000000000..7373ae8d22a8
--- /dev/null
+++ b/tools/test/stress2/misc/ftruncate3.sh
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+# Test scenario from Bug 64816: [nfs] [patch] mmap and/or ftruncate does not work correctly on nfs mounted file systems
+
+. ../default.cfg
+
+set -u
+grep -q $mntpoint /etc/exports ||
+ { echo "$mntpoint missing from /etc/exports"; exit 0; }
+rpcinfo 2>/dev/null | grep -q mountd || exit 0
+
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+#include <sys/types.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+void error(char *msg)
+{
+ fprintf(stderr, "Error: %s\nSystem error %d: %s\n", msg, errno, strerror(errno));
+ exit(-1);
+}
+
+#define SZ 1024 // Less than page size
+
+int main(int argn, char *argv[])
+{
+ int fd, s;
+ char buffer[SZ];
+ char *map;
+
+ if (argn!=2)
+ {
+ fprintf(stderr, "Usage:\n %s [filename]\n", argv[0]);
+ _exit(-1);
+ }
+
+ memset(buffer, 0, SZ);
+ s = 0;
+
+ fd=open(argv[1], O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR);
+ if (fd==-1)
+ error("Could not create file");
+
+ if (write(fd, buffer, SZ)!=SZ)
+ error("Could not write buffer");
+
+ map=mmap(NULL, SZ, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
+ if (map==MAP_FAILED)
+ error("Map failed");
+ map[SZ-1]=1;
+
+ if (ftruncate(fd, SZ+1)!=0)
+ error("Could not truncate file");
+
+ if (map[SZ-1]==1)
+ printf("Test passed\n");
+ else {
+ printf("Test failed\n");
+ s = 1;
+ }
+
+ exit(s);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 -g /tmp/$prog.c || exit 1
+
+mount | grep -q "on $mntpoint " && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -s 1g -u $mdstart
+newfs -n $newfs_flags /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+
+mp2=${mntpoint}2
+mkdir -p $mp2
+mount | grep -q "on $mp2 " && umount -f $mp2
+mount -t nfs -o retrycnt=3 127.0.0.1:$mntpoint $mp2 || exit 1
+sleep .2
+mount | grep $mntpoint
+
+cd $mp2
+/tmp/$prog $prog.data; s=$?
+ls -ls $mp2/$prog.data
+cd -
+
+umount $mp2
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -f /tmp/$prog /tmp/$prog.c
+exit $s
diff --git a/tools/test/stress2/misc/geomleak2.sh b/tools/test/stress2/misc/geomleak2.sh
index 19b6f03d6333..1fc2405da66b 100755
--- a/tools/test/stress2/misc/geomleak2.sh
+++ b/tools/test/stress2/misc/geomleak2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/getrandom.sh b/tools/test/stress2/misc/getrandom.sh
index 3b2de3ec2a7a..402ff8a40544 100755
--- a/tools/test/stress2/misc/getrandom.sh
+++ b/tools/test/stress2/misc/getrandom.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/getrandom2.sh b/tools/test/stress2/misc/getrandom2.sh
index 941ffb737a6d..23eaa5aedb8e 100755
--- a/tools/test/stress2/misc/getrandom2.sh
+++ b/tools/test/stress2/misc/getrandom2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/gnop10.sh b/tools/test/stress2/misc/gnop10.sh
index 012104cbf9ed..5ab05280279c 100755
--- a/tools/test/stress2/misc/gnop10.sh
+++ b/tools/test/stress2/misc/gnop10.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
@@ -32,6 +32,10 @@
# Copy of gnop9.sh. Uses SU instead of SUJ.
+# https://people.freebsd.org/~pho/stress/log/log0269.txt
+# https://people.freebsd.org/~pho/stress/log/log0370.txt
+# https://people.freebsd.org/~pho/stress/log/log0396.txt
+
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
. ../default.cfg
diff --git a/tools/test/stress2/misc/gnop11.sh b/tools/test/stress2/misc/gnop11.sh
index 4d4f936bd8c6..48da18f1c425 100755
--- a/tools/test/stress2/misc/gnop11.sh
+++ b/tools/test/stress2/misc/gnop11.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Kirk McKusick <mckusick@mckusick.com>
#
diff --git a/tools/test/stress2/misc/gnop12.sh b/tools/test/stress2/misc/gnop12.sh
index d22a82b35a7e..1b5d311d7723 100755
--- a/tools/test/stress2/misc/gnop12.sh
+++ b/tools/test/stress2/misc/gnop12.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/gnop13.sh b/tools/test/stress2/misc/gnop13.sh
new file mode 100755
index 000000000000..45668b9d8e82
--- /dev/null
+++ b/tools/test/stress2/misc/gnop13.sh
@@ -0,0 +1,138 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Snapshot test
+# Variation of force13.sh, but uses "gnop -f destroy"
+
+# Seen:
+# UFS: forcibly unmounting /dev/md10.nop from /mnt
+# panic: flush_pagedep_deps: failed to flush inodedep
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+set -u
+log=/tmp/gnop13.sh.log
+mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+truncate -s 10g $diskimage
+mdconfig -a -t vnode -f $diskimage -u $mdstart
+flags=$newfs_flags
+[ `jot -r 1 0 1` -eq 1 ] && flags="-j"
+
+echo "newfs $flags md$mdstart"
+newfs $flags md$mdstart > /dev/null 2>&1
+
+# Exclude rename for now due to log0374.txt
+export TESTPROGS=`cd ..; find testcases/ -perm -1 -type f | \
+ egrep -Ev "/run/|/badcode/|/pty/|/shm/|/socket/|sysctl|tcp|thr|udp|rename"`
+export runRUNTIME=3m
+export RUNDIR=$mntpoint/stressX
+export CTRLDIR=$mntpoint/stressX.control
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt $((15 * 60)) ]; do
+ gnop create /dev/md$mdstart || exit 1
+ mount /dev/md$mdstart.nop $mntpoint || exit 1
+ rm -fr $mntpoint/lost+found
+ chmod 777 $mntpoint
+
+ su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > \
+ /dev/null 2>&1 &
+
+ t=`jot -r 1 60 120`
+ st=`date +%s`
+ for i in `jot 10`; do
+ [ -d $mntpoint/.snap ] || break
+ rm -f $mntpoint/.snap/$i
+ echo "mksnap_ffs $mntpoint $mntpoint/.snap/$i"
+ mksnap_ffs $mntpoint $mntpoint/.snap/$i
+ sleep `jot -r 1 1 5`
+ [ $((`date +%s` - st)) -ge $t ] && break
+ done &
+ sleep `jot -r 1 60 120`
+ while [ -c /dev/md$mdstart.nop ]; do
+ echo "gnop destroy -f /dev/md$mdstart.nop"
+ gnop destroy -f /dev/md$mdstart.nop || sleep 1
+ done
+ n=0
+ st=`date +%s`
+ while mount | grep -q "on $mntpoint "; do
+ [ $n -eq 0 ] && /bin/echo -n "Waiting for $mntpoint to force umount ..."
+ n=$((n + 1))
+ sleep 2
+ if [ $((`date +%s` - st)) -ge 180 ]; then
+ echo "Giving up on waiting for umount of $mntpoint"
+ umount $mntpoint || umount -f $mntpoint
+ break
+ fi
+ done
+ [ $n -ne 0 ] && echo
+
+ ../tools/killall.sh
+ wait
+ mount | grep -q "on $mntpoint " && umount -f $mntpoint
+ c=0
+ # Run fsck minimum two times
+ for i in `jot 5`; do
+ fsck_ffs -fy /dev/md$mdstart > $log 2>&1; s=$?
+ grep -q CLEAN $log && grep -q "MODIFIED" $log && c=$((c+=1))
+ grep -Eq "FILE SYSTEM WAS MODIFIED" $log || break
+ done
+ [ $c -gt 1 ] &&
+ { echo "Note: FS marked clean+modified $c times out of $i fsck runs"; s=101; }
+ [ $s -ne 0 ] && break
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log || { s=102; break; }
+done
+[ $s -eq 101 ] && s=0 # Ignore CLEANish problem for now
+if [ $s -eq 0 ]; then
+ mount /dev/md$mdstart.nop $mntpoint
+ cp -R /usr/include $mntpoint
+ dd if=/dev/zero of=$mntpoint/big bs=1m count=10 status=none
+ find $mntpoint/* -delete
+
+ # Check the RO snapshots
+ for f in $mntpoint/.snap/*; do
+ c=0
+ for i in `jot 5`; do
+ echo "fsck_ffs -fy $f"
+ fsck_ffs -fy $f > $log 2>&1; s=$?
+ grep -q CLEAN $log && grep -q "MODIFIED" $log && c=$((c+=1))
+ grep -Eq "FILE SYSTEM WAS MODIFIED" $log || break
+ done
+ [ $c -gt 1 ] &&
+ { echo "Note: snapshot $i marked clean+modified $c times out of $i fsck runs"; s=201; }
+ [ $s -ne 0 ] && break
+ grep -Eq "IS CLEAN|MARKED CLEAN" $log ||
+ { s=202; tail -10 $log; break; }
+ done
+ umount $mntpoint
+ mdconfig -d -u $mdstart
+ rm -f $diskimage $log
+fi
+exit $s
diff --git a/tools/test/stress2/misc/gnop2.sh b/tools/test/stress2/misc/gnop2.sh
index d38754d58456..0a6b830ce749 100755
--- a/tools/test/stress2/misc/gnop2.sh
+++ b/tools/test/stress2/misc/gnop2.sh
@@ -71,8 +71,10 @@ test() {
gnop status || exit 1
+start=`date +%s`
for i in 1k 2k 4k 8k; do
test $i
+ [ $((`date +%s` - start)) -gt 1200 ] && break
done
[ $notloaded ] && gnop unload
diff --git a/tools/test/stress2/misc/gnop4.sh b/tools/test/stress2/misc/gnop4.sh
index f938dd3b790b..1b4da74266f6 100755
--- a/tools/test/stress2/misc/gnop4.sh
+++ b/tools/test/stress2/misc/gnop4.sh
@@ -34,6 +34,8 @@
# https://people.freebsd.org/~pho/stress/log/kostik1017.txt
# Fixed by r322175
+# Seen with p=513: Threads stuck in "ffsrca"
+
. ../default.cfg
gigs=9
@@ -62,6 +64,7 @@ cd $mntpoint/src
export MAKEOBJDIRPREFIX=$mntpoint/obj
p=$((`sysctl -n hw.ncpu`+ 1))
+[ $p -gt 32 ] && p=32 # Temporary work around
timeout 10m \
make -i -j $p buildworld DESTDIR=$mntpoint TARGET=amd64 \
TARGET_ARCH=amd64 > /dev/null
diff --git a/tools/test/stress2/misc/gnop6.sh b/tools/test/stress2/misc/gnop6.sh
index 63301d8fe841..4d32f584662e 100755
--- a/tools/test/stress2/misc/gnop6.sh
+++ b/tools/test/stress2/misc/gnop6.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/gnop7.sh b/tools/test/stress2/misc/gnop7.sh
index 3f3118ff0fab..76008aabe925 100755
--- a/tools/test/stress2/misc/gnop7.sh
+++ b/tools/test/stress2/misc/gnop7.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/gnop8.sh b/tools/test/stress2/misc/gnop8.sh
index 6916c14e41f4..e9067c8c8066 100755
--- a/tools/test/stress2/misc/gnop8.sh
+++ b/tools/test/stress2/misc/gnop8.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Kirk McKusick <mckusick@mckusick.com>
#
diff --git a/tools/test/stress2/misc/gnop9.sh b/tools/test/stress2/misc/gnop9.sh
index 0389391398f3..12c6fff0a3bf 100755
--- a/tools/test/stress2/misc/gnop9.sh
+++ b/tools/test/stress2/misc/gnop9.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/gpt.sh b/tools/test/stress2/misc/gpt.sh
index 51b4ba39afda..5c1818921321 100755
--- a/tools/test/stress2/misc/gpt.sh
+++ b/tools/test/stress2/misc/gpt.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/growfs2.sh b/tools/test/stress2/misc/growfs2.sh
new file mode 100755
index 000000000000..0990f71423a3
--- /dev/null
+++ b/tools/test/stress2/misc/growfs2.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# growfs(8) test with output to FS to be grown.
+# A regression test for D37896 ufs/suspend: deny suspension if calling
+# process has file from mp opened for write
+# Before D37896 this would result in growfs(8) hanging.
+
+. ../default.cfg
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+log=/tmp/growfs2.sh.log
+s=0
+set -eu
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 32g -u $mdstart
+/sbin/gpart create -s GPT md$mdstart > /dev/null
+/sbin/gpart add -t freebsd-ufs -s 2g -a 4k md$mdstart > /dev/null
+set +e
+
+newfs $newfs_flags md${mdstart}p1 > /dev/null
+mount /dev/md${mdstart}p1 $mntpoint
+cp -r /usr/include $mntpoint/inc1
+
+gpart resize -i 1 -s 31g -a 4k md$mdstart
+echo "Expect: growfs: UFSSUSPEND: Resource deadlock avoided"
+growfs -y md${mdstart}p1 > $mntpoint/log && s=1 || s=0
+
+cp -r /usr/include $mntpoint/inc2
+umount $mntpoint
+fsck -fy /dev/md${mdstart}p1 > $log 2>&1
+grep -q "WAS MODIFIED" $log && s=2
+grep -q CLEAN $log || s=3
+[ $s -ne 0 ] && cat $log
+
+mdconfig -d -u $mdstart
+rm -f $log
+exit $s
diff --git a/tools/test/stress2/misc/growfs3.sh b/tools/test/stress2/misc/growfs3.sh
new file mode 100755
index 000000000000..33e8327cdbbc
--- /dev/null
+++ b/tools/test/stress2/misc/growfs3.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+. ../default.cfg
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+set -eu
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 32g -u $mdstart
+/sbin/gpart create -s GPT md$mdstart > /dev/null
+/sbin/gpart add -t freebsd-ufs -s 2g -a 4k md$mdstart > /dev/null
+set +e
+
+newfs_flags=$(echo "-O1" "-O2" "-U" "-j" | awk -v N=`jot -r 1 1 4` '{print $N}')
+echo "newfs $newfs_flags md${mdstart}p1"
+newfs $newfs_flags md${mdstart}p1 > /dev/null
+[ "$newfs_flags" = "-O2" ] &&
+ tunefs -n disable md${mdstart}p1 > /dev/null 2>&1
+mount /dev/md${mdstart}p1 $mntpoint
+cp -r /usr/include $mntpoint/inc1
+umount $mntpoint
+
+gpart resize -i 1 -s 31g -a 4k md$mdstart
+growfs -y md${mdstart}p1 > /dev/null
+
+mount /dev/md${mdstart}p1 $mntpoint
+cp -r /usr/include $mntpoint/inc2
+umount $mntpoint
+fsck -fy /dev/md${mdstart}p1 > $log 2>&1; s=$?
+grep -q "WAS MODIFIED" $log && { cat $log; s=1; }
+rm -f $log
+mdconfig -d -u $mdstart
+exit $s
diff --git a/tools/test/stress2/misc/gunion.sh b/tools/test/stress2/misc/gunion.sh
index c7d376e5409e..ceecc55b2f13 100755
--- a/tools/test/stress2/misc/gunion.sh
+++ b/tools/test/stress2/misc/gunion.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
@@ -50,7 +50,10 @@ cp -r ../../stress2 $mp1
umount $mp1
mdconfig -a -t swap -s 5g -u $md2
-gunion create -v /dev/md$md2 /dev/md$md1
+set +e
+gunion create -v /dev/md$md2 /dev/md$md1; s=$?
+[ $s -ne 0 ] && echo "gunion create returned $s"
+set -e
mount /dev/md$md2-md$md1.union $mntpoint
export RUNDIR=$mntpoint/stressX
@@ -71,7 +74,7 @@ for i in `jot 6`; do
done
fsck_ffs -fyR /dev/md$md2-md$md1.union > $log 2>&1
grep -Eq "IS CLEAN|MARKED CLEAN" $log || { s=2; cat $log; }
-set +e
+set -e
gunion commit /dev/md$md2-md$md1.union
gunion list | egrep Block\|Current | egrep -v 0 && s=3
gunion destroy /dev/md$md2-md$md1.union
diff --git a/tools/test/stress2/misc/gunion2.sh b/tools/test/stress2/misc/gunion2.sh
index a8fe180c48af..0d14c17b24eb 100755
--- a/tools/test/stress2/misc/gunion2.sh
+++ b/tools/test/stress2/misc/gunion2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
@@ -50,7 +50,10 @@ cp -r ../../stress2 $mp1
umount $mp1
mdconfig -a -t swap -s 5g -u $md2
-gunion create -v /dev/md$md2 /dev/md$md1
+set +e
+gunion create -v /dev/md$md2 /dev/md$md1; s=$?
+[ $s -ne 0 ] && echo "gunion create returned $s"
+set -e
mount /dev/md$md2-md$md1.union $mntpoint
export CTRLDIR=$mntpoint/stressX.control
@@ -79,7 +82,7 @@ testcases/swap/swap
"
export TESTPROGS=`echo $TESTPROGS | sed 's/\n/ /g'`
-set +e
+set -e
chmod 777 $mntpoint
su $testuser -c \
"(cd $mntpoint/stress2; ./testcases/run/run $TESTPROGS)"
diff --git a/tools/test/stress2/misc/holdcnt05.sh b/tools/test/stress2/misc/holdcnt05.sh
index efafa984bdd8..fa6c7b4bd628 100755
--- a/tools/test/stress2/misc/holdcnt05.sh
+++ b/tools/test/stress2/misc/holdcnt05.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/ifconfig.sh b/tools/test/stress2/misc/ifconfig.sh
index 7b3c7e317ec3..0fe768d8c53c 100755
--- a/tools/test/stress2/misc/ifconfig.sh
+++ b/tools/test/stress2/misc/ifconfig.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/ifconfig2.sh b/tools/test/stress2/misc/ifconfig2.sh
index 273db43a329d..77b0d4860647 100755
--- a/tools/test/stress2/misc/ifconfig2.sh
+++ b/tools/test/stress2/misc/ifconfig2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/indir.sh b/tools/test/stress2/misc/indir.sh
index d2d28cd650ab..1f0b873833ee 100755
--- a/tools/test/stress2/misc/indir.sh
+++ b/tools/test/stress2/misc/indir.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/indir_trunc.sh b/tools/test/stress2/misc/indir_trunc.sh
index 64c11f3570ee..e7f1b7cb4fe6 100755
--- a/tools/test/stress2/misc/indir_trunc.sh
+++ b/tools/test/stress2/misc/indir_trunc.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/jexec.sh b/tools/test/stress2/misc/jexec.sh
index c5c2ab605e08..00fb17a27a92 100755
--- a/tools/test/stress2/misc/jexec.sh
+++ b/tools/test/stress2/misc/jexec.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/jumbo.sh b/tools/test/stress2/misc/jumbo.sh
index 8dcc5aa7aca3..a2d09bafaa82 100755
--- a/tools/test/stress2/misc/jumbo.sh
+++ b/tools/test/stress2/misc/jumbo.sh
@@ -131,7 +131,7 @@ reader(void) {
if ((buf = malloc(MX)) == NULL)
err(1, "malloc(%d), %s:%d", MX, __FILE__, __LINE__);
setproctitle("reader");
- for (i = 4096; i < MX; i += 1024) {
+ for (i = sysconf(_SC_PAGESIZE); i < MX; i += 1024) {
alarm(TIMEOUT);
if ((n = recvfrom(msgsock, buf, i, MSG_WAITALL, NULL,
NULL)) < 0) {
diff --git a/tools/test/stress2/misc/kcmp.sh b/tools/test/stress2/misc/kcmp.sh
new file mode 100755
index 000000000000..7c571dd8e8a1
--- /dev/null
+++ b/tools/test/stress2/misc/kcmp.sh
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Seen:
+# UID PID PPID C PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND
+# 0 3730 3668 11 20 0 13596 2904 exithold DE+ 0 1:59.68 ./kcmp
+
+# Fixed by: 5b3e5c6ce3e5
+
+. ../default.cfg
+
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+#include <sys/types.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+static void *
+t1(void *data __unused)
+{
+ for (;;)
+ pause();
+
+ return (NULL);
+}
+
+int
+main(void)
+{
+ pid_t p1, p2;
+ pthread_t tid[2];
+ time_t start;
+ uintptr_t idx1, idx2;
+ int r;
+
+ if ((r = pthread_create(&tid[0], NULL, t1, NULL)) != 0)
+ errc(1, r, "pthread_create");
+ if ((r = pthread_create(&tid[1], NULL, t1, NULL)) != 0)
+ errc(1, r, "pthread_create");
+
+ start = time(NULL);
+ while (time(NULL) - start < 60) {
+ idx1 = idx2 = 0;
+ p1 = arc4random() % 1000000;
+ p2 = arc4random() % 1000000;
+ kcmp(p1, p2, KCMP_VM, idx1, idx2);
+ }
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+/tmp/$prog
+
+rm /tmp/$prog.c /tmp/$prog
+exit 0
diff --git a/tools/test/stress2/misc/kern_umtx_inf_loop.sh b/tools/test/stress2/misc/kern_umtx_inf_loop.sh
index b8088814d7b2..2c4d99149480 100755
--- a/tools/test/stress2/misc/kern_umtx_inf_loop.sh
+++ b/tools/test/stress2/misc/kern_umtx_inf_loop.sh
@@ -46,7 +46,6 @@ EOF
* SUCH DAMAGE.
*/
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <machine/cpufunc.h>
diff --git a/tools/test/stress2/misc/kevent10.sh b/tools/test/stress2/misc/kevent10.sh
index 6efdedfc28cd..b7f74f487cec 100755
--- a/tools/test/stress2/misc/kevent10.sh
+++ b/tools/test/stress2/misc/kevent10.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/kevent12.sh b/tools/test/stress2/misc/kevent12.sh
index 3ae0085f1e5d..1a022e2d1b47 100755
--- a/tools/test/stress2/misc/kevent12.sh
+++ b/tools/test/stress2/misc/kevent12.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/kevent13.sh b/tools/test/stress2/misc/kevent13.sh
index 82a7a10b983c..0e2f8982f4ab 100755
--- a/tools/test/stress2/misc/kevent13.sh
+++ b/tools/test/stress2/misc/kevent13.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/kevent14.sh b/tools/test/stress2/misc/kevent14.sh
index 2531b15caecf..3cf88fd87ba7 100755
--- a/tools/test/stress2/misc/kevent14.sh
+++ b/tools/test/stress2/misc/kevent14.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/kevent15.sh b/tools/test/stress2/misc/kevent15.sh
index 52925365c865..56a3bc4fbd0a 100755
--- a/tools/test/stress2/misc/kevent15.sh
+++ b/tools/test/stress2/misc/kevent15.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/killpg2.sh b/tools/test/stress2/misc/killpg2.sh
new file mode 100755
index 000000000000..5e986f059637
--- /dev/null
+++ b/tools/test/stress2/misc/killpg2.sh
@@ -0,0 +1,197 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# killpg(2) version of reaper.sh. No problems seen.
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+static volatile u_int *share;
+
+#define CONT 0
+#define GID 1
+#define SYNC 2
+#define MAXP 10000
+
+static void
+hand(int i __unused) {
+ _exit(0);
+}
+
+static void
+looper(void)
+{
+ struct sigaction sa;
+ time_t start;
+ struct passwd *pw;
+ pid_t pids[MAXP];
+ int i, parallel;
+
+ setproctitle("looper");
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGUSR1, &sa, NULL) == -1)
+ err(1, "sigaction");
+
+ if ((pw = getpwnam("TUSER")) == NULL)
+ err(1, "no such user: TUSER");
+
+ if (setgroups(1, &pw->pw_gid) ||
+ setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
+ seteuid(pw->pw_uid) || setuid(pw->pw_uid))
+ err(1, "Can't drop privileges to \"TUSER\"");
+ endpwent();
+ setpgrp(0, 0);
+ share[GID] = getpgrp();
+ share[SYNC] = 1;
+ start = time(NULL);
+ while (time(NULL) - start < 120) {
+ parallel = arc4random() % MAXP + 1;
+ for (i = 0; i < parallel; i++) {
+ if ((pids[i] = fork()) == 0) {
+ sa.sa_handler = hand;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGUSR1, &sa, NULL) == -1)
+ err(1, "sigaction");
+ setproctitle("child");
+ for (;;)
+ pause();
+ _exit(0); /* never reached */
+ }
+ if (pids[i] == -1)
+ err(1, "fork()");
+ }
+ for (i = 0; i < parallel; i++) {
+ if (waitpid(pids[i], NULL, 0) != pids[i])
+ err(1, "waitpid(%d) in looper", pids[i]);
+ }
+ }
+ _exit(0);
+}
+
+static void
+killer(void)
+{
+ int e, gid;
+
+ while (share[SYNC] == 0)
+ ;
+ gid = share[GID];
+ while (share[CONT] == 1) {
+ usleep(arc4random() % 50000);
+ gid = share[GID];
+ if (gid != 0) {
+ e = 0;
+ while (e == 0) {
+ if (killpg(gid, SIGUSR1) == -1) {
+ e = 1;
+ if (errno != ESRCH)
+ err(1, "pgkill(%d)", gid);
+ }
+ usleep(5000 + arc4random() % 5000);
+ }
+ }
+ }
+ _exit(0);
+}
+
+int
+main(void)
+{
+ size_t len;
+ time_t start;
+ int lpid, kpid, s1, s2;
+
+ len = PAGE_SIZE;
+ if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
+ err(1, "mmap");
+
+ start = time(NULL);
+ while (time(NULL) - start < 120) {
+ share[CONT] = 1;
+ share[GID] = 0;
+ share[SYNC] = 0;
+ if ((lpid = fork()) == 0)
+ looper();
+ usleep(arc4random() % 100000);
+ if ((kpid = fork()) == 0)
+ killer();
+
+ if (waitpid(lpid, &s1, 0) != lpid)
+ err(1, "waitpid looper");
+ usleep(arc4random() % 1000);
+ share[CONT] = 0;
+ waitpid(kpid, &s2, 0);
+ }
+
+ return (0);
+}
+EOF
+sed -i '' "s#TUSER#$testuser#" /tmp/$prog.c
+cc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1
+rm /tmp/$prog.c
+
+n=1
+start=`date +%s`
+while true; do
+ /tmp/$prog
+ for i in `jot 50`; do
+ pgrep -q $prog || break
+ sleep .5
+ done
+ if pgrep -q $prog; then
+ e=$((`date +%s` - start))
+ echo "Failed in loop #$n after $e seconds."
+ pgrep "$prog|timeout" | xargs ps -jp
+ pkill $prog
+ rm -f /tmp/$prog
+ exit 1
+ fi
+ [ $((`date +%s` - start)) -ge 600 ] && break
+ n=$((n + 1))
+done
+rm /tmp/$prog
+exit 0
diff --git a/tools/test/stress2/misc/killpg3.sh b/tools/test/stress2/misc/killpg3.sh
new file mode 100755
index 000000000000..304b3e320f2f
--- /dev/null
+++ b/tools/test/stress2/misc/killpg3.sh
@@ -0,0 +1,192 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# killpg(2) version of reaper.sh. No problems seen.
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/wait.h>
+
+
+#include <err.h>
+#include <errno.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdatomic.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+static _Atomic(int) *share;
+
+#define GID 0
+#define PARALLEL 10
+#define RDY 1
+#define MAXP 7000
+
+static void
+hand(int i __unused) {
+ _exit(0);
+}
+
+static void
+innerloop(int parallel)
+{
+ pid_t pids[MAXP];
+ struct sigaction sa;
+ int i;
+
+ usleep(1000);
+ for (i = 0; i < parallel; i++) {
+ if ((pids[i] = fork()) == 0) {
+ sa.sa_handler = hand;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGUSR1, &sa, NULL) == -1)
+ err(1, "sigaction");
+ atomic_fetch_add(&share[RDY], 1);
+ setproctitle("child");
+ for (;;)
+ pause();
+ _exit(0); /* never reached */
+ }
+ if (pids[i] == -1)
+ err(1, "fork()");
+ }
+ for (i = 0; i < parallel; i++) {
+ if (waitpid(pids[i], NULL, 0) != pids[i])
+ err(1, "waitpid(%d) in looper", pids[i]);
+ }
+ _exit(0);
+}
+
+static void
+looper(void)
+{
+ struct sigaction sa;
+ struct passwd *pw;
+ pid_t pids[MAXP];
+ int i, parallel;
+
+ setproctitle("looper");
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = 0;
+ if (sigaction(SIGUSR1, &sa, NULL) == -1)
+ err(1, "sigaction");
+
+ if ((pw = getpwnam("TUSER")) == NULL)
+ err(1, "no such user: TUSER");
+
+ if (setgroups(1, &pw->pw_gid) ||
+ setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
+ seteuid(pw->pw_uid) || setuid(pw->pw_uid))
+ err(1, "Can't drop privileges to \"TUSER\"");
+ endpwent();
+ setpgrp(0, 0);
+ share[GID] = getpgrp();
+ parallel = arc4random() % MAXP + 1;
+ parallel = parallel / PARALLEL * PARALLEL;
+ for (i = 0; i < PARALLEL; i++) {
+ if ((pids[i] = fork()) == 0)
+ innerloop(parallel / PARALLEL);
+ }
+ while (atomic_load(&share[RDY]) != parallel)
+ usleep(10000);
+ if (killpg(share[GID], SIGUSR1) == -1)
+ err(1, "pgkill(%d)", share[GID]);
+ for (i = 0; i < 4; i++) {
+ if (waitpid(pids[i], NULL, 0) != pids[i])
+ err(1, "waitpid(%d) in looper", pids[i]);
+ }
+ _exit(0);
+}
+
+int
+main(void)
+{
+ size_t len;
+ time_t start;
+ int lpid, s1;
+
+ len = PAGE_SIZE;
+ if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
+ err(1, "mmap");
+
+ start = time(NULL);
+ while (time(NULL) - start < 120) {
+ share[GID] = 0;
+ share[RDY] = 0;
+ if ((lpid = fork()) == 0)
+ looper();
+ if (waitpid(lpid, &s1, 0) != lpid)
+ err(1, "waitpid looper");
+ }
+
+ return (0);
+}
+EOF
+sed -i '' "s#TUSER#$testuser#" /tmp/$prog.c
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1
+rm /tmp/$prog.c
+
+export MAXSWAPPCT=70
+n=1
+start=`date +%s`
+while true; do
+ ../testcases/swap/swap -t 2m -i 20 > /dev/null &
+ /tmp/$prog & pid=$!
+ st=`date +%s`
+ while kill -0 $pid > /dev/null 2>&1; do
+ e=$((`date +%s` - st))
+ if [ $e -ge 120 ]; then
+ while pgrep -q swap; do pkill swap; done
+ fi
+ if [ $e -ge 600 ]; then
+ echo "Failed in loop #$n after $e seconds."
+ ps -jU$testuser | head -20
+ kill $pid
+ pkill -U$testuser
+ wait
+ rm -f /tmp/$prog
+ exit 1
+ fi
+ done
+ wait
+ [ $((`date +%s` - start)) -ge 300 ] && break
+ n=$((n + 1))
+done
+rm /tmp/$prog
+exit 0
diff --git a/tools/test/stress2/misc/killpg4.sh b/tools/test/stress2/misc/killpg4.sh
new file mode 100755
index 000000000000..448a7f60dd4b
--- /dev/null
+++ b/tools/test/stress2/misc/killpg4.sh
@@ -0,0 +1,114 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Another killpg(2) test scenario. No problems seen.
+
+. ../default.cfg
+export prog=$(basename "$0" .sh)
+set -u
+
+cat > /tmp/$prog.c <<EOF
+#include <sys/wait.h>
+#include <err.h>
+#include <time.h>
+#include <stdlib.h>
+#include <unistd.h>
+#define PARALLEL 2
+
+int
+test(void)
+{
+ pid_t pid;
+ time_t start;
+
+ start = time(NULL);
+ while (time(NULL) - start < 300) {
+ if ((pid = fork()) == -1)
+ err(1, "fork()");
+ if (pid == 0) {
+ if (arc4random() % 100 < 20)
+ usleep(arc4random() % 5000);
+ _exit(0); /* Not reached */
+ }
+ if (waitpid(pid, NULL, 0) != pid)
+ err(1, "waitpid()");
+ }
+ _exit(0);
+}
+
+int
+main(void)
+{
+ pid_t pids[PARALLEL];
+ int i;
+
+ for (i = 0; i < PARALLEL; i++) {
+ test();
+ }
+ for (i = 0; i < PARALLEL; i++) {
+ if (waitpid(pids[i], NULL, 0) != pids[i])
+ err(1, "waotpid() main");
+ }
+
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O2 /tmp/$prog.c || exit 1
+
+export MAXSWAPPCT=80
+../testcases/swap/swap -t 2m -i 5 > /dev/null 2>&1 &
+sleep .5
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 120 ]; do
+ for i in `jot 200 100`; do
+ (
+ sl=$prog.$i
+ sleep=/tmp/$sl
+ cp /tmp/$prog $sleep
+ su $testuser -c "$sleep & $sleep & $sleep &" & pid=$!
+ for j in `jot 10`; do
+ pgrep -q "$sl" && break
+ sleep .5
+ done
+ pgrep -q "$sl" || { echo "No start"; exit 1; }
+ pgid=`pgrep "$sl" | xargs ps -jp | sed 1d | \
+ tail -1 | awk '{print $4}'`
+ [ -z "$pgid" ] && { echo "Zero pgid:$pgid"; ps aj | \
+ sed -n "1p;/$sl/p"; exit 1; }
+ sleep 1.`jot -r 1 2 9`
+ kill -- -$pgid || { echo "kill -$pgid failed"; exit 1; }
+ wait $pid
+ rm -f $sleep
+ ) &
+ done
+ while [ `ps -U$testuser | wc -l` -gt 1 ] ; do sleep 2; done
+done
+while pkill swap; do :; done
+wait
+rm /tmp/$prog /tmp/$prog.c
+exit 0
diff --git a/tools/test/stress2/misc/kpti.sh b/tools/test/stress2/misc/kpti.sh
index c5ca254a48d6..fdd516197482 100755
--- a/tools/test/stress2/misc/kpti.sh
+++ b/tools/test/stress2/misc/kpti.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/largepage.sh b/tools/test/stress2/misc/largepage.sh
index 7e492de748fa..6e7baeca0bfc 100755
--- a/tools/test/stress2/misc/largepage.sh
+++ b/tools/test/stress2/misc/largepage.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/ldt.sh b/tools/test/stress2/misc/ldt.sh
index 21c7055d76fe..7b23548c9eea 100755
--- a/tools/test/stress2/misc/ldt.sh
+++ b/tools/test/stress2/misc/ldt.sh
@@ -284,7 +284,6 @@ EOF
cat > fault.c <<EOF
/* \$Id: fault.c,v 1.5 2008/10/28 17:39:16 kostik Exp \$ */
-#include <sys/cdefs.h>
#include <sys/types.h>
#include <sys/ucontext.h>
#include <errno.h>
diff --git a/tools/test/stress2/misc/linux.sh b/tools/test/stress2/misc/linux.sh
index 1cbbfb8b27a1..9f5a14d8324f 100755
--- a/tools/test/stress2/misc/linux.sh
+++ b/tools/test/stress2/misc/linux.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/mapwrite.sh b/tools/test/stress2/misc/mapwrite.sh
new file mode 100755
index 000000000000..1fef81942b64
--- /dev/null
+++ b/tools/test/stress2/misc/mapwrite.sh
@@ -0,0 +1,189 @@
+#!/bin/sh
+
+# File corruption scenario
+
+# Test program by Rob Norris <rob norris klarasystems com>
+# Test program obtained from: https://gist.github.com/robn/9804c60cd0275086d26893d73e7af35c
+# https://github.com/openzfs/zfs/issues/15654
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+/*
+ * Some kind of clone-related crasher. Not sure if legit or just outdated
+ * assertion.
+ *
+ * Creates clone, maps it, writes from map back into itself.
+ *
+ * Compile a recent (2.2+) ZFS with --enable-debug.
+ *
+ * cc -o mapwrite mapwrite.c
+ *
+ * echo 1 > /sys/modules/zfs/parameters/zfs_bclone_enabled
+ * zpool create tank ...
+ * cd /tank
+ * mapwrite
+ *
+ * [ 7.666305] VERIFY(arc_released(db->db_buf)) failed
+ * [ 7.666443] PANIC at dbuf.c:2150:dbuf_redirty()
+ * [ 7.666489] Showing stack for process 608
+ * [ 7.666534] CPU: 1 PID: 608 Comm: mapwrite Tainted: P O 5.10.170 #3
+ * [ 7.666610] Call Trace:
+ * [ 7.666646] dump_stack+0x57/0x6e
+ * [ 7.666717] spl_panic+0xd3/0xfb [spl]
+ * [ 7.667113] ? zfs_btree_find+0x16a/0x300 [zfs]
+ * [ 7.667278] ? range_tree_find_impl+0x55/0xa0 [zfs]
+ * [ 7.667333] ? _cond_resched+0x1a/0x50
+ * [ 7.667371] ? __kmalloc_node+0x14a/0x2b0
+ * [ 7.667415] ? spl_kmem_alloc_impl+0xb0/0xd0 [spl]
+ * [ 7.667555] ? __list_add+0x12/0x30 [zfs]
+ * [ 7.667681] spl_assert+0x17/0x20 [zfs]
+ * [ 7.667807] dbuf_redirty+0xad/0xb0 [zfs]
+ * [ 7.667963] dbuf_dirty+0xe76/0x1310 [zfs]
+ * [ 7.668011] ? mutex_lock+0xe/0x30
+ * [ 7.668133] ? dbuf_noread+0x112/0x240 [zfs]
+ * [ 7.668271] dmu_write_uio_dnode+0x101/0x1b0 [zfs]
+ * [ 7.668411] dmu_write_uio_dbuf+0x4a/0x70 [zfs]
+ * [ 7.668555] zfs_write+0x500/0xc80 [zfs]
+ * [ 7.668610] ? page_add_file_rmap+0xe/0xb0
+ * [ 7.668740] zpl_iter_write+0xe4/0x130 [zfs]
+ * [ 7.668803] new_sync_write+0x119/0x1b0
+ * [ 7.668843] vfs_write+0x1ce/0x260
+ * [ 7.668880] __x64_sys_pwrite64+0x91/0xc0
+ * [ 7.668918] do_syscall_64+0x30/0x40
+ * [ 7.668957] entry_SYSCALL_64_after_hwframe+0x61/0xc6
+ */
+
+#define _GNU_SOURCE
+
+#include <fcntl.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+
+#define DATASIZE (1024*1024)
+char data[DATASIZE];
+
+#define NDATA (512)
+
+#define FILE_NAME "file"
+#define CLONE_NAME "clone"
+
+static int
+_create_file(void)
+{
+ memset(data, 0x5a, DATASIZE);
+
+ int fd;
+ if ((fd = open(FILE_NAME, O_RDWR | O_CREAT | O_APPEND,
+ S_IRUSR | S_IWUSR)) < 0) {
+ perror("open '" FILE_NAME "'");
+ abort();
+ }
+
+ for (int i = 0; i < NDATA; i++) {
+ int nwr = write(fd, data, DATASIZE);
+ if (nwr < 0) {
+ perror("write");
+ abort();
+ }
+ if (nwr < DATASIZE) {
+ fprintf(stderr, "short write\n");
+ abort();
+ }
+ }
+
+ if (lseek(fd, 0, SEEK_SET) < 0) {
+ perror("lseek");
+ abort();
+ }
+
+ sync();
+
+ return (fd);
+}
+
+static int
+_clone_file(int sfd)
+{
+ int dfd;
+ if ((dfd = open(CLONE_NAME, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR)) < 0) {
+ perror("open '" CLONE_NAME "'");
+ abort();
+ }
+
+ if (copy_file_range(sfd, 0, dfd, 0, DATASIZE * NDATA, 0) < 0) {
+ perror("copy_file_range");
+ abort();
+ }
+
+ return (dfd);
+}
+
+static void *
+_map_file(int fd)
+{
+ void *p = mmap(NULL, DATASIZE*NDATA, PROT_READ, MAP_SHARED, fd, 0);
+ if (p == MAP_FAILED) {
+ perror("mmap");
+ abort();
+ }
+
+ return (p);
+}
+
+static void
+_map_write(void *p, int fd)
+{
+ if (pwrite(fd, p, DATASIZE, 0) < 0) {
+ perror("pwrite");
+ abort();
+ }
+}
+
+int
+main(void)
+{
+ int sfd = _create_file();
+ int dfd = _clone_file(sfd);
+ void *p = _map_file(dfd);
+ _map_write(p, dfd);
+ return (0);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O2 /tmp/$prog.c || exit 1
+
+mount | grep -q "on $mntpoint " && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -s 5g -u $mdstart
+
+newfs -n $newfs_flags /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+
+mycc -o /tmp/swap -Wall -Wextra -O0 ../tools/swap.c || exit 1
+timeout -k 90 60 /tmp/swap -d 100 &
+for i in `jot 10`; do
+ capacity=`swapinfo | tail -1 | sed 's/.* //; s/%//'`
+ [ $capacity -gt 1 ] && break
+ sleep 2 # Wait for swapping
+done
+
+cd $mntpoint
+/tmp/$prog; s=$?
+pkill swap
+wait
+cmp $mntpoint/file $mntpoint/clone || { echo Fail; s=1; }
+cd -
+
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm /tmp/$prog /tmp/$prog.c
+exit $s
diff --git a/tools/test/stress2/misc/marcus6.sh b/tools/test/stress2/misc/marcus6.sh
index 1a209b2256ee..e541a552233e 100755
--- a/tools/test/stress2/misc/marcus6.sh
+++ b/tools/test/stress2/misc/marcus6.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/marcus7.sh b/tools/test/stress2/misc/marcus7.sh
index e196a1e60269..ac34c5419a14 100755
--- a/tools/test/stress2/misc/marcus7.sh
+++ b/tools/test/stress2/misc/marcus7.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/marcus8.sh b/tools/test/stress2/misc/marcus8.sh
new file mode 100755
index 000000000000..0c6110c8ec4c
--- /dev/null
+++ b/tools/test/stress2/misc/marcus8.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+# Run with marcus.cfg on a 5g swap backed MD with UFS non SU fs.
+# Check for non empty file system after test.
+
+. ../default.cfg
+
+set -u
+mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 4g -u $mdstart
+newfs_flags="" # With SU this test runs out of disk space
+newfs $newfs_flags md$mdstart > /dev/null
+tunefs -n disable md$mdstart # Remove the default SU flag
+mount /dev/md$mdstart $mntpoint
+chmod 777 $mntpoint
+
+export runRUNTIME=5m
+export CTRLDIR=$mntpoint/stressX.control
+export RUNDIR=$mntpoint/stressX
+
+su $testuser -c 'cd ..; ./run.sh marcus.cfg'
+
+nb=`find $RUNDIR | wc -l`
+[ $nb -gt 1 ] && { find $RUNDIR -ls | head -12; s=1; } || s=0
+n=0
+while mount | grep $mntpoint | grep -q /dev/md; do
+ umount $mntpoint || sleep 1
+ [ $((n += 1)) -gt 300 ] && { echo FAIL; exit 1; }
+done
+checkfs /dev/md$mdstart; s2=$?
+mdconfig -d -u $mdstart
+exit $((s + s2))
diff --git a/tools/test/stress2/misc/mdconfig3.sh b/tools/test/stress2/misc/mdconfig3.sh
index 7fbdcbc1a5ff..5c145e34cc6d 100755
--- a/tools/test/stress2/misc/mdconfig3.sh
+++ b/tools/test/stress2/misc/mdconfig3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/mdconfig4.sh b/tools/test/stress2/misc/mdconfig4.sh
index c8e0530741c0..284ce1b08045 100755
--- a/tools/test/stress2/misc/mdconfig4.sh
+++ b/tools/test/stress2/misc/mdconfig4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/mdconfig5.sh b/tools/test/stress2/misc/mdconfig5.sh
index b0b25cc5d64b..b3ecd913bc4b 100755
--- a/tools/test/stress2/misc/mdconfig5.sh
+++ b/tools/test/stress2/misc/mdconfig5.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm
#
diff --git a/tools/test/stress2/misc/midi.sh b/tools/test/stress2/misc/midi.sh
index 47594734b4e0..de9161e262ca 100755
--- a/tools/test/stress2/misc/midi.sh
+++ b/tools/test/stress2/misc/midi.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Mark Johnston <markj@freebsd.org>
#
diff --git a/tools/test/stress2/misc/midi2.sh b/tools/test/stress2/misc/midi2.sh
index 91f15aa3cc3b..80a485437dbb 100755
--- a/tools/test/stress2/misc/midi2.sh
+++ b/tools/test/stress2/misc/midi2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/mincore.sh b/tools/test/stress2/misc/mincore.sh
index 85c09cc0ceaf..8f42971144a7 100755
--- a/tools/test/stress2/misc/mincore.sh
+++ b/tools/test/stress2/misc/mincore.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/minherit.sh b/tools/test/stress2/misc/minherit.sh
index facb018a0337..ba5b0d9d1aeb 100755
--- a/tools/test/stress2/misc/minherit.sh
+++ b/tools/test/stress2/misc/minherit.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Peter Holm
#
diff --git a/tools/test/stress2/misc/mkdir.sh b/tools/test/stress2/misc/mkdir.sh
new file mode 100755
index 000000000000..734b8994ad4e
--- /dev/null
+++ b/tools/test/stress2/misc/mkdir.sh
@@ -0,0 +1,81 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Demonstrate incorrect "out of inodes" message with SU enabled.
+# No issue seen with SU+J
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+set -eu
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+s=0
+mount | grep -q "on $mntpoint " && umount $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+
+mdconfig -a -t swap -s 100m -u $mdstart
+[ $# -eq 1 ] && flags="$@" || flags="-Un"
+echo "newfs $flags /dev/md$mdstart"
+newfs $flags /dev/md$mdstart > /dev/null
+[ "$flags" = "" ] && tunefs -n disable md$mdstart
+mount /dev/md$mdstart $mntpoint
+set +e
+
+ifree1=`df -i $mntpoint | tail -1 | awk '{print $7}'`
+before=`df -i $mntpoint`
+n=$(((ifree1 - 5) / 10))
+jot 10 | xargs -I% mkdir $mntpoint/%
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 180 ]; do
+ for j in `jot 10`; do
+ jot $n | xargs -P0 -I% mkdir $mntpoint/$j/%
+ jot $n | xargs -P0 -I% rmdir $mntpoint/$j/%
+ done
+done 2>&1 | tee $log | head -5
+[ -s $log ] && s=3
+jot 10 | xargs -I% rmdir $mntpoint/%
+umount $mntpoint; mount /dev/md$mdstart $mntpoint
+
+ifree2=`df -i $mntpoint | tail -1 | awk '{print $7}'`
+after=`df -i $mntpoint | tail -1`
+if [ $ifree1 -ne $ifree2 ]; then
+ echo "$before"
+ echo "$after"
+ s=1
+ ls -alsrt $mntpoint | head -20
+fi
+
+umount $mntpoint
+fsck -fy /dev/md$mdstart > $log 2>&1
+grep -Eq "WAS MODIFIED" $log && { s=2; cat $log; }
+
+mdconfig -d -u $mdstart
+rm -f $log
+exit $s
diff --git a/tools/test/stress2/misc/mkfifo5.sh b/tools/test/stress2/misc/mkfifo5.sh
index c0355cef2db0..96d30e5fe024 100755
--- a/tools/test/stress2/misc/mkfifo5.sh
+++ b/tools/test/stress2/misc/mkfifo5.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# mkfifo(2), select(2) with tmpfs(5) scenario.
+# mkfifo(2), select(2) with tmpfs(4) scenario.
. ../default.cfg
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
diff --git a/tools/test/stress2/misc/mkfifo6.sh b/tools/test/stress2/misc/mkfifo6.sh
index 5647bf9493d6..13a62b5e0286 100755
--- a/tools/test/stress2/misc/mkfifo6.sh
+++ b/tools/test/stress2/misc/mkfifo6.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# mkfifo(2), select(2) with tmpfs(5) scenario.
+# mkfifo(2), select(2) with tmpfs(4) scenario.
. ../default.cfg
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
diff --git a/tools/test/stress2/misc/mkfifo7.sh b/tools/test/stress2/misc/mkfifo7.sh
index b17e84536bed..c1af3374526e 100755
--- a/tools/test/stress2/misc/mkfifo7.sh
+++ b/tools/test/stress2/misc/mkfifo7.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# mkfifo(2), poll(2) with tmpfs(5) scenario.
+# mkfifo(2), poll(2) with tmpfs(4) scenario.
. ../default.cfg
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
diff --git a/tools/test/stress2/misc/mkfifo8.sh b/tools/test/stress2/misc/mkfifo8.sh
index 6227070f016e..eeed86bd98ec 100755
--- a/tools/test/stress2/misc/mkfifo8.sh
+++ b/tools/test/stress2/misc/mkfifo8.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/mlockall4.sh b/tools/test/stress2/misc/mlockall4.sh
index 778256fa8976..66ae05fa4ae1 100755
--- a/tools/test/stress2/misc/mlockall4.sh
+++ b/tools/test/stress2/misc/mlockall4.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# mlockall(2) / nullfs(5) scenario causes:
+# mlockall(2) / nullfs(4) scenario causes:
# http://people.freebsd.org/~pho/stress/log/kostik619.txt
# kern/182661, fixed in r256211.
diff --git a/tools/test/stress2/misc/mlockall6.sh b/tools/test/stress2/misc/mlockall6.sh
index 33b20ce3137a..b47f9be9bb1e 100755
--- a/tools/test/stress2/misc/mlockall6.sh
+++ b/tools/test/stress2/misc/mlockall6.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
@@ -30,6 +30,9 @@
# "panic: Lock (rw) vm object not locked @ vm/vm_page.c:1013" seen:
# https://people.freebsd.org/~pho/stress/log/mlockall6-2.txt
+# "panic: vm_page_unwire: wire count underflow for page..." seen:
+# https://people.freebsd.org/~pho/stress/log/log0430.txt
+
. ../default.cfg
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
diff --git a/tools/test/stress2/misc/mmap10.sh b/tools/test/stress2/misc/mmap10.sh
index a29768c36691..0bb7845f4d15 100755
--- a/tools/test/stress2/misc/mmap10.sh
+++ b/tools/test/stress2/misc/mmap10.sh
@@ -40,18 +40,22 @@ sed '1,/^EOF/d' < $here/$0 > mmap10.c
mycc -o mmap10 -Wall -Wextra -O2 -g mmap10.c -lpthread || exit 1
rm -f mmap10.c
-daemon sh -c "(cd $here/../testcases/swap; ./swap -t 2m -i 20 -k)"
+daemon sh -c "(cd $here/../testcases/swap; ./swap -t 2m -i 20 -k > /dev/null)"
+ulimit -c 0
sleep `jot -r 1 0 9`
for i in `jot 2`; do
- /tmp/mmap10 &
+ su $testuser -c /tmp/mmap10 &
done
-sleep 300
+start=`date +%s`
while pgrep -q mmap10; do
- pkill -9 mmap10
+ [ $((`date +%s` - start)) -ge 300 ] && break
+ sleep 2
+done
+while pgrep -q 'mmap10|swap'; do
+ pkill -9 mmap10 swap
sleep 2
done
wait
-killall -q swap
rm -f /tmp/mmap10 /tmp/mmap10.core
exit 0
@@ -76,6 +80,7 @@ EOF
#define N (128 * 1024 / (int)sizeof(u_int32_t))
#define PARALLEL 50
+static int debug = 0; /* set to "1" for debug output */
void *p;
u_int32_t r[N];
@@ -169,7 +174,7 @@ tmlock(void *arg __unused)
if (munlock(makeptr(), len) == 0)
n++;
}
- if (n < 10)
+ if (debug == 1 && n < 10)
fprintf(stderr, "Note: tmlock() only succeeded %d times.\n",
n);
@@ -193,7 +198,7 @@ tmprotect(void *arg __unused)
n++;
usleep(1000);
}
- if (n < 10)
+ if (debug == 1 && n < 10)
fprintf(stderr, "Note: tmprotect() only succeeded %d times.\n",
n);
@@ -215,7 +220,7 @@ tmlockall(void *arg __unused)
munlockall();
usleep(1000);
}
- if (n < 10)
+ if (debug == 1 && n < 10)
fprintf(stderr, "Note: tmlockall() only succeeded %d times.\n",
n);
diff --git a/tools/test/stress2/misc/mmap18.sh b/tools/test/stress2/misc/mmap18.sh
index 065b5bb7df6c..f2b19c07fe60 100755
--- a/tools/test/stress2/misc/mmap18.sh
+++ b/tools/test/stress2/misc/mmap18.sh
@@ -89,6 +89,7 @@ EOF
static u_int32_t r[N];
static void *p;
+static int debug; /* set to 1 for debug output */
static unsigned long
makearg(void)
@@ -176,11 +177,9 @@ tmlock(void *arg __unused)
if (munlock(makeptr(), len) == 0)
n++;
}
-#if defined(DEBUG)
- if (n < 10)
+ if (debug != 0 && n < 10)
fprintf(stderr, "Note: tmlock() only succeeded %d "
"times.\n", n);
-#endif
return (NULL);
}
@@ -202,11 +201,9 @@ tmprotect(void *arg __unused)
n++;
usleep(1000);
}
-#if defined(DEBUG)
- if (n < 10)
+ if (debug != 0 && n < 10)
fprintf(stderr, "Note: tmprotect() only succeeded %d "
"times.\n", n);
-#endif
return (NULL);
}
@@ -226,11 +223,9 @@ tmlockall(void *arg __unused)
munlockall();
usleep(1000);
}
-#if defined(DEBUG)
- if (n < 10)
+ if (debug != 0 && n < 10)
fprintf(stderr, "Note: tmlockall() only succeeded %d "
"times.\n", n);
-#endif
return (NULL);
}
diff --git a/tools/test/stress2/misc/mmap32.sh b/tools/test/stress2/misc/mmap32.sh
index a775b756084e..334327a85989 100755
--- a/tools/test/stress2/misc/mmap32.sh
+++ b/tools/test/stress2/misc/mmap32.sh
@@ -62,6 +62,7 @@ EOF
#include <unistd.h>
#define N 4096
+static int debug; /* set to 1 for debug output */
static uint32_t r[N];
static unsigned long
@@ -133,10 +134,8 @@ fuzz(int arg, void *addr, size_t len, int prot, int flags, int fd,
n++;
}
}
-#if defined(DEBUG)
- if (n == 0 && arg != 5)
+ if (debug != 0 &&n == 0 && arg != 5)
fprintf(stderr, "%s(%d) failed\n", __func__, arg);
-#endif
exit(0);
}
diff --git a/tools/test/stress2/misc/mmap33.sh b/tools/test/stress2/misc/mmap33.sh
index de7262c1bf1f..8ecd9e22180b 100755
--- a/tools/test/stress2/misc/mmap33.sh
+++ b/tools/test/stress2/misc/mmap33.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/mmap34.sh b/tools/test/stress2/misc/mmap34.sh
index 02bd193421b9..f1bf09200d8a 100755
--- a/tools/test/stress2/misc/mmap34.sh
+++ b/tools/test/stress2/misc/mmap34.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/mmap35.sh b/tools/test/stress2/misc/mmap35.sh
index 6e76434e77ec..f613b7006a89 100755
--- a/tools/test/stress2/misc/mmap35.sh
+++ b/tools/test/stress2/misc/mmap35.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/mmap36.sh b/tools/test/stress2/misc/mmap36.sh
index 89fc6721fbeb..4a38d5073344 100755
--- a/tools/test/stress2/misc/mmap36.sh
+++ b/tools/test/stress2/misc/mmap36.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/mmap37.sh b/tools/test/stress2/misc/mmap37.sh
index f5e25a282927..9d5f9d74c1c7 100755
--- a/tools/test/stress2/misc/mmap37.sh
+++ b/tools/test/stress2/misc/mmap37.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/mmap38.sh b/tools/test/stress2/misc/mmap38.sh
index b4cf60afe25b..06ff8770f36f 100755
--- a/tools/test/stress2/misc/mmap38.sh
+++ b/tools/test/stress2/misc/mmap38.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/mmap39.sh b/tools/test/stress2/misc/mmap39.sh
index f4b97717624b..d94b40593a10 100755
--- a/tools/test/stress2/misc/mmap39.sh
+++ b/tools/test/stress2/misc/mmap39.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/mmap40.sh b/tools/test/stress2/misc/mmap40.sh
index 4bf60fc8f44d..2314596e2f5d 100755
--- a/tools/test/stress2/misc/mmap40.sh
+++ b/tools/test/stress2/misc/mmap40.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
@@ -53,13 +53,14 @@ mount /dev/md$mdstart $mntpoint
set +e
u1=`swapinfo | tail -1 | awk '{print $3}'`
-(nice $odir/../testcases/swap/swap -t 10m -i 30 -h -l 100) &
-while [ $((`swapinfo | tail -1 | awk '{print $3}'` - $u1)) -le 100 ]; do
+(nice $odir/../testcases/swap/swap -t 10m -i 30 -h -l 100) > /dev/null &
+for i in `jot 120`; do
+ u2=`swapinfo | tail -1 | awk '{print $3}'`
+ [ $u2 -lt $u1 ] && u1=$u2
+ [ $((u2 - $u1)) -gt 100 ] && break
sleep 1
done
-
-$dir/mmap40
-s=0
+/usr/bin/timeout 10m $dir/mmap40; s=$?
while pkill swap; do :; done
wait
[ -f mmap40.core -a $s -eq 0 ] &&
diff --git a/tools/test/stress2/misc/mmap41.sh b/tools/test/stress2/misc/mmap41.sh
new file mode 100755
index 000000000000..5051681aaf31
--- /dev/null
+++ b/tools/test/stress2/misc/mmap41.sh
@@ -0,0 +1,160 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Based on code from https://syzkaller.appspot.com/text?tag=ReproC&x=15d9baada80000
+# No problems seen
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+odir=`pwd`
+cd /tmp
+sed '1,/^EOF/d' < $odir/$0 > $prog.c
+mycc -o $prog -Wall -Wextra -O0 $prog.c -lpthread || exit 1
+rm -f $prog.c
+
+set -e
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 2g -u $mdstart
+newfs $newfs_flags md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+set +e
+
+$odir/../testcases/swap/swap -t 2m -i 10 > /dev/null &
+cd $mntpoint
+/tmp/$prog
+cd $odir
+while pkill swap; do :; done
+wait
+
+for i in `jot 6`; do
+ mount | grep -q "on $mntpoint " || break
+ umount $mntpoint && break || sleep 10
+ [ $i -eq 6 ] &&
+ { echo FATAL; fstat -mf $mntpoint; exit 1; }
+done
+mdconfig -d -u $mdstart
+rm -f /tmp/$prog
+exit 0
+
+EOF
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/uio.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define DEBUG 0 /* 1 to enable */
+#define THREADS 2
+
+static volatile int go;
+static int fd;
+static char *p, path[128];
+
+#define ADDR (void *) 0x20000000ul
+#define LEN 0x1000000ul
+
+void *
+thr(void *arg)
+{
+ struct iovec iov;
+ long n, w;
+ char *p1;
+
+ if (*(int *)arg == 0) {
+ while (go == 0)
+ usleep(100);
+ while (go == 1) {
+ if ((p1 = mmap(ADDR, LEN, PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ err(1, "mmap() in %s", __func__);
+ usleep(arc4random() % 50);
+ if ((p1 = mmap(ADDR, LEN, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ err(1, "mmap() in %s", __func__);
+ usleep(arc4random() % 10000);
+ }
+ } else {
+ while (go == 0)
+ usleep(100);
+ n = w = 0;
+ while (go == 1) {
+ iov.iov_base = p;
+ iov.iov_len = 0x100000;
+ if (pwritev(fd, &iov, 1, 0) != -1)
+ w++;
+ n++;
+ }
+ if (DEBUG == 1)
+ fprintf(stderr, "%ld out of %ld writes (%ld%%)\n", w, n, w * 100 / n);
+ }
+
+
+ return (0);
+}
+
+void
+test(void)
+{
+ pthread_t threads[THREADS];
+ int nr[THREADS];
+ int i, r;
+
+ sprintf(path, "mmap.%06d", getpid());
+ if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == -1)
+ err(1,"open()");
+
+
+ if ((p = mmap(ADDR, LEN, PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)) == MAP_FAILED)
+ err(1, "mmap() in %s", __func__);
+
+ go = 0;
+ for (i = 0; i < THREADS; i++) {
+ nr[i] = i;
+ if ((r = pthread_create(&threads[i], NULL, thr,
+ (void *)&nr[i])) != 0)
+ errc(1, r, "pthread_create()");
+ }
+
+ go = 1;
+ sleep(60);
+ go = 2;
+
+ for (i = 0; i < THREADS; i++) {
+ if ((r = pthread_join(threads[i], NULL)) != 0)
+ errc(1, r, "pthread_join(%d)", i);
+ }
+ close(fd);
+ if (DEBUG == 0) {
+ if (unlink(path) == -1)
+ err(1, "unlink(%s)", path);
+ }
+
+ _exit(0);
+}
+
+int
+main(void)
+{
+ pid_t pid;
+ int i;
+
+ for (i = 0; i < 2; i++) {
+ if ((pid = fork()) == 0)
+ test();
+ if (waitpid(pid, NULL, 0) != pid)
+ err(1, "waitpid()");
+ }
+}
diff --git a/tools/test/stress2/misc/mmap42.sh b/tools/test/stress2/misc/mmap42.sh
new file mode 100755
index 000000000000..11235e581e73
--- /dev/null
+++ b/tools/test/stress2/misc/mmap42.sh
@@ -0,0 +1,101 @@
+#!/bin/sh
+
+# Test scenario by: kib@
+# Test program obtained from Kyle Evans <kevans@FreeBSD.org>
+
+# Demonstrate UFS SU file corruption:
+# ffs: on write into a buffer without content
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+set -u
+prog=$(basename "$0" .sh)
+s=0
+cat > /tmp/$prog.c <<EOF
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#define FILE "file"
+
+int
+main(void)
+{
+ struct stat sb;
+ ssize_t wsz;
+ size_t bufsz;
+ void *buf, *obuf;
+ int mfd, fd;
+ int done = 0;
+
+ mfd = open(FILE, O_RDONLY);
+ assert(mfd >= 0);
+
+ assert(fstat(mfd, &sb) == 0);
+ bufsz = sb.st_size;
+ buf = obuf = mmap(NULL, bufsz, PROT_READ, MAP_SHARED, mfd, 0);
+ assert(buf != MAP_FAILED);
+
+ /* O_RDWR */
+ fd = open(FILE, O_RDWR);
+ if (fd < 0)
+ err(1, "open");
+ assert(fd >= 0);
+
+again:
+ while (bufsz > 0) {
+ wsz = write(fd, buf, bufsz);
+ if (wsz < 0)
+ err(1, "write");
+ else if (wsz == 0)
+ fprintf(stderr, "Huh?\n");
+ bufsz -= wsz;
+ buf += wsz;
+ }
+
+ bufsz = sb.st_size;
+ buf = obuf;
+
+ if (++done < 2)
+ goto again;
+
+ close(fd);
+ munmap(obuf, sb.st_size);
+ close(mfd);
+ return (0);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1
+
+mount | grep -q "on $mntpoint " && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -s 32m -u $mdstart
+
+pagesize=$(sysctl -n hw.pagesize)
+newfs -Un -b $pagesize /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+dd if=/dev/random of=/mnt/file.orig bs=${pagesize} count=1 status=none
+cp $mntpoint/file.orig $mntpoint/file
+cat $mntpoint/file $mntpoint/file > $mntpoint/file.post
+umount $mntpoint
+
+mount /dev/md$mdstart $mntpoint
+(cd $mntpoint; /tmp/$prog)
+
+if ! cmp $mntpoint/file $mntpoint/file.post; then
+ echo "Files differ"
+ ls -l $mntpoint/file $mntpoint/file.post
+ s=1
+fi
+
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm /tmp/$prog /tmp/$prog.c
+exit $s
diff --git a/tools/test/stress2/misc/mmap43.sh b/tools/test/stress2/misc/mmap43.sh
new file mode 100755
index 000000000000..98f1de174d54
--- /dev/null
+++ b/tools/test/stress2/misc/mmap43.sh
@@ -0,0 +1,182 @@
+#!/bin/sh
+
+# Test program obtained from Kyle Evans <kevans@FreeBSD.org>
+
+# Demonstrate UFS SU file corruption
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+set -u
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+rm -f $log
+cat > /tmp/$prog.c <<EOF
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#define FILE "file"
+
+int
+main(void)
+{
+ struct stat sb;
+ ssize_t wsz;
+ size_t bufsz;
+ void *buf, *obuf;
+ int mfd, fd;
+ int done = 0;
+
+ mfd = open(FILE, O_RDONLY);
+ assert(mfd >= 0);
+
+ assert(fstat(mfd, &sb) == 0);
+ bufsz = sb.st_size;
+ buf = obuf = mmap(NULL, bufsz, PROT_READ, MAP_SHARED, mfd, 0);
+ assert(buf != MAP_FAILED);
+
+ /* O_RDWR */
+ fd = open(FILE, O_RDWR);
+ if (fd < 0)
+ err(1, "open");
+ assert(fd >= 0);
+
+again:
+ while (bufsz > 0) {
+ wsz = write(fd, buf, bufsz);
+ if (wsz < 0)
+ err(1, "write");
+ else if (wsz == 0)
+ fprintf(stderr, "Huh?\n");
+ bufsz -= wsz;
+ buf += wsz;
+ }
+
+ bufsz = sb.st_size;
+ buf = obuf;
+
+ if (++done < 2)
+ goto again;
+
+ close(fd);
+ munmap(obuf, sb.st_size);
+ close(mfd);
+ return (0);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1
+
+cat > /tmp/$prog.serial.c <<EOF
+/* Fill a file with sequential numbers */
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main(int argc, char *argv[])
+{
+ size_t i, size;
+ long ix, *lp;
+ int fd;
+ char *file;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s <file> <file length in bytes>\n", argv[0]);
+ exit(1);
+ }
+ file = argv[1];
+ size = atol(argv[2]);
+
+ if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0)
+ err(1, "%s", file);
+
+ if (lseek(fd, size - 1, SEEK_SET) == -1)
+ err(1, "lseek error");
+
+ /* write a dummy byte at the last location */
+ if (write(fd, "\0", 1) != 1)
+ err(1, "write error");
+
+ if ((lp = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED)
+ err(1, "mmap()");
+
+ for (i = 0, ix = 0; i < size; i += sizeof(long), ix++)
+ lp[ix] = ix;
+
+ if (munmap(lp, size) == -1)
+ err(1, "munmap");
+ close(fd);
+}
+EOF
+mycc -o /tmp/$prog.serial -Wall -Wextra -O0 /tmp/$prog.serial.c || exit 1
+
+mount | grep -q "on $mntpoint " && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -s 5g -u $mdstart
+
+newfs -n $newfs_flags /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+
+here=`pwd`
+cd $mntpoint
+
+size=875998990
+pagesize=`sysctl -n hw.pagesize`
+tail=$((size % pagesize))
+/tmp/$prog.serial file $size
+
+cat file file > file.post
+mv file file.orig
+md5=`md5 < file.post`
+
+cp /usr/bin/sort /tmp/$prog.sort
+counter=1
+n=$((`sysctl -n hw.ncpu`))
+[ $n -gt 10 ] && n=10
+s=0
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 300 ]; do
+ st=`date +%s`
+ cp file.orig file
+ for i in `jot $n`; do
+ timeout -k 70s 1m /tmp/$prog.sort /dev/zero &
+ done
+ sleep $n
+ /tmp/$prog
+ while pkill $prog.sort; do sleep .2; done
+ wait
+ m=`md5 < file`
+ if [ $md5 != $m ]; then
+ echo "Failed @ iteration $counter"
+ ls -l
+ od -t x8 file > /var/tmp/$prog.file1
+ od -t x8 file.post > /var/tmp/$prog.file2
+ diff /var/tmp/$prog.file1 /var/tmp/$prog.file2 > $log
+ head -10 $log
+ rm /var/tmp/$prog.file1 /var/tmp/$prog.file2
+ s=1
+ break
+ fi
+ echo "`date +%T` Loop #$counter, elapsed $((`date +%s` - st)) seconds."
+ counter=$((counter + 1))
+done
+cd $here
+
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm /tmp/$prog /tmp/$prog.c /tmp/$prog.sort
+[ $s -eq 0 ] &&
+ printf "OK File size is %9d, tail is %4d bytes. (%3d loops)\n" $size $tail $counter ||
+ printf "FAIL File size is %9d, tail is %4d bytes. (%3d loops)\n" $size $tail $counter
+exit $s
diff --git a/tools/test/stress2/misc/mmap44.sh b/tools/test/stress2/misc/mmap44.sh
new file mode 100755
index 000000000000..f5999ac62536
--- /dev/null
+++ b/tools/test/stress2/misc/mmap44.sh
@@ -0,0 +1,255 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Demonstrate issue described in:
+# [Bug 276002] nfscl: data corruption using both copy_file_range and mmap'd I/O
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+grep -q $mntpoint /etc/exports ||
+ { echo "$mntpoint missing from /etc/exports"; exit 0; }
+
+cat > /tmp/$prog.c <<EOF
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static off_t siz;
+static pthread_mutex_t write_mutex;
+static int fd, go;
+static char *cp;
+
+static void *
+memread(void *arg __unused)
+{
+ int i;
+ char c;
+
+ while (go == 1) {
+ i = arc4random() % siz;
+ c = cp[i];
+ if (c != 0x77) /* No unused vars here */
+ usleep(arc4random() % 400);
+ }
+ return (0);
+}
+
+static void *
+memwrite(void *arg __unused)
+{
+ int i;
+ char c;
+
+ while (go == 1) {
+ i = arc4random() % siz;
+ pthread_mutex_lock(&write_mutex);
+ c = cp[i];
+ cp[i] = 0xee; /* This value seems to linger with NFS */
+ cp[i] = c;
+ pthread_mutex_unlock(&write_mutex);
+ usleep(arc4random() % 400);
+ }
+ return (0);
+}
+
+static void *
+wr(void *arg __unused)
+{
+ off_t pos;
+ int r, s;
+ char buf[1024];
+
+ while (go == 1) {
+ s = arc4random() % sizeof(buf) + 1;
+ pos = arc4random() % (siz - s);
+ pthread_mutex_lock(&write_mutex);
+ if (lseek(fd, pos, SEEK_SET) == -1)
+ err(1, "lseek(%d)", (int)pos);
+ if ((r = read(fd, buf, s)) != s) {
+ fprintf(stderr, "r = %d, s = %d, pos = %d\n", r, s, (int)pos);
+ err(1, "read():2");
+ }
+ if (lseek(fd, pos, SEEK_SET) == -1)
+ err(1, "lseek(%d)", (int)pos);
+ if (write(fd, buf, s) != s)
+ err(1, "write()");
+ pthread_mutex_unlock(&write_mutex);
+ usleep(arc4random() % 400);
+ }
+ return (0);
+}
+
+static void *
+s1(void *arg __unused)
+{
+
+ while (go == 1) {
+ if (fdatasync(fd) == -1)
+ err(1, "fdatasync()");
+ usleep(arc4random() % 1000);
+ }
+ return (0);
+}
+
+static void *
+s2(void *arg __unused)
+{
+
+ while (go == 1) {
+ if (fsync(fd) == -1)
+ err(1, "fdatasync()");
+ usleep(arc4random() % 1000);
+ }
+ return (0);
+}
+
+static void *
+tr(void *arg __unused)
+{
+ int i, s;
+ char buf[1024];
+
+ memset(buf, 0x5a, sizeof(buf));
+ while (go == 1) {
+ pthread_mutex_lock(&write_mutex);
+ if (lseek(fd, arc4random() % siz, SEEK_END) == -1)
+ err(1, "lseek() END");
+ s = sizeof(buf);
+ for (i = 0; i < 50; i++) {
+ if (write(fd, buf, s) != s)
+ warn("write()");
+ }
+ if (ftruncate(fd, siz) == -1)
+ err(1, "truncate()");
+ pthread_mutex_unlock(&write_mutex);
+ usleep(arc4random() % 400);
+ }
+ return (0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+ pthread_t tp[6];
+ int e, i;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <file>\n", argv[0]);
+ exit(1);
+ }
+ if ((fd = open(argv[1], O_RDWR)) == -1)
+ err(1, "open(%s)", argv[1]);
+ if (fstat(fd, &st) == -1)
+ err(1, "stat(%s)", argv[1]);
+ siz = st.st_size;
+ cp = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (cp == MAP_FAILED)
+ err(1, "mmap()");
+
+ go = 1;
+ pthread_mutex_init(&write_mutex, NULL);
+ if ((e = pthread_create(&tp[0], NULL, memwrite, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[1], NULL, memread, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[2], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[3], NULL, s1, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[4], NULL, s2, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[5], NULL, tr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+
+ sleep(60);
+ go = 0;
+ for (i = 0; i < (int)(sizeof(tp) / sizeof(tp[0])); i++)
+ pthread_join(tp[i], NULL);
+ if (munmap(cp, siz) == -1)
+ err(1, "munmap()");
+ close(fd);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+mycc -o /tmp/serial -Wall -Wextra -O2 ../tools/serial.c || exit 1
+mount | grep -q "on $mntpoint " && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -s 5g -u $mdstart
+newfs -n $newfs_flags /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+
+mp2=${mntpoint}2
+mkdir -p $mp2
+mount | grep -q "on $mp2 " && umount -f $mp2
+mount -t nfs -o retrycnt=3 127.0.0.1:$mntpoint $mp2 || exit 1
+sleep .2
+
+here=`pwd`
+mount | grep $mntpoint
+cd $mp2
+$here/../testcases/swap/swap -t 5m -i 20 > /dev/null &
+sleep 2
+
+size=262144
+/tmp/serial file $size
+cp file file.orig
+
+s=0
+/tmp/$prog file || s=1
+
+while pgrep -q swap; do pkill swap; done
+wait
+if ! cmp -s file.orig file; then
+ od -t x1 file.orig > /var/tmp/$prog.file1
+ od -t x1 file > /var/tmp/$prog.file2
+ diff /var/tmp/$prog.file1 /var/tmp/$prog.file2 > $log
+ head -20 $log
+ rm /var/tmp/$prog.file1 /var/tmp/$prog.file2
+ ls -ls file.orig file
+ s=2
+fi
+
+cd $here
+umount $mp2
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -f /tmp/serial /tmp/$prog /tmp/$prog.c $log
+exit $s
diff --git a/tools/test/stress2/misc/mmap45.sh b/tools/test/stress2/misc/mmap45.sh
new file mode 100755
index 000000000000..59450b41bb5e
--- /dev/null
+++ b/tools/test/stress2/misc/mmap45.sh
@@ -0,0 +1,230 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Demonstrate issue described in:
+# [Bug 276002] nfscl: data corruption using both copy_file_range and mmap'd I/O
+
+# Issue seen:
+#
+# 8994c8994
+# < 0431020 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
+# ---
+# > 0431020 10 11 ee 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
+# 256 -rw------- 1 root wheel 262144 Feb 28 19:44 file
+# 256 -rw------- 1 root wheel 262144 Feb 28 19:43 file.orig
+# 19:44:34, elapsed 0 days, 00:13.59
+# Failed with exit code 2 after 13 loops.
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+serial=/tmp/$prog.serial
+grep -q $mntpoint /etc/exports ||
+ { echo "$mntpoint missing from /etc/exports"; exit 0; }
+rpcinfo 2>/dev/null | grep -q mountd || exit 0
+
+cat > /tmp/$prog.c <<EOF
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static off_t siz;
+static pthread_mutex_t write_mutex;
+static int fd, go;
+static char *cp;
+
+static void *
+memread(void *arg __unused)
+{
+ int i;
+ char c;
+
+ while (go == 1) {
+ i = arc4random() % siz;
+ c = cp[i];
+ if (c != 0x77) /* No unused vars here */
+ usleep(arc4random() % 400);
+ }
+ return (0);
+}
+
+static void *
+memwrite(void *arg __unused)
+{
+ int i;
+ char c;
+
+ while (go == 1) {
+ i = arc4random() % siz;
+ pthread_mutex_lock(&write_mutex);
+ c = cp[i];
+ cp[i] = 0xee; /* This value seems to linger with NFS */
+ cp[i] = c;
+ pthread_mutex_unlock(&write_mutex);
+ usleep(arc4random() % 400);
+ }
+ return (0);
+}
+
+static void *
+wr(void *arg __unused)
+{
+ off_t pos;
+ int r, s;
+ char buf[1024];
+
+ while (go == 1) {
+ s = arc4random() % sizeof(buf) + 1;
+ pos = arc4random() % (siz - s);
+ pthread_mutex_lock(&write_mutex);
+ if (lseek(fd, pos, SEEK_SET) == -1)
+ err(1, "lseek(%d)", (int)pos);
+ if ((r = read(fd, buf, s)) != s) {
+ fprintf(stderr, "r = %d, s = %d, pos = %d\n", r, s, (int)pos);
+ err(1, "read():2");
+ }
+ if (lseek(fd, pos, SEEK_SET) == -1)
+ err(1, "lseek(%d)", (int)pos);
+ if (write(fd, buf, s) != s)
+ err(1, "write()");
+ pthread_mutex_unlock(&write_mutex);
+ usleep(arc4random() % 400);
+ }
+ return (0);
+}
+
+static void *
+s1(void *arg __unused)
+{
+
+ while (go == 1) {
+ if (fdatasync(fd) == -1)
+ err(1, "fdatasync()");
+ usleep(arc4random() % 1000);
+ }
+ return (0);
+}
+
+static void *
+s2(void *arg __unused)
+{
+
+ while (go == 1) {
+ if (fsync(fd) == -1)
+ err(1, "fdatasync()");
+ usleep(arc4random() % 1000);
+ }
+ return (0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+ pthread_t tp[10];
+ int e, i;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <file>\n", argv[0]);
+ exit(1);
+ }
+ if ((fd = open(argv[1], O_RDWR)) == -1)
+ err(1, "open(%s)", argv[1]);
+ if (fstat(fd, &st) == -1)
+ err(1, "stat(%s)", argv[1]);
+ siz = st.st_size;
+ cp = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (cp == MAP_FAILED)
+ err(1, "mmap()");
+
+ go = 1;
+ pthread_mutex_init(&write_mutex, NULL);
+ if ((e = pthread_create(&tp[0], NULL, memwrite, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[1], NULL, memwrite, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[2], NULL, memread, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[3], NULL, memread, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[4], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[5], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[6], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[7], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[8], NULL, s1, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[9], NULL, s2, NULL)) != 0)
+ errc(1, e, "pthread_create");
+
+ sleep(60);
+ go = 0;
+ for (i = 0; i < (int)(sizeof(tp) / sizeof(tp[0])); i++)
+ pthread_join(tp[i], NULL);
+ if (munmap(cp, siz) == -1)
+ err(1, "munmap()");
+ close(fd);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+mycc -o $serial -Wall -Wextra -O2 ../tools/serial.c || exit 1
+mount | grep -q "on $mntpoint " && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -s 5g -u $mdstart
+newfs -n $newfs_flags /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+
+mp2=${mntpoint}2
+mkdir -p $mp2
+mount | grep -q "on $mp2 " && umount -f $mp2
+mount -t nfs -o retrycnt=3 127.0.0.1:$mntpoint $mp2 || exit 1
+sleep .2
+
+here=`pwd`
+cd $mp2
+$here/../testcases/swap/swap -t 5m -i 20 > /dev/null &
+sleep 2
+
+size=262144
+$serial file $size
+cp file file.orig
+
+s=0
+/tmp/$prog file || s=1
+
+while pgrep -q swap; do pkill swap; done
+wait
+if ! cmp -s file.orig file; then
+ od -t x1 file.orig > /var/tmp/$prog.file1
+ od -t x1 file > /var/tmp/$prog.file2
+ diff /var/tmp/$prog.file1 /var/tmp/$prog.file2 > $log
+ head -20 $log
+ rm /var/tmp/$prog.file1 /var/tmp/$prog.file2
+ ls -ls file.orig file
+ s=2
+fi
+
+cd $here
+umount $mp2
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -f $serial /tmp/$prog /tmp/$prog.c $log
+exit $s
diff --git a/tools/test/stress2/misc/mmap46.sh b/tools/test/stress2/misc/mmap46.sh
new file mode 100755
index 000000000000..a739f36f3f9e
--- /dev/null
+++ b/tools/test/stress2/misc/mmap46.sh
@@ -0,0 +1,233 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Demonstrate issue described in:
+# [Bug 276002] nfscl: data corruption using both copy_file_range and mmap'd I/O
+
+# Issue seen:
+#
+# 8994c8994
+# < 0431020 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
+# ---
+# > 0431020 10 11 ee 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f
+# 256 -rw------- 1 root wheel 262144 Feb 28 19:44 file
+# 256 -rw------- 1 root wheel 262144 Feb 28 19:43 file.orig
+# 19:44:34, elapsed 0 days, 00:13.59
+# Failed with exit code 2 after 13 loops.
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+serial=/tmp/$prog.serial
+grep -q $mntpoint /etc/exports ||
+ { echo "$mntpoint missing from /etc/exports"; exit 0; }
+rpcinfo 2>/dev/null | grep -q mountd || exit 0
+
+cat > /tmp/$prog.c <<EOF
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static off_t siz;
+static pthread_mutex_t write_mutex;
+static int fd, go;
+static char *cp;
+
+static void *
+memread(void *arg __unused)
+{
+ int i;
+ char c;
+
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ i = arc4random() % siz;
+ c = cp[i];
+ if (c != 0x77) /* No unused vars here */
+ usleep(arc4random() % 200);
+ }
+ return (0);
+}
+
+static void *
+memwrite(void *arg __unused)
+{
+ int i;
+ char c;
+
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ i = arc4random() % siz;
+ pthread_mutex_lock(&write_mutex);
+ c = cp[i];
+ cp[i] = 0xee; /* This value seems to linger with NFS */
+ cp[i] = c;
+ pthread_mutex_unlock(&write_mutex);
+ usleep(arc4random() % 200);
+ }
+ return (0);
+}
+
+static void *
+wr(void *arg __unused)
+{
+ off_t pos;
+ int r, s;
+ char buf[1024];
+
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ s = arc4random() % sizeof(buf) + 1;
+ pos = arc4random() % (siz - s);
+ pthread_mutex_lock(&write_mutex);
+ if (lseek(fd, pos, SEEK_SET) == -1)
+ err(1, "lseek(%d)", (int)pos);
+ if ((r = read(fd, buf, s)) != s) {
+ fprintf(stderr, "r = %d, s = %d, pos = %d\n", r, s, (int)pos);
+ err(1, "read():2");
+ }
+ if (lseek(fd, pos, SEEK_SET) == -1)
+ err(1, "lseek(%d)", (int)pos);
+ if (write(fd, buf, s) != s)
+ err(1, "write()");
+ pthread_mutex_unlock(&write_mutex);
+ usleep(arc4random() % 200);
+ }
+ return (0);
+}
+
+static void *
+tr(void *arg __unused)
+{
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ if (ftruncate(fd, siz) == -1) /* No size change */
+ err(1, "truncate)");
+ usleep(arc4random() % 1000);
+ }
+ return (0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+ pthread_t tp[13];
+ int e, i;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <file>\n", argv[0]);
+ exit(1);
+ }
+ if ((fd = open(argv[1], O_RDWR)) == -1)
+ err(1, "open(%s)", argv[1]);
+ if (fstat(fd, &st) == -1)
+ err(1, "stat(%s)", argv[1]);
+ siz = st.st_size;
+ cp = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (cp == MAP_FAILED)
+ err(1, "mmap()");
+
+ go = -1;
+ pthread_mutex_init(&write_mutex, NULL);
+ if ((e = pthread_create(&tp[0], NULL, memwrite, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[1], NULL, memwrite, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[2], NULL, memread, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[3], NULL, memread, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[4], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[5], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[6], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[7], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[8], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[9], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[10], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[11], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ if ((e = pthread_create(&tp[12], NULL, tr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+
+ sleep(1);
+ go = 1;
+ sleep(60);
+ go = 0;
+ for (i = 0; i < (int)(sizeof(tp) / sizeof(tp[0])); i++)
+ pthread_join(tp[i], NULL);
+ if (munmap(cp, siz) == -1)
+ err(1, "munmap()");
+ close(fd);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+mycc -o $serial -Wall -Wextra -O2 ../tools/serial.c || exit 1
+mount | grep -q "on $mntpoint " && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -s 5g -u $mdstart
+newfs -n $newfs_flags /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+
+mp2=${mntpoint}2
+mkdir -p $mp2
+mount | grep -q "on $mp2 " && umount -f $mp2
+mount -t nfs -o retrycnt=3 127.0.0.1:$mntpoint $mp2 || exit 1
+sleep .2
+
+here=`pwd`
+cd $mp2
+$here/../testcases/swap/swap -t 5m -i 20 > /dev/null &
+sleep 2
+
+size=262144
+$serial file $size
+cp file file.orig
+
+s=0
+/tmp/$prog file || s=1
+
+while pgrep -q swap; do pkill swap; done
+wait
+if ! cmp -s file.orig file; then
+ od -t x1 file.orig > /var/tmp/$prog.file1
+ od -t x1 file > /var/tmp/$prog.file2
+ diff /var/tmp/$prog.file1 /var/tmp/$prog.file2 > $log
+ head -20 $log
+ rm /var/tmp/$prog.file1 /var/tmp/$prog.file2
+ ls -ls file.orig file
+ s=2
+fi
+
+cd $here
+umount $mp2
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -f $serial /tmp/$prog /tmp/$prog.c $log
+exit $s
diff --git a/tools/test/stress2/misc/mmap47.sh b/tools/test/stress2/misc/mmap47.sh
new file mode 100755
index 000000000000..43778a193202
--- /dev/null
+++ b/tools/test/stress2/misc/mmap47.sh
@@ -0,0 +1,237 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Demonstrate issue described in:
+# [Bug 276002] nfscl: data corruption using both copy_file_range and mmap'd I/O
+
+# This version only uses mapped read/write, read(2)/write(2) and ftruncate(2)
+
+# Issue seen:
+
+# 19:50:53 Start test of mmap47.sh
+# 19:51:56, elapsed 0 days, 00:01.03
+# 19:53:01, elapsed 0 days, 00:02.08
+# 19:54:06, elapsed 0 days, 00:03.13
+# 19:55:40, elapsed 0 days, 00:04.47
+# 617c617
+# < 0023200 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f
+# ---
+# > 0023200 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e ee
+# 256 -rw------- 1 root wheel 262144 Mar 1 19:56 file
+# 256 -rw------- 1 root wheel 262144 Mar 1 19:55 file.orig
+# 19:56:44, elapsed 0 days, 00:05.51
+# Failed with exit code 2 after 5 loops of mmap47.sh.
+# 19:56 /usr/src/tools/test/stress2/misc $
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+serial=/tmp/$prog.serial
+grep -q $mntpoint /etc/exports ||
+ { echo "$mntpoint missing from /etc/exports"; exit 0; }
+rpcinfo 2>/dev/null | grep -q mountd || exit 0
+
+cat > /tmp/$prog.c <<EOF
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static off_t siz;
+static pthread_mutex_t write_mutex;
+static int fd, go;
+static char *cp;
+
+static void *
+memread(void *arg __unused)
+{
+ int i;
+ char c;
+
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ i = arc4random() % siz;
+ c = cp[i];
+ if (c != 0x77) /* No unused vars here */
+ usleep(arc4random() % 200);
+ }
+ return (0);
+}
+
+static void *
+memwrite(void *arg __unused)
+{
+ int i;
+ char c;
+
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ i = arc4random() % siz;
+ pthread_mutex_lock(&write_mutex);
+ c = cp[i];
+ cp[i] = 0xee; /* This value seems to linger with NFS */
+ cp[i] = c;
+ pthread_mutex_unlock(&write_mutex);
+ usleep(arc4random() % 200);
+ }
+ return (0);
+}
+
+static void *
+wr(void *arg __unused)
+{
+ off_t pos;
+ int r, s;
+ char buf[1024];
+
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ s = arc4random() % sizeof(buf) + 1;
+ pos = arc4random() % (siz - s);
+ pthread_mutex_lock(&write_mutex);
+ if (lseek(fd, pos, SEEK_SET) == -1)
+ err(1, "lseek(%d)", (int)pos);
+ if ((r = read(fd, buf, s)) != s) {
+ fprintf(stderr, "r = %d, s = %d, pos = %d\n", r, s, (int)pos);
+ err(1, "read():2");
+ }
+ if (lseek(fd, pos, SEEK_SET) == -1)
+ err(1, "lseek(%d)", (int)pos);
+ if (write(fd, buf, s) != s)
+ err(1, "write()");
+ pthread_mutex_unlock(&write_mutex);
+ usleep(arc4random() % 200);
+ }
+ return (0);
+}
+
+/* Both ftruncate() and fdatasync() triggers the problem */
+
+static void *
+tr(void *arg __unused)
+{
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+#if 0
+ if (ftruncate(fd, siz) == -1) /* No size change */
+ err(1, "truncate)");
+#else
+ if (fdatasync(fd) == -1)
+ err(1, "fdatasync()");
+#endif
+ usleep(arc4random() % 1000);
+ }
+ return (0);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+ pthread_t tp[31];
+ int e, i, idx;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <file>\n", argv[0]);
+ exit(1);
+ }
+ if ((fd = open(argv[1], O_RDWR)) == -1)
+ err(1, "open(%s)", argv[1]);
+ if (fstat(fd, &st) == -1)
+ err(1, "stat(%s)", argv[1]);
+ siz = st.st_size;
+ cp = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (cp == MAP_FAILED)
+ err(1, "mmap()");
+
+ go = -1;
+ pthread_mutex_init(&write_mutex, NULL);
+ idx = 0;
+ for (i = 0; i < (int)(arc4random() % 10 + 1); i++) {
+ if ((e = pthread_create(&tp[idx++], NULL, memread, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ }
+ for (i = 0; i < (int)(arc4random() % 10 + 1); i++) {
+ if ((e = pthread_create(&tp[idx++], NULL, memwrite, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ }
+ for (i = 0; i < (int)(arc4random() % 10 + 1); i++) {
+ if ((e = pthread_create(&tp[idx++], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ }
+ if ((e = pthread_create(&tp[idx++], NULL, tr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+
+ sleep(1);
+ go = 1;
+ sleep(60);
+ go = 0;
+ for (i = 0; i < idx; i++)
+ pthread_join(tp[i], NULL);
+ if (munmap(cp, siz) == -1)
+ err(1, "munmap()");
+ close(fd);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+mycc -o $serial -Wall -Wextra -O2 ../tools/serial.c || exit 1
+mount | grep -q "on $mntpoint " && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -s 5g -u $mdstart
+newfs -n $newfs_flags /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+
+mp2=${mntpoint}2
+mkdir -p $mp2
+mount | grep -q "on $mp2 " && umount -f $mp2
+mount -t nfs -o retrycnt=3 127.0.0.1:$mntpoint $mp2 || exit 1
+sleep .2
+
+here=`pwd`
+cd $mp2
+$here/../testcases/swap/swap -t 5m -i 20 > /dev/null &
+sleep 2
+
+size=262144
+$serial file $size
+cp file file.orig
+
+s=0
+/tmp/$prog file || s=1
+
+while pgrep -q swap; do pkill swap; done
+wait
+if ! cmp -s file.orig file; then
+ od -t x1 file.orig > /var/tmp/$prog.file1
+ od -t x1 file > /var/tmp/$prog.file2
+ diff /var/tmp/$prog.file1 /var/tmp/$prog.file2 > $log
+ head -20 $log
+ rm /var/tmp/$prog.file1 /var/tmp/$prog.file2
+ ls -ls file.orig file
+ s=2
+fi
+
+cd $here
+umount $mp2
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -f $serial /tmp/$prog /tmp/$prog.c $log
+exit $s
diff --git a/tools/test/stress2/misc/mmap48.sh b/tools/test/stress2/misc/mmap48.sh
new file mode 100755
index 000000000000..35da78a98c26
--- /dev/null
+++ b/tools/test/stress2/misc/mmap48.sh
@@ -0,0 +1,289 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Demonstrate issue described in:
+# [Bug 276002] nfscl: data corruption using both copy_file_range and mmap'd I/O
+
+# This version only uses mapped read/write, read(2)/write(2), fstat(2) and ftruncate(2)
+
+# Issue seen:
+# 20241003 10:04:24 all: mmap48.sh
+# 5257c5257
+# < 0244200 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f
+# ---
+# > 0244200 80 81 82 83 84 85 86 87 88 ee 8a 8b 8c 8d 8e 8f
+# 256 -rw------- 1 root wheel 262144 Oct 3 10:05 file
+# 256 -rw------- 1 root wheel 262144 Oct 3 10:04 file.orig
+# FAIL mmap48.sh exit code 2
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+serial=/tmp/$prog.serial
+grep -q $mntpoint /etc/exports ||
+ { echo "$mntpoint missing from /etc/exports"; exit 0; }
+rpcinfo 2>/dev/null | grep -q mountd || exit 0
+
+cat > /tmp/$prog.c <<EOF
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <err.h>
+#include <fcntl.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static off_t siz;
+static pthread_mutex_t write_mutex;
+static int fd, go;
+static char *cp;
+
+#define THREADS 100
+
+static void *
+memread(void *arg __unused)
+{
+ int i;
+ char c;
+
+ if (arc4random() % 100 < 10)
+ return (0);
+ pthread_set_name_np(pthread_self(), __func__);
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ i = arc4random() % siz;
+ c = cp[i];
+ if (c != 0x77) /* No unused vars here */
+ usleep(arc4random() % 400);
+ }
+ return (NULL);
+}
+
+static void *
+memwrite(void *arg __unused)
+{
+ int i;
+ char c;
+
+ if (arc4random() % 100 < 10)
+ return (0);
+ pthread_set_name_np(pthread_self(), __func__);
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ i = arc4random() % siz;
+ pthread_mutex_lock(&write_mutex);
+ c = cp[i];
+ cp[i] = 0xee; /* This value seems to linger with NFS */
+ cp[i] = c;
+ pthread_mutex_unlock(&write_mutex);
+ usleep(arc4random() % 400);
+ }
+ return (NULL);
+}
+
+static void *
+wr(void *arg __unused)
+{
+ off_t pos;
+ int r, s;
+ char buf[1024];
+
+ if (arc4random() % 100 < 10)
+ return (0);
+ pthread_set_name_np(pthread_self(), __func__);
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ s = arc4random() % sizeof(buf) + 1;
+ pos = arc4random() % (siz - s);
+ pthread_mutex_lock(&write_mutex);
+ if (lseek(fd, pos, SEEK_SET) == -1)
+ err(1, "lseek(%d)", (int)pos);
+ if ((r = read(fd, buf, s)) != s) {
+ fprintf(stderr, "r = %d, s = %d, pos = %d\n", r, s, (int)pos);
+ err(1, "read():2");
+ }
+ if (lseek(fd, pos, SEEK_SET) == -1)
+ err(1, "lseek(%d)", (int)pos);
+ if (write(fd, buf, s) != s)
+ err(1, "write()");
+ pthread_mutex_unlock(&write_mutex);
+ usleep(arc4random() % 200);
+ }
+ return (NULL);
+}
+
+/* Both ftruncate() and fdatasync() triggers the problem */
+
+static void *
+sy(void *arg __unused)
+{
+
+ if (arc4random() % 100 < 10)
+ return (0);
+ pthread_set_name_np(pthread_self(), __func__);
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ if (fdatasync(fd) == -1)
+ err(1, "fdatasync()");
+ usleep(arc4random() % 1000);
+ }
+ return (NULL);
+}
+
+static void *
+tr(void *arg __unused)
+{
+
+ if (arc4random() % 100 < 10)
+ return (0);
+ pthread_set_name_np(pthread_self(), __func__);
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ if (ftruncate(fd, siz) == -1) /* No size change */
+ err(1, "truncate)");
+ usleep(arc4random() % 1000);
+ }
+ return (NULL);
+}
+
+static void *
+fs(void *arg __unused)
+{
+ struct stat st;
+
+ if (arc4random() % 100 < 10)
+ return (0);
+ pthread_set_name_np(pthread_self(), __func__);
+ while (go == -1)
+ usleep(50);
+ while (go == 1) {
+ if (fstat(fd, &st) == -1)
+ err(1, "stat()");
+ usleep(arc4random() % 1000);
+ }
+ return (NULL);
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct stat st;
+ pthread_t tp[THREADS];
+ int e, i, idx;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <file>\n", argv[0]);
+ exit(1);
+ }
+ if ((fd = open(argv[1], O_RDWR)) == -1)
+ err(1, "open(%s)", argv[1]);
+ if (fstat(fd, &st) == -1)
+ err(1, "stat(%s)", argv[1]);
+ siz = st.st_size;
+ cp = mmap(NULL, st.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ if (cp == MAP_FAILED)
+ err(1, "mmap()");
+
+ go = -1;
+ pthread_mutex_init(&write_mutex, NULL);
+ idx = 0;
+ for (i = 0; i < (int)(arc4random() % 3 + 1); i++) {
+ if ((e = pthread_create(&tp[idx++], NULL, memread, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ }
+ for (i = 0; i < (int)(arc4random() % 3 + 1); i++) {
+ if ((e = pthread_create(&tp[idx++], NULL, memwrite, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ }
+ for (i = 0; i < (int)(arc4random() % 3 + 1); i++) {
+ if ((e = pthread_create(&tp[idx++], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ }
+ for (i = 0; i < (int)(arc4random() % 3 + 1); i++) {
+ if ((e = pthread_create(&tp[idx++], NULL, fs, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ }
+ for (i = 0; i < (int)(arc4random() % 3 + 1); i++) {
+ if ((e = pthread_create(&tp[idx++], NULL, tr, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ }
+ for (i = 0; i < (int)(arc4random() % 3 + 1); i++) {
+ if ((e = pthread_create(&tp[idx++], NULL, sy, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ }
+ assert(idx <= THREADS);
+
+ sleep(1);
+ go = 1;
+ sleep(60);
+ go = 0;
+ for (i = 0; i < idx; i++)
+ pthread_join(tp[i], NULL);
+ if (munmap(cp, siz) == -1)
+ err(1, "munmap()");
+ close(fd);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+mycc -o $serial -Wall -Wextra -O2 ../tools/serial.c || exit 1
+mount | grep -q "on $mntpoint " && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -s 5g -u $mdstart
+newfs -n $newfs_flags /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+
+mp2=${mntpoint}2
+mkdir -p $mp2
+mount | grep -q "on $mp2 " && umount -f $mp2
+mount -t nfs -o retrycnt=3 127.0.0.1:$mntpoint $mp2 || exit 1
+sleep .2
+
+here=`pwd`
+cd $mp2
+#$here/../testcases/swap/swap -t 5m -i 20 > /dev/null &
+sleep 2
+
+size=262144
+$serial file $size
+cp file file.orig
+
+s=0
+#ktrace -id -f $here/ktrace.out /tmp/$prog file || s=1
+/tmp/$prog file || s=1
+
+while pgrep -q swap; do pkill swap; done
+wait
+if ! cmp -s file.orig file; then
+ od -t x1 file.orig > /var/tmp/$prog.file1
+ od -t x1 file > /var/tmp/$prog.file2
+ diff /var/tmp/$prog.file1 /var/tmp/$prog.file2 > $log
+ head -20 $log
+ rm /var/tmp/$prog.file1 /var/tmp/$prog.file2
+ ls -ls file.orig file
+ s=2
+fi
+
+cd $here
+umount $mp2
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -f $serial /tmp/$prog /tmp/$prog.c $log
+exit $s
diff --git a/tools/test/stress2/misc/mmap5.sh b/tools/test/stress2/misc/mmap5.sh
index e6dee6d551de..c7369118e0e2 100755
--- a/tools/test/stress2/misc/mmap5.sh
+++ b/tools/test/stress2/misc/mmap5.sh
@@ -52,15 +52,16 @@ rm -f /tmp/mmap5 /tmp/mmap5.inputfile
exit
EOF
-#include <err.h>
-#include <errno.h>
-#include <stdlib.h>
+#include <sys/param.h>
#include <sys/fcntl.h>
#include <sys/mman.h>
-#include <sys/param.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <err.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <time.h>
#include <unistd.h>
const char *file;
@@ -113,13 +114,14 @@ test(void)
int
main(int argc, char *argv[])
{
- int i;
+ time_t start;
if (argc != 2)
errx(1, "Usage: %s <file>", argv[0]);
file = argv[1];
- for (i = 0; i < 30000; i++) {
+ start = time(NULL);
+ while (time(NULL) - start < 120) {
if (fork() == 0)
test();
wait(NULL);
diff --git a/tools/test/stress2/misc/vmstat2.sh b/tools/test/stress2/misc/mount7.sh
index db3cb1a697e2..2489421c544d 100755
--- a/tools/test/stress2/misc/vmstat2.sh
+++ b/tools/test/stress2/misc/mount7.sh
@@ -1,9 +1,8 @@
#!/bin/sh
-
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
-# Copyright (c) 2019 Dell EMC Isilon
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -27,15 +26,40 @@
# SUCH DAMAGE.
#
-# "0xFFFFFFFFFFFFFFFF in vmstat output" seen.
+# Another parallel mount(8) test scenario
+
+# Seen:
+# UID PID PPID C PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND
+# 0 37225 99871 1 32 0 13280 3116 sdstart D+ 0 0:00.04 mount /dev/md21 /mnt21
+# 0 37236 99550 9 68 0 13280 3112 sdstart D+ 0 0:00.04 mount /dev/md19 /mnt19
+
+# https://people.freebsd.org/~pho/stress/log/log0549.txt
+# Fixed by kib@ in 4b273a7fb9e6
+
+. ../default.cfg
-(cd ../testcases/swap; ./swap -t 2m -i 20 -h -l 100 &)
-sleep .5
-s=0
-while pgrep -q swap; do
- vmstat -z | awk '{if (length($4) > 11) { print $0; exit 1}}' ||
- { pkill swap; s=1; }
- sleep 2
+mounts=15
+
+../testcases/swap/swap -t 2m -i 20 &
+for i in `jot $mounts $mdstart`; do
+ mdconfig -a -s 50m -u $i
+ newfs -U /dev/md$i > /dev/null
+ mkdir -p $mntpoint$i
+ start=`date +%s`
+ while [ $((`date +%s` - start)) -lt 120 ]; do
+ mount /dev/md$i $mntpoint$i && cp /etc/passwd $mntpoint$i
+ while mount | grep -q " on $mntpoint$i "; do
+ umount $mntpoint$i > /dev/null 2>&1
+ done
+ done &
+ while [ $((`date +%s` - start)) -lt 120 ]; do
+ find $mntpoint$i -ls > /dev/null 2>&1
+ done &
done
wait
+
+for i in `jot $mounts $mdstart`; do
+ mdconfig -d -u $i
+ rmdir $mntpoint$i
+done
exit $s
diff --git a/tools/test/stress2/misc/mountro4.sh b/tools/test/stress2/misc/mountro4.sh
index eddc345c85af..906639d9dc3a 100755
--- a/tools/test/stress2/misc/mountro4.sh
+++ b/tools/test/stress2/misc/mountro4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/mountro5.sh b/tools/test/stress2/misc/mountro5.sh
index 67663df54145..bcc77694b6d0 100755
--- a/tools/test/stress2/misc/mountro5.sh
+++ b/tools/test/stress2/misc/mountro5.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/mountro6.sh b/tools/test/stress2/misc/mountro6.sh
index 398cbeed4fea..d19a73d76c4c 100755
--- a/tools/test/stress2/misc/mountro6.sh
+++ b/tools/test/stress2/misc/mountro6.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/mountu.sh b/tools/test/stress2/misc/mountu.sh
index 838850ef3e96..abd3c744d160 100755
--- a/tools/test/stress2/misc/mountu.sh
+++ b/tools/test/stress2/misc/mountu.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2012 Peter Holm <pho@FreeBSD.org>
# Copyright (c) 2019 Dell EMC Isilon
diff --git a/tools/test/stress2/misc/mprotect.sh b/tools/test/stress2/misc/mprotect.sh
index e3e6e765c331..cdb3b2cccd13 100755
--- a/tools/test/stress2/misc/mprotect.sh
+++ b/tools/test/stress2/misc/mprotect.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Mark Johnston <markj@freebsd.org>
#
diff --git a/tools/test/stress2/misc/mprotect2.sh b/tools/test/stress2/misc/mprotect2.sh
index c5cdc44a0f39..6f8d0c3ce6fd 100755
--- a/tools/test/stress2/misc/mprotect2.sh
+++ b/tools/test/stress2/misc/mprotect2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/mprotect3.sh b/tools/test/stress2/misc/mprotect3.sh
new file mode 100755
index 000000000000..9bd4a6f9be79
--- /dev/null
+++ b/tools/test/stress2/misc/mprotect3.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+# Test scenario from:
+# Bug 272585 - calling mprotect in an mmap-ed stack can affect non-target pages
+# Test scenario by: John F. Carr <jfc mit edu>
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+/* Test program from:
+ Bug 272585 - calling mprotect in an mmap-ed stack can affect non-target pages
+ */
+#include <err.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sysexits.h>
+#include <unistd.h>
+
+#ifndef MAP_GROWSDOWN
+#define MAP_GROWSDOWN 0
+#endif
+#ifndef MAP_STACK
+#define MAP_STACK 0
+#endif
+
+int main(void)
+{
+ long pagesize;
+ char *addr, *guard;
+ size_t alloc_size;
+
+ pagesize = sysconf(_SC_PAGESIZE);
+ if (pagesize < 0)
+ err(EX_OSERR, "getPAGESIZE");
+
+ alloc_size = 0x200000 + pagesize;
+
+ addr = mmap(0, alloc_size, PROT_READ|PROT_WRITE,
+ MAP_GROWSDOWN|MAP_STACK|MAP_PRIVATE|MAP_ANONYMOUS,
+ -1, 0);
+ if (addr == MAP_FAILED) {
+ err(EX_OSERR, "mmap");
+ }
+
+ /* Only 0x20 causes a failure. */
+ guard = addr + alloc_size - 0x20 * pagesize;
+
+ if (mprotect(guard, pagesize, PROT_NONE)) {
+ err(EX_OSERR, "mprotect");
+ }
+
+ printf("mapped %p..%p, guard at %p\n", addr, addr + alloc_size, guard);
+ fflush(stdout);
+
+ ((volatile char *)guard)[-1];
+
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 0
+
+cd /tmp
+./$prog; s=$?
+cd -
+
+rm -f /tmp/$prog /tmp/$prog.c /tmp/$prog.core
+exit $s
diff --git a/tools/test/stress2/misc/mprotect4.sh b/tools/test/stress2/misc/mprotect4.sh
new file mode 100755
index 000000000000..c233d20852a2
--- /dev/null
+++ b/tools/test/stress2/misc/mprotect4.sh
@@ -0,0 +1,109 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+/* N readers and 1 writer threaded test scenario */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <assert.h>
+#include <err.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+static int go, n, ps;
+static char *cp;
+static volatile char v;
+
+void *
+rd(void *arg __unused)
+{
+ int i;
+
+ while (go == 0)
+ usleep(100);
+ while (go == 1) {
+ for (i = 0; i < n; i += ps) {
+ v = cp[i];
+ }
+ pthread_yield();
+ }
+ return(NULL);
+}
+
+void
+usage(char *prog) {
+ fprintf(stderr, "Usage: %s <number of threads>\n", prog);
+ _exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ pthread_t *tid;
+ time_t start;
+ int e, i, nb;
+
+ if (argc != 2)
+ usage(argv[0]);
+ if (sscanf(argv[1], "%d", &n) != 1)
+ usage(argv[0]);
+ if (n > 1)
+ n--;
+ if ((tid = calloc(n, sizeof(pthread_t *))) == NULL)
+ err(1, "calloc()");
+
+ ps = getpagesize();
+ cp = mmap(NULL, n * ps, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0);
+ go = 0;
+ for (i = 0; i < n; i++) {
+ if ((e = pthread_create(&tid[i], NULL, rd, NULL)) != 0)
+ errc(1, e, "pthread_create()");
+ }
+ go = 1;
+
+ nb = 0;
+ start = time(NULL);
+ while (time(NULL) - start < 120) {
+ for (i = 0; i < n; i += ps) {
+ if (mprotect(&cp[i], ps, PROT_READ|PROT_WRITE) == -1)
+ err(1, "mprotect(PROT_READ)");
+ cp[i] = 1;
+ if (mprotect(&cp[i], ps, PROT_READ) == -1)
+ err(1, "mprotect(PROT_READ)");
+ nb++;
+ }
+ }
+ go = 0;
+ for (i = 0; i < n; i++) {
+ if ((e = pthread_join(tid[i], NULL)) != 0)
+ errc(1, e, "pthread_join() in loop %d", i);
+ }
+ if (nb >= 0) {
+#if defined(DEBUG)
+ fprintf(stderr, "%d loops\n", nb);
+#endif
+ ;
+ }
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+/tmp/$prog `sysctl -n hw.ncpu`; s=$?
+
+rm -d /tmp/$prog /tmp/$prog.c
+exit $s
diff --git a/tools/test/stress2/misc/mprotect5.sh b/tools/test/stress2/misc/mprotect5.sh
new file mode 100755
index 000000000000..ab4d2eeee118
--- /dev/null
+++ b/tools/test/stress2/misc/mprotect5.sh
@@ -0,0 +1,118 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+/* N writers threaded test scenario */
+
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <assert.h>
+#include <err.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+static pthread_mutex_t write_mutex;
+static int go, n, ps;
+static char *cp, *wp;
+
+void *
+wr(void *arg __unused)
+{
+ while (go == 0)
+ usleep(100);
+ while (go == 1) {
+ pthread_mutex_lock(&write_mutex);
+ if (wp != NULL)
+ *wp += 1;
+ pthread_mutex_unlock(&write_mutex);
+ }
+ return(NULL);
+}
+
+void
+usage(char *prog) {
+ fprintf(stderr, "Usage: %s <number of threads>\n", prog);
+ _exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ pthread_t *tid;
+ time_t start;
+ int e, i, nb;
+
+ if (argc != 2)
+ usage(argv[0]);
+ if (sscanf(argv[1], "%d", &n) != 1)
+ usage(argv[0]);
+ if (n > 1)
+ n--;
+ if ((tid = calloc(n, sizeof(pthread_t *))) == NULL)
+ err(1, "calloc()");
+
+ ps = getpagesize();
+ cp = mmap(NULL, n * ps, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0);
+ pthread_mutex_init(&write_mutex, NULL);
+ pthread_mutex_lock(&write_mutex);
+ go = 0;
+ for (i = 0; i < n; i++) {
+ if ((e = pthread_create(&tid[i], NULL, wr, NULL)) != 0)
+ errc(1, e, "pthread_create()");
+ }
+ go = 1;
+
+ nb = 0;
+ start = time(NULL);
+ while (time(NULL) - start < 120) {
+ for (i = 0; i < n; i += ps) {
+ pthread_mutex_lock(&write_mutex);
+ if (mprotect(&cp[i], ps, PROT_READ|PROT_WRITE) == -1)
+ err(1, "mprotect(PROT_READ)");
+ cp[i] = 0;
+ wp = &cp[i];
+ pthread_mutex_unlock(&write_mutex);
+
+ usleep(100);
+
+ pthread_mutex_lock(&write_mutex);
+ if (mprotect(&cp[i], ps, PROT_READ) == -1)
+ err(1, "mprotect(PROT_READ)");
+ wp = NULL;
+ pthread_mutex_unlock(&write_mutex);
+ nb++;
+ }
+ }
+ go = 0;
+ for (i = 0; i < n; i++) {
+ if ((e = pthread_join(tid[i], NULL)) != 0)
+ errc(1, e, "pthread_join() in loop %d", i);
+ }
+ if (nb >= 0) {
+#if defined(DEBUG)
+ fprintf(stderr, "%d loops\n", nb);
+#endif
+ ;
+ }
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+/tmp/$prog `sysctl -n hw.ncpu`; s=$?
+
+rm -d /tmp/$prog /tmp/$prog.c
+exit $s
diff --git a/tools/test/stress2/misc/mprotect6.sh b/tools/test/stress2/misc/mprotect6.sh
new file mode 100755
index 000000000000..ef1443c216d3
--- /dev/null
+++ b/tools/test/stress2/misc/mprotect6.sh
@@ -0,0 +1,146 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <assert.h>
+#include <err.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+static pthread_mutex_t write_mutex;
+static volatile int done;
+static int go, n, *once, *p, ps;
+
+static void *
+wr(void *arg)
+{
+ int idx;
+
+ alarm(180);
+ idx = *(int *)arg;
+ while (go == 0)
+ usleep(100);
+ while (go == 1) {
+ while (go == 1 && once[idx] == 0)
+ usleep(100);
+ if (go == 0)
+ break;
+ p[idx]++;
+ once[idx] = 0;
+ pthread_mutex_lock(&write_mutex);
+ done++;
+ pthread_mutex_unlock(&write_mutex);
+ }
+ return(NULL);
+}
+
+static void
+setonce(int val)
+{
+ int i;
+
+ for (i = 0; i < n; i++)
+ once[i] = val;
+}
+
+static void
+usage(char *prog) {
+ fprintf(stderr, "Usage: %s <number of threads>\n", prog);
+ _exit(1);
+}
+
+int
+main(int argc, char *argv[])
+{
+ pthread_t *tid;
+ time_t start;
+ int *arg;
+ int e, i, nb, r;
+
+ if (argc != 2)
+ usage(argv[0]);
+ if (sscanf(argv[1], "%d", &n) != 1)
+ usage(argv[0]);
+ if (n > 1)
+ n--;
+ if ((tid = calloc(n, sizeof(pthread_t *))) == NULL)
+ err(1, "calloc()");
+ if ((once = calloc(n, sizeof(int *))) == NULL)
+ err(1, "calloc()");
+ setonce(0);
+
+ ps = getpagesize();
+ p = mmap(NULL, n * ps, PROT_READ, MAP_PRIVATE | MAP_ANON, -1, 0);
+ go = 0;
+ pthread_mutex_init(&write_mutex, NULL);
+ for (i = 0; i < n; i++) {
+ arg = malloc(sizeof(int));
+ *arg = i;
+ if ((e = pthread_create(&tid[i], NULL, wr, (void *)arg)) != 0)
+ errc(1, e, "pthread_create()");
+ }
+ go = 1;
+
+ nb = 0;
+ start = time(NULL);
+ while (time(NULL) - start < 120) {
+ if (mprotect(p, n * ps, PROT_READ|PROT_WRITE) == -1)
+ err(1, "mprotect(PROT_READ)");
+ done = 0;
+ setonce(1);
+ while (done != n)
+ usleep(100);
+ if (mprotect(p, n * ps, PROT_READ) == -1)
+ err(1, "mprotect(PROT_READ)");
+ nb++;
+ usleep(100);
+ }
+ go = 0;
+ for (i = 0; i < n; i++) {
+ if ((e = pthread_join(tid[i], NULL)) != 0)
+ errc(1, e, "pthread_join() in loop %d", i);
+ }
+ r = 0;
+ for (i = 1; i < n; i++) {
+ if (p[0] != p[i])
+ r++;
+ }
+ if (r != 0) {
+ fprintf(stderr, "%d loops.\n", nb);
+ for (i = 0; i < n; i++)
+ fprintf(stderr, "p[%3d] = %d\n", i, p[i]);
+ }
+
+ return (r);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 -g /tmp/$prog.c -lpthread || exit 1
+
+n=`sysctl -n hw.ncpu`
+if [ $# -eq 1 ]; then
+ echo $1 | grep -Eq '^[0-9]+$' && n=$1
+fi
+../testcases/swap/swap -t 2m > /dev/null &
+sleep 10
+/tmp/$prog $n; s=$?
+pkill -9 swap
+wait
+
+rm -d /tmp/$prog /tmp/$prog.c
+exit $s
diff --git a/tools/test/stress2/misc/msdos11.sh b/tools/test/stress2/misc/msdos11.sh
index c14ef55f1f7c..023a16af08c7 100755
--- a/tools/test/stress2/misc/msdos11.sh
+++ b/tools/test/stress2/misc/msdos11.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
diff --git a/tools/test/stress2/misc/msdos12.sh b/tools/test/stress2/misc/msdos12.sh
index da5c8104c3a6..8e3984305cd7 100755
--- a/tools/test/stress2/misc/msdos12.sh
+++ b/tools/test/stress2/misc/msdos12.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
diff --git a/tools/test/stress2/misc/msdos13.sh b/tools/test/stress2/misc/msdos13.sh
index 52c3d9ece686..2f714ba120a8 100755
--- a/tools/test/stress2/misc/msdos13.sh
+++ b/tools/test/stress2/misc/msdos13.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
diff --git a/tools/test/stress2/misc/msdos14.sh b/tools/test/stress2/misc/msdos14.sh
index 0f5b5b9ab736..aaa95144c14e 100755
--- a/tools/test/stress2/misc/msdos14.sh
+++ b/tools/test/stress2/misc/msdos14.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
@@ -27,7 +27,7 @@
# SUCH DAMAGE.
#
-# Rename(2) test with msdosfs(5)
+# Rename(2) test with msdosfs(4)
# Test scenario by kib@
. ../default.cfg
diff --git a/tools/test/stress2/misc/msdos15.sh b/tools/test/stress2/misc/msdos15.sh
index 79e60972e34b..b07defd677af 100755
--- a/tools/test/stress2/misc/msdos15.sh
+++ b/tools/test/stress2/misc/msdos15.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/msdos16.sh b/tools/test/stress2/misc/msdos16.sh
index e188795e1851..965be8233881 100755
--- a/tools/test/stress2/misc/msdos16.sh
+++ b/tools/test/stress2/misc/msdos16.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/msdos17.sh b/tools/test/stress2/misc/msdos17.sh
new file mode 100755
index 000000000000..392a9a622b9a
--- /dev/null
+++ b/tools/test/stress2/misc/msdos17.sh
@@ -0,0 +1,144 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# No problems observed
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+set -u
+prog=$(basename "$0" .sh)
+mount | grep -q "on $mntpoint " && umount $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+
+mdconfig -a -t swap -s 1g -u $mdstart
+gpart create -s bsd md$mdstart > /dev/null
+gpart add -t freebsd-ufs md$mdstart > /dev/null
+part=a
+newfs_msdos -F 32 -b 8192 /dev/md${mdstart}$part > /dev/null || exit 1
+mount -t msdosfs /dev/md${mdstart}$part $mntpoint
+
+here=`pwd`
+cd /tmp
+cat > $prog.c <<EOF
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <machine/atomic.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static volatile u_int *share;
+static char file1[80], file2[80];
+
+#define SYNC 0
+#define STOP 1
+
+static void
+test0(void)
+{
+ struct stat sb;
+
+ while (share[STOP] == 0) {
+ while (share[SYNC] != 0)
+ usleep(100);
+ if (rename(file1, file2) == -1)
+ err(1, "rename(%s, %s)", file1, file2);
+ if (stat(file1, &sb) == 0)
+ err(1, "stat(%s)", file1);
+ atomic_add_int(&share[SYNC], 1);
+ }
+
+ _exit(0);
+}
+
+static void
+test1(void)
+{
+ struct stat sb;
+
+ while (share[STOP] == 0) {
+ while (share[SYNC] != 1)
+ usleep(100);
+ if (rename(file2, file1) == -1)
+ err(1, "rename(%s, %s)", file2, file1);
+ if (stat(file2, &sb) == 0)
+ err(1, "stat(%s)", file2);
+ atomic_add_int(&share[SYNC], -1);
+ }
+
+ _exit(0);
+}
+
+int
+main(void)
+{
+ pid_t pids[2];
+ size_t len;
+ int fd;
+ char cwd[80];
+
+ len = PAGE_SIZE;
+ if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
+ err(1, "mmap");
+
+ if (getcwd(cwd, sizeof(cwd)) == NULL)
+ err(1, "getcwd()");
+ snprintf(file1, sizeof(file1), "%s/a.%06d", cwd, getpid());
+ snprintf(file2, sizeof(file2), "%s/b.%06d", cwd, getpid());
+ if ((fd = open(file1, O_CREAT, 0640)) == -1)
+ err(1, "open(%s)", file1);
+ close(fd);
+
+ if ((pids[0] = fork()) == 0)
+ test0();
+ if ((pids[1] = fork()) == 0)
+ test1();
+
+ sleep(120);
+ share[STOP] = 1;
+
+ if (waitpid(pids[0], NULL, 0) == -1)
+ err(1, "waitpid(%d)", pids[0]);
+ if (waitpid(pids[1], NULL, 0) == -1)
+ err(1, "waitpid(%d)", pids[1]);
+ unlink(file1);
+ unlink(file2);
+}
+EOF
+mycc -o $prog -Wall $prog.c || exit 1
+rm -f $prog.c
+cd $here
+
+(cd ../testcases/swap; ./swap -t 5m -i 20 -l 100) &
+cd $mntpoint
+pids=""
+for i in `jot 30`; do
+ /tmp/$prog &
+ pids="$pids $!"
+done
+for pid in $pids; do
+ wait $pid
+done
+cd $here
+while pkill swap; do :; done
+wait
+
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -f /tmp/$prog
+exit 0
diff --git a/tools/test/stress2/misc/msdos18.sh b/tools/test/stress2/misc/msdos18.sh
new file mode 100755
index 000000000000..faeed9dca944
--- /dev/null
+++ b/tools/test/stress2/misc/msdos18.sh
@@ -0,0 +1,250 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# D38549: msdosfs deextend: validate pages of the partial buffer
+
+# https://people.freebsd.org/~pho/stress/log/log0420.txt
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+set -eu
+prog=$(basename "$0" .sh)
+mkdir -p $mntpoint
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 1g -u $mdstart
+newfs_msdos /dev/md$mdstart > /dev/null 2>&1
+mount -t msdosfs /dev/md$mdstart $mntpoint
+mount | grep $mntpoint
+set +e
+
+odir=`pwd`
+
+cd /tmp
+sed '1,/^EOF/d' < $odir/$0 > $prog.c
+cc -o $prog -Wall -O0 $prog.c -pthread || exit 1
+rm -f $prog.c
+cd $mntpoint
+
+in=inputFile
+out=outputFile
+
+/tmp/$prog $in $out 12345
+ls -al
+
+cd $odir
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -f /tmp/$prog
+exit
+EOF
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+int fd, port;
+volatile int go;
+char *inputFile;
+char *outputFile;
+
+#define FSIZE 936374
+char buf[FSIZE];
+
+static void
+reader(void) {
+ struct sockaddr_in inetaddr, inetpeer;
+ socklen_t len;
+ int on, n, tcpsock, msgsock;
+
+ on = 1;
+ if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ err(1, "socket(), %s:%d", __FILE__, __LINE__);
+
+ if (setsockopt(tcpsock,
+ SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
+ err(1, "setsockopt(), %s:%d", __FILE__, __LINE__);
+
+ inetaddr.sin_family = AF_INET;
+ inetaddr.sin_addr.s_addr = INADDR_ANY;
+ inetaddr.sin_port = htons(port);
+ inetaddr.sin_len = sizeof(inetaddr);
+
+ if (bind(tcpsock,
+ (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0)
+ err(1, "bind(), %s:%d", __FILE__, __LINE__);
+
+ if (listen(tcpsock, 5) < 0)
+ err(1, "listen(), %s:%d", __FILE__, __LINE__);
+
+ len = sizeof(inetpeer);
+ if ((msgsock = accept(tcpsock,
+ (struct sockaddr *)&inetpeer, &len)) < 0)
+ err(1, "accept(), %s:%d", __FILE__, __LINE__);
+
+ if ((fd = open(outputFile, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1)
+ err(1, "open(%s)", outputFile);
+
+ usleep(arc4random() % 1000);
+ for (;;) {
+ if ((n = read(msgsock, buf, FSIZE)) < 0)
+ err(1, "read(), %s:%d", __FILE__, __LINE__);
+ if (n == 0)
+ break;
+
+ }
+ close(msgsock);
+ close(tcpsock);
+ close(fd);
+ return;
+}
+
+static void *
+thr(void *data __unused)
+{
+ pthread_set_name_np(pthread_self(), __func__);
+ go = 1;
+ while (go == 1) {
+ ftruncate(fd, FSIZE / 2);
+ ftruncate(fd, FSIZE);
+ }
+
+ return (NULL);
+}
+
+static void
+writer(void) {
+ struct hostent *hostent;
+ struct sockaddr_in inetaddr;
+ pthread_t tid;
+ off_t off = 0;
+ size_t size;
+ int i, on, r, tcpsock;
+
+ on = 1;
+ for (i = 1; i < 5; i++) {
+ if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+ err(1, "socket(), %s:%d", __FILE__, __LINE__);
+
+ if (setsockopt(tcpsock,
+ SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0)
+ err(1, "setsockopt(), %s:%d", __FILE__, __LINE__);
+
+ size = getpagesize();
+ if (setsockopt(tcpsock, SOL_SOCKET, SO_SNDBUF, (void *)&size,
+ sizeof(size)) < 0)
+ err(1, "setsockopt(SO_SNDBUF), %s:%d",
+ __FILE__, __LINE__);
+
+ hostent = gethostbyname ("localhost");
+ memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr,
+ sizeof (struct in_addr));
+
+ inetaddr.sin_family = AF_INET;
+ inetaddr.sin_port = htons(port);
+ inetaddr.sin_len = sizeof(inetaddr);
+
+ r = connect(tcpsock, (struct sockaddr *) &inetaddr,
+ sizeof(inetaddr));
+ if (r == 0)
+ break;
+ sleep(1);
+ close(tcpsock);
+ }
+ if (r < 0)
+ err(1, "connect(), %s:%d", __FILE__, __LINE__);
+
+ if ((fd = open(inputFile, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1)
+ err(1, "open(%s)", inputFile);
+
+ if (write(fd, buf, sizeof(buf)) != sizeof(buf))
+ err(1, "write()");
+
+ r = pthread_create(&tid, NULL, thr, NULL);
+ if (r)
+ errc(1, r, "pthread_create");
+
+ usleep(5000);
+ if (sendfile(fd, tcpsock, 0, FSIZE, NULL, &off, 0) == -1)
+ err(1, "sendfile");
+
+ usleep(arc4random() % 20000);
+ go = 0;
+ if ((r = pthread_join(tid, NULL)) != 0)
+ errc(1, r, "pthread_join");
+
+ _exit(0);
+}
+
+int
+main(int argc, char **argv)
+{
+ pid_t pid;
+ time_t start;
+
+ if (argc != 4) {
+ fprintf(stderr, "Usage: %s <inputFile outputFile portNumber\n",
+ argv[0]);
+ return (1);
+ }
+ inputFile = argv[1];
+ outputFile = argv[2];
+ port = atoi(argv[3]);
+ pthread_set_name_np(pthread_self(), __func__);
+
+ start = time(NULL);
+ while (time(NULL) - start < 120) {
+ if ((pid = fork()) == 0) {
+ writer();
+ } else if (pid > 0) {
+ reader();
+ kill(pid, SIGINT);
+ if (waitpid(pid, NULL, 0) != pid)
+ err(1, "waitpid()");
+ } else
+ err(1, "fork(), %s:%d", __FILE__, __LINE__);
+ }
+
+ return (0);
+}
diff --git a/tools/test/stress2/misc/msdos20.sh b/tools/test/stress2/misc/msdos20.sh
new file mode 100755
index 000000000000..96c224a629f3
--- /dev/null
+++ b/tools/test/stress2/misc/msdos20.sh
@@ -0,0 +1,87 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# msdosfs disk image fuzz test.
+# No problems seen
+
+. ../default.cfg
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+cc -o /tmp/flip -Wall -Wextra -O2 ../tools/flip.c || exit 1
+
+set -eu
+u1=$mdstart
+u2=$((mdstart + 1))
+mp1=${mntpoint}$u1
+mp2=${mntpoint}$u2
+mkdir -p $mp1 $mp2
+prog=$(basename "$0" .sh)
+backup=/tmp/$prog.sh.diskimage.`date +%Y%m%dT%H%M%S`
+cap=$((32 * 1024)) # Only fuzz the first 32k
+log=$mp1/$prog.sh.log
+diskimage=$mp1/msdos20.sh.diskimage
+
+set +e
+mount | grep "on $mp2 " | grep -q /dev/md && umount -f $mp2
+mount | grep "on $mp1 " | grep -q /dev/md && umount -f $mp1
+[ -c /dev/md$u2 ] && mdconfig -d -u $u2
+[ -c /dev/md$u1 ] && mdconfig -d -u $u1
+mdconfig -a -t swap -s 2g -u $u1
+newfs -U /dev/md$u1 > /dev/null
+mount /dev/md$u1 $mp1
+
+size=32m
+type=`jot -r 1 1 3`
+[ $type -eq 3 ] && size=260m
+[ -c /dev/md$u2 ] && mdconfig -d -u $u2
+dd if=/dev/zero of=$diskimage bs=$size count=1 status=none
+mdconfig -a -t vnode -f $diskimage -u $u2
+[ $type -eq 1 ] && newfs_msdos -F 12 /dev/md$u2 > /dev/null 2>&1
+[ $type -eq 2 ] && newfs_msdos -F 16 /dev/md$u2 > /dev/null 2>&1
+[ $type -eq 3 ] && newfs_msdos -F 32 -b 4096 /dev/md$u2 > /dev/null 2>&1
+
+mount -t msdosfs /dev/md$u2 $mp2 || { echo "Initial mount of type $type failed"; exit 1; }
+if [ -d /usr/include/sys ]; then
+ mkdir $mp2/sys
+ cp /usr/include/sys/elf_common.h $mp2/sys
+ cp /usr/include/sys/soundcard.h $mp2/sys
+ cp /usr/include/sys/sysproto.h $mp2/sys
+fi
+umount $mp2
+
+cd $mp1
+start=`date +%s`
+nn=0
+s=0
+while [ $((`date +%s` - start)) -lt 240 ]; do
+ mount -t msdosfs /dev/md$u2 $mp2 2>/dev/null || { s=1; break; }
+ ls -lR $mp2 > /dev/null 2>&1 || { s=2; break; }
+ rm -rf $mp2/* > /dev/null 2>&1 || { s=3; break; }
+ touch $mp2/`jot -rc 8 a z | tr -d '\n'` || { s=4; break; }
+ while mount | grep -q "on $mp2 "; do umount $mp2; done
+ echo * | grep -q core && { s=5; break; }
+ sync
+ mdconfig -d -u $u2
+ /tmp/flip -n 10 -s $cap $diskimage
+ cp $diskimage $backup
+ fsync $backup
+ sync
+ mdconfig -a -t vnode -f $diskimage -u $u2
+ nn=$((nn + 1))
+done
+#echo "Exit after $nn loops on a type $type MSDOS FS with code $s"
+mount | grep -q "on $mp2 " && umount $mp2
+mdconfig -d -u $u2 || exit 1
+
+echo * | grep -q core && { ls -l *.core; cp $log /tmp; exit 106; } ||
+cd /tmp
+umount $mp1
+mdconfig -d -u $u1
+rm -f /tmp/flip $backup
+exit 0
diff --git a/tools/test/stress2/misc/msdos21.sh b/tools/test/stress2/misc/msdos21.sh
new file mode 100755
index 000000000000..68ea94eab105
--- /dev/null
+++ b/tools/test/stress2/misc/msdos21.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+# Test scenario from https://reviews.freebsd.org/D43951 "Fix MSDOSFS rename (in case target exists)"
+# Test scenario by se@
+
+# Triggered a panic with a WiP kernel patch.
+
+set -u
+[ -f "`which rsync`" ] || exit 0
+[ -d /usr/src/lib ] || exit 0
+
+MDUNIT=10
+FS=/mnt/test
+mdconfig -u $MDUNIT -t malloc -s 512m
+newfs_msdos -c 8 -F 32 /dev/md$MDUNIT > /dev/null 2>&1
+mkdir -p $FS
+mount -t msdos /dev/md$MDUNIT $FS
+rsync -r /usr/src/lib/libsysdecode $FS
+rsync -r /usr/src/lib/libsysdecode $FS
+rsync -r /usr/src/lib/libsysdecode $FS
+umount $FS
+fsck_msdosfs -y /dev/md$MDUNIT; s=$?
+mdconfig -d -u $MDUNIT
+
+exit $s
diff --git a/tools/test/stress2/misc/namecache2.sh b/tools/test/stress2/misc/namecache2.sh
index 9fcfe5e0226c..b32d41974468 100755
--- a/tools/test/stress2/misc/namecache2.sh
+++ b/tools/test/stress2/misc/namecache2.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# UFS cache inconsistancy for rename(2) demonstrated
+# UFS cache inconsistency for rename(2) demonstrated
# Fails with:
# ls -ali /mnt
# ls: tfa1022: No such file or directory
diff --git a/tools/test/stress2/misc/newfs.sh b/tools/test/stress2/misc/newfs.sh
index 44c76f78b599..252629c04b90 100755
--- a/tools/test/stress2/misc/newfs.sh
+++ b/tools/test/stress2/misc/newfs.sh
@@ -78,8 +78,8 @@ for opt in -O1 -O2 -U -j; do
done
blocksize=$((blocksize * 2))
done
- if [ $((`date '+%s'` - start)) -gt 1200 ]; then
- echo "Timed out"
+ if [ $((`date '+%s'` - start)) -gt 1800 ]; then
+ echo "Timed out in $opt"
s=4
break
fi
diff --git a/tools/test/stress2/misc/md4.sh b/tools/test/stress2/misc/newfs6.sh
index 0d760b99b058..cf481569ee9c 100755
--- a/tools/test/stress2/misc/md4.sh
+++ b/tools/test/stress2/misc/newfs6.sh
@@ -1,8 +1,9 @@
#!/bin/sh
#
-# Copyright (c) 2013 Peter Holm <pho@FreeBSD.org>
-# All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -26,19 +27,38 @@
# SUCH DAMAGE.
#
-# Demonstrate data corruption on the swap-backed md.
-# Test scenario by Nigel Williams <njwilliams swin edu au>.
-# Fixed in r250966.
+# A fast version of newfs.sh
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
-[ -z "`which bsdlabel`" ] && exit 0
-status=0
-MD_DEV=`mdconfig -an -t swap -s 1m -x 63 -y 16`
-fdisk -I md$MD_DEV > /dev/null 2>&1
-bsdlabel -w -B md${MD_DEV}s1 || exit 1
-dd if=/dev/md$MD_DEV of=/dev/null bs=64k status=none
-bsdlabel md${MD_DEV}s1 > /dev/null ||
- { echo FAIL; status=1; }
-mdconfig -d -u $MD_DEV
-exit $status
+. ../default.cfg
+
+mount | grep "on $mntpoint " | grep -q md$mdstart &&
+ umount $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 1g -u $mdstart || exit 1
+
+log=/tmp/newfs6.sh.log
+s=0
+for opt in -O1 -O2 -U -j; do
+ bs=4096
+ while [ $bs -le 65536 ]; do
+ for i in 8 4 2 1; do
+ fragsize=$((bs / i))
+ echo "newfs $opt -b $bs -f $fragsize md$mdstart "
+ newfs $opt -b $bs -f $fragsize \
+ md$mdstart > /dev/null || { s=1; continue; }
+ mount /dev/md$mdstart $mntpoint || s=2 &&
+ umount $mntpoint
+ fsck -fy /dev/md$mdstart > $log 2>&1
+ grep -q "WAS MODIFIED" $log && {
+ s=3
+ cat $log
+ }
+ done
+ bs=$((bs * 2))
+ done
+done
+mdconfig -d -u $mdstart
+rm -f $log
+exit $s
diff --git a/tools/test/stress2/misc/gbde.sh b/tools/test/stress2/misc/newfs7.sh
index f47d8e9e15bf..1456d1360bc1 100755
--- a/tools/test/stress2/misc/gbde.sh
+++ b/tools/test/stress2/misc/newfs7.sh
@@ -1,8 +1,9 @@
#!/bin/sh
#
-# Copyright (c) 2012 Peter Holm <pho@FreeBSD.org>
-# All rights reserved.
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
@@ -26,30 +27,27 @@
# SUCH DAMAGE.
#
-# "panic: bio_driver1 used by the consumer (geom ffs.md5.bde)" seen
-# http://people.freebsd.org/~pho/stress/log/gbde.txt
-
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
-
. ../default.cfg
-mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart
-mdconfig -a -t swap -s 1g -u $mdstart
-
-gbde init /dev/md$mdstart -P pass-phrase || exit
-gbde attach md$mdstart -p pass-phrase || exit
-
-newfs $newfs_flags /dev/md$mdstart.bde > /dev/null
-mount /dev/md$mdstart.bde $mntpoint
-chmod 777 $mntpoint
-
-export runRUNTIME=20m
-export RUNDIR=$mntpoint/stressX
-
-su $testuser -c 'cd ..; ./run.sh marcus.cfg'
-
-while mount | grep $mntpoint | grep -q bde; do
- umount $mntpoint || sleep 1
-done
-gbde detach md$mdstart
+# "mount: /dev/md10: Invalid fstype: Invalid argument" seen.
+# Reported by: soralx@cydem.org
+# Fixed by: 017367c1146a
+
+set -eu
+prog=`basename ${0%.sh}`
+log=/tmp/$prog.log
+s=0
+mdconfig -a -t swap -s 32T -u $mdstart
+newfs -L tst0 -U -b 65536 -f 8192 -d 1048576 -g 131072 -h 16 -i 1048576 \
+ /dev/md$mdstart > /dev/null || s=1
+set +e
+mount /dev/md$mdstart $mntpoint && umount $mntpoint || s=$((s | 2))
+fsck_ffs -fy md$mdstart > $log 2>&1 || s=$((s | 4))
+grep -Eq "IS CLEAN|MARKED CLEAN" $log || s=$((s | 8))
+grep -Eq "WAS MODIFIED" $log && s=$((s | 16))
+[ $s -ne 0 ] && tail -10 $log
mdconfig -d -u $mdstart
+rm -f $log
+
+exit $s
diff --git a/tools/test/stress2/misc/newfs8.sh b/tools/test/stress2/misc/newfs8.sh
new file mode 100755
index 000000000000..56ee07cba9b1
--- /dev/null
+++ b/tools/test/stress2/misc/newfs8.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Variation of newfs.sh with VM pressure added
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+set -u
+mount | grep "$mntpoint" | grep md$mdstart > /dev/null &&
+ umount $mntpoint
+mdconfig -l | grep md$mdstart > /dev/null && mdconfig -d -u $mdstart
+
+mdconfig -a -t swap -s 20g -u $mdstart
+
+log=/tmp/newfs.sh.log
+s=0
+export RUNDIR=$mntpoint/stressX
+export runRUNTIME=2m
+export RUNTIME=$runRUNTIME
+export CTRLDIR=$mntpoint/stressX.control
+start=`date '+%s'`
+for opt in -O2 -U -j; do
+ blocksize=4096
+ while [ $blocksize -le 65536 ]; do
+ for i in 8 4 2 1; do
+ fragsize=$((blocksize / i))
+ echo "`date +%T` newfs $opt -b $blocksize -f $fragsize"\
+ "md$mdstart"
+ newfs $opt -b $blocksize -f $fragsize \
+ md$mdstart > /dev/null || { s=1; continue; }
+ [ "$opt" = "-O2" ] && tunefs -n disable md$mdstart > /dev/null 2>&1
+ mount /dev/md$mdstart $mntpoint || { s=2; continue; }
+ chmod 777 $mntpoint
+ su $testuser -c \
+ "(cd ..; ./run.sh io.cfg > /dev/null 2>&1)" &
+ sleep 30
+ while pkill swap; do :; done
+ while pkill -U $testuser; do :; done
+ ../tools/killall.sh || { echo "Failed at $opt -b $blocksize -f $fragsize$"; \
+ exit 3; }
+ wait
+ while mount | grep "$mntpoint" | \
+ grep -q md$mdstart; do
+ umount $mntpoint > /dev/null 2>&1 || sleep 1
+ done
+ fsck -fy /dev/md$mdstart > $log 2>&1
+ grep -q "WAS MODIFIED" $log && {
+ s=4
+ cat $log
+ }
+ done
+ blocksize=$((blocksize * 2))
+ done
+ if [ $((`date '+%s'` - start)) -gt 3600 ]; then
+ echo "Timed out in $opt -b $blocksize -f $fragsize$"
+ s=5
+ break
+ fi
+done
+mdconfig -d -u $mdstart
+rm -f $log
+exit $s
diff --git a/tools/test/stress2/misc/nfs17.sh b/tools/test/stress2/misc/nfs17.sh
index 2a012e476e55..86f045a34bdf 100755
--- a/tools/test/stress2/misc/nfs17.sh
+++ b/tools/test/stress2/misc/nfs17.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/nfs18.sh b/tools/test/stress2/misc/nfs18.sh
index 46330a0290a1..b1432dd355d2 100755
--- a/tools/test/stress2/misc/nfs18.sh
+++ b/tools/test/stress2/misc/nfs18.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
diff --git a/tools/test/stress2/misc/nfs_halfpage.sh b/tools/test/stress2/misc/nfs_halfpage.sh
index b665e84d7ddf..8d02ca8ebbcf 100755
--- a/tools/test/stress2/misc/nfs_halfpage.sh
+++ b/tools/test/stress2/misc/nfs_halfpage.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2017 Konstantin Belousov <kib@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/nfs_halfpage2.sh b/tools/test/stress2/misc/nfs_halfpage2.sh
index 15895da2da21..b916531c7a9d 100755
--- a/tools/test/stress2/misc/nfs_halfpage2.sh
+++ b/tools/test/stress2/misc/nfs_halfpage2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2017 Konstantin Belousov <kib@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/nfsrename.sh b/tools/test/stress2/misc/nfsrename.sh
index b6513fba1553..864c64aed8ac 100755
--- a/tools/test/stress2/misc/nfsrename.sh
+++ b/tools/test/stress2/misc/nfsrename.sh
@@ -137,7 +137,7 @@ write_file(void)
unlink(path);
}
- fprintf(fp, "blah blah blah garbage %ld\n", random());
+ fprintf(fp, "blah blah blah garbage %ld\n", (long)arc4random());
fclose(fp);
if (rename(path, filename) < 0) {
warn("rename");
@@ -150,7 +150,7 @@ random_sleep(int base, int slop)
{
long val;
- val = random() % slop;
+ val = arc4random() % slop;
usleep(base + val);
}
diff --git a/tools/test/stress2/misc/nlink.sh b/tools/test/stress2/misc/nlink.sh
index 1d3bde8c7d42..f06752290ac3 100755
--- a/tools/test/stress2/misc/nlink.sh
+++ b/tools/test/stress2/misc/nlink.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/nlink2.sh b/tools/test/stress2/misc/nlink2.sh
index 41cdaa676fc9..559ad5cfa417 100755
--- a/tools/test/stress2/misc/nlink2.sh
+++ b/tools/test/stress2/misc/nlink2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/nlink3.sh b/tools/test/stress2/misc/nlink3.sh
index 2484e8569928..55557124c9c2 100755
--- a/tools/test/stress2/misc/nlink3.sh
+++ b/tools/test/stress2/misc/nlink3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
@@ -52,7 +52,7 @@ main (void) {
err(1, "creat(%s)", file);
close(fd);
- mx = UFS_LINK_MAX - 1; /* UFS_LINK_MAX = 32767 */
+ mx = UFS_LINK_MAX - 1;
for (i = 0; i < mx; i++) {
snprintf(file, sizeof(file), "%d", i);
if (link("f", file) == -1)
diff --git a/tools/test/stress2/misc/nlink4.sh b/tools/test/stress2/misc/nlink4.sh
index 12412666b182..cce8bb06985a 100755
--- a/tools/test/stress2/misc/nlink4.sh
+++ b/tools/test/stress2/misc/nlink4.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
@@ -51,7 +51,7 @@ main (void) {
err(1, "creat(%s)", file);
close(fd);
- mx = UFS_LINK_MAX - 1; /* UFS_LINK_MAX = 32767 */
+ mx = UFS_LINK_MAX - 1;
for (i = 0; i < mx; i++) {
snprintf(file, sizeof(file), "%d", i);
if (link("f", file) == -1)
diff --git a/tools/test/stress2/misc/nlink5.sh b/tools/test/stress2/misc/nlink5.sh
index c90f43b35dd5..0738bc7548bf 100755
--- a/tools/test/stress2/misc/nlink5.sh
+++ b/tools/test/stress2/misc/nlink5.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
@@ -33,6 +33,9 @@
. ../default.cfg
+UFS_LINK_MAX=`grep UFS_LINK_MAX /usr/include/ufs/ufs/dinode.h 2>/dev/null`
+[ -z "$UFS_LINK_MAX" ] && exit 0
+UFS_LINK_MAX=`echo $UFS_LINK_MAX | awk '{print $3}'`
cat > /tmp/nlink5.c <<EOF
#include <sys/stat.h>
#include <ufs/ufs/dinode.h>
@@ -46,7 +49,7 @@ main (void) {
int i, mx;
char dir[100];
- mx = UFS_LINK_MAX - 2; /* UFS_LINK_MAX = 32767 */
+ mx = UFS_LINK_MAX - 2;
for (i = 0; i < mx; i++) {
snprintf(dir, sizeof(dir), "%d", i);
if (mkdir(dir, 0700) == -1)
@@ -111,7 +114,7 @@ set +e
cd $mntpoint
/tmp/nlink5; s=$?
n=`find . -type d -maxdepth 1 | wc -l`
-[ $n -ne 32766 ] && s=2
+[ $n -ne $((UFS_LINK_MAX - 1)) ] && s=2
cd $here
umount $mntpoint
diff --git a/tools/test/stress2/misc/nullfs18.sh b/tools/test/stress2/misc/nullfs18.sh
index 0ee0a1c2ef6b..3936ea64c6a3 100755
--- a/tools/test/stress2/misc/nullfs18.sh
+++ b/tools/test/stress2/misc/nullfs18.sh
@@ -28,7 +28,7 @@
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
-# Demonstate nullfs(5) inode leak.
+# Demonstate nullfs(4) inode leak.
# Fixed by r295717.
. ../default.cfg
@@ -41,6 +41,7 @@ mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
mdconfig -a -t swap -s 2g -u $mdstart || exit 1
newfs -n md$mdstart > /dev/null
+tunefs -n disable md$mdstart 2>/dev/null
mount /dev/md$mdstart $mntpoint
chmod 777 $mntpoint
diff --git a/tools/test/stress2/misc/nullfs25.sh b/tools/test/stress2/misc/nullfs25.sh
index 57f63c6d2330..b98d4599a7ad 100755
--- a/tools/test/stress2/misc/nullfs25.sh
+++ b/tools/test/stress2/misc/nullfs25.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/nullfs26.sh b/tools/test/stress2/misc/nullfs26.sh
index 720021e9e199..ae3dfa23dc2b 100755
--- a/tools/test/stress2/misc/nullfs26.sh
+++ b/tools/test/stress2/misc/nullfs26.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/nullfs27.sh b/tools/test/stress2/misc/nullfs27.sh
index 907e9de14253..bf7b2a5fea61 100755
--- a/tools/test/stress2/misc/nullfs27.sh
+++ b/tools/test/stress2/misc/nullfs27.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/nullfs28.sh b/tools/test/stress2/misc/nullfs28.sh
index 3e313de6f64c..6ebb47974ffe 100755
--- a/tools/test/stress2/misc/nullfs28.sh
+++ b/tools/test/stress2/misc/nullfs28.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/nullfs30.sh b/tools/test/stress2/misc/nullfs30.sh
new file mode 100755
index 000000000000..8b8f35aed4c0
--- /dev/null
+++ b/tools/test/stress2/misc/nullfs30.sh
@@ -0,0 +1,112 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Parallel mount and umount test of file mounts,
+# mounting over non-directories
+
+# panic: free: address 0xffffffff80b229b4 ... has not been allocated
+# https://people.freebsd.org/~pho/stress/log/log0454.txt
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+cont=/tmp/nullfs30.continue
+mounts=3 # Number of parallel scripts
+
+set -eu
+md1=$mdstart
+md2=$((md1 + 1))
+mp1=$mntpoint$md1
+mp2=$mntpoint$md2
+mkdir -p $mp1 $mp2
+
+mdconfig -a -t swap -s 256m -u $md1
+newfs $newfs_flags -n md$md1 > /dev/null
+mount /dev/md$md1 $mp1
+mdconfig -a -t swap -s 256m -u $md2
+newfs $newfs_flags -n md$md2 > /dev/null
+mount /dev/md$md2 $mp2
+
+for i in `jot $mounts`; do
+ cp /etc/group $mp1/f$i
+ touch $mp2/m$i
+done
+set +e
+
+mount -t nullfs $mp1/f1 $mp2/m1 || {
+ umount $mp2
+ umount $mp1
+ mdconfig -d -u $md2
+ mdconfig -d -u $md1
+ echo "File mount not implemented"
+ exit 0
+}
+
+(cd ../testcases/swap; ./swap -t 5m -i 20 > /dev/null) &
+
+# Start the parallel tests
+touch $cont
+while [ -f $cont ]; do
+ while mount | grep -q "on $mp2/m1 "; do umount $mp2/m1; done 2> /dev/null
+ mount -t nullfs $mp1/f1 $mp2/m1
+done &
+while [ -f $cont ]; do
+ while mount | grep -q "on $mp2/m2 "; do umount $mp2/m2; done 2> /dev/null
+ mount -t nullfs $mp1/f2 $mp2/m2
+done &
+while [ -f $cont ]; do
+ while mount | grep -q "on $mp2/m3 "; do umount $mp2/m3; done 2> /dev/null
+ mount -t nullfs $mp1/f3 $mp2/m3
+done &
+
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 300 ]; do
+ cat $mp2/m1 $mp2/m2 $mp2/m3 > /dev/null
+done
+rm -f $cont
+while pgrep -q swap; do pkill swap; done
+wait
+
+for i in 1 2 3; do
+ while mount | grep -q "on $mp2/m$i "; do umount $mp2/m$i; done 2> /dev/null
+done
+
+# Check error handling
+mount -t nullfs $mp1/f1 $mp2/m1
+mount -t nullfs $mp1/f1 $mp2/m1 2>/dev/null && s=1 || s=0
+while mount | grep -q "on $mp2/m1 "; do umount $mp2/m1; done 2> /dev/null
+
+mkdir $mp2/dir
+mount -t nullfs $mp1/f1 $mp2/dir 2>/dev/null && s=2
+
+umount $mp2
+umount $mp1
+mdconfig -d -u $md2
+mdconfig -d -u $md1
+exit $s
diff --git a/tools/test/stress2/misc/nullfs31.sh b/tools/test/stress2/misc/nullfs31.sh
new file mode 100755
index 000000000000..381ec6bf041c
--- /dev/null
+++ b/tools/test/stress2/misc/nullfs31.sh
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Variation of nullfs25.sh, using cp(1) (copy_file_range())
+
+# Page fault in vn_copy_file_range() seen:
+# https://people.freebsd.org/~pho/stress/log/log0497.txt
+# Fixed by: 23210f538a00
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+set -u
+mounts=4 # Number of parallel scripts
+: ${nullfs_srcdir:=$mntpoint}
+: ${nullfs_dstdir:=$mntpoint}
+prog=$(basename "$0" .sh)
+CONT=/tmp/$prog.continue
+
+mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 1g -u $mdstart
+newfs $newfs_flags md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+chmod 777 $mntpoint
+(cd $mntpoint; jot 500 | xargs touch)
+(cd ../testcases/swap; ./swap -t 5m -i 20 > /dev/null) &
+
+for i in `jot $mounts $mdstart`; do
+ [ ! -d ${nullfs_dstdir}$i ] && mkdir ${nullfs_dstdir}$i
+ mount | grep -q " ${nullfs_dstdir}$i " &&
+ umount ${nullfs_dstdir}$i
+done
+
+# Start the parallel tests
+touch $CONT
+for i in `jot $mounts $mdstart`; do
+ while [ -f $CONT ]; do
+ cp /etc/group ${nullfs_dstdir}$i > \
+ /dev/null 2>&1
+ done &
+ # The test: Parallel mount and unmount
+ start=`date +%s`
+ (
+ while [ $((`date +%s` - start)) -lt 300 ]; do
+ mount_nullfs $nullfs_srcdir ${nullfs_dstdir}$i > \
+ /dev/null 2>&1
+ opt=$([ `jot -r 1 0 1` -eq 0 ] && echo "-f")
+ while mount | grep -q ${nullfs_dstdir}$i; do
+ umount $opt ${nullfs_dstdir}$i > \
+ /dev/null 2>&1
+ done
+ done
+ rm -f $CONT
+ ) &
+done
+while [ -f $CONT ] ; do sleep 1; done
+while pgrep -q swap; do pkill swap; done
+wait
+
+for i in `jot $mounts`; do
+ umount ${nullfs_dstdir}$i > /dev/null 2>&1
+done
+n=0
+while mount | grep $mntpoint | grep -q /dev/md; do
+ umount $mntpoint || sleep 1
+ [ $((n += 1)) -gt 300 ] && { echo FAIL; exit 1; }
+done
+mdconfig -d -u $mdstart
+exit 0
diff --git a/tools/test/stress2/misc/nullfs32.sh b/tools/test/stress2/misc/nullfs32.sh
new file mode 100755
index 000000000000..567a40d4d373
--- /dev/null
+++ b/tools/test/stress2/misc/nullfs32.sh
@@ -0,0 +1,43 @@
+#!/bin/sh
+
+# Test scenario from:
+# Bug 254210 - jail: nullfs: deleted files does not free up space
+# Fixed by: 1a0cb938f7b4
+
+# Test scenario idea by: ronald@FreeBSD.org
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+set -u
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+df -h | grep "$mntpoint"
+mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 2g -u $mdstart
+newfs $newfs_flags -n md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+
+cd $mntpoint
+mkdir storage test1 test2
+mount_nullfs -o rw,noatime ./storage ./test1
+mount_nullfs -o rw,noatime ./storage ./test2
+
+dd if=/dev/random of=./test1/random.dd bs=1M count=1024 status=none
+
+rm ./test2/random.dd
+df -h | grep "$mntpoint" > $log
+grep -E "${mntpoint}$" $log | grep -q '16K 1.8G 0%' && s=0 || s=1
+if [ $s -eq 1 ]; then
+ echo "Leaking:"
+ cat $log
+ find $mntpoint -type f -ls
+fi
+cd -
+umount $mntpoint/test1
+umount $mntpoint/test2
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -f rm -f $log
+exit $s
diff --git a/tools/test/stress2/misc/numa.sh b/tools/test/stress2/misc/numa.sh
index 048eb1201714..afa153ec1ed1 100755
--- a/tools/test/stress2/misc/numa.sh
+++ b/tools/test/stress2/misc/numa.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/open2.sh b/tools/test/stress2/misc/open2.sh
index 7c0994bfd4e4..fc3f7c9b05eb 100755
--- a/tools/test/stress2/misc/open2.sh
+++ b/tools/test/stress2/misc/open2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/overflow3.sh b/tools/test/stress2/misc/overflow3.sh
index a5a29721a30b..d09794e57bca 100755
--- a/tools/test/stress2/misc/overflow3.sh
+++ b/tools/test/stress2/misc/overflow3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Mark Johnston <markj@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/pageout.sh b/tools/test/stress2/misc/pageout.sh
index eafeb22d3417..92eb899880ac 100755
--- a/tools/test/stress2/misc/pageout.sh
+++ b/tools/test/stress2/misc/pageout.sh
@@ -33,6 +33,10 @@
# "panic: handle_written_filepage: not started" seen:
# https://people.freebsd.org/~pho/stress/log/pageout-2.txt
+# "panic: ffs_geom_strategy: bad I/O" seen:
+# https://people.freebsd.org/~pho/stress/log/log0434.txt
+# Fixed by: 7aeea73e3078
+
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
. ../default.cfg
@@ -49,6 +53,8 @@ mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
mdconfig -a -t swap -s 2g -u $mdstart || exit 1
+[ "$newfs_flags" = "-U" ] && [ `jot -r 1 0 1` -eq 1 ] && newfs_flags="-j"
+[ $# -eq 1 ] && newfs_flags="$1" # or use script argument
newfs $newfs_flags md$mdstart > /dev/null
mount /dev/md$mdstart $mntpoint
@@ -61,8 +67,8 @@ daemon sh -c "(cd ../testcases/swap; ./swap -t 5m -i 20 -l 100 -h)" > /dev/null
(cd /tmp; /tmp/pageout $f1) &
sleep .2
while kill -0 $! 2> /dev/null; do
- mksnap_ffs $mntpoint $mntpoint/.snap/stress2 &&
- rm -f $mntpoint/.snap/stress2
+ rm -f $mntpoint/.snap/stress2
+ mksnap_ffs $mntpoint $mntpoint/.snap/stress2
done
while pgrep -q swap; do
pkill swap
diff --git a/tools/test/stress2/misc/pager_read_error.sh b/tools/test/stress2/misc/pager_read_error.sh
new file mode 100755
index 000000000000..9a2f3c7cc380
--- /dev/null
+++ b/tools/test/stress2/misc/pager_read_error.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Hunt for "vm_fault: pager read error, pid 32939 (mmap)"
+
+# "panic: namei: unexpected flags: 0x10000000" seen:
+# https://people.freebsd.org/~pho/stress/log/log0585.txt
+# Fixed by: 58b2bd33aff7
+
+. ../default.cfg
+
+md=$mdstart
+mp=$mntpoint
+mdconfig -l | grep -q md$md && mdconfig -d -u $md
+mount | grep -q "on $mp " && umount -f $mp
+
+mdconfig -a -t swap -s 1g -u $md
+newfs -U /dev/md$md > /dev/null
+mount /dev/md$md $mp
+
+export RUNDIR=$mp/stressX
+../testcases/swap/swap -t 5m -i 20 -l 100 > /dev/null &
+sleep 5
+../testcases/mmap/mmap -t 5m -i 20 -l 100 > /dev/null 2>&1 &
+sleep 5
+umount -f $mp
+pkill swap mmap
+wait
+
+mdconfig -d -u $md
+exit 0
diff --git a/tools/test/stress2/misc/perf.sh b/tools/test/stress2/misc/perf.sh
index 89e9dd8d371c..de6c20028c59 100755
--- a/tools/test/stress2/misc/perf.sh
+++ b/tools/test/stress2/misc/perf.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
@@ -84,6 +84,7 @@ tst() {
s=0
for i in "" "-U" "-j"; do
newfs $i /dev/md$mdstart > /dev/null 2>&1
+ [ "$i" = "" ] && tunefs -n disable md$mdstart
mount /dev/md$mdstart $mntpoint
t1=`date +%s`
diff --git a/tools/test/stress2/misc/ping.sh b/tools/test/stress2/misc/ping.sh
index 2594c6d5e43c..29ed6dec955f 100755
--- a/tools/test/stress2/misc/ping.sh
+++ b/tools/test/stress2/misc/ping.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/pipe3.sh b/tools/test/stress2/misc/pipe3.sh
index 6208e1a52f90..654b94e3caaf 100755
--- a/tools/test/stress2/misc/pipe3.sh
+++ b/tools/test/stress2/misc/pipe3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Peter Holm
#
diff --git a/tools/test/stress2/misc/pipe_enomem.sh b/tools/test/stress2/misc/pipe_enomem.sh
index 92558b164336..9a00aac5cb6b 100755
--- a/tools/test/stress2/misc/pipe_enomem.sh
+++ b/tools/test/stress2/misc/pipe_enomem.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Konstantin Belousov
#
diff --git a/tools/test/stress2/misc/pkru.sh b/tools/test/stress2/misc/pkru.sh
index 9ac0a5000daf..047b7f8f8745 100755
--- a/tools/test/stress2/misc/pkru.sh
+++ b/tools/test/stress2/misc/pkru.sh
@@ -1,6 +1,6 @@
#/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Konstantin Belousov <kib@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/pmc6.sh b/tools/test/stress2/misc/pmc6.sh
index 4cbdf278125f..f0869333b0ff 100755
--- a/tools/test/stress2/misc/pmc6.sh
+++ b/tools/test/stress2/misc/pmc6.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/poll2.sh b/tools/test/stress2/misc/poll2.sh
index 13db2d0d22d3..aa5ad5f995dd 100755
--- a/tools/test/stress2/misc/poll2.sh
+++ b/tools/test/stress2/misc/poll2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
@@ -136,11 +136,11 @@ static void *
pl(void *data __unused)
{
struct pollfd pfd;
- int i, r;
+ int r;
pfd.fd = fds[0];
pfd.events = POLLIN;
- for (i = 0; done == 0; i++) {
+ while (done == 0) {
pfd.fd = fds[0];
pfd.events = POLLIN;
pthread_set_name_np(pthread_self(), "pl-idle");
diff --git a/tools/test/stress2/misc/pread.sh b/tools/test/stress2/misc/pread.sh
index 1bf3b874e6af..24ee2efb696a 100755
--- a/tools/test/stress2/misc/pread.sh
+++ b/tools/test/stress2/misc/pread.sh
@@ -46,13 +46,13 @@ mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
mount -t tmpfs tmpfs $mntpoint
cp -a /usr/include $mntpoint
-echo "Testing tmpfs(5)"
+echo "Testing tmpfs(4)"
/tmp/pread $mntpoint
while mount | grep -q "on $mntpoint "; do
umount $mntpoint || sleep 1
done
-echo "Testing fdescfs(5)"
+echo "Testing fdescfs(4)"
mount -t fdescfs null /dev/fd
for i in `jot 100`; do
/tmp/pread /dev/fd
@@ -62,7 +62,7 @@ while mount | grep -q "on /dev/fd "; do
umount /dev/fd || sleep 1
done
-echo "Testing procfs(5)"
+echo "Testing procfs(4)"
mount -t procfs procfs $mntpoint
/tmp/pread $mntpoint
while mount | grep -q "on $mntpoint "; do
@@ -81,13 +81,13 @@ done
mdconfig -d -u $mdstart
mount -t nullfs /bin $mntpoint
-echo "Testing nullfs(5)"
+echo "Testing nullfs(4)"
/tmp/pread $mntpoint
while mount | grep -q "on $mntpoint "; do
umount $mntpoint || sleep 1
done
-echo "Testing procfs(5)"
+echo "Testing procfs(4)"
mount -t procfs procfs $mntpoint
/tmp/pread $mntpoint
while mount | grep -q "on $mntpoint "; do
diff --git a/tools/test/stress2/misc/proccontrol.sh b/tools/test/stress2/misc/proccontrol.sh
index 52f7cc824372..cea8c0dc0f0a 100755
--- a/tools/test/stress2/misc/proccontrol.sh
+++ b/tools/test/stress2/misc/proccontrol.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/procfs.sh b/tools/test/stress2/misc/procfs.sh
index 6b445b0d7e48..a59235c6d521 100755
--- a/tools/test/stress2/misc/procfs.sh
+++ b/tools/test/stress2/misc/procfs.sh
@@ -56,7 +56,8 @@ else
else
# The test: Parallel mount and unmounts
- for i in `jot 128`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
m=$1
mount -t procfs proc ${mntpoint}$m
while mount | grep -qw $mntpoint$m; do
diff --git a/tools/test/stress2/misc/procfs3.sh b/tools/test/stress2/misc/procfs3.sh
index c9c4820adbff..30bcc8b3cd62 100755
--- a/tools/test/stress2/misc/procfs3.sh
+++ b/tools/test/stress2/misc/procfs3.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# procfs(5) test scenario.
+# procfs(4) test scenario.
# "panic: wchan 0xc10a4f68 has no wmesg" seen
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
diff --git a/tools/test/stress2/misc/procfs4.sh b/tools/test/stress2/misc/procfs4.sh
index ffa812a7f73d..18e5c0a6f803 100755
--- a/tools/test/stress2/misc/procfs4.sh
+++ b/tools/test/stress2/misc/procfs4.sh
@@ -68,6 +68,7 @@ EOF
#define MAXRUN 1200
#define PARALLEL 10
+static int debug; /* Set to 1 for debug output */
char *files[] = {
"cmdline",
"ctl",
@@ -116,10 +117,8 @@ test(void)
close(fd);
}
kill(p, SIGHUP);
-#if 0
- if (opens < 1)
- fprintf(stderr, "Warn %d open(s) for pid %d\n", opens, getpid());
-#endif
+ if (debug != 0 && opens == 0)
+ fprintf(stderr, "No ioctl() calls succeeded.\n");
}
for (i = 0; i < 64; i++)
diff --git a/tools/test/stress2/misc/procfs6.sh b/tools/test/stress2/misc/procfs6.sh
index b4cc4c1eb4c0..24ea6ae47588 100755
--- a/tools/test/stress2/misc/procfs6.sh
+++ b/tools/test/stress2/misc/procfs6.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/procstat.sh b/tools/test/stress2/misc/procstat.sh
index 91a846ba91ee..c760583c8bbd 100755
--- a/tools/test/stress2/misc/procstat.sh
+++ b/tools/test/stress2/misc/procstat.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/procstat2.sh b/tools/test/stress2/misc/procstat2.sh
index 712f53c11b3b..758b684dbf0a 100755
--- a/tools/test/stress2/misc/procstat2.sh
+++ b/tools/test/stress2/misc/procstat2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/pthread10.sh b/tools/test/stress2/misc/pthread10.sh
new file mode 100755
index 000000000000..ddeab0f9bb57
--- /dev/null
+++ b/tools/test/stress2/misc/pthread10.sh
@@ -0,0 +1,106 @@
+#!/bin/sh
+
+# Original test scenario by nabijaczleweli@nabijaczleweli.xyz:
+# Bug 283101 - pthread_cancel() doesn't cancel a thread that's currently in pause()
+# Fixed by: 9f78c837d94f check_cancel: when in_sigsuspend, send SIGCANCEL unconditionally
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static void *
+thread(void *arg __unused)
+{
+ for(;;) {
+ pause();
+ printf("woke up from pause\n");
+ }
+}
+
+static void
+thread_cancel_and_join(pthread_t ptid)
+{
+ void *status = NULL;
+
+ if (pthread_cancel(ptid)) {
+ printf("pthread_cancel() failed\n");
+ exit(1);
+ }
+
+ (void) pthread_join(ptid, &status);
+ int error = (int)(uintptr_t)status;
+
+ if (error) {
+ if (status == PTHREAD_CANCELED) {
+ printf("pthread_cancel() succeeded\n");
+ } else {
+ printf("pthread_join() error (not PTHREAD_CANCELED)\n");
+ exit(1);
+ }
+ }
+}
+
+int
+main(void)
+{
+ // Empirically, I've noticed that either the hang occurs somewhere between
+ // 10 and 500 iterations, or it runs infinitely without ever hanging.
+ // Therefore, stopping at 500th iteration, and looping from a shell script.
+
+ // For quick results (usually under 10 minutes), invoke "./run" from a dozen
+ // consoles or GNU screen windows in parallel.
+
+ pid_t pid = getpid();
+
+ for (uint64_t iteration = 1; iteration <= 500; ++iteration) {
+ printf("PID %d, iteration %lu...", pid, iteration);
+
+ pthread_t ptid;
+ int err;
+
+ err = pthread_create(&ptid, NULL, thread, NULL);
+
+ if (err) {
+ printf("pthread_create() failed with error: %d\n", err);
+ return 1;
+ }
+
+ thread_cancel_and_join(ptid);
+
+ printf("OK\n");
+
+ // Tiny sleep
+ usleep(20000);
+ }
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O2 /tmp/$prog.c -lpthread || exit 1
+(cd ../testcases/swap; ./swap -t 3m -i 20 > /dev/null) &
+sleep 5
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 180 ]; do
+ /tmp/$prog > /dev/null & pid=$!
+ t1=`date +%s`
+ while kill -0 $pid 2> /dev/null; do
+ if [ $((`date +%s` - t1)) -gt 180 ]; then
+ ps -lH $pid
+# exit 1 # For DEBUG
+ kill -9 $pid; s=1
+ echo fail
+ break 2
+ else
+ sleep 1
+ fi
+ done
+ wait $pid; s=$?
+ [ $s -ne 0 ] && break
+done
+while pkill swap; do :; done
+wait
+rm -f /tmp/$prog /tmp/$prog.c
+exit $s
diff --git a/tools/test/stress2/misc/ptrace10.sh b/tools/test/stress2/misc/ptrace10.sh
index c2dec736a240..205efe2cc27a 100755
--- a/tools/test/stress2/misc/ptrace10.sh
+++ b/tools/test/stress2/misc/ptrace10.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Mark Johnston <markj@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/ptrace11.sh b/tools/test/stress2/misc/ptrace11.sh
index 9fbd44481624..f5231bc1850f 100755
--- a/tools/test/stress2/misc/ptrace11.sh
+++ b/tools/test/stress2/misc/ptrace11.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/ptrace12.sh b/tools/test/stress2/misc/ptrace12.sh
index b7381c4937e1..b80ba69b1327 100755
--- a/tools/test/stress2/misc/ptrace12.sh
+++ b/tools/test/stress2/misc/ptrace12.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/ptrace9.sh b/tools/test/stress2/misc/ptrace9.sh
index ac1329fd1a2a..ffd5fce0d646 100755
--- a/tools/test/stress2/misc/ptrace9.sh
+++ b/tools/test/stress2/misc/ptrace9.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2016 Mark Johnston <markj@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/pts2.sh b/tools/test/stress2/misc/pts2.sh
index 84f7bbd78255..32adb98f2cfe 100755
--- a/tools/test/stress2/misc/pts2.sh
+++ b/tools/test/stress2/misc/pts2.sh
@@ -40,11 +40,11 @@ sed '1,/^EOF/d' < $here/$0 > pts2.c
mycc -o pts2 -Wall -Wextra -O2 pts2.c || exit 1
rm -f pts2.c
-pts=`vmstat -m | grep pts | awk '{print $2}'`
+pts=`vmstat -m | awk '/ pts / {print $2}'`
for i in `jot 10`; do
/tmp/pts2
done
-new=`vmstat -m | grep pts | awk '{print $2}'`
+new=`vmstat -m | awk '/ pts / {print $2}'`
s=0
[ $((new - pts)) -gt 1 ] && { s=1; echo "Leaked $((new - pts)) pts."; }
diff --git a/tools/test/stress2/misc/pts3.sh b/tools/test/stress2/misc/pts3.sh
index b398e92916af..ebd854b82bf7 100755
--- a/tools/test/stress2/misc/pts3.sh
+++ b/tools/test/stress2/misc/pts3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/quota12.sh b/tools/test/stress2/misc/quota12.sh
index 2b2094f22460..cd0855b07584 100755
--- a/tools/test/stress2/misc/quota12.sh
+++ b/tools/test/stress2/misc/quota12.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/quota5.sh b/tools/test/stress2/misc/quota5.sh
index 050ea4a822d9..ee69dac4be01 100755
--- a/tools/test/stress2/misc/quota5.sh
+++ b/tools/test/stress2/misc/quota5.sh
@@ -39,6 +39,6 @@ edquota -g -f /tmp -e /tmp:1500000:1400000:200000:180000 $testuser
quotaon /tmp
su $testuser -c "export runRUNTIME=60m; cd ../testcases/mkdir; \
- ./mkdir -t 30m -i 200 -v -v"
+ ./mkdir -t 10m -i 200 -v -v"
quotaoff /tmp
diff --git a/tools/test/stress2/misc/r335171.sh b/tools/test/stress2/misc/r335171.sh
index 2d2e9ad72fee..09a11f304198 100755
--- a/tools/test/stress2/misc/r335171.sh
+++ b/tools/test/stress2/misc/r335171.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/radix.sh b/tools/test/stress2/misc/radix.sh
index fa85512c79c5..b102c09aca92 100755
--- a/tools/test/stress2/misc/radix.sh
+++ b/tools/test/stress2/misc/radix.sh
@@ -46,14 +46,14 @@ mycc -o radix -Wall -Wextra radix.c || exit 1
rm -f radix.c
cd $odir
-set -e
+set -u
trap "rm -f rendezvous" EXIT INT
parallel=1
usermem=`sysctl hw.usermem | sed 's/.* //'`
pagesize=`pagesize`
start=`date +%s`
while true; do
- timeout 2m /tmp/radix $parallel > $log; s=$?
+ timeout 20m /tmp/radix $parallel > $log; s=$?
[ $s -eq 124 ] && { echo "Timed out"; break; }
[ $s -ne 0 ] && cat $log
used=`awk '{print $4}' < $log`
@@ -63,7 +63,7 @@ while true; do
[ $parallel -eq 1 ] &&
parallel=$((usermem / pagesize / used))
parallel=$((parallel + 1))
- echo "`date +%T` parallel=$parallel" # XXX
+ [ $parallel -gt 10 ] && parallel=10
done
cat /tmp/radix.log
diff --git a/tools/test/stress2/misc/random.sh b/tools/test/stress2/misc/random.sh
index 04a0075d0c2c..100d9d9b88d0 100755
--- a/tools/test/stress2/misc/random.sh
+++ b/tools/test/stress2/misc/random.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/rangelocks.sh b/tools/test/stress2/misc/rangelocks.sh
new file mode 100755
index 000000000000..fa855359d72b
--- /dev/null
+++ b/tools/test/stress2/misc/rangelocks.sh
@@ -0,0 +1,194 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Range lock test scenario suggestion by kib@
+
+. ../default.cfg
+
+set -u
+prog=$(basename "$0" .sh)
+dir=/tmp
+odir=`pwd`
+cd $dir
+sed '1,/^EOF/d' < $odir/$0 > $dir/$prog.c
+mycc -o $prog -Wall -Wextra -O2 -g $prog.c || exit 1
+rm -f $prog.c
+cd $odir
+
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+set -e
+mdconfig -a -t swap -s 6g -u $mdstart
+newfs $newfs_flags -n /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+set +e
+wd="$mntpoint/$prog.dir"
+mkdir -p $wd
+dd if=/dev/zero of=$wd/file bs=1m count=5k status=none
+
+[ `jot -r 1 1 100` -le 25 ] &&
+ ../testcases/swap/swap -t 10m -i 20 > /dev/null 2>&1 &
+cd $wd
+/tmp/$prog $wd/file; s=$?
+cd $odir
+while pkill swap; do :; done
+wait
+
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -rf /tmp/$prog $wd
+exit $s
+
+EOF
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <machine/atomic.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+#define DONE 1
+#define MAXBLK 10240
+//#define MAXPROC 32
+#define MAXPROC 1024
+#define MAXSIZ (5LL * 1024 * 1024 *1024)
+#define RUNTIME (5 * 60)
+#define SYNC 0
+
+static volatile u_int *share;
+static int parallel;
+
+static char *file;
+
+static off_t
+newpos(int lng)
+{
+ off_t p;
+
+ do {
+ arc4random_buf(&p, sizeof(p));
+ p = p & 0xfffffff;
+ } while (p + lng > MAXSIZ);
+ return (p);
+}
+
+static void
+test(int indx, int num)
+{
+ off_t pos;
+ ssize_t i, l, r;
+ time_t start;
+ int fd, n;
+ char *buf;
+
+ atomic_add_int(&share[SYNC], 1);
+ while (share[SYNC] != (unsigned int)parallel)
+ sched_yield();
+
+ if ((buf = malloc(MAXBLK)) == NULL)
+ err(1, "malloc");
+ n = 0;
+ start = time(NULL);
+ while (share[DONE] != (unsigned int)parallel) {
+ setproctitle("test(%d) num %d, n %d", indx, num, n);
+ if ((fd = open(file, O_RDWR)) == -1)
+ err(1, "open(%s)", file);
+
+ for (i = 0; i < arc4random() % 512; i++) {
+ if (arc4random() % 100 < 50) {
+ l = arc4random() % MAXBLK + 1;
+ pos = newpos(l);
+ if (lseek(fd, pos, SEEK_SET) == -1)
+ err(1, "lseek");
+ if ((r = read(fd, buf, l)) != l) {
+ warn("read %jd @ %jd returned %zd\n", (intmax_t)l, (intmax_t)pos, r);
+ goto done;
+ }
+ }
+
+ l = arc4random() % MAXBLK + 1;
+ pos = newpos(l);
+ if (lseek(fd, pos, SEEK_SET) == -1)
+ err(1, "lseek");
+ if ((r = write(fd, buf, l)) != l) {
+ warn("write returned %zd\n", r);
+ goto done;
+ }
+ }
+
+ close(fd);
+ if (n++ == 0)
+ atomic_add_int(&share[DONE], 1);
+ if (time(NULL) - start >= RUNTIME * 4) {
+ fprintf(stderr, "test(%d), %d Timed out\n", indx, num);
+ break;
+ }
+ }
+done:
+ if (n++ == 0)
+ atomic_add_int(&share[DONE], 1);
+
+ _exit(0);
+}
+
+void
+setup(void)
+{
+
+ parallel = arc4random() % MAXPROC + 1;
+}
+
+int
+main(int argc, char *argv[])
+{
+ size_t len;
+ time_t start;
+ int e, i, n, *pids, status;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <file>\n", argv[0]);
+ _exit(1);
+ }
+ e = 0;
+ file = argv[1];
+ len = PAGE_SIZE;
+ if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
+ err(1, "mmap");
+
+ n = 0;
+ start = time(NULL);
+ while ((time(NULL) - start) < RUNTIME && e == 0) {
+ setup();
+
+ pids = malloc(sizeof(pid_t) * parallel);
+ share[SYNC] = share[DONE] = 0;
+ for (i = 0; i < parallel; i++) {
+ if ((pids[i] = fork()) == 0)
+ test(i, n);
+ }
+ for (i = 0; i < parallel; i++) {
+ if (waitpid(pids[i], &status, 0) != pids[i])
+ err(1, "waitpid %d", pids[i]);
+ e += status == 0 ? 0 : 1;
+ }
+ n++;
+ n = n % 10;
+ free(pids);
+ }
+
+ return (e);
+}
diff --git a/tools/test/stress2/misc/rangelocks2.sh b/tools/test/stress2/misc/rangelocks2.sh
new file mode 100755
index 000000000000..2df4cf346bc8
--- /dev/null
+++ b/tools/test/stress2/misc/rangelocks2.sh
@@ -0,0 +1,178 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+. ../default.cfg
+
+set -u
+prog=$(basename "$0" .sh)
+dir=/tmp
+odir=`pwd`
+cd $dir
+sed '1,/^EOF/d' < $odir/$0 > $dir/$prog.c
+mycc -o $prog -Wall -Wextra -O2 -g $prog.c || exit 1
+rm -f $prog.c
+cd $odir
+
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+set -e
+mdconfig -a -t swap -s 6g -u $mdstart
+newfs $newfs_flags -n /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+set +e
+wd="$mntpoint/$prog.dir"
+mkdir -p $wd
+dd if=/dev/zero of=$wd/file bs=1m count=5k status=none
+
+[ `jot -r 1 1 100` -le 25 ] &&
+ ../testcases/swap/swap -t 10m -i 20 > /dev/null 2>&1 &
+cd $wd
+touch $wd/out
+/tmp/$prog $wd/file $wd/out; s=$?
+cd $odir
+while pkill swap; do :; done
+wait
+
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -rf /tmp/$prog $wd
+exit $s
+
+EOF
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+#include <machine/atomic.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+#define DONE 1
+#define MAXBLK (100 * 1024 * 1024)
+#define MAXPROC 32
+#define MAXSIZ (5LL * 1024 * 1024 *1024)
+#define RUNTIME (5 * 60)
+#define SYNC 0
+
+static volatile u_int *share;
+static int parallel;
+
+static char *file, *file2;
+
+static off_t
+newpos(int lng)
+{
+ off_t p;
+
+ do {
+ arc4random_buf(&p, sizeof(p));
+ p = p & 0xfffffff;
+ } while (p + lng > MAXSIZ);
+ return (p);
+}
+
+static void
+test(int indx, int num)
+{
+ off_t pos, pos2;
+ ssize_t i, l;
+ time_t start;
+ int fd, fd2, n;
+
+ atomic_add_int(&share[SYNC], 1);
+ while (share[SYNC] != (unsigned int)parallel)
+ sched_yield();
+
+ n = 0;
+ start = time(NULL);
+ while (share[DONE] != (unsigned int)parallel) {
+ setproctitle("test(%d) num %d, n %d", indx, num, n);
+ if ((fd = open(file, O_RDWR)) == -1)
+ err(1, "open(%s)", file);
+ if ((fd2 = open(file2, O_RDWR)) == -1)
+ err(1, "open(%s)", file2);
+
+ for (i = 0; i < arc4random() % 512; i++) {
+ l = arc4random() % MAXBLK + 1;
+ pos = newpos(l);
+ pos2 = newpos(l);
+ if (copy_file_range(fd, &pos, fd2, &pos2, l, 0) == -1)
+ err(1, "copy_file_range()");
+ }
+
+ close(fd2);
+ close(fd);
+ if (n++ == 0)
+ atomic_add_int(&share[DONE], 1);
+ if (time(NULL) - start >= RUNTIME * 4) {
+ fprintf(stderr, "test(%d), %d Timed out\n", indx, num);
+ break;
+ }
+ }
+ if (n++ == 0)
+ atomic_add_int(&share[DONE], 1);
+
+ _exit(0);
+}
+
+void
+setup(void)
+{
+
+ parallel = arc4random() % MAXPROC + 1;
+}
+
+int
+main(int argc, char *argv[])
+{
+ size_t len;
+ time_t start;
+ int e, i, n, *pids, status;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s <in file> <out file>\n", argv[0]);
+ _exit(1);
+ }
+ e = 0;
+ file = argv[1];
+ file2 = argv[2];
+ len = PAGE_SIZE;
+ if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
+ err(1, "mmap");
+
+ n = 0;
+ start = time(NULL);
+ while ((time(NULL) - start) < RUNTIME && e == 0) {
+ setup();
+
+ pids = malloc(sizeof(pid_t) * parallel);
+ share[SYNC] = share[DONE] = 0;
+ for (i = 0; i < parallel; i++) {
+ if ((pids[i] = fork()) == 0)
+ test(i, n);
+ }
+ for (i = 0; i < parallel; i++) {
+ if (waitpid(pids[i], &status, 0) != pids[i])
+ err(1, "waitpid %d", pids[i]);
+ e += status == 0 ? 0 : 1;
+ }
+ n++;
+ n = n % 10;
+ free(pids);
+ }
+
+ return (e);
+}
diff --git a/tools/test/stress2/misc/rdgsbase.sh b/tools/test/stress2/misc/rdgsbase.sh
index 66a44592d419..3c5597e3f9c2 100755
--- a/tools/test/stress2/misc/rdgsbase.sh
+++ b/tools/test/stress2/misc/rdgsbase.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2017 Konstantin Belousov <kib@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/rdwr.sh b/tools/test/stress2/misc/rdwr.sh
index c77c955dc210..893056558560 100755
--- a/tools/test/stress2/misc/rdwr.sh
+++ b/tools/test/stress2/misc/rdwr.sh
@@ -28,6 +28,11 @@
# Test with read/write length of INT_MAX (i386) or INT_MAX+1 (amd64)
+# Seen:
+# rdwr: readv(). Expected 2147483648 (80000000), got -2147483648 (ffffffff80000000) bytes: No error: 0
+# rdwr: writev(). Expected 2147483648 (80000000), got -2147483648 (ffffffff80000000) bytes: No error: 0
+# Fixed by: 78101d437a92
+
. ../default.cfg
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
@@ -61,11 +66,22 @@ EOF
#include <fcntl.h>
#include <unistd.h>
+static int s;
+
+static void
+er(char * syscall, size_t len, ssize_t ret)
+{
+ warn("%8s. Expected %zu (%zx), got %zd (%zx) bytes",
+ syscall, len, len, ret, ret);
+ s=1;
+}
+
int
main(int argc, char **argv)
{
int fd1, fd2;
size_t len;
+ ssize_t r;
void *p;
struct iovec iov;
@@ -85,34 +101,34 @@ main(int argc, char **argv)
MAP_FAILED)
err(1, "mmap");
- if (read(fd2, p, len) != len)
- err(1, "read");
+ if ((r = read(fd2, p, len)) != len)
+ er("read()", len, r);
- if (write(fd1, p, len) != len)
- err(1, "write");
+ if ((r = write(fd1, p, len)) != len)
+ er("write()", len, r);
- if (pread(fd2, p, len, 0) != len)
- err(1, "pread");
+ if ((r = pread(fd2, p, len, 0)) != len)
+ er("pread()", len, r);
- if (pwrite(fd1, p, len, 0) != len)
- err(1, "pwrite");
+ if ((r = pwrite(fd1, p, len, 0)) != len)
+ er("pwrite()", len, r);
iov.iov_base = p;
iov.iov_len = len;
- if (readv(fd2, &iov, 1) != len)
- err(1, "readv");
+ if ((r = readv(fd2, &iov, 1)) != len)
+ er("readv()", len, r);
- if (writev(fd1, &iov, 1) != len)
- err(1, "writev");
+ if ((r = writev(fd1, &iov, 1)) != len)
+ er("writev()", len, r);
- if (preadv(fd2, &iov, 1, 0) != len)
- err(1, "preadv");
+ if ((r = preadv(fd2, &iov, 1, 0)) != len)
+ er("preadv()", len, r);
- if (pwritev(fd1, &iov, 1, 0) != len)
- err(1, "pwritev");
+ if ((r = pwritev(fd1, &iov, 1, 0)) != len)
+ er("pwritev()", len, r);
close(fd1);
close(fd2);
- return (0);
+ return (s);
}
diff --git a/tools/test/stress2/misc/readdir.sh b/tools/test/stress2/misc/readdir.sh
index 8616a8a40206..425295631181 100755
--- a/tools/test/stress2/misc/readdir.sh
+++ b/tools/test/stress2/misc/readdir.sh
@@ -45,19 +45,19 @@ mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint
mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
mount -t tmpfs tmpfs $mntpoint
-echo "Testing tmpfs(5)"
+echo "Testing tmpfs(4)"
cp -a /usr/include $mntpoint
/tmp/readdir $mntpoint
umount $mntpoint
-echo "Testing fdescfs(5)"
+echo "Testing fdescfs(4)"
kldstat -v | grep -q fdescfs || { kldload fdescfs.ko; loaded=1; }
mount -t fdescfs null /dev/fd
/tmp/readdir /dev/fd
umount /dev/fd
[ $unload ] && kldunload fdescfs.ko
-echo "Testing procfs(5)"
+echo "Testing procfs(4)"
mount -t procfs procfs $mntpoint
/tmp/readdir $mntpoint
umount $mntpoint
@@ -89,7 +89,7 @@ umount $mntpoint
mdconfig -d -u $mdstart
mount -t nullfs /bin $mntpoint
-echo "Testing nullfs(5)"
+echo "Testing nullfs(4)"
/tmp/readdir $mntpoint
umount $mntpoint
diff --git a/tools/test/stress2/misc/reaper.sh b/tools/test/stress2/misc/reaper.sh
index 1d2d5ade8c6e..5ad19a55d60b 100755
--- a/tools/test/stress2/misc/reaper.sh
+++ b/tools/test/stress2/misc/reaper.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/reaper2.sh b/tools/test/stress2/misc/reaper2.sh
index 8290e38d34e4..ee9cf927f1d9 100755
--- a/tools/test/stress2/misc/reaper2.sh
+++ b/tools/test/stress2/misc/reaper2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
@@ -65,8 +65,9 @@ test(void) {
struct procctl_reaper_kill killemall;
pid_t pid;
time_t start;
- int data[20], e, n, m;
+ int data[20], debug, e, n, m;
+ debug = 0; /* set to 1 for debug output */
n = m = 0;
if (procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL) == -1)
err(EXIT_FAILURE, "Fail to acquire the reaper");
@@ -94,9 +95,8 @@ test(void) {
if (waitpid(pid, NULL, 0) != pid)
err(1, "waitpid()");
}
-#if defined(DEBUG)
- fprintf(stderr, "n = %d out of %d\n", n, m);
-#endif
+ if (debug == 1)
+ fprintf(stderr, "n = %d out of %d\n", n, m);
_exit(0);
}
diff --git a/tools/test/stress2/misc/reaper3.sh b/tools/test/stress2/misc/reaper3.sh
index fdf715fa7b0b..59012d2c45ca 100755
--- a/tools/test/stress2/misc/reaper3.sh
+++ b/tools/test/stress2/misc/reaper3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
@@ -59,14 +59,13 @@ flip(void *ap, size_t len)
{
unsigned char *cp;
int byte;
- unsigned char bit, buf, mask, old __unused;
+ unsigned char bit, buf, mask;
cp = (unsigned char *)ap;
byte = random_long(0, len);
bit = random_long(0,7);
mask = ~(1 << bit);
buf = cp[byte];
- old = cp[byte];
buf = (buf & mask) | (~buf & ~mask);
cp[byte] = buf;
}
@@ -86,8 +85,9 @@ test(void) {
struct procctl_reaper_kill killemall;
pid_t pid;
time_t start;
- int data[20], e, n, m;
+ int data[20], debug, e, n, m;
+ debug = 0; /* set to 1 for debug output */
n = m = 0;
if (procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL) == -1)
err(EXIT_FAILURE, "Fail to acquire the reaper");
@@ -118,9 +118,8 @@ test(void) {
if (waitpid(pid, NULL, 0) != pid)
err(1, "waitpid()");
}
-#if defined(DEBUG)
- fprintf(stderr, "n = %d out of %d\n", n, m);
-#endif
+ if (debug == 1)
+ fprintf(stderr, "n = %d out of %d\n", n, m);
_exit(0);
}
diff --git a/tools/test/stress2/misc/reaper4.sh b/tools/test/stress2/misc/reaper4.sh
index bf400e396e63..0fdb3f75ccff 100755
--- a/tools/test/stress2/misc/reaper4.sh
+++ b/tools/test/stress2/misc/reaper4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
@@ -59,14 +59,13 @@ flip(void *ap, size_t len)
{
unsigned char *cp;
int byte;
- unsigned char bit, buf, mask, old __unused;
+ unsigned char bit, buf, mask;
cp = (unsigned char *)ap;
byte = random_long(0, len);
bit = random_long(0,7);
mask = ~(1 << bit);
buf = cp[byte];
- old = cp[byte];
buf = (buf & mask) | (~buf & ~mask);
cp[byte] = buf;
}
@@ -85,8 +84,9 @@ test(void) {
struct procctl_reaper_kill killemall;
pid_t pid;
time_t start;
- int data[20], e, n, m;
+ int data[20], debug, e, n, m;
+ debug = 0; /* set to 1 for debug output */
n = m = 0;
if (procctl(P_PID, getpid(), PROC_REAP_ACQUIRE, NULL) == -1)
err(EXIT_FAILURE, "Fail to acquire the reaper");
@@ -117,9 +117,8 @@ test(void) {
if (waitpid(pid, NULL, 0) != pid)
err(1, "waitpid()");
}
-#if defined(DEBUG)
- fprintf(stderr, "n = %d out of %d\n", n, m);
-#endif
+ if (debug == 1)
+ fprintf(stderr, "n = %d out of %d\n", n, m);
_exit(0);
}
diff --git a/tools/test/stress2/misc/reaper5.sh b/tools/test/stress2/misc/reaper5.sh
index eec58c36713a..944475479e2c 100755
--- a/tools/test/stress2/misc/reaper5.sh
+++ b/tools/test/stress2/misc/reaper5.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/rename14.sh b/tools/test/stress2/misc/rename14.sh
index 83612a2632df..cf7f5f6d8148 100755
--- a/tools/test/stress2/misc/rename14.sh
+++ b/tools/test/stress2/misc/rename14.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
@@ -33,6 +33,9 @@
# Based on a syzkaller scenario reported by tuexen@freebsd.org
+# "panic: journal_jremref: Lost inodedep":
+# https://people.freebsd.org/~pho/stress/log/log0279.txt
+
. ../default.cfg
[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
diff --git a/tools/test/stress2/misc/rename15.sh b/tools/test/stress2/misc/rename15.sh
index aa884e045010..0831343101e5 100755
--- a/tools/test/stress2/misc/rename15.sh
+++ b/tools/test/stress2/misc/rename15.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/rename16.sh b/tools/test/stress2/misc/rename16.sh
new file mode 100755
index 000000000000..09e796299794
--- /dev/null
+++ b/tools/test/stress2/misc/rename16.sh
@@ -0,0 +1,261 @@
+#!/bin/sh
+
+# Copy of suj30.sh but with SU instead of SUJ
+
+# Rename test scenario by Andrey Zonov <zont@FreeBSD.org>
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+set -u
+prog=$(basename "$0" .sh)
+here=`pwd`
+log=/tmp/$prog.sh.log
+cd /tmp
+sed '1,/^EOF/d' < $here/$0 > $prog.c
+mycc -o $prog -Wall -Wextra -O2 $prog.c -lpthread
+rm -f $prog.c
+
+mount | grep "on $mntpoint " | grep -q md$mdstart && umount $mntpoint
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+
+mdconfig -a -t swap -s 8g -u $mdstart
+newfs -U md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+chmod 777 $mntpoint
+
+t=`date +%s`
+/tmp/$prog $mntpoint/test-0 100000
+t=$((`date +%s` - t))
+[ $t -gt 60 ] && n=20000 || n=100000
+
+for i in `jot 10`; do
+ /tmp/$prog $mntpoint/test-$i $n &
+done
+wait
+
+while mount | grep -q $mntpoint; do
+ umount $mntpoint || sleep 1
+done
+fsck -fy /dev/md$mdstart > $log
+grep -q "WAS MODIFIED" $log && s=1 || s=0
+mdconfig -d -u $mdstart
+rm -f /tmp/$prog $log
+exit $s
+EOF
+/*
+ * Andrey Zonov (c) 2012
+ *
+ * compile as `cc -o rename rename.c -lpthread'
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/queue.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <pthread.h>
+#ifdef __FreeBSD__
+#include <pthread_np.h>
+#define __NP__
+#endif
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+
+#define LOCK(x) pthread_mutex_lock(&x.mtx)
+#define UNLOCK(x) pthread_mutex_unlock(&x.mtx)
+#define SIGNAL(x) pthread_cond_signal(&x.wait)
+#define WAIT(x) pthread_cond_wait(&x.wait, &x.mtx)
+
+int max;
+int exited;
+char *dirname1;
+char *dirname2;
+
+struct file {
+ char *name;
+ STAILQ_ENTRY(file) next;
+};
+
+struct files {
+ pthread_mutex_t mtx;
+ pthread_cond_t wait;
+ STAILQ_HEAD(, file) list;
+};
+
+static struct files newfiles;
+static struct files renamedfiles;
+
+void *loop_create(void *arg __unused);
+void *loop_rename(void *arg __unused);
+void *loop_unlink(void *arg __unused);
+
+int
+main(int argc, char **argv)
+{
+ int i;
+ int rc;
+ pthread_t tid[3];
+
+ if (argc != 3)
+ errx(1, "usage: pthread_count <dirname> <max>");
+
+ asprintf(&dirname1, "%s.1", argv[1]);
+ asprintf(&dirname2, "%s.2", argv[1]);
+ if (mkdir(dirname1, 0755) == -1)
+ err(1, "mkdir(%s)", dirname1);
+ if (mkdir(dirname2, 0755) == -1)
+ err(1, "mkdir(%s)", dirname2);
+ max = atoi(argv[2]);
+
+ STAILQ_INIT(&newfiles.list);
+ STAILQ_INIT(&renamedfiles.list);
+
+ rc = pthread_mutex_init(&newfiles.mtx, NULL);
+ if (rc != 0)
+ errc(1, rc, "pthread_mutex_init()");
+ rc = pthread_cond_init(&newfiles.wait, NULL);
+ if (rc != 0)
+ errc(1, rc, "pthread_cond_init()");
+ rc = pthread_mutex_init(&renamedfiles.mtx, NULL);
+ if (rc != 0)
+ errc(1, rc, "pthread_mutex_init()");
+ rc = pthread_cond_init(&renamedfiles.wait, NULL);
+ if (rc != 0)
+ errc(1, rc, "pthread_cond_init()");
+
+ rc = pthread_create(&tid[0], NULL, loop_create, NULL);
+ if (rc != 0)
+ errc(1, rc, "pthread_create()");
+ rc = pthread_create(&tid[1], NULL, loop_rename, NULL);
+ if (rc != 0)
+ errc(1, rc, "pthread_create()");
+ rc = pthread_create(&tid[2], NULL, loop_unlink, NULL);
+ if (rc != 0)
+ errc(1, rc, "pthread_create()");
+
+ for (i = 0; i < 3; i++) {
+ rc = pthread_join(tid[i], NULL);
+ if (rc != 0)
+ errc(1, rc, "pthread_join(%d)", i);
+ }
+
+ rc = pthread_mutex_destroy(&newfiles.mtx);
+ if (rc != 0)
+ errc(1, rc, "pthread_mutex_destroy(newfiles)");
+ rc = pthread_cond_destroy(&newfiles.wait);
+ if (rc != 0)
+ errc(1, rc, "pthread_cond_destroy(newfiles)");
+ rc = pthread_mutex_destroy(&renamedfiles.mtx);
+ if (rc != 0)
+ errc(1, rc, "pthread_mutex_destroy(renamedfiles)");
+ rc = pthread_cond_destroy(&renamedfiles.wait);
+ if (rc != 0)
+ errc(1, rc, "pthread_cond_destroy(renamedfiles)");
+ rmdir(dirname1);
+ rmdir(dirname2);
+ free(dirname1);
+ free(dirname2);
+
+ exit(0);
+}
+
+void *
+loop_create(void *arg __unused)
+{
+ int i;
+ struct file *file;
+
+#ifdef __NP__
+ pthread_set_name_np(pthread_self(), __func__);
+#endif
+
+ for (i = 0; i < max; i++) {
+ file = malloc(sizeof(*file));
+ asprintf(&file->name, "%s/filename_too-long:%d", dirname1, i);
+ if (mkdir(file->name, 0666) == -1) {
+ warn("mkdir(%s)", file->name);
+ free(file->name);
+ free(file);
+ break;
+ }
+ LOCK(newfiles);
+ STAILQ_INSERT_TAIL(&newfiles.list, file, next);
+ UNLOCK(newfiles);
+ SIGNAL(newfiles);
+ }
+ exited = 1;
+ SIGNAL(newfiles);
+ pthread_exit(NULL);
+}
+
+void *
+loop_rename(void *arg __unused)
+{
+ char *filename, *newname;
+ struct file *file;
+
+#ifdef __NP__
+ pthread_set_name_np(pthread_self(), __func__);
+#endif
+
+ for ( ;; ) {
+ LOCK(newfiles);
+ while (STAILQ_EMPTY(&newfiles.list) && exited < 1)
+ WAIT(newfiles);
+ if (STAILQ_EMPTY(&newfiles.list) && exited == 1) {
+ UNLOCK(newfiles);
+ break;
+ }
+ file = STAILQ_FIRST(&newfiles.list);
+ STAILQ_REMOVE_HEAD(&newfiles.list, next);
+ UNLOCK(newfiles);
+ filename = strrchr(file->name, '/');
+ asprintf(&newname, "%s/%s", dirname2, filename);
+ if (rename(file->name, newname) == -1)
+ err(1, "rename(%s, %s)", file->name, newname);
+ free(file->name);
+ file->name = newname;
+ LOCK(renamedfiles);
+ STAILQ_INSERT_TAIL(&renamedfiles.list, file, next);
+ UNLOCK(renamedfiles);
+ SIGNAL(renamedfiles);
+ }
+ exited = 2;
+ SIGNAL(renamedfiles);
+ pthread_exit(NULL);
+}
+
+void *
+loop_unlink(void *arg __unused)
+{
+ struct file *file;
+
+#ifdef __NP__
+ pthread_set_name_np(pthread_self(), __func__);
+#endif
+
+ for ( ;; ) {
+ LOCK(renamedfiles);
+ while (STAILQ_EMPTY(&renamedfiles.list) && exited < 2)
+ WAIT(renamedfiles);
+ if (STAILQ_EMPTY(&renamedfiles.list) && exited == 2) {
+ UNLOCK(renamedfiles);
+ break;
+ }
+ file = STAILQ_FIRST(&renamedfiles.list);
+ STAILQ_REMOVE_HEAD(&renamedfiles.list, next);
+ UNLOCK(renamedfiles);
+ rmdir(file->name);
+ free(file->name);
+ free(file);
+ }
+ pthread_exit(NULL);
+}
diff --git a/tools/test/stress2/misc/rename3.sh b/tools/test/stress2/misc/rename3.sh
index c7ce91f0d359..aa4a3754bfab 100755
--- a/tools/test/stress2/misc/rename3.sh
+++ b/tools/test/stress2/misc/rename3.sh
@@ -36,7 +36,8 @@
# Test scenario by Tor Egge
root=/tmp
-for i in `jot 10000`; do
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 60 ]; do
rm -rf $root/a
mkdir -p $root/a/b/c/d/e/f/g
mkdir -p $root/a/b/c/d/e/f/z
diff --git a/tools/test/stress2/misc/rename7.sh b/tools/test/stress2/misc/rename7.sh
index 9f6954916411..fdaa8f575117 100755
--- a/tools/test/stress2/misc/rename7.sh
+++ b/tools/test/stress2/misc/rename7.sh
@@ -122,7 +122,8 @@ int
main(void)
{
pid_t wpid, spid;
- int e, fd, i, status;
+ time_t start;
+ int e, fd, status;
if ((wpid = fork()) == 0)
r1();
@@ -132,7 +133,8 @@ main(void)
setproctitle("main");
e = 0;
- for (i = 0; i < 800000; i++) {
+ start = time(NULL);
+ while (time(NULL) - start < 60) {
if ((fd = open(logfile, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1)
warn("creat(%s)", logfile);
close(fd);
diff --git a/tools/test/stress2/misc/rmdir.sh b/tools/test/stress2/misc/rmdir.sh
new file mode 100755
index 000000000000..2df62a5576a8
--- /dev/null
+++ b/tools/test/stress2/misc/rmdir.sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Based on msdos11.sh
+
+. ../default.cfg
+
+set -u
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+
+cat > /tmp/$prog.c <<EOF
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdatomic.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+
+static _Atomic(int) *share;
+
+#define PARALLEL 3
+#define RUNTIME (2 * 60)
+#define SYNC 0
+
+static void
+test(void)
+{
+ time_t start;
+
+ atomic_fetch_add(&share[SYNC], 1);
+ while (share[SYNC] != PARALLEL)
+ ;
+ start = time(NULL);
+ while ((time(NULL) - start) < 30) {
+ mkdir("a", 0755);
+ rename("a", "b");
+ rmdir("b");
+ }
+
+ _exit(0);
+}
+
+int
+main(void)
+{
+ pid_t pids[PARALLEL];
+ size_t len;
+ time_t start;
+ int e, i, status;
+
+ e = 0;
+ len = PAGE_SIZE;
+ if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE,
+ MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED)
+ err(1, "mmap");
+
+ start = time(NULL);
+ while ((time(NULL) - start) < RUNTIME && e == 0) {
+ share[SYNC] = 0;
+ for (i = 0; i < PARALLEL; i++) {
+ if ((pids[i] = fork()) == 0)
+ test();
+ if (pids[i] == -1)
+ err(1, "fork()");
+ }
+ for (i = 0; i < PARALLEL; i++) {
+ if (waitpid(pids[i], &status, 0) == -1)
+ err(1, "waitpid(%d)", pids[i]);
+ if (status != 0) {
+ if (WIFSIGNALED(status))
+ fprintf(stderr,
+ "pid %d exit signal %d\n",
+ pids[i], WTERMSIG(status));
+ }
+ e += status == 0 ? 0 : 1;
+ }
+ }
+
+ return (e);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1
+
+set -e
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 512m -u $mdstart
+newfs $newfs_flags md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+set +e
+
+here=`pwd`
+(cd $here/../testcases/swap; ./swap -t 2m -i 20 -l 100 > /dev/null) &
+sleep .5
+
+cd $mntpoint
+/tmp/$prog; s=$?
+cd -
+wait
+umount $mntpoint
+fsck_ffs /dev/md$mdstart > $log 2>&1
+grep -Eq "WAS MODIFIED" $log && { cat $log; s=32; }
+mdconfig -d -u $mdstart
+rm -f /tmp/$prog /tmp/$prog.c $log
+exit $s
diff --git a/tools/test/stress2/misc/rsync.sh b/tools/test/stress2/misc/rsync.sh
new file mode 100755
index 000000000000..fa52f98c6f02
--- /dev/null
+++ b/tools/test/stress2/misc/rsync.sh
@@ -0,0 +1,49 @@
+#/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+[ -f "`which rsync`" ] || exit 0
+[ -d /usr/src/sys ] || exit 0
+
+set -eu
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 15g -u $mdstart
+newfs $newfs_flags md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+set +e
+
+mkdir -p $mntpoint/usr/src
+rsync -avrq /usr/src/sys $mntpoint/usr/src; s=$?
+if [ $s -eq 0 ]; then
+ (cd $mntpoint; umount $mntpoint > /dev/null 2>&1) # sync
+ rsync -avrq /usr/src/sys $mntpoint/usr/src; s=$?
+fi
+
+if [ $s -eq 0 ]; then
+ diff -rq /usr/src/sys $mntpoint/usr/src/sys > $log; s=$?
+ [ $s -ne 0 ] &&
+ { echo "/usr/src $mntpoint/usr/src differ!"; head -10 $log; }
+fi
+
+while mount | grep -q "on $mntpoint "; do
+ umount $mntpoint || break
+ sleep 1
+done
+if [ $s -eq 0 ]; then
+ fsck_ffs -fy /dev/md$mdstart > $log 2>&1; s=$?
+ grep -Eq "WAS MODIFIED" $log && { cat $log; s=1; }
+fi
+mdconfig -d -u $mdstart
+rm -f $log
+exit $s
diff --git a/tools/test/stress2/misc/rsync2.sh b/tools/test/stress2/misc/rsync2.sh
new file mode 100755
index 000000000000..882753fe596f
--- /dev/null
+++ b/tools/test/stress2/misc/rsync2.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# Test scenario by se@ from https://reviews.freebsd.org/D43951
+
+set -u
+MDUNIT=10
+FS=/mnt/test
+mdconfig -u $MDUNIT -t malloc -s 512m
+newfs_msdos -c 8 -F 32 /dev/md$MDUNIT
+mkdir -p $FS
+mount -t msdos /dev/md$MDUNIT $FS
+rsync -r /usr/src/lib/libsysdecode $FS
+rsync -r /usr/src/lib/libsysdecode $FS
+rsync -r /usr/src/lib/libsysdecode $FS
+umount $FS
+fsck_msdosfs -y /dev/md$MDUNIT; s=$?
+exit $s
diff --git a/tools/test/stress2/misc/rsync3.sh b/tools/test/stress2/misc/rsync3.sh
new file mode 100755
index 000000000000..1d77bdfbcaa5
--- /dev/null
+++ b/tools/test/stress2/misc/rsync3.sh
@@ -0,0 +1,43 @@
+#/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# tmpfs version of rsync.sh
+
+[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+[ -f "`which rsync`" ] || exit 0
+[ -d /usr/src/sys ] || exit 0
+
+set -eu
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mount -t tmpfs dummy $mntpoint
+set +e
+
+mkdir -p $mntpoint/usr/src
+rsync -avrq /usr/src/sys $mntpoint/usr/src; s=$?
+if [ $s -eq 0 ]; then
+ rsync -avrq /usr/src/sys $mntpoint/usr/src; s=$?
+fi
+
+if [ $s -eq 0 ]; then
+ diff -rq /usr/src/sys $mntpoint/usr/src/sys > $log; s=$?
+ [ $s -ne 0 ] &&
+ { echo "/usr/src $mntpoint/usr/src differ!"; head -10 $log; }
+fi
+
+while mount | grep -q "on $mntpoint "; do
+ umount $mntpoint || break
+ sleep 1
+done
+rm -f $log
+exit $s
diff --git a/tools/test/stress2/misc/seekhole.sh b/tools/test/stress2/misc/seekhole.sh
new file mode 100755
index 000000000000..40c397b04521
--- /dev/null
+++ b/tools/test/stress2/misc/seekhole.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# A SEEK_HOLE / SEEK_DATA test scenario
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+exp=/tmp/$prog.exp
+here=`pwd`
+log=/tmp/$prog.log
+
+cc -o /tmp/lsholes -Wall -Wextra -O2 $here/../tools/lsholes.c | exit 1
+cat > $exp <<EXP
+Min hole size is 32768, file size is 524288000.
+data #1 @ 0, size=32768)
+hole #2 @ 32768, size=32768
+data #3 @ 65536, size=32768)
+hole #4 @ 98304, size=32768
+data #5 @ 131072, size=32768)
+hole #6 @ 163840, size=524091392
+data #7 @ 524255232, size=32768)
+hole #8 @ 524288000, size=0
+EXP
+
+set -eu
+mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
+mdconfig -s 2g -u $mdstart
+newfs -U /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+set +e
+
+file=$mntpoint/file
+truncate -s 500m $file
+bs=`getconf MIN_HOLE_SIZE $file`
+printf "\001" | dd of=$file seek=$((0*bs)) bs=1 count=1 conv=notrunc status=none
+printf "\002" | dd of=$file seek=$((2*bs)) bs=1 count=1 conv=notrunc status=none
+printf "\003" | dd of=$file seek=$((4*bs)) bs=1 count=1 conv=notrunc status=none
+s1=0
+s2=0
+/tmp/lsholes $file > $log 2>&1; s1=$?
+
+cat $log
+cmp -s $exp $log || s2=1
+
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -f /tmp/lsholes $exp $log
+exit $((s1 + s2))
diff --git a/tools/test/stress2/misc/seekhole2.sh b/tools/test/stress2/misc/seekhole2.sh
new file mode 100755
index 000000000000..e3f08779061d
--- /dev/null
+++ b/tools/test/stress2/misc/seekhole2.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2025 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# A SEEK_HOLE / SEEK_DATA test scenario, FFS version
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+exp=/tmp/$prog.exp
+here=`pwd`
+log=/tmp/$prog.log
+
+cc -o /tmp/lsholes -Wall -Wextra -O2 $here/../tools/lsholes.c | exit 1
+cat > $exp <<EXP
+Min hole size is 32768, file size is 524288000.
+data #1 @ 0, size=32768)
+hole #2 @ 32768, size=32768
+data #3 @ 65536, size=32768)
+hole #4 @ 98304, size=32768
+data #5 @ 131072, size=32768)
+hole #6 @ 163840, size=524091392
+data #7 @ 524255232, size=32768)
+hole #8 @ 524288000, size=0
+EXP
+
+set -eu
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 2g -u $mdstart
+newfs $newfs_flags md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+set +e
+
+file=$mntpoint/file
+copy=$mntpoint/copy
+truncate -s 500m $file
+bs=`getconf MIN_HOLE_SIZE $file`
+printf "\001" | dd of=$file seek=$((0*bs)) bs=1 count=1 conv=notrunc status=none
+printf "\002" | dd of=$file seek=$((2*bs)) bs=1 count=1 conv=notrunc status=none
+printf "\003" | dd of=$file seek=$((4*bs)) bs=1 count=1 conv=notrunc status=none
+s1=0
+s2=0
+s3=0
+/tmp/lsholes $file > $log 2>&1; s1=$?
+
+sdiff -s $exp $log || s2=1
+
+$here/../testcases/swap/swap -t 2m -i 20 -h > /dev/null &
+sleep 10
+cp $file $copy
+while pkill swap; do :; done
+wait
+cmp $file $copy || { echo "copy error"; s3=1; }
+
+umount $mntpoint
+mdconfig -d -u $mdstart
+rm -f /tmp/lsholes $exp $log
+exit $((s1 + s2 + s3))
diff --git a/tools/test/stress2/misc/segnp.sh b/tools/test/stress2/misc/segnp.sh
index 3dbe91e04550..96f163070db7 100755
--- a/tools/test/stress2/misc/segnp.sh
+++ b/tools/test/stress2/misc/segnp.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2017 Konstantin Belousov <kib@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/segregs.sh b/tools/test/stress2/misc/segregs.sh
index 0ecc3565546a..63aa3abb5354 100755
--- a/tools/test/stress2/misc/segregs.sh
+++ b/tools/test/stress2/misc/segregs.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2017 Konstantin Belousov <kib@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/sem_post.sh b/tools/test/stress2/misc/sem_post.sh
index 2f1d7c4c004f..7fc2ffdd8778 100755
--- a/tools/test/stress2/misc/sem_post.sh
+++ b/tools/test/stress2/misc/sem_post.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/sem_timedwait.sh b/tools/test/stress2/misc/sem_timedwait.sh
index 33e5c1933f37..86c33f7e2ac3 100755
--- a/tools/test/stress2/misc/sem_timedwait.sh
+++ b/tools/test/stress2/misc/sem_timedwait.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/sem_wait.sh b/tools/test/stress2/misc/sem_wait.sh
index 6d8bc49c9199..2a4474eff4d5 100755
--- a/tools/test/stress2/misc/sem_wait.sh
+++ b/tools/test/stress2/misc/sem_wait.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/sendfile15.sh b/tools/test/stress2/misc/sendfile15.sh
index 90cbdd86ada6..c5f46d72c280 100755
--- a/tools/test/stress2/misc/sendfile15.sh
+++ b/tools/test/stress2/misc/sendfile15.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/sendfile17.sh b/tools/test/stress2/misc/sendfile17.sh
index 560cb6b83081..3ebd992fcd8e 100755
--- a/tools/test/stress2/misc/sendfile17.sh
+++ b/tools/test/stress2/misc/sendfile17.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/sendfile18.sh b/tools/test/stress2/misc/sendfile18.sh
index 3b13292932f1..f8bb111e2986 100755
--- a/tools/test/stress2/misc/sendfile18.sh
+++ b/tools/test/stress2/misc/sendfile18.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Mark Johnston <markj@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/sendfile19.sh b/tools/test/stress2/misc/sendfile19.sh
index 0254a495d5cf..faf08ca87d85 100755
--- a/tools/test/stress2/misc/sendfile19.sh
+++ b/tools/test/stress2/misc/sendfile19.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/sendfile20.sh b/tools/test/stress2/misc/sendfile20.sh
index 88c0a344a926..aefbb58eeb6c 100755
--- a/tools/test/stress2/misc/sendfile20.sh
+++ b/tools/test/stress2/misc/sendfile20.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/sendfile21.sh b/tools/test/stress2/misc/sendfile21.sh
index c50c0f0ccdab..88b59c018c81 100755
--- a/tools/test/stress2/misc/sendfile21.sh
+++ b/tools/test/stress2/misc/sendfile21.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/sendfile22.sh b/tools/test/stress2/misc/sendfile22.sh
index d948d8c001b6..a9bff35d8662 100755
--- a/tools/test/stress2/misc/sendfile22.sh
+++ b/tools/test/stress2/misc/sendfile22.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/sendfile23.sh b/tools/test/stress2/misc/sendfile23.sh
index 02c354cdf48e..f7079eabc5f2 100755
--- a/tools/test/stress2/misc/sendfile23.sh
+++ b/tools/test/stress2/misc/sendfile23.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/sendfile24.sh b/tools/test/stress2/misc/sendfile24.sh
index b9f7d7ac89c2..363008f69cb3 100755
--- a/tools/test/stress2/misc/sendfile24.sh
+++ b/tools/test/stress2/misc/sendfile24.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/sendfile25.sh b/tools/test/stress2/misc/sendfile25.sh
index dba0378d547a..ae755bf1d4df 100755
--- a/tools/test/stress2/misc/sendfile25.sh
+++ b/tools/test/stress2/misc/sendfile25.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
@@ -105,7 +105,7 @@ reader(void) {
int on;
socklen_t len;
struct sockaddr_in inetaddr, inetpeer;
- int n, t, *buf, fd;
+ int n, *buf, fd;
on = 1;
if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
@@ -132,7 +132,6 @@ reader(void) {
(struct sockaddr *)&inetpeer, &len)) < 0)
err(1, "accept(), %s:%d", __FILE__, __LINE__);
- t = 0;
if ((buf = malloc(bufsize)) == NULL)
err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__);
@@ -142,7 +141,6 @@ reader(void) {
for (;;) {
if ((n = read(msgsock, buf, bufsize)) < 0)
err(1, "read(), %s:%d", __FILE__, __LINE__);
- t += n;
if (n == 0)
break;
diff --git a/tools/test/stress2/misc/sendfile26.sh b/tools/test/stress2/misc/sendfile26.sh
index da9aa52d5f3c..cecf2547a182 100755
--- a/tools/test/stress2/misc/sendfile26.sh
+++ b/tools/test/stress2/misc/sendfile26.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/sendfile5.sh b/tools/test/stress2/misc/sendfile5.sh
index c81515003a13..933e4f94a73c 100755
--- a/tools/test/stress2/misc/sendfile5.sh
+++ b/tools/test/stress2/misc/sendfile5.sh
@@ -52,7 +52,7 @@ mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart
kldstat | grep -q tmpfs.ko || loaded=1
mount -t tmpfs tmpfs $mntpoint
-echo "Testing tmpfs(5)"
+echo "Testing tmpfs(4)"
cp $diskimage $mntpoint
/tmp/sendfile5 $mntpoint/$file
umount $mntpoint
@@ -68,7 +68,7 @@ umount $mntpoint
mdconfig -d -u $mdstart
mount -t nullfs $dir $mntpoint
-echo "Testing nullfs(5)"
+echo "Testing nullfs(4)"
/tmp/sendfile5 $mntpoint/$file
umount $mntpoint
diff --git a/tools/test/stress2/misc/setrlimit.sh b/tools/test/stress2/misc/setrlimit.sh
new file mode 100755
index 000000000000..ca7a2d7f5364
--- /dev/null
+++ b/tools/test/stress2/misc/setrlimit.sh
@@ -0,0 +1,193 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+# Test setrlimit() max file size and ftruncate()
+
+# Problem seen:
+# Testing UFS -O1
+# setrlimit: ftruncate(5413) did not fail. limit = 2791
+# Testing FFS -U
+# setrlimit: ftruncate(9956) did not fail. limit = 7880
+# Testing msdosfs
+# setrlimit: ftruncate(9033) did not fail. limit = 5884
+# Testing tmpfs
+# setrlimit: ftruncate(123) did not fail. limit = 86
+
+. ../default.cfg
+
+cat > /tmp/setrlimit.c <<EOF
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int signals;
+
+static void
+handler(int sig __unused)
+{
+#if defined(DEBUG)
+ fprintf(stderr, "Got signal SIGXFSZ\n");
+#endif
+ signals++;
+}
+
+void
+test(int argc, char *argv[])
+{
+ struct rlimit rlim;
+ rlim_t limit, sz;
+ struct sigaction act;
+ long pos;
+ int e, expected, fd;
+ char file[] = "setrlimit.file";
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <FS size>\n", argv[0]);
+ exit(1);
+ }
+ expected = signals = 0;
+ sz = atol(argv[1]);
+ arc4random_buf(&limit, sizeof(limit));
+ if (limit < 0)
+ limit = -limit;
+ limit = limit % sz + 1;
+ rlim.rlim_cur = rlim.rlim_max = limit;
+ if (setrlimit(RLIMIT_FSIZE, &rlim) == -1)
+ err(1, "setrlimit(%ld)", limit);
+
+ act.sa_handler = handler;
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+ if (sigaction(SIGXFSZ, &act, NULL) != 0)
+ err(1, "sigaction");
+
+ if ((fd = open(file, O_WRONLY | O_CREAT | O_TRUNC, DEFFILEMODE)) == -1)
+ err(1, "open(%s)", file);
+
+ e = 0;
+ arc4random_buf(&pos, sizeof(pos));
+ if (pos < 0)
+ pos = -pos;
+ pos = pos % (limit * 2);
+ if (pos > limit)
+ expected = 1;
+ if (ftruncate(fd, pos) == -1) {
+ e = errno;
+ if (pos <= limit)
+ errc(1, e, "ftruncate(%ld), limit = %ld", pos, limit);
+ } else {
+ if (pos > limit)
+ errx(1, "ftruncate(%ld) did not fail. limit = %ld", pos, limit);
+ }
+
+ if (lseek(fd, limit - 1, SEEK_SET) == -1)
+ err(1, "lseek(limit - 1)");
+ if (write(fd, "a", 1) != 1)
+ err(1, "write() at limit - 1. limit = %ld", limit);
+
+ if (write(fd, "b", 1) != -1)
+ err(1, "write() at limit. limit = %ld", limit);
+ expected++;
+
+ /* Partial write test. No signal is expected */
+ if (lseek(fd, limit - 1, SEEK_SET) == -1)
+ err(1, "lseek(limit - 1)");
+ if (write(fd, "12", 2) != 1)
+ err(1, "write() at limit - 1. limit = %ld", limit);
+
+ if (signals != expected)
+ errx(1, "Expected %d signals, got %d", expected, signals);
+
+ close(fd);
+ unlink(file);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int i;
+
+ for (i = 0; i < 100; i++)
+ test(argc, argv);
+
+}
+EOF
+
+here=`pwd`
+s=0
+cc -o /tmp/setrlimit -Wall -Wextra -O0 -g /tmp/setrlimit.c || exit 1
+
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+
+echo "Testing UFS -O1"
+mdconfig -t swap -s 1g -u $mdstart
+newfs -O1 /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+cd $mntpoint; /tmp/setrlimit 10000 || s=1
+cd $here
+umount $mntpoint
+mdconfig -d -u $mdstart
+
+echo "Testing FFS -U"
+mdconfig -t swap -s 1g -u $mdstart
+newfs -U /dev/md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+cd $mntpoint; /tmp/setrlimit 10000 || s=$((s + 2))
+cd $here
+umount $mntpoint
+mdconfig -d -u $mdstart
+
+echo "Testing msdosfs"
+mdconfig -t swap -s 1g -u $mdstart
+newfs_msdos -F 32 -b 8192 /dev/md$mdstart > /dev/null 2>&1
+mount -t msdosfs /dev/md$mdstart $mntpoint
+cd $mntpoint; /tmp/setrlimit 10000 || s=$((s + 4))
+cd $here
+umount $mntpoint
+mdconfig -d -u $mdstart
+
+echo "Testing tmpfs"
+mount -o size=20000 -t tmpfs dummy $mntpoint
+cd $mntpoint; /tmp/setrlimit 10000 || s=$((s + 8))
+cd $here
+umount $mntpoint
+
+rm -f /tmp/setrlimit /tmp/setrlimit.c
+exit $s
diff --git a/tools/test/stress2/misc/setrlimit2.sh b/tools/test/stress2/misc/setrlimit2.sh
new file mode 100755
index 000000000000..4eea25ef3ee4
--- /dev/null
+++ b/tools/test/stress2/misc/setrlimit2.sh
@@ -0,0 +1,118 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Demonstrate that a mapped SHARED file can be updated past LIMIT_FSIZE
+
+# Kostik wrote:
+# This one should be reproducible when you
+# - have file larger than e.g. RLIMIT_FSIZE
+# - mmaped it without closing the file descriptor
+# - dirty its pages beyond the limit
+# - then unmap
+# - then close the file descriptor.
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+cat > /tmp/setrlimit2.c <<EOF
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+static int signals;
+
+static void
+handler(int sig __unused)
+{
+ signals++;
+}
+
+int
+main(int argc, char *argv[])
+{
+ struct rlimit rlim;
+ struct sigaction act;
+ struct stat st;
+ size_t len;
+ int error, fd, ps;
+ char *file, *p;
+
+ if (argc != 2) {
+ fprintf(stderr, "Usage: %s <data file>\n", argv[0]);
+ exit(1);
+ }
+ act.sa_handler = handler;
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+ if (sigaction(SIGXFSZ, &act, NULL) != 0)
+ err(1, "sigaction");
+
+ file = argv[1];
+ ps = getpagesize();
+ if ((fd = open(file, O_RDWR)) == -1)
+ err(1, "open(%s)", file);
+ if ((error = fstat(fd, &st)) == -1)
+ err(1, "stat(%s)", file);
+ len = round_page(st.st_size);
+ if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED)
+ err(1, "mmap");
+ rlim.rlim_cur = rlim.rlim_max = len / 2;;
+ if (setrlimit(RLIMIT_FSIZE, &rlim) == -1)
+ err(1, "setrlimit(%ld)", len / 2);
+
+ p[len / 2 + ps] = 'a';
+
+ if (munmap(p, len) == -1)
+ err(1, "unmap()");
+ close(fd);
+
+}
+EOF
+here=`pwd`
+cd /tmp
+mycc -o setrlimit2 -Wall -Wextra -O0 -g setrlimit2.c || exit 1
+data=/tmp/setrlimit2.data
+dd if=/dev/zero of=$data bs=1m count=1 status=none
+h1=`md5 < $data`
+
+./setrlimit2 $data
+
+h2=`md5 < $data`
+rm -f /tmp/setrlimit2 /tmp/setrlimit2.c
+[ $h1 = $h2 ] && exit 1 || exit 0
diff --git a/tools/test/stress2/misc/setsockopt.sh b/tools/test/stress2/misc/setsockopt.sh
index 969c7b23069b..439b1984cb3c 100755
--- a/tools/test/stress2/misc/setsockopt.sh
+++ b/tools/test/stress2/misc/setsockopt.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/setsockopt2.sh b/tools/test/stress2/misc/setsockopt2.sh
index d032c68f77c4..13cc3175cce3 100755
--- a/tools/test/stress2/misc/setsockopt2.sh
+++ b/tools/test/stress2/misc/setsockopt2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
@@ -86,6 +86,7 @@ EOF
#include <time.h>
#include <unistd.h>
+static int debug; /* set to 1 for debug output */
static volatile u_int *share;
#define PARALLEL 128
@@ -165,6 +166,8 @@ bad:
if (waitpid(pid, NULL, 0) != pid)
err(1, "waitpid(%d)", pid);
}
+ if (debug != 0 && success == 0)
+ fprintf(stderr, "No calls to connect() succeded.\n");
_exit(0);
}
diff --git a/tools/test/stress2/misc/shm2.sh b/tools/test/stress2/misc/shm2.sh
index 55d63b19f462..e45f9f45ac4f 100755
--- a/tools/test/stress2/misc/shm2.sh
+++ b/tools/test/stress2/misc/shm2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/shm_super.sh b/tools/test/stress2/misc/shm_super.sh
index 8437eb5be92f..59d142002264 100755
--- a/tools/test/stress2/misc/shm_super.sh
+++ b/tools/test/stress2/misc/shm_super.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Konstantin Belousov <kib@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/sigfastblock.sh b/tools/test/stress2/misc/sigfastblock.sh
index 403dbde31553..ce655a611e6d 100755
--- a/tools/test/stress2/misc/sigfastblock.sh
+++ b/tools/test/stress2/misc/sigfastblock.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Konstantin Belousov
#
diff --git a/tools/test/stress2/misc/sigfastblock2.sh b/tools/test/stress2/misc/sigfastblock2.sh
index 8354307f6f7a..c8474333cbca 100755
--- a/tools/test/stress2/misc/sigfastblock2.sh
+++ b/tools/test/stress2/misc/sigfastblock2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 corydoras@ridiculousfish.com
#
diff --git a/tools/test/stress2/misc/signal2.sh b/tools/test/stress2/misc/signal2.sh
new file mode 100755
index 000000000000..2cb0589f1dce
--- /dev/null
+++ b/tools/test/stress2/misc/signal2.sh
@@ -0,0 +1,53 @@
+#!/bin/sh
+
+# Test scenario from:
+# Bug 265889 - sys.kern.basic_signal.trap_signal_test crashes bhyve in i386 VM
+# Test scenario by: Li-Wen Hsu <lwhsu@FreeBSD.org>
+
+cat > /tmp/signal2.c <<EOF
+#include <stdio.h>
+#include <signal.h>
+
+#include <machine/psl.h>
+#define SET_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_eflags |= PSL_T
+#define CLR_TRACE_FLAG(ucp) (ucp)->uc_mcontext.mc_eflags &= ~PSL_T
+
+static volatile sig_atomic_t trap_signal_fired = 0;
+
+static void
+trap_sig_handler(int signo __unused, siginfo_t *info __unused, void *_ucp)
+{
+ ucontext_t *ucp = _ucp;
+
+ if (trap_signal_fired < 9) {
+ SET_TRACE_FLAG(ucp);
+ } else {
+ CLR_TRACE_FLAG(ucp);
+ }
+ trap_signal_fired++;
+}
+
+int main() {
+ struct sigaction sa = {
+ .sa_sigaction = trap_sig_handler,
+ .sa_flags = SA_SIGINFO,
+ };
+
+ sigemptyset(&sa.sa_mask);
+ sigaction(SIGTRAP, &sa, NULL);
+
+ raise(SIGTRAP);
+
+ printf("test\n");
+}
+EOF
+cc -o /tmp/signal2 -Wall -Wextra -O0 -m32 /tmp/signal2.c || exit 1
+
+/tmp/signal2; s=$?
+for i in `jot 30`; do
+ /tmp/signal2 &
+done > /dev/null
+wait
+
+rm -f /tmp/signal2 /tmp/signal2.c
+exit $s
diff --git a/tools/test/stress2/misc/sigreturn2.sh b/tools/test/stress2/misc/sigreturn2.sh
new file mode 100755
index 000000000000..8960b9b3958c
--- /dev/null
+++ b/tools/test/stress2/misc/sigreturn2.sh
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# A sigreturn(2) syscall fuzzer
+
+# panic: vm_fault_lookup: fault on nofault entry, addr: 0
+# cpuid = 0
+# time = 1661248103
+# KDB: stack backtrace:
+# db_trace_self_wrapper(e,27e1dae0,27e1dae2,ffc07db8,c1f0490,...) at db_trace_self_wrapper+0x28/frame 0xffc07d24
+# vpanic(150b260,ffc07d60,ffc07d60,ffc07e20,12cb565,...) at vpanic+0xf4/frame 0xffc07d40
+# panic(150b260,14ec2f3,0,149349d,1430,...) at panic+0x14/frame 0xffc07d54
+# vm_fault(1e37000,0,4,0,0) at vm_fault+0x1725/frame 0xffc07e20
+# vm_fault_trap(1e37000,3b,4,0,0,0) at vm_fault_trap+0x52/frame 0xffc07e48
+# trap_pfault(3b,0,0) at trap_pfault+0x176/frame 0xffc07e94
+# trap(ffc07f6c,8,28,28,1915b000,...) at trap+0x2d9/frame 0xffc07f60
+# calltrap() at 0xffc031ef/frame 0xffc07f60
+# --- trap 0xc, eip = 0x3b, esp = 0xffc07fac, ebp = 0xffc0340c ---
+# (null)() at 0x3b/frame 0xffc0340c
+# KDB: enter: panic
+# [ thread pid 26126 tid 120029 ]
+# Stopped at kdb_enter+0x34: movl $0,kdb_why
+# db> x/s version
+# version: FreeBSD 14.0-CURRENT #0 ast-n257558-eb20af97a66-dirty: Mon Aug 22 17:53:22 CEST 2022
+# pho@mercat1.netperf.freebsd.org:/media/obj/var/tmp/deviant3/i386.i386/sys/PHO
+# db>
+
+inc=/usr/include/sys/syscall.h
+[ -f $inc ] || exit 0
+num=`awk '/SYS_sigreturn/ {print $NF}' < $inc`
+old=`grep -E 'sigreturn \*' < $inc | \
+ sed 's/.* \([0-9]\{1,3\}\) .*/\1/' | tr '\n' ' '`
+num="$num $old"
+
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 180 ]; do
+ for i in $num; do
+ echo "noswap=1 ./syscall4.sh $i"
+ noswap=1 ./syscall4.sh $i
+ done
+done
+
+exit 0
diff --git a/tools/test/stress2/misc/sigreturn3.sh b/tools/test/stress2/misc/sigreturn3.sh
new file mode 100755
index 000000000000..271ade287e9a
--- /dev/null
+++ b/tools/test/stress2/misc/sigreturn3.sh
@@ -0,0 +1,181 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Fatal trap -4186856: UNKNOWN while in kernel mode
+# cpuid = 1; apic id = 01
+# error code = 0xfbafcf8c
+# instruction pointer = 0x79e4:0x4
+# stack pointer = 0x28:0xffc0aff0
+# frame pointer = 0x28:0x204620d4
+# code segment = base 0x0, limit 0x0, type 0x0
+# = DPL 0, pres 0, def32 0, gran 0
+# processor eflags = trace trap, at 0x3b/frame 0xffc0340c
+# KDB: enter: panic
+# [ thread pid 15631 tid 114622 ]
+# Stopped at kdb_enter+0x34: movl $0,kdb_why
+# db>
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+prog=sigreturn3
+
+cat > /tmp/$prog.c <<EOF
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libutil.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define N 4096
+#define RUNTIME 120
+#define THREADS 1
+
+static uint32_t r[N];
+
+static void
+hand(int i __unused) { /* handler */
+ exit(1);
+}
+
+static void *
+churn(void *arg __unused)
+{
+ time_t start;
+
+ pthread_set_name_np(pthread_self(), __func__);
+ start = time(NULL);
+ while (time(NULL) - start < 10) {
+ arc4random_buf(r, sizeof(r));
+ usleep(100);
+ }
+ return(NULL);
+}
+
+static void *
+calls(void *arg __unused)
+{
+ time_t start;
+
+ start = time(NULL);
+ while (time(NULL) - start < 10) {
+ arc4random_buf(r, sizeof(r));
+ alarm(1);
+ syscall(SYS_sigreturn, r);
+ }
+
+ return (NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+ struct passwd *pw;
+ struct rlimit limit;
+ pid_t pid;
+ pthread_t rp, cp[THREADS];
+ time_t start;
+ int e, j;
+
+ if ((pw = getpwnam("nobody")) == NULL)
+ err(1, "failed to resolve nobody");
+
+ if (getenv("USE_ROOT") && argc == 2)
+ fprintf(stderr, "Running syscall4 as root for %s.\n",
+ argv[1]);
+ else {
+ if (setgroups(1, &pw->pw_gid) ||
+ setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
+ seteuid(pw->pw_uid) || setuid(pw->pw_uid))
+ err(1, "Can't drop privileges to \"nobody\"");
+ endpwent();
+ }
+
+ limit.rlim_cur = limit.rlim_max = 1000;
+#if defined(RLIMIT_NPTS)
+ if (setrlimit(RLIMIT_NPTS, &limit) < 0)
+ err(1, "setrlimit");
+#endif
+
+ signal(SIGALRM, hand);
+ signal(SIGILL, hand);
+ signal(SIGFPE, hand);
+ signal(SIGSEGV, hand);
+ signal(SIGBUS, hand);
+ signal(SIGURG, hand);
+ signal(SIGSYS, hand);
+ signal(SIGTRAP, hand);
+
+ if (daemon(1, 1) == -1)
+ err(1, "daemon()");
+
+ start = time(NULL);
+ while ((time(NULL) - start) < RUNTIME) {
+ if ((pid = fork()) == 0) {
+ if ((e = pthread_create(&rp, NULL, churn, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ for (j = 0; j < THREADS; j++)
+ if ((e = pthread_create(&cp[j], NULL, calls,
+ NULL)) != 0)
+ errc(1, e, "pthread_create");
+ for (j = 0; j < THREADS; j++)
+ pthread_join(cp[j], NULL);
+
+ if ((e = pthread_kill(rp, SIGINT)) != 0)
+ errc(1, e, "pthread_kill");
+ if ((e = pthread_join(rp, NULL)) != 0)
+ errc(1, e, "pthread_join");
+ _exit(0);
+ }
+ waitpid(pid, NULL, 0);
+ }
+
+ return (0);
+}
+EOF
+
+cd /tmp
+cc -o $prog -Wall -Wextra -O0 $prog.c -lpthread || exit 1
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 300 ]; do
+ ./$prog > /dev/null 2>&1
+done
+rm -f /tmp/$prog /tmp/$ptog.c /tmp/$prog.core
+exit 0
diff --git a/tools/test/stress2/misc/sigreturn4.sh b/tools/test/stress2/misc/sigreturn4.sh
new file mode 100755
index 000000000000..9e2a6a32715c
--- /dev/null
+++ b/tools/test/stress2/misc/sigreturn4.sh
@@ -0,0 +1,207 @@
+#!/bin/sh
+
+# panic: vm_fault_lookup: fault on nofault entry, addr: 0
+# cpuid = 2
+# time = 1661698922
+# KDB: stack backtrace:
+# db_trace_self_wrapper(b,2931e740,2931e742,ffc0ddb8,190431,...) at db_trace_self_wrapper+0x28/frame 0xffc0dd24
+# vpanic(150acba,ffc0dd60,ffc0dd60,ffc0de20,12cc155,...) at vpanic+0xf4/frame 0xffc0dd40
+# panic(150acba,14ec1ab,0,146253d,1430,...) at panic+0x14/frame 0xffc0dd54
+# vm_fault(1e360c8,0,4,0,0) at vm_fault+0x1725/frame 0xffc0de20
+# vm_fault_trap(1e360c8,3b,4,0,0,0) at vm_fault_trap+0x52/frame 0xffc0de48
+# trap_pfault(3b,0,0) at trap_pfault+0x176/frame 0xffc0de94
+# trap(ffc0df6c,8,28,28,19156000,...) at trap+0x2d9/frame 0xffc0df60
+# calltrap() at 0xffc031ef/frame 0xffc0df60
+# --- trap 0xc, eip = 0x3b, esp = 0xffc0dfac, ebp = 0xffc0340c ---
+# (null)() at 0x3b/frame 0xffc0340c
+# KDB: enter: panic
+# [ thread pid 54680 tid 102765 ]
+# Stopped at kdb_enter+0x34: movl $0,kdb_why
+# db> x/s version
+# version: FreeBSD 14.0-CURRENT #0 main-n257606-9ea2716b775-dirty: Thu Aug 25 10:47:45 CEST 2022
+# pho@mercat1.netperf.freebsd.org:/media/ob
+# j/usr/src/i386.i386/sys/PHO\012
+# db> show proc
+# Process 54680 (date) at 0x28905d50:
+# state: NORMAL
+# uid: 0 gids: 0, 0, 5
+# parent: pid 785 at 0x26c14000
+# ABI: FreeBSD ELF32
+# flag: 0x10004002 flag2: 0
+# arguments: date +%s
+# reaper: 0x18c710a4 reapsubtree: 1
+# sigparent: 20
+# vmspace: 0x29332100
+# (map 0x29332100)
+# (map.pmap 0x29332174)
+# (pmap 0x293321b0)
+# threads: 1
+# 102765 Run CPU 2 date
+# db>
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+prog=sigreturn4
+
+cat > /tmp/$prog.c <<EOF
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+
+#include <ucontext.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <libutil.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define RUNTIME 120
+#define THREADS 1
+
+static void
+hand(int i __unused) { /* handler */
+ _exit(1);
+}
+
+static long
+random_long(long mi, long ma)
+{
+ return (arc4random() % (ma - mi + 1) + mi);
+}
+
+static void
+flip(void *ap, size_t len)
+{
+ unsigned char *cp;
+ int byte;
+ unsigned char bit, buf, mask, old __unused;
+
+ cp = (unsigned char *)ap;
+ byte = random_long(0, len);
+ bit = random_long(0,7);
+ mask = ~(1 << bit);
+ buf = cp[byte];
+ old = cp[byte];
+ buf = (buf & mask) | (~buf & ~mask);
+ cp[byte] = buf;
+}
+
+static void *
+churn(void *arg __unused)
+{
+ time_t start;
+
+ start = time(NULL);
+ while (time(NULL) - start < 10) {
+ usleep(100);
+ }
+ return(NULL);
+}
+
+static void *
+calls(void *arg __unused)
+{
+ time_t start;
+ ucontext_t uc;
+ int n;
+
+ start = time(NULL);
+ while (time(NULL) - start < 10) {
+ n = 0;
+ if (getcontext(&uc) == -1)
+ err(1, "getcontext");
+ n++;
+
+ if (n == 1) {
+ flip(&uc, sizeof(uc));
+ alarm(1);
+ if (sigreturn(&uc) == -1)
+ err(1, "sigreturn()");
+ } else
+ break;
+ }
+ return (NULL);
+}
+
+int
+main(int argc, char **argv)
+{
+ struct passwd *pw;
+ struct rlimit limit;
+ pid_t pid;
+ pthread_t rp, cp[THREADS];
+ time_t start;
+ int e, j;
+
+ if ((pw = getpwnam("nobody")) == NULL)
+ err(1, "failed to resolve nobody");
+
+ if (getenv("USE_ROOT") && argc == 2)
+ fprintf(stderr, "Running sigreturn4 as root for %s.\n",
+ argv[1]);
+ else {
+ if (setgroups(1, &pw->pw_gid) ||
+ setegid(pw->pw_gid) || setgid(pw->pw_gid) ||
+ seteuid(pw->pw_uid) || setuid(pw->pw_uid))
+ err(1, "Can't drop privileges to \"nobody\"");
+ endpwent();
+ }
+
+ limit.rlim_cur = limit.rlim_max = 1000;
+#if defined(RLIMIT_NPTS)
+ if (setrlimit(RLIMIT_NPTS, &limit) < 0)
+ err(1, "setrlimit");
+#endif
+
+ signal(SIGALRM, hand);
+ signal(SIGILL, hand);
+ signal(SIGFPE, hand);
+ signal(SIGSEGV, hand);
+ signal(SIGBUS, hand);
+ signal(SIGURG, hand);
+ signal(SIGSYS, hand);
+ signal(SIGTRAP, hand);
+
+ if (daemon(1, 1) == -1)
+ err(1, "daemon()");
+
+ start = time(NULL);
+ while ((time(NULL) - start) < RUNTIME) {
+ if ((pid = fork()) == 0) {
+ if ((e = pthread_create(&rp, NULL, churn, NULL)) != 0)
+ errc(1, e, "pthread_create");
+ for (j = 0; j < THREADS; j++)
+ if ((e = pthread_create(&cp[j], NULL, calls,
+ NULL)) != 0)
+ errc(1, e, "pthread_create");
+ for (j = 0; j < THREADS; j++)
+ pthread_join(cp[j], NULL);
+
+ if ((e = pthread_kill(rp, SIGINT)) != 0)
+ errc(1, e, "pthread_kill");
+ if ((e = pthread_join(rp, NULL)) != 0)
+ errc(1, e, "pthread_join");
+ _exit(0);
+ }
+ waitpid(pid, NULL, 0);
+ }
+
+ return (0);
+}
+EOF
+
+cd /tmp
+cc -o $prog -Wall -Wextra -O0 $prog.c -lpthread || exit 1
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 300 ]; do
+ ./$prog > /dev/null 2>&1
+done
+rm -f /tmp/$prog /tmp/$ptog.c /tmp/$prog.core
+exit 0
diff --git a/tools/test/stress2/misc/sigstop2.sh b/tools/test/stress2/misc/sigstop2.sh
index 286936c2fb1a..640af0801318 100755
--- a/tools/test/stress2/misc/sigstop2.sh
+++ b/tools/test/stress2/misc/sigstop2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/smrstress.sh b/tools/test/stress2/misc/smrstress.sh
index 5806f9231520..b174cb5aa087 100755
--- a/tools/test/stress2/misc/smrstress.sh
+++ b/tools/test/stress2/misc/smrstress.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/smrstress2.sh b/tools/test/stress2/misc/smrstress2.sh
index 8f9f4d86a4fd..054fc922708d 100755
--- a/tools/test/stress2/misc/smrstress2.sh
+++ b/tools/test/stress2/misc/smrstress2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/snap12.sh b/tools/test/stress2/misc/snap12.sh
index 759b00be33d4..bca6af6efe5d 100755
--- a/tools/test/stress2/misc/snap12.sh
+++ b/tools/test/stress2/misc/snap12.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/snap13.sh b/tools/test/stress2/misc/snap13.sh
new file mode 100755
index 000000000000..75550e76a784
--- /dev/null
+++ b/tools/test/stress2/misc/snap13.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2023 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Test mounting of snapshots for different UFS types
+
+# Seen: mount of a -O1 snapshot failed
+# Fixed by:
+# f1549d7d5229 Write out corrected superblock when creating a UFS/FFS snapshot.
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+set -u
+s=0
+m2=$((mdstart + 1))
+mp2=$mntpoint$m2
+[ -d $mp2 ] || mkdir -p $mp2
+mount | grep -q "on $mntpoint " && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+[ -c /dev/md$m2 ] && mdconfig -d -u $m2
+mdconfig -a -t swap -s 2g -u $mdstart || exit 1
+for newfs_flags in "-O2" "-U" "-j" "-O1"; do
+ echo "newfs $newfs_flags md$mdstart"
+ newfs $newfs_flags md$mdstart > /dev/null
+ mount /dev/md$mdstart $mntpoint
+ touch $mntpoint/file
+
+ rm -f $mntpoint/.snap/stress2
+ mksnap_ffs $mntpoint $mntpoint/.snap/stress2 || { s=1; break; }
+ mdconfig -a -t vnode -f $mntpoint/.snap/stress2 -u $m2 -o readonly ||
+ { s=2; break; }
+ mount -t ufs -o ro /dev/md$m2 $mp2 || {
+ echo "mount of a $newfs_flags snapshot failed"
+ dumpfs -s /dev/md$m2; s=3; break; }
+ [ -f $mp2/file ] || { s=4; ls -l $mp2; }
+ umount $mp2
+ mdconfig -d -u $m2
+ umount $mntpoint
+done
+mount | grep -q "on $mntpoint " && umount $mntpoint
+
+mdconfig -d -u $mdstart
+exit $s
diff --git a/tools/test/stress2/misc/socketpair4.sh b/tools/test/stress2/misc/socketpair4.sh
index 65fb55d975ad..c9e07b3494fc 100755
--- a/tools/test/stress2/misc/socketpair4.sh
+++ b/tools/test/stress2/misc/socketpair4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/softupdate.sh b/tools/test/stress2/misc/softupdate.sh
index ecf7c5d04e9c..37f819579f83 100755
--- a/tools/test/stress2/misc/softupdate.sh
+++ b/tools/test/stress2/misc/softupdate.sh
@@ -47,6 +47,7 @@ mdconfig -a -t vnode -f $D -u $mdstart
for mode in "" "-U"; do
printf "newfs -O2 $mode /dev/md${mdstart}\n\n"
newfs -O2 $mode /dev/md$mdstart > /dev/null 2>&1
+ [ "$mode" = "" ] && tunefs -n disable md$mdstart
mount /dev/md$mdstart $mntpoint
for i in `jot 5`; do
diff --git a/tools/test/stress2/misc/sort2.sh b/tools/test/stress2/misc/sort2.sh
index ba3d5a0a01f8..fb2965ea6c02 100755
--- a/tools/test/stress2/misc/sort2.sh
+++ b/tools/test/stress2/misc/sort2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/split.sh b/tools/test/stress2/misc/split.sh
index 59e3c6f140e1..2709a38e77b5 100755
--- a/tools/test/stress2/misc/split.sh
+++ b/tools/test/stress2/misc/split.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/su.sh b/tools/test/stress2/misc/su.sh
index da29146c3ab6..c4ed6eee93ac 100755
--- a/tools/test/stress2/misc/su.sh
+++ b/tools/test/stress2/misc/su.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/suj11.sh b/tools/test/stress2/misc/suj11.sh
index 362d33caf8a4..01f3a49be087 100755
--- a/tools/test/stress2/misc/suj11.sh
+++ b/tools/test/stress2/misc/suj11.sh
@@ -42,7 +42,7 @@ newfs -j md$mdstart > /dev/null
mount /dev/md$mdstart $mntpoint
chmod 777 $mntpoint
-export runRUNTIME=30m
+export runRUNTIME=10m
export RUNDIR=$mntpoint/stressX
su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1
diff --git a/tools/test/stress2/misc/suj12.sh b/tools/test/stress2/misc/suj12.sh
index d0cbecfb1a37..48b138fbd2d3 100755
--- a/tools/test/stress2/misc/suj12.sh
+++ b/tools/test/stress2/misc/suj12.sh
@@ -32,6 +32,9 @@
# OOM seen: https://people.freebsd.org/~pho/stress/log/suj12.txt
+# watchdogd fired:
+# https://people.freebsd.org/~pho/stress/log/log0428.txt
+
. ../default.cfg
gnop load || exit 0
diff --git a/tools/test/stress2/misc/suj15.sh b/tools/test/stress2/misc/suj15.sh
index 6ab9e653f12c..86bf2f4e3f1d 100755
--- a/tools/test/stress2/misc/suj15.sh
+++ b/tools/test/stress2/misc/suj15.sh
@@ -48,7 +48,7 @@ newfs -j md$mdstart > /dev/null
mount /dev/md$mdstart $mntpoint
chmod 777 $mntpoint
-export runRUNTIME=30m
+export runRUNTIME=10m
export RUNDIR=$mntpoint/stressX
su $testuser -c 'cd ..; ./run.sh jeff.cfg > /dev/null' &
diff --git a/tools/test/stress2/misc/suj16.sh b/tools/test/stress2/misc/suj16.sh
index b58f406e7564..64e64dd65fbc 100755
--- a/tools/test/stress2/misc/suj16.sh
+++ b/tools/test/stress2/misc/suj16.sh
@@ -46,7 +46,7 @@ newfs -j md$mdstart > /dev/null 2>&1
mount /dev/md$mdstart $mntpoint
chmod 777 $mntpoint
-export runRUNTIME=30m
+export runRUNTIME=10m
export RUNDIR=$mntpoint/stressX
export creatINCARNATIONS=2
diff --git a/tools/test/stress2/misc/suj26.sh b/tools/test/stress2/misc/suj26.sh
index 940ef5c92a29..427f94dbc664 100755
--- a/tools/test/stress2/misc/suj26.sh
+++ b/tools/test/stress2/misc/suj26.sh
@@ -45,7 +45,7 @@ newfs $opt md$mdstart > /dev/null 2>&1
mount /dev/md$mdstart $mntpoint
chmod 777 $mntpoint
-export runRUNTIME=30m
+export runRUNTIME=10m
export RUNDIR=$mntpoint/stressX
export creatINCARNATIONS=2
diff --git a/tools/test/stress2/misc/suj27.sh b/tools/test/stress2/misc/suj27.sh
index 8253243f5868..02cc70af5520 100755
--- a/tools/test/stress2/misc/suj27.sh
+++ b/tools/test/stress2/misc/suj27.sh
@@ -45,7 +45,7 @@ newfs $opt md$mdstart > /dev/null 2>&1
mount /dev/md$mdstart $mntpoint
chmod 777 $mntpoint
-export runRUNTIME=30m
+export runRUNTIME=10m
export RUNDIR=$mntpoint/stressX
export creatINCARNATIONS=2
diff --git a/tools/test/stress2/misc/suj36.sh b/tools/test/stress2/misc/suj36.sh
new file mode 100755
index 000000000000..686274418901
--- /dev/null
+++ b/tools/test/stress2/misc/suj36.sh
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# SU+J and snapshots
+
+# "panic: handle_disk_io_initiation: Unexpected type jnewblk" seen
+# https://people.freebsd.org/~pho/stress/log/log0392.txt
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+set -eu
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+
+mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint
+[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart
+mdconfig -a -t swap -s 5g -u $mdstart
+[ "$newfs_flags" = "-U" ] && newfs_flags="-j"
+newfs $newfs_flags md$mdstart > /dev/null
+mount /dev/md$mdstart $mntpoint
+chmod 777 $mntpoint
+
+export LOAD=80
+export rwLOAD=80
+export runRUNTIME=10m
+export RUNDIR=$mntpoint/stressX
+export CTRLDIR=$mntpoint/stressX.control
+export MAXSWAPPCT=80
+export TESTPROGS=`cd ..; find testcases/ -perm -1 -type f | \
+ egrep -Ev "/run/|/badcode/|/pty/|/shm/|/socket/|sysctl|tcp|thr|udp"`
+
+su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > /dev/null &
+
+sleep 5
+for i in `jot 10`; do
+ for j in `jot 5`; do
+ rm -f $mntpoint/.snap/snap.$j
+ mksnap_ffs $mntpoint $mntpoint/.snap/snap.$j
+ sleep 10
+ done
+ sleep 10
+done
+wait
+
+../tools/killall.sh
+for i in `jot 6`; do
+ mount | grep -q "on $mntpoint " || break
+ umount $mntpoint && break || sleep 10
+ [ $i -eq 6 ] &&
+ { echo FATAL; fstat -mf $mntpoint; exit 1; }
+done
+fsck_ffs -fy /dev/md$mdstart > $log 2>&1; s=$?
+grep -q "WAS MODIFIED" $log && { tail -12 $log; s=100; }
+mdconfig -d -u $mdstart
+rm -f $log
+exit $s
diff --git a/tools/test/stress2/misc/suj4.sh b/tools/test/stress2/misc/suj4.sh
index 27001a64a0e5..928909077cef 100755
--- a/tools/test/stress2/misc/suj4.sh
+++ b/tools/test/stress2/misc/suj4.sh
@@ -40,7 +40,7 @@ mount /dev/md$mdstart $mntpoint
chmod 777 $mntpoint
export RUNDIR=$mntpoint/stressX
-export runRUNTIME=30m
+export runRUNTIME=10m
set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'`
export KBLOCKS=$(($1 / 2))
export INODES=$(($2 / 2))
diff --git a/tools/test/stress2/misc/suj5.sh b/tools/test/stress2/misc/suj5.sh
index 2e49e0706d6f..957065adc60c 100755
--- a/tools/test/stress2/misc/suj5.sh
+++ b/tools/test/stress2/misc/suj5.sh
@@ -28,7 +28,8 @@
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
-# Deadlock seen
+# "panic: general protection fault" seen:
+# https://people.freebsd.org/~pho/stress/log/log0398.txt
. ../default.cfg
diff --git a/tools/test/stress2/misc/swap5.sh b/tools/test/stress2/misc/swap5.sh
index a0d746e1d2e2..c9f715d57b9a 100755
--- a/tools/test/stress2/misc/swap5.sh
+++ b/tools/test/stress2/misc/swap5.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/swap6.sh b/tools/test/stress2/misc/swap6.sh
index 30a3fd8e703a..a1eaea6b86a6 100755
--- a/tools/test/stress2/misc/swap6.sh
+++ b/tools/test/stress2/misc/swap6.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
@@ -33,7 +33,7 @@
. ../default.cfg
[ `sysctl -n vm.swap_total` -eq 0 ] && exit 0
-min=5 # percent swap usage
+min=10 # percent swap usage
(cd ../testcases/swap; ./swap -t 10m -i 100 -l 100 -h > /dev/null) &
sleep 1
mx=0
diff --git a/tools/test/stress2/misc/swapoff3.sh b/tools/test/stress2/misc/swapoff3.sh
index 89b775a4f59c..5bd9e338a80f 100755
--- a/tools/test/stress2/misc/swapoff3.sh
+++ b/tools/test/stress2/misc/swapoff3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Mark Johnston
#
diff --git a/tools/test/stress2/misc/swapoff4.sh b/tools/test/stress2/misc/swapoff4.sh
index 8bba94faebd1..564715030478 100755
--- a/tools/test/stress2/misc/swapoff4.sh
+++ b/tools/test/stress2/misc/swapoff4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/swapoff5.sh b/tools/test/stress2/misc/swapoff5.sh
index fa4e0fe37a17..9801c5956716 100755
--- a/tools/test/stress2/misc/swapoff5.sh
+++ b/tools/test/stress2/misc/swapoff5.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Mark Johnston
#
diff --git a/tools/test/stress2/misc/swapoff6.sh b/tools/test/stress2/misc/swapoff6.sh
new file mode 100755
index 000000000000..b6ab08784f87
--- /dev/null
+++ b/tools/test/stress2/misc/swapoff6.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# A swap test scenario, using swapoff(8) and sort(1) for VM pressure
+
+# Out of free pages seen:://people.freebsd.org/~pho/stress/log/log0540.txt
+
+. ../default.cfg
+[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1
+
+[ `swapinfo | wc -l` -eq 1 ] && exit 0
+set -u
+nmax=`sysctl -n hw.ncpu`
+[ $nmax -gt 4 ] && nmax=4
+
+for i in `jot $nmax`; do
+ timeout -k 2m 1m sort /dev/zero &
+ sleep .`jot -r 1 1 9`
+done
+while [ `swapinfo | tail -1 | awk '{sub("%","");print $NF}'` -lt 2 ]; do sleep 1; done
+
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 300 ]; do
+ while ! swapoff -a > /dev/null 2>&1; do sleep .1; done
+ swapon -a > /dev/null
+ ncur=`pgrep sort | wc -l`
+ if [ $ncur -lt $nmax ]; then
+ echo "Starting $((nmax - ncur)) sort"
+ for i in `jot $((nmax - ncur))`; do
+ timeout -k 2m 1m sort /dev/zero &
+ sleep .`jot -r 1 1 9`
+ done
+ fi
+done
+pkill -9 sort
+wait
+exit 0
diff --git a/tools/test/stress2/misc/symlink.sh b/tools/test/stress2/misc/symlink.sh
index 47257aa92a24..1d30636d6b25 100755
--- a/tools/test/stress2/misc/symlink.sh
+++ b/tools/test/stress2/misc/symlink.sh
@@ -71,6 +71,7 @@ tst() {
s=0
for i in "" "-U" "-j"; do
newfs $i /dev/md$mdstart > /dev/null 2>&1
+ [ "$i" = "" ] && tunefs -n disable md$mdstart
mount /dev/md$mdstart $mntpoint
t1=`date +%s`
diff --git a/tools/test/stress2/misc/symlink2.sh b/tools/test/stress2/misc/symlink2.sh
index f13065badb4a..210702defe4a 100755
--- a/tools/test/stress2/misc/symlink2.sh
+++ b/tools/test/stress2/misc/symlink2.sh
@@ -53,6 +53,7 @@ for i in "" "-U"; do
[ "$i" = "-U" -a "$newfs_flags" != "-U" ] && continue
echo "newfs $i /dev/md$mdstart"
newfs $i /dev/md$mdstart > /dev/null 2>&1
+ [ "$i" = "" ] && tunefs -n disable md$mdstart
mount /dev/md$mdstart $mntpoint
mkdir $mntpoint/dir
diff --git a/tools/test/stress2/misc/symlink5.sh b/tools/test/stress2/misc/symlink5.sh
index 00ada39e5002..9332f906a3e0 100755
--- a/tools/test/stress2/misc/symlink5.sh
+++ b/tools/test/stress2/misc/symlink5.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
@@ -79,6 +79,7 @@ for i in "" "-U"; do
t1=`date +%s`
echo "newfs $i /dev/md$mdstart"
newfs $i /dev/md$mdstart > /dev/null 2>&1
+ [ "$i" = "" ] && tunefs -n disable md$mdstart
mount /dev/md$mdstart $mntpoint
tst; s=$?
diff --git a/tools/test/stress2/misc/syscall4.sh b/tools/test/stress2/misc/syscall4.sh
index ce7e99dcde54..3937d45c0303 100755
--- a/tools/test/stress2/misc/syscall4.sh
+++ b/tools/test/stress2/misc/syscall4.sh
@@ -260,7 +260,7 @@ static void *
calls(void *arg __unused)
{
time_t start;
- int i, j, num;
+ int i __unused, j, num;
unsigned long arg1, arg2, arg3, arg4, arg5, arg6, arg7;
#ifdef __NP__
diff --git a/tools/test/stress2/misc/systrace.sh b/tools/test/stress2/misc/systrace.sh
index aa7b8426dddf..c41675e77da3 100755
--- a/tools/test/stress2/misc/systrace.sh
+++ b/tools/test/stress2/misc/systrace.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/systrace2.sh b/tools/test/stress2/misc/systrace2.sh
index a8c4d05106a7..0ebdfd9549d1 100755
--- a/tools/test/stress2/misc/systrace2.sh
+++ b/tools/test/stress2/misc/systrace2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/syzkaller11.sh b/tools/test/stress2/misc/syzkaller11.sh
index 9586092cd5b3..788ea3a9557a 100755
--- a/tools/test/stress2/misc/syzkaller11.sh
+++ b/tools/test/stress2/misc/syzkaller11.sh
@@ -218,7 +218,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter;
+ int iter __unused;
for (iter = 0;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller12.sh b/tools/test/stress2/misc/syzkaller12.sh
index dc026dc348bc..f5468c6c5e1f 100755
--- a/tools/test/stress2/misc/syzkaller12.sh
+++ b/tools/test/stress2/misc/syzkaller12.sh
@@ -94,7 +94,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter;
+ int iter __unused;
for (iter = 0;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller14.sh b/tools/test/stress2/misc/syzkaller14.sh
index 5fa99004f838..9181fe71a2af 100755
--- a/tools/test/stress2/misc/syzkaller14.sh
+++ b/tools/test/stress2/misc/syzkaller14.sh
@@ -229,7 +229,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter;
+ int iter __unused;
for (iter = 0;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller15.sh b/tools/test/stress2/misc/syzkaller15.sh
index d15017d7eb12..7a13bd819f0b 100755
--- a/tools/test/stress2/misc/syzkaller15.sh
+++ b/tools/test/stress2/misc/syzkaller15.sh
@@ -112,7 +112,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter;
+ int iter __unused;
for (iter = 0;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller16.sh b/tools/test/stress2/misc/syzkaller16.sh
index 8671b46474ac..7035223b8f0e 100755
--- a/tools/test/stress2/misc/syzkaller16.sh
+++ b/tools/test/stress2/misc/syzkaller16.sh
@@ -273,7 +273,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter;
+ int iter __unused;
for (iter = 0;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller19.sh b/tools/test/stress2/misc/syzkaller19.sh
index b36b12e524f2..116ab539c152 100755
--- a/tools/test/stress2/misc/syzkaller19.sh
+++ b/tools/test/stress2/misc/syzkaller19.sh
@@ -78,7 +78,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter;
+ int iter __unused;
for (iter = 0;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller24.sh b/tools/test/stress2/misc/syzkaller24.sh
index 12a816598b8f..98d4f90b146f 100755
--- a/tools/test/stress2/misc/syzkaller24.sh
+++ b/tools/test/stress2/misc/syzkaller24.sh
@@ -81,7 +81,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller26.sh b/tools/test/stress2/misc/syzkaller26.sh
index f14806199ff5..857ba0eaac65 100755
--- a/tools/test/stress2/misc/syzkaller26.sh
+++ b/tools/test/stress2/misc/syzkaller26.sh
@@ -82,7 +82,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller27.sh b/tools/test/stress2/misc/syzkaller27.sh
index b003f6aec319..a84c921e462d 100755
--- a/tools/test/stress2/misc/syzkaller27.sh
+++ b/tools/test/stress2/misc/syzkaller27.sh
@@ -86,7 +86,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller28.sh b/tools/test/stress2/misc/syzkaller28.sh
index c6ba56d1e222..7062d84a8234 100755
--- a/tools/test/stress2/misc/syzkaller28.sh
+++ b/tools/test/stress2/misc/syzkaller28.sh
@@ -220,7 +220,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller29.sh b/tools/test/stress2/misc/syzkaller29.sh
index bc5dc94768d0..5976e2cc596d 100755
--- a/tools/test/stress2/misc/syzkaller29.sh
+++ b/tools/test/stress2/misc/syzkaller29.sh
@@ -26,7 +26,7 @@
# Fixed by r368116
-# May change policy for random threads to to domainset_fixed
+# May change policy for random threads to domainset_fixed
exit 0
. ../default.cfg
@@ -79,7 +79,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller30.sh b/tools/test/stress2/misc/syzkaller30.sh
index f798386a83d1..d159da78307c 100755
--- a/tools/test/stress2/misc/syzkaller30.sh
+++ b/tools/test/stress2/misc/syzkaller30.sh
@@ -29,7 +29,7 @@
# Fixed by r368462
-# May change policy for random threads to to domainset_fixed
+# May change policy for random threads to domainset_fixed
exit 0
. ../default.cfg
diff --git a/tools/test/stress2/misc/syzkaller31.sh b/tools/test/stress2/misc/syzkaller31.sh
index 12eb98bd8c57..9815ac16f404 100755
--- a/tools/test/stress2/misc/syzkaller31.sh
+++ b/tools/test/stress2/misc/syzkaller31.sh
@@ -228,7 +228,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller32.sh b/tools/test/stress2/misc/syzkaller32.sh
index 03a13738c58a..1d96f1e3deff 100755
--- a/tools/test/stress2/misc/syzkaller32.sh
+++ b/tools/test/stress2/misc/syzkaller32.sh
@@ -231,7 +231,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller33.sh b/tools/test/stress2/misc/syzkaller33.sh
index 7f017cd167f1..fac3318e4d0d 100755
--- a/tools/test/stress2/misc/syzkaller33.sh
+++ b/tools/test/stress2/misc/syzkaller33.sh
@@ -88,7 +88,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller34.sh b/tools/test/stress2/misc/syzkaller34.sh
index 247079e1cd1a..d8b89991c2f2 100755
--- a/tools/test/stress2/misc/syzkaller34.sh
+++ b/tools/test/stress2/misc/syzkaller34.sh
@@ -53,7 +53,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller4.sh b/tools/test/stress2/misc/syzkaller4.sh
index 2a14d4d2b776..06797980b2a0 100755
--- a/tools/test/stress2/misc/syzkaller4.sh
+++ b/tools/test/stress2/misc/syzkaller4.sh
@@ -215,7 +215,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter;
+ int iter __unused;
for (iter = 0;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller42.sh b/tools/test/stress2/misc/syzkaller42.sh
index b5b234de9cd6..e0a02e18df2d 100755
--- a/tools/test/stress2/misc/syzkaller42.sh
+++ b/tools/test/stress2/misc/syzkaller42.sh
@@ -75,7 +75,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller43.sh b/tools/test/stress2/misc/syzkaller43.sh
index ffa6e1c6857c..fb32ea77ab66 100755
--- a/tools/test/stress2/misc/syzkaller43.sh
+++ b/tools/test/stress2/misc/syzkaller43.sh
@@ -214,7 +214,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller50.sh b/tools/test/stress2/misc/syzkaller50.sh
index d50e90866b8c..e813db054458 100755
--- a/tools/test/stress2/misc/syzkaller50.sh
+++ b/tools/test/stress2/misc/syzkaller50.sh
@@ -71,7 +71,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller51.sh b/tools/test/stress2/misc/syzkaller51.sh
index bd5b5da16d9a..772d6cc556c0 100755
--- a/tools/test/stress2/misc/syzkaller51.sh
+++ b/tools/test/stress2/misc/syzkaller51.sh
@@ -78,7 +78,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller53.sh b/tools/test/stress2/misc/syzkaller53.sh
index ecb0843b8c1f..bfbabe70a571 100755
--- a/tools/test/stress2/misc/syzkaller53.sh
+++ b/tools/test/stress2/misc/syzkaller53.sh
@@ -119,7 +119,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller54.sh b/tools/test/stress2/misc/syzkaller54.sh
index dc3ce0dc876c..252ba4e0f6f4 100755
--- a/tools/test/stress2/misc/syzkaller54.sh
+++ b/tools/test/stress2/misc/syzkaller54.sh
@@ -216,7 +216,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller55.sh b/tools/test/stress2/misc/syzkaller55.sh
index 9914587926cf..e1d3e7a28121 100755
--- a/tools/test/stress2/misc/syzkaller55.sh
+++ b/tools/test/stress2/misc/syzkaller55.sh
@@ -77,7 +77,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller58.sh b/tools/test/stress2/misc/syzkaller58.sh
index 0083e13f1692..6c11cd583b9d 100755
--- a/tools/test/stress2/misc/syzkaller58.sh
+++ b/tools/test/stress2/misc/syzkaller58.sh
@@ -216,7 +216,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller59.sh b/tools/test/stress2/misc/syzkaller59.sh
index b628c25d3298..1644ce627934 100755
--- a/tools/test/stress2/misc/syzkaller59.sh
+++ b/tools/test/stress2/misc/syzkaller59.sh
@@ -94,7 +94,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter = 0;
+ int iter __unused = 0;
for (;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller61.sh b/tools/test/stress2/misc/syzkaller61.sh
new file mode 100755
index 000000000000..a25ae4cf00d8
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller61.sh
@@ -0,0 +1,319 @@
+#!/bin/sh
+
+# Seen:
+# [root@mercat1 /usr/src/tools/test/stress2/misc]# pgrep syzkaller61 | xargs procstat -k
+# PID TID COMM TDNAME KSTACK
+# 13332 106396 syzkaller61 - mi_switch thread_suspend_check ast_suspend ast_handler ast doreti_ast
+# 13332 560662 syzkaller61 - mi_switch sleepq_switch sleepq_catch_signals sleepq_wait_sig _sleep umtxq_sleep do_wait __umtx_op_wait_uint_private sys__umtx_op amd64_syscall fast_syscall_common
+# 13332 560776 syzkaller61 - mi_switch thread_suspend_switch thread_single fork1 sys_rfork amd64_syscall fast_syscall_common
+# 13662 356440 syzkaller61 - mi_switch thread_suspend_check ast_suspend ast_handler ast doreti_ast
+# 13662 561098 syzkaller61 - mi_switch sleepq_switch sleepq_catch_signals sleepq_wait_sig _sleep umtxq_sleep do_wait __umtx_op_wait_uint_private sys__umtx_op amd64_syscall fast_syscall_common
+# 13662 561160 syzkaller61 - mi_switch thread_suspend_switch thread_single fork1 sys_rfork amd64_syscall fast_syscall_common
+# [root@mercat1 /usr/src/tools/test/stress2/misc]#
+
+[ `uname -p` != "amd64" ] && exit 0
+
+. ../default.cfg
+cat > /tmp/syzkaller61.c <<EOF
+// https://syzkaller.appspot.com/bug?id=00d8ca63243899ffb67b15ec93aee4ffa2f06637
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// Reported-by: syzbot+647212368c3f32c6f13f@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+static __thread int clone_ongoing;
+static __thread int skip_segv;
+static __thread jmp_buf segv_env;
+
+static void segv_handler(int sig, siginfo_t* info, void* ctx __unused)
+{
+ if (__atomic_load_n(&clone_ongoing, __ATOMIC_RELAXED) != 0) {
+ exit(sig);
+ }
+ uintptr_t addr = (uintptr_t)info->si_addr;
+ const uintptr_t prog_start = 1 << 20;
+ const uintptr_t prog_end = 100 << 20;
+ int skip = __atomic_load_n(&skip_segv, __ATOMIC_RELAXED) != 0;
+ int valid = addr < prog_start || addr > prog_end;
+ if (sig == SIGBUS)
+ valid = 1;
+ if (skip && valid) {
+ _longjmp(segv_env, 1);
+ }
+ exit(sig);
+}
+
+static void install_segv_handler(void)
+{
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = segv_handler;
+ sa.sa_flags = SA_NODEFER | SA_SIGINFO;
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGBUS, &sa, NULL);
+}
+
+#define NONFAILING(...) \
+ ({ \
+ int ok = 1; \
+ __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \
+ if (_setjmp(segv_env) == 0) { \
+ __VA_ARGS__; \
+ } else \
+ ok = 0; \
+ __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \
+ ok; \
+ })
+
+static void kill_and_wait(int pid, int* status)
+{
+ kill(pid, SIGKILL);
+ while (waitpid(-1, status, 0) != pid) {
+ }
+}
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+ pthread_t th;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 128 << 10);
+ int i = 0;
+ for (; i < 100; i++) {
+ if (pthread_create(&th, &attr, fn, arg) == 0) {
+ pthread_attr_destroy(&attr);
+ return;
+ }
+ if (errno == EAGAIN) {
+ usleep(50);
+ continue;
+ }
+ break;
+ }
+ exit(1);
+}
+
+typedef struct {
+ pthread_mutex_t mu;
+ pthread_cond_t cv;
+ int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+ if (pthread_mutex_init(&ev->mu, 0))
+ exit(1);
+ if (pthread_cond_init(&ev->cv, 0))
+ exit(1);
+ ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+ ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ if (ev->state)
+ exit(1);
+ ev->state = 1;
+ pthread_mutex_unlock(&ev->mu);
+ pthread_cond_broadcast(&ev->cv);
+}
+
+static void event_wait(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ while (!ev->state)
+ pthread_cond_wait(&ev->cv, &ev->mu);
+ pthread_mutex_unlock(&ev->mu);
+}
+
+static int event_isset(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+ uint64_t start = current_time_ms();
+ uint64_t now = start;
+ pthread_mutex_lock(&ev->mu);
+ for (;;) {
+ if (ev->state)
+ break;
+ uint64_t remain = timeout - (now - start);
+ struct timespec ts;
+ ts.tv_sec = remain / 1000;
+ ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+ pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
+ now = current_time_ms();
+ if (now - start > timeout)
+ break;
+ }
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+struct thread_t {
+ int created, call;
+ event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+ struct thread_t* th = (struct thread_t*)arg;
+ for (;;) {
+ event_wait(&th->ready);
+ event_reset(&th->ready);
+ execute_call(th->call);
+ __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->done);
+ }
+ return 0;
+}
+
+static void execute_one(void)
+{
+ int i, call, thread;
+ for (call = 0; call < 2; call++) {
+ for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+ thread++) {
+ struct thread_t* th = &threads[thread];
+ if (!th->created) {
+ th->created = 1;
+ event_init(&th->ready);
+ event_init(&th->done);
+ event_set(&th->done);
+ thread_start(thr, th);
+ }
+ if (!event_isset(&th->done))
+ continue;
+ event_reset(&th->done);
+ th->call = call;
+ __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->ready);
+ event_timedwait(&th->done, 50);
+ break;
+ }
+ }
+ for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+ sleep_ms(1);
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS 0
+
+static void loop(void)
+{
+ int iter __unused = 0;
+ for (;; iter++) {
+ int pid = fork();
+ if (pid < 0)
+ exit(1);
+ if (pid == 0) {
+ execute_one();
+ exit(0);
+ }
+ int status = 0;
+ uint64_t start = current_time_ms();
+ for (;;) {
+ if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+ break;
+ sleep_ms(1);
+ if (current_time_ms() - start < 5000)
+ continue;
+ kill_and_wait(pid, &status);
+ break;
+ }
+ }
+}
+
+void execute_call(int call)
+{
+ switch (call) {
+ case 0:
+ NONFAILING(*(uint32_t*)0x20001f00 = 0x16);
+ NONFAILING(*(uint32_t*)0x20001f04 = 0);
+ NONFAILING(*(uint32_t*)0x20001f08 = 0);
+ NONFAILING(*(uint32_t*)0x20001f0c = 0);
+ NONFAILING(*(uint32_t*)0x20001f10 = 0);
+ NONFAILING(memset((void*)0x20001f14, 0, 60));
+ syscall(SYS_procctl, 0ul, 0, 6ul, 0x20001f00ul);
+ break;
+ case 1:
+ syscall(SYS_rfork, 0x85000ul);
+ break;
+ }
+}
+int main(void)
+{
+ syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
+ install_segv_handler();
+ loop();
+ return 0;
+}
+EOF
+mycc -o /tmp/syzkaller61 -Wall -Wextra -O0 /tmp/syzkaller61.c -lpthread ||
+ exit 1
+
+(cd ../testcases/swap; ./swap -t 3m -i 10 -l 100 > /dev/null 2>&1) &
+for i in `jot 300`; do
+ (cd /tmp; timeout -k 3s 2s ./syzkaller61) &
+ pids="$pids $!"
+done
+sleep 5
+pkill -9 syzkaller61 swap; sleep 1
+pgrep -q syzkaller61 && { pgrep syzkaller61 | xargs ps -lHp; exit 1; }
+for pid in $pids; do
+ wait $pid
+done
+while pkill swap; do :; done
+wait
+
+rm -rf /tmp/syzkaller61 /tmp/syzkaller61.c /tmp/syzkaller61.core \
+ /tmp/syzkaller.??????
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller62.sh b/tools/test/stress2/misc/syzkaller62.sh
new file mode 100755
index 000000000000..aa2d33ebaf9e
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller62.sh
@@ -0,0 +1,83 @@
+#!/bin/sh
+
+# panic: Assertion sb->sb_hiwat >= sb->uxdg_cc failed at ../../../kern/uipc_usrreq.c:1099
+# cpuid = 9
+# time = 1660909804
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe01401e7970
+# vpanic() at vpanic+0x151/frame 0xfffffe01401e79c0
+# panic() at panic+0x43/frame 0xfffffe01401e7a20
+# uipc_dgram_sbspace() at uipc_dgram_sbspace+0x51/frame 0xfffffe01401e7a30
+# uipc_sosend_dgram() at uipc_sosend_dgram+0x690/frame 0xfffffe01401e7ac0
+# sosend() at sosend+0x49/frame 0xfffffe01401e7af0
+# soo_write() at soo_write+0x43/frame 0xfffffe01401e7b20
+# filemon_close_log() at filemon_close_log+0xd5/frame 0xfffffe01401e7b90
+# filemon_dtr() at filemon_dtr+0x31/frame 0xfffffe01401e7bb0
+# devfs_destroy_cdevpriv() at devfs_destroy_cdevpriv+0xab/frame 0xfffffe01401e7bd0
+# devfs_close_f() at devfs_close_f+0x64/frame 0xfffffe01401e7c00
+# _fdrop() at _fdrop+0x1b/frame 0xfffffe01401e7c20
+# closef() at closef+0x1db/frame 0xfffffe01401e7cb0
+# fdescfree() at fdescfree+0x433/frame 0xfffffe01401e7d80
+# exit1() at exit1+0x4df/frame 0xfffffe01401e7df0
+# sys_exit() at sys_exit+0xd/frame 0xfffffe01401e7e00
+# amd64_syscall() at amd64_syscall+0x145/frame 0xfffffe01401e7f30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe01401e7f30
+# --- syscall (1, FreeBSD ELF64, sys_exit), rip = 0x82301d16a, rsp = 0x8209bf628, rbp = 0x8209bf640 ---
+# KDB: enter: panic
+# [ thread pid 2876 tid 100222 ]
+# Stopped at x32: movq $0,0x12a1323(%rip)
+# db> x/s version
+# version: FreeBSD 14.0-CURRENT #0 main-n257506-eed634d113d-dirty: Thu Aug 18 13:56:53 CEST 2022
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO\012
+# db>
+
+. ../default.cfg
+cat > /tmp/syzkaller62.c <<EOF
+// https://syzkaller.appspot.com/bug?id=582310beb894769fc836748eec49b8d2f905e5ef
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// Reported-by: syzbot+6e8be1ec8d77578a3df4@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
+
+int main(void)
+{
+ syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
+ intptr_t res = 0;
+ memcpy((void*)0x20000040, "/dev/filemon\000", 13);
+ res = syscall(SYS_openat, 0xffffffffffffff9cul, 0x20000040ul, 0ul, 0ul);
+ if (res != -1)
+ r[0] = res;
+ res = syscall(SYS_socketpair, 1ul, 2ul, 0, 0x20000080ul);
+ if (res != -1)
+ r[1] = *(uint32_t*)0x20000084;
+ *(uint32_t*)0x200000c0 = r[1];
+ syscall(SYS_ioctl, r[0], 0xc0045301ul, 0x200000c0ul);
+ *(uint32_t*)0x20000040 = 3;
+ syscall(SYS_setsockopt, r[1], 0xffff, 0x1001, 0x20000040ul, 4ul);
+ return 0;
+}
+EOF
+mycc -o /tmp/syzkaller62 -Wall -Wextra -O0 /tmp/syzkaller62.c || exit 1
+
+kldstat | grep -q filemon || { kldload filemon.ko && loaded=1; }
+
+(cd /tmp; timeout -k 3s 2s ./syzkaller62)
+
+rm -rf /tmp/syzkaller62 /tmp/syzkaller62.c /tmp/syzkaller62.core \
+ /tmp/syzkaller.??????
+# Unload causes: Fatal trap 12: page fault while in kernel mode
+#[ $loaded ] && kldunload -f filemon.ko
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller63.sh b/tools/test/stress2/misc/syzkaller63.sh
new file mode 100755
index 000000000000..647801dbdbb9
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller63.sh
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+# Fatal trap 12: page fault while in kernel mode
+# cpuid = 1; apic id = 01
+# fault virtual address = 0x20
+# fault code = supervisor read data, page not present
+# instruction pointer = 0x20:0xfa1a2c
+# stack pointer = 0x28:0x27a41a80
+# frame pointer = 0x28:0x27a41a98
+# code segment = base 0x0, limit 0xfffff, type 0x1b
+# = DPL 0, pres 1, def32 1, gran 1
+# processor eflags = interrupt enabled, resume, IOPL = 0
+# current process = 804 (syzkaller63)
+# trap number = 12
+# panic: page fault
+# cpuid = 1
+# time = 1675071979
+# KDB: stack backtrace:
+# db_trace_self_wrapper(d,2048e3a0,27a41a40,20,c,...) at db_trace_self_wrapper+0x28/frame 0x27a418d0
+# vpanic(146c355,27a4190c,27a4190c,27a41938,141f1d6,...) at vpanic+0xf4/frame 0x27a418ec
+# panic(146c355,15010e8,0,fffff,1dfc39b,...) at panic+0x14/frame 0x27a41900
+# trap_fatal(2048e3a0,2048e3a0,27a4196c,1008e0a,18cd6638,...) at trap_fatal+0x346/frame 0x27a41938
+# trap_pfault(20,0,0) at trap_pfault+0x6f/frame 0x27a4196c
+# trap(27a41a40,8,28,28,0,...) at trap+0x31b/frame 0x27a41a34
+# calltrap() at 0xffc0321f/frame 0x27a41a34
+# --- trap 0xc, eip = 0xfa1a2c, esp = 0x27a41a80, ebp = 0x27a41a98 ---
+# kern_cpuset_getid(141f60e,0,9,0,0,0) at kern_cpuset_getid+0x10c/frame 0x27a41a98
+# sys_cpuset_getid(2048e3a0,2048e644,2048e3a0,2048e3a0,27a41b9c,...) at sys_cpuset_getid+0x32/frame 0x27a41ac0
+# syscall(27a41ba8,3b,3b,3b,ffbfe9fc,...) at syscall+0x1ef/frame 0x27a41b9c
+# Xint0x80_syscall() at 0xffc03479/frame 0x27a41b9c
+# --- syscall (486, FreeBSD ELF32, cpuset_getid), eip = 0x2056317d, esp = 0xffbfe990, ebp = 0xffbfe9b0 ---
+# KDB: enter: panic
+# [ thread pid 804 tid 100092 ]
+# Stopped at kdb_enter+0x34: movl $0,kdb_why
+# db> x/s version
+# version: FreeBSD 14.0-CURRENT #0 main-n260354-34b867ca30479: Mon Jan 30 07:26:30 CET 2023
+# pho@mercat1.netperf.freebsd.org:/mnt25/obj/usr/src/i386.i386/sys/PHO
+# db>
+
+. ../default.cfg
+prog=$(basename "$0" .sh)
+[ `uname -p` = "i386" ] || exit 0
+
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=69dd3c8d867306dd9f97e2dae6ab1557fd8d2679
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// Reported-by: syzbot+331e8402e0f7347f0f2a@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+int main(void)
+{
+ syscall(SYS_mmap, 0x10000000, 0x1000000, 7, 0x1012, -1, 0);
+ syscall(SYS_cpuset_getid, 0, 9, 0ull, 0);
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1
+
+(cd /tmp; timeout -k 3s 2s ./$prog)
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core \
+ /tmp/syzkaller.??????
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller64.sh b/tools/test/stress2/misc/syzkaller64.sh
new file mode 100755
index 000000000000..f13fd415087b
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller64.sh
@@ -0,0 +1,328 @@
+#!/bin/sh
+
+[ `uname -p` != "amd64" ] && exit 0
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+[ "`sysctl -in kern.features.kasan`" != "1" ] && exit 0
+
+. ../default.cfg
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=749aa1fdb67018e9c0179373a60d523511bff02c
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// Reported-by: syzbot+5cb51285603332d9be11@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+static __thread int clone_ongoing;
+static __thread int skip_segv;
+static __thread jmp_buf segv_env;
+
+static void segv_handler(int sig, siginfo_t* info, void* ctx __unused)
+{
+ if (__atomic_load_n(&clone_ongoing, __ATOMIC_RELAXED) != 0) {
+ exit(sig);
+ }
+ uintptr_t addr = (uintptr_t)info->si_addr;
+ const uintptr_t prog_start = 1 << 20;
+ const uintptr_t prog_end = 100 << 20;
+ int skip = __atomic_load_n(&skip_segv, __ATOMIC_RELAXED) != 0;
+ int valid = addr < prog_start || addr > prog_end;
+ if (sig == SIGBUS)
+ valid = 1;
+ if (skip && valid) {
+ _longjmp(segv_env, 1);
+ }
+ exit(sig);
+}
+
+static void install_segv_handler(void)
+{
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = segv_handler;
+ sa.sa_flags = SA_NODEFER | SA_SIGINFO;
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGBUS, &sa, NULL);
+}
+
+#define NONFAILING(...) \
+ ({ \
+ int ok = 1; \
+ __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \
+ if (_setjmp(segv_env) == 0) { \
+ __VA_ARGS__; \
+ } else \
+ ok = 0; \
+ __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \
+ ok; \
+ })
+
+static void kill_and_wait(int pid, int* status)
+{
+ kill(pid, SIGKILL);
+ while (waitpid(-1, status, 0) != pid) {
+ }
+}
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+ pthread_t th;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 128 << 10);
+ int i = 0;
+ for (; i < 100; i++) {
+ if (pthread_create(&th, &attr, fn, arg) == 0) {
+ pthread_attr_destroy(&attr);
+ return;
+ }
+ if (errno == EAGAIN) {
+ usleep(50);
+ continue;
+ }
+ break;
+ }
+ exit(1);
+}
+
+typedef struct {
+ pthread_mutex_t mu;
+ pthread_cond_t cv;
+ int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+ if (pthread_mutex_init(&ev->mu, 0))
+ exit(1);
+ if (pthread_cond_init(&ev->cv, 0))
+ exit(1);
+ ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+ ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ if (ev->state)
+ exit(1);
+ ev->state = 1;
+ pthread_mutex_unlock(&ev->mu);
+ pthread_cond_broadcast(&ev->cv);
+}
+
+static void event_wait(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ while (!ev->state)
+ pthread_cond_wait(&ev->cv, &ev->mu);
+ pthread_mutex_unlock(&ev->mu);
+}
+
+static int event_isset(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+ uint64_t start = current_time_ms();
+ uint64_t now = start;
+ pthread_mutex_lock(&ev->mu);
+ for (;;) {
+ if (ev->state)
+ break;
+ uint64_t remain = timeout - (now - start);
+ struct timespec ts;
+ ts.tv_sec = remain / 1000;
+ ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+ pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
+ now = current_time_ms();
+ if (now - start > timeout)
+ break;
+ }
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static void sandbox_common()
+{
+ struct rlimit rlim;
+ rlim.rlim_cur = rlim.rlim_max = 128 << 20;
+ setrlimit(RLIMIT_AS, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 8 << 20;
+ setrlimit(RLIMIT_MEMLOCK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+ setrlimit(RLIMIT_FSIZE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+ setrlimit(RLIMIT_STACK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ setrlimit(RLIMIT_CORE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 256;
+ setrlimit(RLIMIT_NOFILE, &rlim);
+}
+
+static void loop();
+
+static int do_sandbox_none(void)
+{
+ sandbox_common();
+ loop();
+ return 0;
+}
+
+struct thread_t {
+ int created, call;
+ event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+ struct thread_t* th = (struct thread_t*)arg;
+ for (;;) {
+ event_wait(&th->ready);
+ event_reset(&th->ready);
+ execute_call(th->call);
+ __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->done);
+ }
+ return 0;
+}
+
+static void execute_one(void)
+{
+ int i, call, thread;
+ for (call = 0; call < 5; call++) {
+ for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+ thread++) {
+ struct thread_t* th = &threads[thread];
+ if (!th->created) {
+ th->created = 1;
+ event_init(&th->ready);
+ event_init(&th->done);
+ event_set(&th->done);
+ thread_start(thr, th);
+ }
+ if (!event_isset(&th->done))
+ continue;
+ event_reset(&th->done);
+ th->call = call;
+ __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->ready);
+ event_timedwait(&th->done, 50);
+ break;
+ }
+ }
+ for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+ sleep_ms(1);
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS 0
+
+static void loop(void)
+{
+ int iter __unused = 0;
+ for (;; iter++) {
+ int pid = fork();
+ if (pid < 0)
+ exit(1);
+ if (pid == 0) {
+ execute_one();
+ exit(0);
+ }
+ int status = 0;
+ uint64_t start = current_time_ms();
+ for (;;) {
+ if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+ break;
+ sleep_ms(1);
+ if (current_time_ms() - start < 5000)
+ continue;
+ kill_and_wait(pid, &status);
+ break;
+ }
+ }
+}
+
+void execute_call(int call)
+{
+ switch (call) {
+ case 0:
+ syscall(SYS_thr_new, 0ul, 0ul);
+ break;
+ case 1:
+ syscall(SYS_setloginclass, 0ul);
+ break;
+ case 2:
+ syscall(SYS_vfork);
+ break;
+ case 3:
+ NONFAILING(*(uint32_t*)0x20001880 = 4);
+ syscall(SYS_sysarch, 8ul, 0x20001880ul);
+ break;
+ case 4:
+ syscall(SYS_getsid, 0);
+ break;
+ }
+}
+int main(void)
+{
+ syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
+ install_segv_handler();
+ do_sandbox_none();
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+(cd /tmp; timeout 2m ./$prog)
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/syzkaller.*
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller65.sh b/tools/test/stress2/misc/syzkaller65.sh
new file mode 100755
index 000000000000..8806a55e2733
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller65.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+# panic: in_pcblookup_hash_locked: invalid local address
+# cpuid = 11
+# time = 1678303805
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0657e466d0
+# vpanic() at vpanic+0x152/frame 0xfffffe0657e46720
+# panic() at panic+0x43/frame 0xfffffe0657e46780
+# in_pcblookup_hash_locked() at in_pcblookup_hash_locked+0x4e2/frame 0xfffffe0657e467f0
+# in_pcb_lport_dest() at in_pcb_lport_dest+0x28a/frame 0xfffffe0657e468a0
+# in_pcbconnect_setup() at in_pcbconnect_setup+0x31b/frame 0xfffffe0657e46940
+# udp_send() at udp_send+0x68b/frame 0xfffffe0657e46a50
+# udp6_send() at udp6_send+0x287/frame 0xfffffe0657e46c10
+# sosend_dgram() at sosend_dgram+0x327/frame 0xfffffe0657e46c70
+# sousrsend() at sousrsend+0x7e/frame 0xfffffe0657e46cd0
+# kern_sendit() at kern_sendit+0x1bc/frame 0xfffffe0657e46d60
+# sendit() at sendit+0xba/frame 0xfffffe0657e46db0
+# sys_sendto() at sys_sendto+0x4d/frame 0xfffffe0657e46e00
+# amd64_syscall() at amd64_syscall+0x15a/frame 0xfffffe0657e46f30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0657e46f30
+# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x822a3a31a, rsp = 0x8208224d8, rbp = 0x820822500 ---
+# KDB: enter: panic
+# [ thread pid 47141 tid 357973 ]
+# Stopped at kdb_enter+0x32: movq $0,0x12906d3(%rip)
+# db> x/s version
+# FreeBSD 14.0-CURRENT #0 main-n261389-109abf744bf76: Wed Mar 8 06:10:24 CET 2023
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/a
+# db>
+
+[ `uname -p` != "amd64" ] && exit 0
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=7cae38958ddfe2c338548b4217587bd6d89b43e2
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// Reported-by: syzbot+c8e3dac881bba85bc029@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+int main(void)
+{
+ syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
+ intptr_t res = 0;
+ res = syscall(SYS_socket, 0x1cul, 2ul, 0);
+ if (res != -1)
+ r[0] = res;
+ *(uint32_t*)0x200001c0 = 0;
+ syscall(SYS_setsockopt, r[0], 0x29, 0x1b, 0x200001c0ul, 4ul);
+ *(uint8_t*)0x20000000 = 0x1c;
+ *(uint8_t*)0x20000001 = 0x1c;
+ *(uint16_t*)0x20000002 = htobe16(0x4e22);
+ *(uint32_t*)0x20000004 = 0;
+ memset((void*)0x20000008, 0, 10);
+ memset((void*)0x20000012, 255, 2);
+ *(uint32_t*)0x20000014 = htobe32(0);
+ *(uint32_t*)0x20000018 = 0;
+ syscall(SYS_sendto, r[0], 0ul, 0ul, 0ul, 0x20000000ul, 0x1cul);
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+(cd /tmp; timeout 2m ./$prog)
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/syzkaller.*
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller66.sh b/tools/test/stress2/misc/syzkaller66.sh
new file mode 100755
index 000000000000..8d1e9afe6f6c
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller66.sh
@@ -0,0 +1,156 @@
+#!/bin/sh
+
+# panic: in_pcbconnect: inp is already connected
+# cpuid = 2
+# time = 1687326262
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe016e604b60
+# vpanic() at vpanic+0x150/frame 0xfffffe016e604bb0
+# panic() at panic+0x43/frame 0xfffffe016e604c10
+# in_pcbconnect_setup() at in_pcbconnect_setup/frame 0xfffffe016e604c60
+# tcp_connect() at tcp_connect+0xa3/frame 0xfffffe016e604ca0
+# tcp_usr_connect() at tcp_usr_connect+0xf3/frame 0xfffffe016e604d10
+# soconnectat() at soconnectat+0xaf/frame 0xfffffe016e604d60
+# kern_connectat() at kern_connectat+0xe1/frame 0xfffffe016e604dc0
+# sys_connect() at sys_connect+0x75/frame 0xfffffe016e604e00
+# amd64_syscall() at amd64_syscall+0x157/frame 0xfffffe016e604f30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe016e604f30
+# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x823c81a6a, rsp = 0x8210ed3c8, rbp = 0x8210ed3e0 ---
+# KDB: enter: panic
+# [ thread pid 46907 tid 100356 ]
+# Stopped at kdb_enter+0x32: movq $0,0xddf693(%rip)
+# db> x/s version
+# version: FreeBSD 14.0-CURRENT #0 main-n263725-1efa7dbc0798e: Wed Jun 21 09:13:50 CEST 2023
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO-KASAN\012
+# db>
+
+[ `uname -p` != "amd64" ] && exit 0
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=44e3d85e927362a22cc594b9d1d3072f38da7972
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// Reported-by: syzbot+f0f7871ec5397602b446@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+static void kill_and_wait(int pid, int* status)
+{
+ kill(pid, SIGKILL);
+ while (waitpid(-1, status, 0) != pid) {
+ }
+}
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS 0
+
+static void loop(void)
+{
+ int iter __unused = 0;
+ for (;; iter++) {
+ int pid = fork();
+ if (pid < 0)
+ exit(1);
+ if (pid == 0) {
+ execute_one();
+ exit(0);
+ }
+ int status = 0;
+ uint64_t start = current_time_ms();
+ for (;;) {
+ if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+ break;
+ sleep_ms(1);
+ if (current_time_ms() - start < 5000)
+ continue;
+ kill_and_wait(pid, &status);
+ break;
+ }
+ }
+}
+
+uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
+
+void execute_one(void)
+{
+ intptr_t res = 0;
+ res = syscall(SYS_socket, 2ul, 1ul, 0);
+ if (res != -1)
+ r[0] = res;
+ *(uint8_t*)0x200001c0 = 0x10;
+ *(uint8_t*)0x200001c1 = 2;
+ *(uint16_t*)0x200001c2 = htobe16(0x4e22);
+ *(uint32_t*)0x200001c4 = htobe32(0x7f000001);
+ memset((void*)0x200001c8, 0, 8);
+ syscall(SYS_bind, r[0], 0x200001c0ul, 0x10ul);
+ syscall(SYS_listen, r[0], 0);
+ res = syscall(SYS_socket, 2ul, 1ul, 0);
+ if (res != -1)
+ r[1] = res;
+ *(uint8_t*)0x200000c0 = 0x10;
+ *(uint8_t*)0x200000c1 = 2;
+ *(uint16_t*)0x200000c2 = htobe16(0x4e22);
+ *(uint32_t*)0x200000c4 = htobe32(0x7f000001);
+ memset((void*)0x200000c8, 0, 8);
+ syscall(SYS_connect, r[1], 0x200000c0ul, 0x10ul);
+ *(uint64_t*)0x20002580 = 0;
+ *(uint32_t*)0x20002588 = 0;
+ *(uint64_t*)0x20002590 = 0;
+ *(uint64_t*)0x20002598 = 0;
+ *(uint64_t*)0x200025a0 = 0;
+ *(uint64_t*)0x200025a8 = 0;
+ *(uint32_t*)0x200025b0 = 0;
+ syscall(SYS_sendmsg, r[1], 0x20002580ul, 0x20104ul);
+ syscall(SYS_shutdown, r[1], 1ul);
+ *(uint8_t*)0x200000c0 = 0x10;
+ *(uint8_t*)0x200000c1 = 2;
+ *(uint16_t*)0x200000c2 = htobe16(0x4e22);
+ *(uint32_t*)0x200000c4 = htobe32(0x7f000001);
+ memset((void*)0x200000c8, 0, 8);
+ syscall(SYS_connect, r[1], 0x200000c0ul, 0x10ul);
+}
+int main(void)
+{
+ syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
+ loop();
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1
+
+(cd /tmp; timeout 2m ./$prog)
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/syzkaller.*
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller67.sh b/tools/test/stress2/misc/syzkaller67.sh
new file mode 100755
index 000000000000..d5dc340442ae
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller67.sh
@@ -0,0 +1,99 @@
+#!/bin/sh
+
+# panic: ASan: Invalid access, 8-byte read at 0xfffffe01fece46f8, StackMiddle(f2)
+# cpuid = 4
+# time = 1687335671
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0xa5/frame 0xfffffe01fece42f0
+# kdb_backtrace() at kdb_backtrace+0xc7/frame 0xfffffe01fece4450
+# vpanic() at vpanic+0x1d7/frame 0xfffffe01fece4510
+# panic() at panic+0xb5/frame 0xfffffe01fece45e0
+# kasan_report() at kasan_report+0xdc/frame 0xfffffe01fece46b0
+# __cap_rights_is_set() at __cap_rights_is_set+0x186/frame 0xfffffe01fece47d0
+# fget_fcntl() at fget_fcntl+0xd7/frame 0xfffffe01fece48d0
+# kern_fcntl() at kern_fcntl+0x602/frame 0xfffffe01fece4c10
+# kern_fcntl_freebsd() at kern_fcntl_freebsd+0x244/frame 0xfffffe01fece4d30
+# ia32_syscall() at ia32_syscall+0x32a/frame 0xfffffe01fece4f30
+# int0x80_syscall_common() at int0x80_syscall_common+0x9c/frame 0xffffdb38
+# KDB: enter: panic
+# [ thread pid 4224 tid 100231 ]
+# Stopped at kdb_enter+0x34: movq $0,0x1e3f7c1(%rip)
+# db> x/s version
+# version: FreeBSD 14.0-CURRENT #0 main-n263725-1efa7dbc0798e: Wed Jun 21 09:13:50 CEST 2023
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO-KASAN
+# db>
+
+uname -p | grep -Eq "amd64|i386" || exit 0
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=81419dc41de046ccb99da6f333074b750ac36680
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// Reported-by: syzbot+d35497494d68b4859367@syzkaller.appspotmail.com
+// i386 + ASan
+
+#define _GNU_SOURCE
+
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+uint64_t r[5] = {0x0, 0x0, 0x0, 0x0, 0x0};
+
+int main(void)
+{
+ syscall(SYS_mmap, 0x10000000, 0x1000000, 7, 0x1012, -1, 0);
+ intptr_t res = 0;
+ syscall(SYS_munmap, 0x10ffa000, 0x3000);
+ syscall(SYS_mmap, 0x10ffd000, 0x1000, 4, 0x1010, -1, 0);
+ syscall(SYS_mmap, 0x10ffc000, 0x1000, 0, 0x1010, -1, 0);
+ syscall(SYS_mmap, 0x10ffc000, 0x1000, 0, 0x1010, -1, 0);
+ syscall(SYS_mprotect, 0x10ffe000, 0x2000, 7);
+ syscall(SYS_mprotect, 0x10ffd000, 0x3000, 0);
+ syscall(SYS_fork);
+ res = syscall(SYS_fork);
+ if (res != -1)
+ r[0] = res;
+ syscall(SYS_fork);
+ res = syscall(SYS_fork);
+ if (res != -1)
+ r[1] = res;
+ syscall(SYS_sigqueue, (intptr_t)r[1], 0x2b, 0);
+ res = syscall(SYS_fork);
+ if (res != -1)
+ r[2] = res;
+ syscall(SYS_sigqueue, (intptr_t)r[2], 0x2b, 0);
+ syscall(SYS_vfork);
+ syscall(SYS_fcntl, -1, 5, 0);
+ syscall(SYS_sigqueue, 0, 0x2b, 0);
+ syscall(SYS_getpgrp, (intptr_t)r[0]);
+ syscall(SYS_fork);
+ res = syscall(SYS_fork);
+ if (res != -1)
+ r[3] = res;
+ syscall(SYS_sigqueue, (intptr_t)r[3], 0x2b, 0);
+ syscall(SYS_getpid);
+ syscall(SYS_mmap, 0x10ffc000, 0x1000, 3, 0x10, -1, 7);
+ syscall(SYS_mmap, 0x10ffc000, 0x1000, 3, 0x10, -1, 7);
+ res = syscall(SYS_fork);
+ if (res != -1)
+ r[4] = res;
+ syscall(SYS_sigqueue, (intptr_t)r[4], 0xc, 0);
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 -m32 /tmp/$prog.c || exit 1
+
+(cd /tmp; timeout 2m ./$prog)
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/syzkaller.*
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller68.sh b/tools/test/stress2/misc/syzkaller68.sh
new file mode 100755
index 000000000000..3d60af5215c5
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller68.sh
@@ -0,0 +1,235 @@
+#!/bin/sh
+
+# panic: mutex Giant owned at ../../../kern/kern_thread.c:1409
+# cpuid = 0
+# time = 1688501618
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0171ba2510
+# vpanic() at vpanic+0x150/frame 0xfffffe0171ba2560
+# panic() at panic+0x43/frame 0xfffffe0171ba25c0
+# __mtx_assert() at __mtx_assert+0xc4/frame 0xfffffe0171ba25d0
+# thread_suspend_check() at thread_suspend_check+0x38/frame 0xfffffe0171ba2610
+# sig_intr() at sig_intr+0x78/frame 0xfffffe0171ba2640
+# fork1() at fork1+0x238/frame 0xfffffe0171ba26c0
+# kproc_create() at kproc_create+0x92/frame 0xfffffe0171ba2790
+# kproc_kthread_add() at kproc_kthread_add+0xdd/frame 0xfffffe0171ba28b0
+# zthr_create_timer() at zthr_create_timer+0x109/frame 0xfffffe0171ba2930
+# arc_init() at arc_init+0x1b44/frame 0xfffffe0171ba2970
+# dmu_init() at dmu_init+0x31/frame 0xfffffe0171ba2980
+# spa_init() at spa_init+0xed/frame 0xfffffe0171ba29a0
+# zfs_kmod_init() at zfs_kmod_init+0x1f/frame 0xfffffe0171ba29c0
+# zfs_modevent() at zfs_modevent+0module_register_init() at module_register_init+0xb0/frame 0xfffffe0171ba2a10
+# linker_load_module() at linker_load_module+0xbd2/frame 0xfffffe0171ba2d10
+# kern_kldload() at kern_kldload+0x16f/frame 0xfffffe0171ba2d60
+# vfs_byname_kld() at vfs_byname_kld+0x31/frame 0xfffffe0171ba2da0
+# sys_mount() at sys_mount+0xa9/frame 0xfffffe0171ba2e00
+# amd64_syscall() at amd64_syscall+0x150/frame 0xfffffe0171ba2f30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0171ba2f30
+# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x823f70e9a, rsp = 0x82513af78, rbp = 0x82513af90 KDB: enter: panic
+# [ thread pid 43886 tid 178779 ]
+# Stopped at kdb_enter+0x32: movq $0,0xde5863(%rip)
+# db> x/s version
+# version: FreeBSD 14.0-CURRENT #0 main-n263953-d7614c010c762: Tue Jul 4 19:29:44 CEST 2023
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO
+# db>
+
+uname -p | grep -Eq "amd64|i386" || exit 0
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=85a795d15aa54816d63f71f69bfb3a2c61635472
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// Reported-by: syzbot+dce5858451a2329877ff@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <time.h>
+#include <unistd.h>
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+ pthread_t th;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 128 << 10);
+ int i = 0;
+ for (; i < 100; i++) {
+ if (pthread_create(&th, &attr, fn, arg) == 0) {
+ pthread_attr_destroy(&attr);
+ return;
+ }
+ if (errno == EAGAIN) {
+ usleep(50);
+ continue;
+ }
+ break;
+ }
+ exit(1);
+}
+
+typedef struct {
+ pthread_mutex_t mu;
+ pthread_cond_t cv;
+ int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+ if (pthread_mutex_init(&ev->mu, 0))
+ exit(1);
+ if (pthread_cond_init(&ev->cv, 0))
+ exit(1);
+ ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+ ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ if (ev->state)
+ exit(1);
+ ev->state = 1;
+ pthread_mutex_unlock(&ev->mu);
+ pthread_cond_broadcast(&ev->cv);
+}
+
+static void event_wait(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ while (!ev->state)
+ pthread_cond_wait(&ev->cv, &ev->mu);
+ pthread_mutex_unlock(&ev->mu);
+}
+
+static int event_isset(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+ uint64_t start = current_time_ms();
+ uint64_t now = start;
+ pthread_mutex_lock(&ev->mu);
+ for (;;) {
+ if (ev->state)
+ break;
+ uint64_t remain = timeout - (now - start);
+ struct timespec ts;
+ ts.tv_sec = remain / 1000;
+ ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+ pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
+ now = current_time_ms();
+ if (now - start > timeout)
+ break;
+ }
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+struct thread_t {
+ int created, call;
+ event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+ struct thread_t* th = (struct thread_t*)arg;
+ for (;;) {
+ event_wait(&th->ready);
+ event_reset(&th->ready);
+ execute_call(th->call);
+ __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->done);
+ }
+ return 0;
+}
+
+static void loop(void)
+{
+ int i, call, thread;
+ for (call = 0; call < 1; call++) {
+ for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+ thread++) {
+ struct thread_t* th = &threads[thread];
+ if (!th->created) {
+ th->created = 1;
+ event_init(&th->ready);
+ event_init(&th->done);
+ event_set(&th->done);
+ thread_start(thr, th);
+ }
+ if (!event_isset(&th->done))
+ continue;
+ event_reset(&th->done);
+ th->call = call;
+ __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->ready);
+ event_timedwait(&th->done, 50);
+ break;
+ }
+ }
+ for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+ sleep_ms(1);
+}
+
+void execute_call(int call)
+{
+ switch (call) {
+ case 0:
+ memcpy((void*)0x20000440, "zfs\000", 4);
+ syscall(SYS_mount, 0x20000440ul, 0ul, 0x8300648ul, 0ul);
+ break;
+ }
+}
+int main(void)
+{
+ syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
+ loop();
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+(cd /tmp; timeout 2m ./$prog)
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/syzkaller.*
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller69.sh b/tools/test/stress2/misc/syzkaller69.sh
new file mode 100755
index 000000000000..fbaa3e5b9c9c
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller69.sh
@@ -0,0 +1,494 @@
+#!/bin/sh
+
+# Fatal trap 12: page fault while in kernel mode
+# cpuid = 6; apic id = 06
+# fault virtual address = 0xb8
+# fault code = supervisor read data, page not present
+# instruction pointer = 0x20:0xffffffff80d3c17b
+# stack pointer = 0x28:0xfffffe00e49fab80
+# frame pointer = 0x28:0xfffffe00e49facc0
+# code segment = base 0x0, limit 0xfffff, type 0x1b
+# = DPL 0, pres 1, long 1, def32 0, gran 1
+# processor eflags = interrupt enabled, resume, IOPL = 0
+# current process = 12 (swi1: netisr 0)
+# rdi: fffff802d2d8daa0 rsi: fffffe00e49fab48 rdx: ffffffff819d5a90
+# rcx: ffffffff819d5a98 r8: 00000000ffffffff r9: 0000000000000000
+# rax: 0000000000000000 rbx: 0000000000000002 rbp: fffffe00e49facc0
+# r10: fffff802d2d8daa0 r11: 0000000000010000 r12: 0000000000000000
+# r13: fffff802d2d8da80 r14: 0000000000000060 r15: fffff802d2d8dab8
+# trap number = 12
+# panic: page fault
+# cpuid = 6
+# time = 1689053386
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe00e49fa930
+# vpanic() at vpanic+0x149/frame 0xfffffe00e49fa980
+# panic() at panic+0x43/frame 0xfffffe00e49fa9e0
+# trap_fatal() at trap_fatal+0x40c/frame 0xfffffe00e49faa40
+# trap_pfault() at trap_pfault+0xae/frame 0xfffffe00e49faab0
+# calltrap() at calltrap+0x8/frame 0xfffffe00e49faab0
+# --- trap 0xc, rip = 0xffffffff80d3c17b, rsp = 0xfffffe00e49fab80, rbp = 0xfffffe00e49facc0 ---
+# tcp_input_with_port() at tcp_input_with_port+0x70b/frame 0xfffffe00e49facc0
+# tcp6_input_with_port() at tcp6_input_with_port+0x6a/frame 0xfffffe00e49facf0
+# tcp6_input() at tcp6_input+0xb/frame 0xfffffe00e49fad00
+# ip6_input() at ip6_input+0xc97/frame 0xfffffe00e49fade0
+# swi_net() at swi_net+0x19b/frame 0xfffffe00e49fae60
+# ithread_loop() at ithread_loop+0x266/frame 0xfffffe00e49faef0
+# fork_exit() at fork_exit+0x82/frame 0xfffffe00e49faf30
+# fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe00e49faf30
+# --- trap 0, rip = 0, rsp = 0, rbp = 0 ---
+# KDB: enter: panic
+# [ thread pid 12 tid 100089 ]
+# Stopped at kdb_enter+0x32: movq $0,0xde5053(%rip)
+# db> x/s version
+# version: FreeBSD 14.0-CURRENT #0 main-n264110-43ed91e00bbb1: Tue Jul 11 06:28:21 CEST 2023
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO
+# db>
+
+uname -p | grep -Eq "amd64" || exit 0
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=44d933862f436b628c77db28122dbfa4e00990aa
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// Reported-by: syzbot+e7d2e451f89fb444319b@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+static unsigned long long procid;
+
+static __thread int clone_ongoing;
+static __thread int skip_segv;
+static __thread jmp_buf segv_env;
+
+static void segv_handler(int sig, siginfo_t* info, void* ctx __unused)
+{
+ if (__atomic_load_n(&clone_ongoing, __ATOMIC_RELAXED) != 0) {
+ exit(sig);
+ }
+ uintptr_t addr = (uintptr_t)info->si_addr;
+ const uintptr_t prog_start = 1 << 20;
+ const uintptr_t prog_end = 100 << 20;
+ int skip = __atomic_load_n(&skip_segv, __ATOMIC_RELAXED) != 0;
+ int valid = addr < prog_start || addr > prog_end;
+ if (sig == SIGBUS)
+ valid = 1;
+ if (skip && valid) {
+ _longjmp(segv_env, 1);
+ }
+ exit(sig);
+}
+
+static void install_segv_handler(void)
+{
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = segv_handler;
+ sa.sa_flags = SA_NODEFER | SA_SIGINFO;
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGBUS, &sa, NULL);
+}
+
+#define NONFAILING(...) \
+ ({ \
+ int ok = 1; \
+ __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \
+ if (_setjmp(segv_env) == 0) { \
+ __VA_ARGS__; \
+ } else \
+ ok = 0; \
+ __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \
+ ok; \
+ })
+
+static void kill_and_wait(int pid, int* status)
+{
+ kill(pid, SIGKILL);
+ while (waitpid(-1, status, 0) != pid) {
+ }
+}
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void use_temporary_dir(void)
+{
+ char tmpdir_template[] = "./syzkaller.XXXXXX";
+ char* tmpdir = mkdtemp(tmpdir_template);
+ if (!tmpdir)
+ exit(1);
+ if (chmod(tmpdir, 0777))
+ exit(1);
+ if (chdir(tmpdir))
+ exit(1);
+}
+
+static void reset_flags(const char* filename)
+{
+ struct stat st;
+ if (lstat(filename, &st))
+ exit(1);
+ st.st_flags &= ~(SF_NOUNLINK | UF_NOUNLINK | SF_IMMUTABLE | UF_IMMUTABLE |
+ SF_APPEND | UF_APPEND);
+ if (lchflags(filename, st.st_flags))
+ exit(1);
+}
+static void __attribute__((noinline)) remove_dir(const char* dir)
+{
+ DIR* dp = opendir(dir);
+ if (dp == NULL) {
+ if (errno == EACCES) {
+ if (rmdir(dir))
+ exit(1);
+ return;
+ }
+ exit(1);
+ }
+ struct dirent* ep = 0;
+ while ((ep = readdir(dp))) {
+ if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
+ continue;
+ char filename[FILENAME_MAX];
+ snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
+ struct stat st;
+ if (lstat(filename, &st))
+ exit(1);
+ if (S_ISDIR(st.st_mode)) {
+ remove_dir(filename);
+ continue;
+ }
+ if (unlink(filename)) {
+ if (errno == EPERM) {
+ reset_flags(filename);
+ reset_flags(dir);
+ if (unlink(filename) == 0)
+ continue;
+ }
+ exit(1);
+ }
+ }
+ closedir(dp);
+ while (rmdir(dir)) {
+ if (errno == EPERM) {
+ reset_flags(dir);
+ if (rmdir(dir) == 0)
+ break;
+ }
+ exit(1);
+ }
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+ pthread_t th;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 128 << 10);
+ int i = 0;
+ for (; i < 100; i++) {
+ if (pthread_create(&th, &attr, fn, arg) == 0) {
+ pthread_attr_destroy(&attr);
+ return;
+ }
+ if (errno == EAGAIN) {
+ usleep(50);
+ continue;
+ }
+ break;
+ }
+ exit(1);
+}
+
+typedef struct {
+ pthread_mutex_t mu;
+ pthread_cond_t cv;
+ int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+ if (pthread_mutex_init(&ev->mu, 0))
+ exit(1);
+ if (pthread_cond_init(&ev->cv, 0))
+ exit(1);
+ ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+ ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ if (ev->state)
+ exit(1);
+ ev->state = 1;
+ pthread_mutex_unlock(&ev->mu);
+ pthread_cond_broadcast(&ev->cv);
+}
+
+static void event_wait(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ while (!ev->state)
+ pthread_cond_wait(&ev->cv, &ev->mu);
+ pthread_mutex_unlock(&ev->mu);
+}
+
+static int event_isset(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+ uint64_t start = current_time_ms();
+ uint64_t now = start;
+ pthread_mutex_lock(&ev->mu);
+ for (;;) {
+ if (ev->state)
+ break;
+ uint64_t remain = timeout - (now - start);
+ struct timespec ts;
+ ts.tv_sec = remain / 1000;
+ ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+ pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
+ now = current_time_ms();
+ if (now - start > timeout)
+ break;
+ }
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static void sandbox_common()
+{
+ struct rlimit rlim;
+ rlim.rlim_cur = rlim.rlim_max = 128 << 20;
+ setrlimit(RLIMIT_AS, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 8 << 20;
+ setrlimit(RLIMIT_MEMLOCK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+ setrlimit(RLIMIT_FSIZE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+ setrlimit(RLIMIT_STACK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ setrlimit(RLIMIT_CORE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 256;
+ setrlimit(RLIMIT_NOFILE, &rlim);
+}
+
+static void loop();
+
+static int do_sandbox_none(void)
+{
+ sandbox_common();
+ loop();
+ return 0;
+}
+
+struct thread_t {
+ int created, call;
+ event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+ struct thread_t* th = (struct thread_t*)arg;
+ for (;;) {
+ event_wait(&th->ready);
+ event_reset(&th->ready);
+ execute_call(th->call);
+ __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->done);
+ }
+ return 0;
+}
+
+static void execute_one(void)
+{
+ int i, call, thread;
+ for (call = 0; call < 7; call++) {
+ for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+ thread++) {
+ struct thread_t* th = &threads[thread];
+ if (!th->created) {
+ th->created = 1;
+ event_init(&th->ready);
+ event_init(&th->done);
+ event_set(&th->done);
+ thread_start(thr, th);
+ }
+ if (!event_isset(&th->done))
+ continue;
+ event_reset(&th->done);
+ th->call = call;
+ __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->ready);
+ if (call == 3)
+ break;
+ event_timedwait(&th->done, 50);
+ break;
+ }
+ }
+ for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+ sleep_ms(1);
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS 0
+
+static void loop(void)
+{
+ int iter = 0;
+ for (;; iter++) {
+ char cwdbuf[32];
+ sprintf(cwdbuf, "./%d", iter);
+ if (mkdir(cwdbuf, 0777))
+ exit(1);
+ int pid = fork();
+ if (pid < 0)
+ exit(1);
+ if (pid == 0) {
+ if (chdir(cwdbuf))
+ exit(1);
+ execute_one();
+ exit(0);
+ }
+ int status = 0;
+ uint64_t start = current_time_ms();
+ for (;;) {
+ if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+ break;
+ sleep_ms(1);
+ if (current_time_ms() - start < 5000)
+ continue;
+ kill_and_wait(pid, &status);
+ break;
+ }
+ remove_dir(cwdbuf);
+ }
+}
+
+uint64_t r[2] = {0xffffffffffffffff, 0xffffffffffffffff};
+
+void execute_call(int call)
+{
+ intptr_t res = 0;
+ switch (call) {
+ case 0:
+ res = syscall(SYS_socket, 0x1cul, 1ul, 0);
+ if (res != -1)
+ r[0] = res;
+ break;
+ case 1:
+ NONFAILING(*(uint32_t*)0x20000080 = 9);
+ syscall(SYS_setsockopt, r[0], 0xffff, 0x10000, 0x20000080ul, 4ul);
+ break;
+ case 2:
+ NONFAILING(*(uint8_t*)0x200000c0 = 0x1c);
+ NONFAILING(*(uint8_t*)0x200000c1 = 0x1c);
+ NONFAILING(*(uint16_t*)0x200000c2 = htobe16(0x4e20 + procid * 4));
+ NONFAILING(*(uint32_t*)0x200000c4 = 0);
+ NONFAILING(memset((void*)0x200000c8, 0, 16));
+ NONFAILING(*(uint32_t*)0x200000d8 = 0);
+ syscall(SYS_bind, r[0], 0x200000c0ul, 0x1cul);
+ break;
+ case 3:
+ NONFAILING(*(uint32_t*)0x20000080 = 9);
+ syscall(SYS_setsockopt, r[0], 0xffff, 0x10000, 0x20000080ul, 4ul);
+ break;
+ case 4:
+ NONFAILING(*(uint32_t*)0x20000040 = 0x72);
+ NONFAILING(*(uint8_t*)0x20000048 = 0x10);
+ NONFAILING(*(uint8_t*)0x20000049 = 2);
+ NONFAILING(*(uint16_t*)0x2000004a = htobe16(0x4e21 + procid * 4));
+ NONFAILING(*(uint32_t*)0x2000004c = htobe32(0x7f000001));
+ NONFAILING(memset((void*)0x20000050, 0, 8));
+ NONFAILING(memset((void*)0x20000058, 0, 112));
+ syscall(SYS_setsockopt, r[0], 0, 0x51, 0x20000040ul, 0x88ul);
+ break;
+ case 5:
+ res = syscall(SYS_socket, 0x1cul, 1ul, 0);
+ if (res != -1)
+ r[1] = res;
+ break;
+ case 6:
+ NONFAILING(*(uint8_t*)0x20000140 = 0x1c);
+ NONFAILING(*(uint8_t*)0x20000141 = 0x1c);
+ NONFAILING(*(uint16_t*)0x20000142 = htobe16(0x4e20 + procid * 4));
+ NONFAILING(*(uint32_t*)0x20000144 = 0);
+ NONFAILING(memset((void*)0x20000148, 0, 16));
+ NONFAILING(*(uint32_t*)0x20000158 = 0);
+ syscall(SYS_connect, r[1], 0x20000140ul, 0x1cul);
+ break;
+ }
+}
+int main(void)
+{
+ syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
+ install_segv_handler();
+ for (procid = 0; procid < 4; procid++) {
+ if (fork() == 0) {
+ use_temporary_dir();
+ do_sandbox_none();
+ }
+ }
+ sleep(1000000);
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+(cd ../testcases/swap; ./swap -t 2m -i 10 -l 100 > /dev/null 2>&1) &
+
+(cd /tmp; timeout 2m ./$prog)
+wait
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/syzkaller.*
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller7.sh b/tools/test/stress2/misc/syzkaller7.sh
index f43747006862..c03a47d8b2d2 100755
--- a/tools/test/stress2/misc/syzkaller7.sh
+++ b/tools/test/stress2/misc/syzkaller7.sh
@@ -80,7 +80,7 @@ static void execute_one(void);
static void loop(void)
{
- int iter;
+ int iter __unused;
for (iter = 0;; iter++) {
int pid = fork();
if (pid < 0)
diff --git a/tools/test/stress2/misc/syzkaller70.sh b/tools/test/stress2/misc/syzkaller70.sh
new file mode 100755
index 000000000000..7f63da7f6475
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller70.sh
@@ -0,0 +1,302 @@
+#!/bin/sh
+
+# db:1:pho1> bt
+# Tracing pid 5640 tid 102468 td 0xfffffe00e4d26ac0
+# kdb_enter() at kdb_enter+0x32/frame 0xfffffe010dbcf260
+# vpanic() at vpanic+0x163/frame 0xfffffe010dbcf390
+# panic() at panic+0x43/frame 0xfffffe010dbcf3f0
+# vm_map_insert1() at vm_map_insert1+0x147/frame 0xfffffe010dbcf4a0
+# vm_map_insert() at vm_map_insert+0x69/frame 0xfffffe010dbcf510
+# vm_map_growstack() at vm_map_growstack+0x90e/frame 0xfffffe010dbcf650
+# vm_map_lookup() at vm_map_lookup+0x15f/frame 0xfffffe010dbcf6e0
+# vm_fault() at vm_fault+0x12f/frame 0xfffffe010dbcf820
+# vm_fault_trap() at vm_fault_trap+0x6f/frame 0xfffffe010dbcf860
+# trap_pfault() at trap_pfault+0x24a/frame 0xfffffe010dbcf8d0
+# calltrap() at calltrap+0x8/frame 0xfffffe010dbcf8d0
+# --- trap 0xc, rip = 0xffffffff81057a06, rsp = 0xfffffe010dbcf9a0, rbp = 0xfffffe010dbcf9a0 ---
+# copyin_nosmap_erms() at copyin_nosmap_erms+0x156/frame 0xfffffe010dbcf9a0
+# uiomove_fromphys() at uiomove_fromphys+0x145/frame 0xfffffe010dbcfa10
+# uiomove_object_page() at uiomove_object_page+0x1dc/frame 0xfffffe010dbcfa70
+# uiomove_object() at uiomove_object+0xa4/frame 0xfffffe010dbcfac0
+# tmpfs_write() at tmpfs_write+0xe4/frame 0xfffffe010dbcfb10
+# VOP_WRITE_APV() at VOP_WRITE_APV+0xcf/frame 0xfffffe010dbcfc20
+# vn_write() at vn_write+0x2f4/frame 0xfffffe010dbcfcb0
+# vn_io_fault() at vn_io_fault+0x1e2/frame 0xfffffe010dbcfd40
+# dofilewrite() at dofilewrite+0x82/frame 0xfffffe010dbcfd90
+# kern_pwritev() at kern_pwritev+0x64/frame 0xfffffe010dbcfdd0
+# sys_pwritev() at sys_pwritev+0x3a/frame 0xfffffe010dbcfe00
+# amd64_syscall() at amd64_syscall+0x14f/frame 0xfffffe010dbcff30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe010dbcff30
+# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x822d56fca, rsp = 0x824255f58, rbp = 0x824255f90 ---
+# FreeBSD 14.0-ALPHA1 #1 main-n264742-81b41b2ef5bfd5-dirty: Tue Aug 15 19:52:50 CEST 2023
+
+uname -p | grep -Eq "amd64" || exit 0
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=4c33ed3d5a9072d2ccaec3b2ef7a129f0997f477
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// Reported-by: syzbot+c325d6a75e4fd0a68714@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+static void kill_and_wait(int pid, int* status)
+{
+ kill(pid, SIGKILL);
+ while (waitpid(-1, status, 0) != pid) {
+ }
+}
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+ pthread_t th;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 128 << 10);
+ int i = 0;
+ for (; i < 100; i++) {
+ if (pthread_create(&th, &attr, fn, arg) == 0) {
+ pthread_attr_destroy(&attr);
+ return;
+ }
+ if (errno == EAGAIN) {
+ usleep(50);
+ continue;
+ }
+ break;
+ }
+ exit(1);
+}
+
+typedef struct {
+ pthread_mutex_t mu;
+ pthread_cond_t cv;
+ int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+ if (pthread_mutex_init(&ev->mu, 0))
+ exit(1);
+ if (pthread_cond_init(&ev->cv, 0))
+ exit(1);
+ ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+ ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ if (ev->state)
+ exit(1);
+ ev->state = 1;
+ pthread_mutex_unlock(&ev->mu);
+ pthread_cond_broadcast(&ev->cv);
+}
+
+static void event_wait(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ while (!ev->state)
+ pthread_cond_wait(&ev->cv, &ev->mu);
+ pthread_mutex_unlock(&ev->mu);
+}
+
+static int event_isset(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+ uint64_t start = current_time_ms();
+ uint64_t now = start;
+ pthread_mutex_lock(&ev->mu);
+ for (;;) {
+ if (ev->state)
+ break;
+ uint64_t remain = timeout - (now - start);
+ struct timespec ts;
+ ts.tv_sec = remain / 1000;
+ ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+ pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
+ now = current_time_ms();
+ if (now - start > timeout)
+ break;
+ }
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+struct thread_t {
+ int created, call;
+ event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+ struct thread_t* th = (struct thread_t*)arg;
+ for (;;) {
+ event_wait(&th->ready);
+ event_reset(&th->ready);
+ execute_call(th->call);
+ __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->done);
+ }
+ return 0;
+}
+
+static void execute_one(void)
+{
+ int i, call, thread;
+ for (call = 0; call < 4; call++) {
+ for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+ thread++) {
+ struct thread_t* th = &threads[thread];
+ if (!th->created) {
+ th->created = 1;
+ event_init(&th->ready);
+ event_init(&th->done);
+ event_set(&th->done);
+ thread_start(thr, th);
+ }
+ if (!event_isset(&th->done))
+ continue;
+ event_reset(&th->done);
+ th->call = call;
+ __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->ready);
+ event_timedwait(&th->done, 50);
+ break;
+ }
+ }
+ for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+ sleep_ms(1);
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS 0
+
+static void loop(void)
+{
+ int iter __unused = 0;
+ for (;; iter++) {
+ int pid = fork();
+ if (pid < 0)
+ exit(1);
+ if (pid == 0) {
+ execute_one();
+ exit(0);
+ }
+ int status = 0;
+ uint64_t start = current_time_ms();
+ for (;;) {
+ if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+ break;
+ sleep_ms(1);
+ if (current_time_ms() - start < 5000)
+ continue;
+ kill_and_wait(pid, &status);
+ break;
+ }
+ }
+}
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+void execute_call(int call)
+{
+ intptr_t res = 0;
+ switch (call) {
+ case 0:
+ memcpy((void*)0x20000240, "./file0\000", 8);
+ res = syscall(SYS_open, /*file=*/0x20000240ul,
+ /*flags=*/0x40000400000002c2ul, /*mode=*/0ul);
+ if (res != -1)
+ r[0] = res;
+ break;
+ case 1:
+ *(uint64_t*)0x20000080 = 0x200006c0;
+ *(uint64_t*)0x20000088 = 0x100000;
+ syscall(SYS_pwritev, /*fd=*/r[0], /*vec=*/0x20000080ul, /*vlen=*/1ul,
+ /*off=*/0ul);
+ break;
+ case 2:
+ syscall(SYS_mmap, /*addr=*/0x20000000ul, /*len=*/0x200000ul, /*prot=*/3ul,
+ /*flags=*/0x410ul, /*fd=*/-1, /*offset=*/0ul);
+ break;
+ case 3:
+ syscall(SYS_mmap, /*addr=*/0x2000c000ul, /*len=*/0x4000ul, /*prot=*/0ul,
+ /*flags=*/0x2010ul, /*fd=*/-1, /*offset=*/0ul);
+ break;
+ }
+}
+int main(void)
+{
+ syscall(SYS_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000ul, /*prot=*/7ul,
+ /*flags=*/0x1012ul, /*fd=*/-1, /*offset=*/0ul);
+ loop();
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+mount | grep -q "on $mntpoint " && umount $mntpoint
+mount -o size=10m -t tmpfs dummy $mntpoint
+
+cd $mntpoint
+for i in `jot 20`; do
+ timeout 3m /tmp/$prog &
+done
+wait
+cd -
+
+umount $mntpoint
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller71.sh b/tools/test/stress2/misc/syzkaller71.sh
new file mode 100755
index 000000000000..58cf7eeb5825
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller71.sh
@@ -0,0 +1,171 @@
+#!/bin/sh
+
+# panic: Counter goes negative
+# cpuid = 4
+# time = 1694583637
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe01bac2a960
+# vpanic() at vpanic+0x132/frame 0xfffffe01bac2aa90
+# panic() at panic+0x43/frame 0xfffffe01bac2aaf0
+# sctp_inpcb_free() at sctp_inpcb_free+0xf28/frame 0xfffffe01bac2ab60
+# sctp_close() at sctp_close+0xc0/frame 0xfffffe01bac2abb0
+# soclose() at soclose+0x154/frame 0xfffffe01bac2ac10
+# _fdrop() at _fdrop+0x1b/frame 0xfffffe01bac2ac30
+# closef() at closef+0x1e3/frame 0xfffffe01bac2acc0
+# fdescfree() at fdescfree+0x41a/frame 0xfffffe01bac2ad80
+# exit1() at exit1+0x4a1/frame 0xfffffe01bac2adf0
+# sys_exit() at sys_exit+0xd/frame 0xfffffe01bac2ae00
+# amd64_syscall() at amd64_syscall+0x14f/frame 0xfffffe01bac2af30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe01bac2af30
+# --- syscall (1, FreeBSD ELF64, exit), rip = 0x824db2f4a, rsp = 0x8211862b8, rbp = 0x8211862d0 ---
+# KDB: enter: pani[ thread pid 9676 tid 346853 ]
+# Stopped at kdb_enter+0x32: movq $0,0xe27583(%rip)
+# db> x/s version
+# version: FreeBSD 15.0-CURRENT #0 main-n265298-10db91ecec98b1: Tue Sep 12 12:16:45 CEST 2023
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO
+# db>
+
+uname -p | grep -Eq "amd64" || exit 0
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=d8a54d453b8e643b807a5c3c56728561f01c0fde
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// Reported-by: syzbot+d4e1d30d578891245f59@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+static unsigned long long procid;
+
+static void kill_and_wait(int pid, int* status)
+{
+ kill(pid, SIGKILL);
+ while (waitpid(-1, status, 0) != pid) {
+ }
+}
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS 0
+
+static void loop(void)
+{
+ int iter __unused = 0;
+ for (;; iter++) {
+ int pid = fork();
+ if (pid < 0)
+ exit(1);
+ if (pid == 0) {
+ execute_one();
+ exit(0);
+ }
+ int status = 0;
+ uint64_t start = current_time_ms();
+ for (;;) {
+ if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+ break;
+ sleep_ms(1);
+ if (current_time_ms() - start < 5000)
+ continue;
+ kill_and_wait(pid, &status);
+ break;
+ }
+ }
+}
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+void execute_one(void)
+{
+ intptr_t res = 0;
+ res = syscall(SYS_socket, 0x1cul, 1ul, 0x84);
+ if (res != -1)
+ r[0] = res;
+ *(uint8_t*)0x20000040 = 0x1c;
+ *(uint8_t*)0x20000041 = 0x1c;
+ *(uint16_t*)0x20000042 = htobe16(0x4e22 + procid * 4);
+ *(uint32_t*)0x20000044 = 0;
+ *(uint64_t*)0x20000048 = htobe64(0);
+ *(uint64_t*)0x20000050 = htobe64(1);
+ *(uint32_t*)0x20000058 = 0;
+ syscall(SYS_bind, r[0], 0x20000040ul, 0x1cul);
+ *(uint8_t*)0x20000180 = 0x1c;
+ *(uint8_t*)0x20000181 = 0x1c;
+ *(uint16_t*)0x20000182 = htobe16(0x4e22 + procid * 4);
+ *(uint32_t*)0x20000184 = 0;
+ *(uint64_t*)0x20000188 = htobe64(0);
+ *(uint64_t*)0x20000190 = htobe64(1);
+ *(uint32_t*)0x20000198 = 0;
+ syscall(SYS_connect, r[0], 0x20000180ul, 0x1cul);
+ *(uint32_t*)0x20000300 = 0x80000021;
+ syscall(SYS_setsockopt, r[0], 0x84, 0x1b, 0x20000300ul, 4ul);
+ memset((void*)0x20000480, 163, 1);
+ syscall(SYS_sendto, r[0], 0x20000480ul, 0xfffffe5cul, 0x188ul, 0ul, 0ul);
+ *(uint16_t*)0x200000c0 = 0;
+ *(uint16_t*)0x200000c2 = 0x200;
+ *(uint32_t*)0x200000c4 = 0;
+ *(uint32_t*)0x200000c8 = 0;
+ *(uint32_t*)0x200000cc = 0;
+ syscall(SYS_setsockopt, r[0], 0x84, 0x21, 0x200000c0ul, 0x10ul);
+ syscall(SYS_shutdown, r[0], 0ul);
+ syscall(SYS_writev, r[0], 0ul, 0ul);
+}
+int main(void)
+{
+ syscall(SYS_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x1012ul, -1, 0ul);
+ for (procid = 0; procid < 4; procid++) {
+ if (fork() == 0) {
+ loop();
+ }
+ }
+ sleep(1000000);
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+mount | grep -q "on $mntpoint " && umount $mntpoint
+mount -o size=10m -t tmpfs dummy $mntpoint
+
+cd $mntpoint
+for i in `jot 20`; do
+ timeout 3m /tmp/$prog &
+done
+wait
+cd -
+
+umount $mntpoint
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller72.sh b/tools/test/stress2/misc/syzkaller72.sh
new file mode 100755
index 000000000000..6dd69987a913
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller72.sh
@@ -0,0 +1,70 @@
+#!/bin/sh
+
+# panic: sbflush_internal: ccc 0 mb 0xfffff8004eee95f0 mbcnt 0
+# cpuid = 9
+# time = 1704448830
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe016a2ccb70
+# vpanic() at vpanic+0x131/frame 0xfffffe016a2ccca0
+# panic() at panic+0x43/frame 0xfffffe016a2ccd00
+# sbrelease_internal() at sbrelease_internal+0x7c/frame 0xfffffe016a2ccd20
+# sbrelease() at sbrelease+0x5e/frame 0xfffffe016a2ccd50
+# sorflush() at sorflush+0x66/frame 0xfffffe016a2ccd70
+# soshutdown() at soshutdown+0x105/frame 0xfffffe016a2ccdb0
+# kern_shutdown() at kern_shutdown+0x60/frame 0xfffffe016a2ccdf0
+# ia32_syscall() at ia32_syscall+0x154/frame 0xfffffe016a2ccf30
+# int0x80_syscall_common() at int0x80_syscall_common+0x9c/frame 0xffffdb44
+# KDB: enter: panic
+# [ thread pid 4927 tid 100275 ]
+# Stopped at : movq $0,0xe37212(%rip)
+# db> x/s version
+# FreeBSD 15.0-CURRENT #0 main-n267418-24cd5c26fe3e: Fri Jan 5 08:21:43 CET 2024
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO
+# db>
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=a9e90e96743f3e20b4a66d9d0d4c08c57ea8cc7f
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// Reported-by: syzbot+a58e1615881c01a51653@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+int main(void)
+{
+ syscall(SYS_mmap, /*addr=*/0x10000000, /*len=*/0x1000000, /*prot=*/7,
+ /*flags=*/0x1012, /*fd=*/-1, /*offset=*/0);
+ intptr_t res = 0;
+ res = syscall(SYS_socket, /*domain=*/0x26, /*type=*/2, /*proto=*/0);
+ if (res != -1)
+ r[0] = res;
+ syscall(SYS_shutdown, /*fd=*/(intptr_t)r[0], /*how=*/0);
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -m32 -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 120 ]; do
+ timeout 3m /tmp/$prog
+done
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller73.sh b/tools/test/stress2/misc/syzkaller73.sh
new file mode 100755
index 000000000000..776ace385f21
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller73.sh
@@ -0,0 +1,537 @@
+#!/bin/sh
+
+# No issues seen (Looks a bit like syzkaller43.sh)
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=cf4c0a08d26692dc8f22b0fcc50db08fd17dd709
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <setjmp.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+#ifndef SYS_aio_writev
+#define SYS_aio_writev 578
+#endif
+
+static __thread int clone_ongoing;
+static __thread int skip_segv;
+static __thread jmp_buf segv_env;
+
+static void segv_handler(int sig, siginfo_t* info, void* ctx __unused)
+{
+ if (__atomic_load_n(&clone_ongoing, __ATOMIC_RELAXED) != 0) {
+ exit(sig);
+ }
+ uintptr_t addr = (uintptr_t)info->si_addr;
+ const uintptr_t prog_start = 1 << 20;
+ const uintptr_t prog_end = 100 << 20;
+ int skip = __atomic_load_n(&skip_segv, __ATOMIC_RELAXED) != 0;
+ int valid = addr < prog_start || addr > prog_end;
+ if (sig == SIGBUS)
+ valid = 1;
+ if (skip && valid) {
+ _longjmp(segv_env, 1);
+ }
+ exit(sig);
+}
+
+static void install_segv_handler(void)
+{
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = segv_handler;
+ sa.sa_flags = SA_NODEFER | SA_SIGINFO;
+ sigaction(SIGSEGV, &sa, NULL);
+ sigaction(SIGBUS, &sa, NULL);
+}
+
+#define NONFAILING(...) \
+ ({ \
+ int ok = 1; \
+ __atomic_fetch_add(&skip_segv, 1, __ATOMIC_SEQ_CST); \
+ if (_setjmp(segv_env) == 0) { \
+ __VA_ARGS__; \
+ } else \
+ ok = 0; \
+ __atomic_fetch_sub(&skip_segv, 1, __ATOMIC_SEQ_CST); \
+ ok; \
+ })
+
+static void kill_and_wait(int pid, int* status)
+{
+ kill(pid, SIGKILL);
+ while (waitpid(-1, status, 0) != pid) {
+ }
+}
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void use_temporary_dir(void)
+{
+ char tmpdir_template[] = "./syzkaller.XXXXXX";
+ char* tmpdir = mkdtemp(tmpdir_template);
+ if (!tmpdir)
+ exit(1);
+ if (chmod(tmpdir, 0777))
+ exit(1);
+ if (chdir(tmpdir))
+ exit(1);
+}
+
+static void reset_flags(const char* filename)
+{
+ struct stat st;
+ if (lstat(filename, &st))
+ exit(1);
+ st.st_flags &= ~(SF_NOUNLINK | UF_NOUNLINK | SF_IMMUTABLE | UF_IMMUTABLE |
+ SF_APPEND | UF_APPEND);
+ if (lchflags(filename, st.st_flags))
+ exit(1);
+}
+static void __attribute__((noinline)) remove_dir(const char* dir)
+{
+ DIR* dp = opendir(dir);
+ if (dp == NULL) {
+ if (errno == EACCES) {
+ if (rmdir(dir))
+ exit(1);
+ return;
+ }
+ exit(1);
+ }
+ struct dirent* ep = 0;
+ while ((ep = readdir(dp))) {
+ if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
+ continue;
+ char filename[FILENAME_MAX];
+ snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
+ struct stat st;
+ if (lstat(filename, &st))
+ exit(1);
+ if (S_ISDIR(st.st_mode)) {
+ remove_dir(filename);
+ continue;
+ }
+ if (unlink(filename)) {
+ if (errno == EPERM) {
+ reset_flags(filename);
+ reset_flags(dir);
+ if (unlink(filename) == 0)
+ continue;
+ }
+ exit(1);
+ }
+ }
+ closedir(dp);
+ while (rmdir(dir)) {
+ if (errno == EPERM) {
+ reset_flags(dir);
+ if (rmdir(dir) == 0)
+ break;
+ }
+ exit(1);
+ }
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+ pthread_t th;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 128 << 10);
+ int i = 0;
+ for (; i < 100; i++) {
+ if (pthread_create(&th, &attr, fn, arg) == 0) {
+ pthread_attr_destroy(&attr);
+ return;
+ }
+ if (errno == EAGAIN) {
+ usleep(50);
+ continue;
+ }
+ break;
+ }
+ exit(1);
+}
+
+typedef struct {
+ pthread_mutex_t mu;
+ pthread_cond_t cv;
+ int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+ if (pthread_mutex_init(&ev->mu, 0))
+ exit(1);
+ if (pthread_cond_init(&ev->cv, 0))
+ exit(1);
+ ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+ ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ if (ev->state)
+ exit(1);
+ ev->state = 1;
+ pthread_mutex_unlock(&ev->mu);
+ pthread_cond_broadcast(&ev->cv);
+}
+
+static void event_wait(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ while (!ev->state)
+ pthread_cond_wait(&ev->cv, &ev->mu);
+ pthread_mutex_unlock(&ev->mu);
+}
+
+static int event_isset(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+ uint64_t start = current_time_ms();
+ uint64_t now = start;
+ pthread_mutex_lock(&ev->mu);
+ for (;;) {
+ if (ev->state)
+ break;
+ uint64_t remain = timeout - (now - start);
+ struct timespec ts;
+ ts.tv_sec = remain / 1000;
+ ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+ pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
+ now = current_time_ms();
+ if (now - start > timeout)
+ break;
+ }
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static void sandbox_common()
+{
+ struct rlimit rlim;
+ rlim.rlim_cur = rlim.rlim_max = 128 << 20;
+ setrlimit(RLIMIT_AS, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 8 << 20;
+ setrlimit(RLIMIT_MEMLOCK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+ setrlimit(RLIMIT_FSIZE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+ setrlimit(RLIMIT_STACK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ setrlimit(RLIMIT_CORE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 256;
+ setrlimit(RLIMIT_NOFILE, &rlim);
+}
+
+static void loop();
+
+static int do_sandbox_none(void)
+{
+ sandbox_common();
+ loop();
+ return 0;
+}
+
+struct thread_t {
+ int created, call;
+ event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+ struct thread_t* th = (struct thread_t*)arg;
+ for (;;) {
+ event_wait(&th->ready);
+ event_reset(&th->ready);
+ execute_call(th->call);
+ __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->done);
+ }
+ return 0;
+}
+
+static void execute_one(void)
+{
+ if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
+ }
+ int i, call, thread;
+ for (call = 0; call < 24; call++) {
+ for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+ thread++) {
+ struct thread_t* th = &threads[thread];
+ if (!th->created) {
+ th->created = 1;
+ event_init(&th->ready);
+ event_init(&th->done);
+ event_set(&th->done);
+ thread_start(thr, th);
+ }
+ if (!event_isset(&th->done))
+ continue;
+ event_reset(&th->done);
+ th->call = call;
+ __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->ready);
+ event_timedwait(&th->done, 50);
+ break;
+ }
+ }
+ for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+ sleep_ms(1);
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS 0
+
+static void loop(void)
+{
+ int iter = 0;
+ for (;; iter++) {
+ char cwdbuf[32];
+ sprintf(cwdbuf, "./%d", iter);
+ if (mkdir(cwdbuf, 0777))
+ exit(1);
+ int pid = fork();
+ if (pid < 0)
+ exit(1);
+ if (pid == 0) {
+ if (chdir(cwdbuf))
+ exit(1);
+ execute_one();
+ exit(0);
+ }
+ int status = 0;
+ uint64_t start = current_time_ms();
+ for (;;) {
+ sleep_ms(10);
+ if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+ break;
+ if (current_time_ms() - start < 5000)
+ continue;
+ kill_and_wait(pid, &status);
+ break;
+ }
+ remove_dir(cwdbuf);
+ }
+}
+
+uint64_t r[3] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff};
+
+void execute_call(int call)
+{
+ intptr_t res = 0;
+ switch (call) {
+ case 0:
+ res = syscall(SYS_socket, /*domain=AF_INET6*/ 0x1cul,
+ /*type=SOCK_STREAM*/ 1ul, /*proto=*/0);
+ if (res != -1)
+ r[0] = res;
+ break;
+ case 1:
+ NONFAILING(*(uint32_t*)0x200000c0 = 0x101);
+ syscall(SYS_setsockopt, /*fd=*/r[0], /*level=*/0xffff,
+ /*optname=SO_SNDBUF*/ 0x1001, /*optval=*/0x200000c0ul,
+ /*optlen=*/4ul);
+ break;
+ case 2:
+ NONFAILING(*(uint8_t*)0x20000140 = 0x1c);
+ NONFAILING(*(uint8_t*)0x20000141 = 0x1c);
+ NONFAILING(*(uint16_t*)0x20000142 = htobe16(0x4e23));
+ NONFAILING(*(uint32_t*)0x20000144 = 0);
+ NONFAILING(memset((void*)0x20000148, 0, 16));
+ NONFAILING(*(uint32_t*)0x20000158 = 0);
+ syscall(SYS_bind, /*fd=*/r[0], /*addr=*/0x20000140ul, /*addrlen=*/0x1cul);
+ break;
+ case 3:
+ NONFAILING(*(uint32_t*)0x20000500 = r[0]);
+ NONFAILING(*(uint64_t*)0x20000508 = 0);
+ NONFAILING(*(uint64_t*)0x20000510 = 0);
+ NONFAILING(*(uint64_t*)0x20000518 = 0);
+ NONFAILING(*(uint32_t*)0x20000520 = 4);
+ NONFAILING(*(uint32_t*)0x20000524 = 0);
+ NONFAILING(*(uint64_t*)0x20000528 = 0);
+ NONFAILING(*(uint32_t*)0x20000530 = 0);
+ NONFAILING(*(uint32_t*)0x20000534 = 4);
+ NONFAILING(*(uint64_t*)0x20000538 = 0x822e);
+ NONFAILING(*(uint64_t*)0x20000540 = 0);
+ NONFAILING(*(uint64_t*)0x20000548 = 0x20000340);
+ NONFAILING(*(uint32_t*)0x20000550 = 0);
+ NONFAILING(*(uint32_t*)0x20000554 = 0);
+ NONFAILING(*(uint64_t*)0x20000558 = 0xfffffffffffffffe);
+ NONFAILING(*(uint64_t*)0x20000560 = 0);
+ NONFAILING(*(uint64_t*)0x20000568 = 0x20000380);
+ NONFAILING(memcpy((void*)0x20000380, "\x3c\x88\x80", 3));
+ syscall(SYS_aio_writev, /*iocb=*/0x20000500ul);
+ break;
+ case 4:
+ NONFAILING(*(uint8_t*)0x20000180 = 0x1c);
+ NONFAILING(*(uint8_t*)0x20000181 = 0x1c);
+ NONFAILING(*(uint16_t*)0x20000182 = htobe16(0x4e23));
+ NONFAILING(*(uint32_t*)0x20000184 = 0);
+ NONFAILING(memset((void*)0x20000188, 0, 16));
+ NONFAILING(*(uint32_t*)0x20000198 = 0);
+ syscall(SYS_connect, /*fd=*/r[0], /*addr=*/0x20000180ul,
+ /*addrlen=*/0x1cul);
+ break;
+ case 5:
+ NONFAILING(memset((void*)0x20000200, 14, 1));
+ syscall(SYS_sendto, /*fd=*/r[0], /*buf=*/0x20000200ul, /*len=*/0xff66ul,
+ /*f=*/0ul, /*addr=*/0ul, /*addrlen=*/0ul);
+ break;
+ case 6:
+ syscall(SYS_sendmsg, /*fd=*/r[0], /*msg=*/0ul, /*f=*/0ul);
+ break;
+ case 7:
+ syscall(SYS_socket, /*domain=AF_INET*/ 2ul, /*type=SOCK_STREAM*/ 1ul,
+ /*proto=*/0);
+ break;
+ case 8:
+ res = syscall(SYS_socket, /*domain=*/2ul, /*type=SOCK_SEQPACKET*/ 5ul,
+ /*proto=*/0x84);
+ if (res != -1)
+ r[1] = res;
+ break;
+ case 9:
+ syscall(SYS_openat, /*fd=*/0xffffffffffffff9cul, /*file=*/0ul,
+ /*flags=O_RDWR*/ 2ul, /*mode=*/0ul);
+ break;
+ case 10:
+ syscall(SYS_openat, /*fd=*/0xffffffffffffff9cul, /*file=*/0ul,
+ /*flags=O_RDWR*/ 2ul, /*mode=*/0ul);
+ break;
+ case 11:
+ syscall(SYS_socket, /*domain=*/2ul, /*type=SOCK_SEQPACKET*/ 5ul,
+ /*proto=*/0x84);
+ break;
+ case 12:
+ syscall(SYS_socket, /*domain=*/0x1cul, /*type=*/1ul, /*proto=*/0);
+ break;
+ case 13:
+ syscall(SYS_shutdown, /*fd=*/-1, /*how=*/0ul);
+ break;
+ case 14:
+ syscall(SYS_shutdown, /*fd=*/-1, /*how=*/0ul);
+ break;
+ case 15:
+ syscall(SYS_sendto, /*fd=*/-1, /*buf=*/0ul, /*len=*/0ul, /*f=*/0ul,
+ /*addr=*/0ul, /*addrlen=*/0ul);
+ break;
+ case 16:
+ syscall(SYS_sendmsg, /*fd=*/-1, /*msg=*/0ul, /*f=*/0ul);
+ break;
+ case 17:
+ syscall(SYS_rfork, /*flags=RFMEM|RFTHREAD|RFCFDG|RFNOWAIT*/ 0x3060ul);
+ break;
+ case 18:
+ syscall(SYS_rfork, /*flags=RFMEM|RFTHREAD|RFCFDG|RFNOWAIT*/ 0x3060ul);
+ break;
+ case 19:
+ syscall(SYS_openat, /*fd=*/0xffffff9cul, /*file=*/0ul,
+ /*flags=O_APPEND*/ 8ul, /*mode=*/0ul);
+ break;
+ case 20:
+ syscall(SYS_openat, /*fd=*/0xffffff9cul, /*file=*/0ul,
+ /*flags=O_APPEND*/ 8ul, /*mode=*/0ul);
+ break;
+ case 21:
+ syscall(SYS_connect, /*fd=*/r[1], /*addr=*/0ul, /*addrlen=*/0ul);
+ break;
+ case 22:
+ res = syscall(SYS_socket, /*domain=*/2ul, /*type=SOCK_STREAM*/ 1ul,
+ /*proto=*/0x84);
+ if (res != -1)
+ r[2] = res;
+ break;
+ case 23:
+ NONFAILING(*(uint32_t*)0x200001c0 = 0);
+ syscall(SYS_getsockopt, /*fd=*/r[2], /*level=*/0x84, /*opt=*/0xc,
+ /*val=*/0ul, /*len=*/0x200001c0ul);
+ break;
+ }
+}
+int main(void)
+{
+ syscall(SYS_mmap, /*addr=*/0x20000000ul, /*len=*/0x1000000ul,
+ /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
+ /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul, /*fd=*/-1,
+ /*offset=*/0ul);
+ const char* reason;
+ (void)reason;
+ install_segv_handler();
+ use_temporary_dir();
+ do_sandbox_none();
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -m32 -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+(cd ../testcases/swap; ./swap -t 2m -i 10 -l 100 > /dev/null 2>&1) &
+sleep 1
+cd /tmp
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 120 ]; do
+ timeout 3m /tmp/$prog > /dev/null 2>&1
+done
+while pkill swap; do :; done
+wait
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller74.sh b/tools/test/stress2/misc/syzkaller74.sh
new file mode 100755
index 000000000000..886c6047585b
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller74.sh
@@ -0,0 +1,469 @@
+#!/bin/sh
+
+# panic: _pctrie_lookup_node: freed node in iter path
+# cpuid = 0
+# time = 1745029155
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe01085d2a30
+# vpanic() at vpanic+0x136/frame 0xfffffe01085d2b60
+# panic() at panic+0x43/frame 0xfffffe01085d2bc0
+# pctrie_iter_lookup_ge() at pctrie_iter_lookup_ge+0x166/frame 0xfffffe01085d2bd0
+# vm_object_page_clean() at vm_object_page_clean+0x22e/frame 0xfffffe01085d2c50
+# vnode_pager_clean_async() at vnode_pager_clean_async+0x48/frame 0xfffffe01085d2c70
+# vinactivef() at vinactivef+0x75/frame 0xfffffe01085d2cb0
+# vput_final() at vput_final+0x29c/frame 0xfffffe01085d2d00
+# vm_map_process_deferred() at vm_map_process_deferred+0xa9/frame 0xfffffe01085d2d20
+# vm_map_remove() at vm_map_remove+0xcb/frame 0xfffffe01085d2d50
+# vmspace_exit() at vmspace_exit+0xa8/frame 0xfffffe01085d2d80
+# exit1() at exit1+0x533/frame 0xfffffe01085d2df0
+# sys_exit() at sys_exit+0xd/frame 0xfffffe01085d2e00
+# amd64_syscall() at amd64_syscall+0x15a/frame 0xfffffe01085d2f30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe01085d2f30
+# --- syscall (1, FreeBSD ELF64, exit), rip = 0x822a9b7fa, rsp = 0x8202b4de8, rbp = 0x8202b4e00 ---
+# KDB: enter: panic
+# [ thread pid 21141 tid 100328 ]
+# Stopped at kdb_enter+0x33: movq $0,0x104d862(%rip)
+# db>
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=8658267170f7f61f4317bb04c1fe9add379ffaf4
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// syzbot+b5f9ebf4c2c63a5db681@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/resource.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+static void kill_and_wait(int pid, int* status)
+{
+ kill(pid, SIGKILL);
+ while (waitpid(-1, status, 0) != pid) {
+ }
+}
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void use_temporary_dir(void)
+{
+ char tmpdir_template[] = "./syzkaller.XXXXXX";
+ char* tmpdir = mkdtemp(tmpdir_template);
+ if (!tmpdir)
+ exit(1);
+ if (chmod(tmpdir, 0777))
+ exit(1);
+ if (chdir(tmpdir))
+ exit(1);
+}
+
+static void reset_flags(const char* filename)
+{
+ struct stat st;
+ if (lstat(filename, &st))
+ exit(1);
+ st.st_flags &= ~(SF_NOUNLINK | UF_NOUNLINK | SF_IMMUTABLE | UF_IMMUTABLE |
+ SF_APPEND | UF_APPEND);
+ if (lchflags(filename, st.st_flags))
+ exit(1);
+}
+static void __attribute__((noinline)) remove_dir(const char* dir)
+{
+ DIR* dp = opendir(dir);
+ if (dp == NULL) {
+ if (errno == EACCES) {
+ if (rmdir(dir))
+ exit(1);
+ return;
+ }
+ exit(1);
+ }
+ struct dirent* ep = 0;
+ while ((ep = readdir(dp))) {
+ if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
+ continue;
+ char filename[FILENAME_MAX];
+ snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
+ struct stat st;
+ if (lstat(filename, &st))
+ exit(1);
+ if (S_ISDIR(st.st_mode)) {
+ remove_dir(filename);
+ continue;
+ }
+ if (unlink(filename)) {
+ if (errno == EPERM) {
+ reset_flags(filename);
+ reset_flags(dir);
+ if (unlink(filename) == 0)
+ continue;
+ }
+ exit(1);
+ }
+ }
+ closedir(dp);
+ while (rmdir(dir)) {
+ if (errno == EPERM) {
+ reset_flags(dir);
+ if (rmdir(dir) == 0)
+ break;
+ }
+ exit(1);
+ }
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+ pthread_t th;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 128 << 10);
+ int i = 0;
+ for (; i < 100; i++) {
+ if (pthread_create(&th, &attr, fn, arg) == 0) {
+ pthread_attr_destroy(&attr);
+ return;
+ }
+ if (errno == EAGAIN) {
+ usleep(50);
+ continue;
+ }
+ break;
+ }
+ exit(1);
+}
+
+typedef struct {
+ pthread_mutex_t mu;
+ pthread_cond_t cv;
+ int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+ if (pthread_mutex_init(&ev->mu, 0))
+ exit(1);
+ if (pthread_cond_init(&ev->cv, 0))
+ exit(1);
+ ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+ ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ if (ev->state)
+ exit(1);
+ ev->state = 1;
+ pthread_mutex_unlock(&ev->mu);
+ pthread_cond_broadcast(&ev->cv);
+}
+
+static void event_wait(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ while (!ev->state)
+ pthread_cond_wait(&ev->cv, &ev->mu);
+ pthread_mutex_unlock(&ev->mu);
+}
+
+static int event_isset(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+ uint64_t start = current_time_ms();
+ uint64_t now = start;
+ pthread_mutex_lock(&ev->mu);
+ for (;;) {
+ if (ev->state)
+ break;
+ uint64_t remain = timeout - (now - start);
+ struct timespec ts;
+ ts.tv_sec = remain / 1000;
+ ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+ pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
+ now = current_time_ms();
+ if (now - start > timeout)
+ break;
+ }
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static void sandbox_common()
+{
+ struct rlimit rlim;
+ rlim.rlim_cur = rlim.rlim_max = 128 << 20;
+ setrlimit(RLIMIT_AS, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 8 << 20;
+ setrlimit(RLIMIT_MEMLOCK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+ setrlimit(RLIMIT_FSIZE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 1 << 20;
+ setrlimit(RLIMIT_STACK, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 0;
+ setrlimit(RLIMIT_CORE, &rlim);
+ rlim.rlim_cur = rlim.rlim_max = 256;
+ setrlimit(RLIMIT_NOFILE, &rlim);
+}
+
+static void loop();
+
+static int do_sandbox_none(void)
+{
+ sandbox_common();
+ loop();
+ return 0;
+}
+
+struct thread_t {
+ int created, call;
+ event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+ struct thread_t* th = (struct thread_t*)arg;
+ for (;;) {
+ event_wait(&th->ready);
+ event_reset(&th->ready);
+ execute_call(th->call);
+ __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->done);
+ }
+ return 0;
+}
+
+static void execute_one(void)
+{
+ if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
+ }
+ int i, call, thread;
+ for (call = 0; call < 12; call++) {
+ for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+ thread++) {
+ struct thread_t* th = &threads[thread];
+ if (!th->created) {
+ th->created = 1;
+ event_init(&th->ready);
+ event_init(&th->done);
+ event_set(&th->done);
+ thread_start(thr, th);
+ }
+ if (!event_isset(&th->done))
+ continue;
+ event_reset(&th->done);
+ th->call = call;
+ __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->ready);
+ event_timedwait(&th->done, 50);
+ break;
+ }
+ }
+ for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+ sleep_ms(1);
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS 0
+
+static void loop(void)
+{
+ int iter = 0;
+ for (;; iter++) {
+ char cwdbuf[32];
+ sprintf(cwdbuf, "./%d", iter);
+ if (mkdir(cwdbuf, 0777))
+ exit(1);
+ int pid = fork();
+ if (pid < 0)
+ exit(1);
+ if (pid == 0) {
+ if (chdir(cwdbuf))
+ exit(1);
+ execute_one();
+ exit(0);
+ }
+ int status = 0;
+ uint64_t start = current_time_ms();
+ for (;;) {
+ sleep_ms(10);
+ if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+ break;
+ if (current_time_ms() - start < 5000)
+ continue;
+ kill_and_wait(pid, &status);
+ break;
+ }
+ remove_dir(cwdbuf);
+ }
+}
+
+uint64_t r[5] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
+ 0xffffffffffffffff, 0xffffffffffffffff};
+
+void execute_call(int call)
+{
+ intptr_t res = 0;
+ switch (call) {
+ case 0:
+ memcpy((void*)0x200000000000, "./file0\000", 8);
+ res = syscall(SYS_openat, /*fd=*/0xffffff9c, /*file=*/0x200000000000ul,
+ /*flags=O_VERIFY|O_CREAT|O_WRONLY*/ 0x200201ul, /*mode=*/0ul);
+ if (res != -1)
+ r[0] = res;
+ break;
+ case 1:
+ *(uint32_t*)0x200000000240 = r[0];
+ *(uint64_t*)0x200000000248 = 0x80000001;
+ *(uint64_t*)0x200000000250 = 0x2000000004c0;
+ memcpy((void*)0x2000000004c0, "\x45\x09\xee\x8f\xcd", 5);
+ *(uint64_t*)0x200000000258 = 5;
+ *(uint32_t*)0x200000000260 = 3;
+ *(uint32_t*)0x200000000264 = 0;
+ *(uint64_t*)0x200000000268 = 0x200000000000000;
+ *(uint32_t*)0x200000000270 = 8;
+ *(uint32_t*)0x200000000274 = 0;
+ *(uint64_t*)0x200000000278 = 1;
+ *(uint64_t*)0x200000000280 = 7;
+ *(uint64_t*)0x200000000288 = 0;
+ *(uint32_t*)0x200000000290 = 0;
+ *(uint32_t*)0x200000000294 = 0x20000005;
+ *(uint32_t*)0x200000000298 = 0x2e5562f1;
+ *(uint16_t*)0x2000000002a0 = 0xc088;
+ syscall(SYS_aio_write, /*iocb=*/0x200000000240ul);
+ break;
+ case 2:
+ memcpy((void*)0x200000000480, "./file0\000", 8);
+ res = syscall(SYS_open, /*file=*/0x200000000480ul,
+ /*flags=O_VERIFY*/ 0x200000ul,
+ /*mode=S_IWOTH|S_IWGRP|S_IXUSR|S_IWUSR*/ 0xd2ul);
+ if (res != -1)
+ r[1] = res;
+ break;
+ case 3:
+ syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x200000ul,
+ /*prot=PROT_WRITE|PROT_READ*/ 3ul,
+ /*flags=MAP_FIXED|MAP_PRIVATE*/ 0x12ul, /*fd=*/r[1],
+ /*offset=*/0ul);
+ break;
+ case 4:
+ memcpy((void*)0x200000000100, "./file0\000", 8);
+ res = syscall(SYS_open, /*file=*/0x200000000100ul,
+ /*flags=O_DIRECT*/ 0x10000ul, /*mode=*/0ul);
+ if (res != -1)
+ r[2] = res;
+ break;
+ case 5:
+ memcpy((void*)0x2000000016c0, "./file0\000", 8);
+ res = syscall(SYS_open, /*file=*/0x2000000016c0ul, /*flags=O_WRONLY*/ 1ul,
+ /*mode=*/0ul);
+ if (res != -1)
+ r[3] = res;
+ break;
+ case 6:
+ *(uint64_t*)0x200000000080 = 0x2000000006c0;
+ *(uint64_t*)0x200000000088 = 0x100000;
+ syscall(SYS_pwritev, /*fd=*/r[3], /*vec=*/0x200000000080ul, /*vlen=*/1ul,
+ /*off=*/0ul);
+ break;
+ case 7:
+ *(uint64_t*)0x200000001780 = 0x200000000180;
+ *(uint64_t*)0x200000001788 = 0x1b133353141e377d;
+ syscall(SYS_preadv, /*fd=*/r[2], /*vec=*/0x200000001780ul,
+ /*vlen=*/0x10000000000000d1ul, /*off=*/0ul);
+ break;
+ case 8:
+ memcpy((void*)0x200000000480, "./file0\000", 8);
+ res = syscall(
+ SYS_open, /*file=*/0x200000000480ul,
+ /*flags=O_NONBLOCK|O_CREAT|O_RDWR|0x80400000000000*/ 0x80400000000206ul,
+ /*mode=*/0ul);
+ if (res != -1)
+ r[4] = res;
+ break;
+ case 9:
+ syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x200000ul,
+ /*prot=PROT_WRITE|PROT_READ*/ 3ul,
+ /*flags=MAP_FIXED|MAP_SHARED|0x20000*/ 0x20011ul, /*fd=*/r[4],
+ /*offset=*/0ul);
+ break;
+ case 10:
+ syscall(SYS_setsockopt, /*fd=*/(intptr_t)-1, /*level=*/6,
+ /*optname=TCP_LOGID*/ 0x24, /*optval=*/0ul, /*optlen=*/0ul);
+ break;
+ case 11:
+ syscall(SYS_setsockopt, /*fd=*/(intptr_t)-1, /*level=*/6,
+ /*optname=TCP_LOGID*/ 0x24, /*optval=*/0ul, /*optlen=*/0ul);
+ break;
+ }
+}
+int main(void)
+{
+ syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
+ /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
+ /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul,
+ /*fd=*/(intptr_t)-1, /*offset=*/0ul);
+ const char* reason;
+ (void)reason;
+ use_temporary_dir();
+ do_sandbox_none();
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+cd /tmp
+timeout 3m /tmp/$prog > /dev/null 2>&1
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.??????
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller75.sh b/tools/test/stress2/misc/syzkaller75.sh
new file mode 100755
index 000000000000..05e1e56bc44d
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller75.sh
@@ -0,0 +1,377 @@
+#!/bin/sh
+
+# panic: vm_pager_assert_in: page 0xfffffe001987bcc0 is mapped
+# cpuid = 10
+# time = 1745335200
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0108807700
+# vpanic() at vpanic+0x136/frame 0xfffffe0108807830
+# panic() at panic+0x43/frame 0xfffffe0108807890
+# vm_pager_assert_in() at vm_pager_assert_in+0x1fa/frame 0xfffffe01088078d0
+# vm_pager_get_pages() at vm_pager_get_pages+0x3d/frame 0xfffffe0108807920
+# vm_fault_getpages() at vm_fault_getpages+0x22b/frame 0xfffffe0108807980
+# vm_fault_object() at vm_fault_object+0x2ab/frame 0xfffffe01088079e0
+# vm_fault() at vm_fault+0x2d1/frame 0xfffffe0108807b40
+# vm_map_wire_locked() at vm_map_wire_locked+0x385/frame 0xfffffe0108807bf0
+# vm_mmap_object() at vm_mmap_object+0x2fd/frame 0xfffffe0108807c50
+# vn_mmap() at vn_mmap+0x152/frame 0xfffffe0108807ce0
+# kern_mmap() at kern_mmap+0x621/frame 0xfffffe0108807dc0
+# sys_mmap() at sys_mmap+0x42/frame 0xfffffe0108807e00
+# amd64_syscall() at amd64_syscall+0x15a/frame 0xfffffe0108807f30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0108807f30
+# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x82438d7fa, rsp = 0x824847f68, rbp = 0x824847f90 ---
+# KDB: enter: panic
+# [ thread pid 43067 tid 146060 ]
+# Stopped at kdb_enter+0x33: movq $0,0x124d7e2(%rip)
+# db> x/s version
+# version: FreeBSD 15.0-CURRENT #2 main-n276647-a098111a28ed-dirty: Tue Apr 22 16:37:39 CEST 2025
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO
+# db>
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=bab5b2c0d3e8f95d52a06ab501ddb3c11200a5c9
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// syzbot+1cc9ede76727d2ea2e8d@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+
+#include <errno.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+static void kill_and_wait(int pid, int* status)
+{
+ kill(pid, SIGKILL);
+ while (waitpid(-1, status, 0) != pid) {
+ }
+}
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+ pthread_t th;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 128 << 10);
+ int i = 0;
+ for (; i < 100; i++) {
+ if (pthread_create(&th, &attr, fn, arg) == 0) {
+ pthread_attr_destroy(&attr);
+ return;
+ }
+ if (errno == EAGAIN) {
+ usleep(50);
+ continue;
+ }
+ break;
+ }
+ exit(1);
+}
+
+typedef struct {
+ pthread_mutex_t mu;
+ pthread_cond_t cv;
+ int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+ if (pthread_mutex_init(&ev->mu, 0))
+ exit(1);
+ if (pthread_cond_init(&ev->cv, 0))
+ exit(1);
+ ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+ ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ if (ev->state)
+ exit(1);
+ ev->state = 1;
+ pthread_mutex_unlock(&ev->mu);
+ pthread_cond_broadcast(&ev->cv);
+}
+
+static void event_wait(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ while (!ev->state)
+ pthread_cond_wait(&ev->cv, &ev->mu);
+ pthread_mutex_unlock(&ev->mu);
+}
+
+static int event_isset(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+ uint64_t start = current_time_ms();
+ uint64_t now = start;
+ pthread_mutex_lock(&ev->mu);
+ for (;;) {
+ if (ev->state)
+ break;
+ uint64_t remain = timeout - (now - start);
+ struct timespec ts;
+ ts.tv_sec = remain / 1000;
+ ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+ pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
+ now = current_time_ms();
+ if (now - start > timeout)
+ break;
+ }
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+struct thread_t {
+ int created, call;
+ event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+ struct thread_t* th = (struct thread_t*)arg;
+ for (;;) {
+ event_wait(&th->ready);
+ event_reset(&th->ready);
+ execute_call(th->call);
+ __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->done);
+ }
+ return 0;
+}
+
+static void execute_one(void)
+{
+ if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
+ }
+ int i, call, thread;
+ for (call = 0; call < 11; call++) {
+ for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+ thread++) {
+ struct thread_t* th = &threads[thread];
+ if (!th->created) {
+ th->created = 1;
+ event_init(&th->ready);
+ event_init(&th->done);
+ event_set(&th->done);
+ thread_start(thr, th);
+ }
+ if (!event_isset(&th->done))
+ continue;
+ event_reset(&th->done);
+ th->call = call;
+ __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->ready);
+ event_timedwait(&th->done, 50);
+ break;
+ }
+ }
+ for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+ sleep_ms(1);
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS 0
+
+static void loop(void)
+{
+// int iter = 0;
+ for (;; /*iter++*/) {
+ int pid = fork();
+ if (pid < 0)
+ exit(1);
+ if (pid == 0) {
+ execute_one();
+ exit(0);
+ }
+ int status = 0;
+ uint64_t start = current_time_ms();
+ for (;;) {
+ sleep_ms(10);
+ if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+ break;
+ if (current_time_ms() - start < 5000)
+ continue;
+ kill_and_wait(pid, &status);
+ break;
+ }
+ }
+}
+
+uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
+ 0xffffffffffffffff};
+
+void execute_call(int call)
+{
+ intptr_t res = 0;
+ switch (call) {
+ case 0:
+ memcpy((void*)0x200000000200, "./file0\000", 8);
+ res = syscall(SYS_openat, /*fd=*/0xffffff9c, /*file=*/0x200000000200ul,
+ /*flags=O_VERIFY|O_CREAT|O_CLOEXEC|O_WRONLY*/ 0x300201ul,
+ /*mode=S_IWGRP|S_IXUSR|S_IWUSR*/ 0xd0ul);
+ if (res != -1)
+ r[0] = res;
+ break;
+ case 1:
+ *(uint32_t*)0x200000000240 = r[0];
+ *(uint64_t*)0x200000000248 = 0x80000002;
+ *(uint64_t*)0x200000000250 = 0x200000000080;
+ memcpy((void*)0x200000000080, "\x1f\x9a\xc4", 3);
+ *(uint64_t*)0x200000000258 = 3;
+ *(uint32_t*)0x200000000260 = 0;
+ *(uint32_t*)0x200000000264 = 0;
+ *(uint64_t*)0x200000000268 = 0;
+ *(uint32_t*)0x200000000270 = 0;
+ *(uint32_t*)0x200000000274 = 0;
+ *(uint64_t*)0x200000000278 = 0;
+ *(uint64_t*)0x200000000280 = 7;
+ *(uint64_t*)0x200000000288 = 0;
+ *(uint32_t*)0x200000000290 = 0;
+ *(uint32_t*)0x200000000294 = 0;
+ *(uint64_t*)0x200000000298 = 0;
+ *(uint64_t*)0x2000000002a0 = 0;
+ *(uint64_t*)0x2000000002a8 = 0;
+ syscall(SYS_aio_write, /*iocb=*/0x200000000240ul);
+ break;
+ case 2:
+ syscall(SYS_mlockall, /*flags=MCL_FUTURE*/ 2ul);
+ break;
+ case 3:
+ memcpy((void*)0x200000000100, "./file0\000", 8);
+ res = syscall(SYS_open, /*file=*/0x200000000100ul,
+ /*flags=O_DIRECT*/ 0x10000ul, /*mode=*/0ul);
+ if (res != -1)
+ r[1] = res;
+ break;
+ case 4:
+ *(uint64_t*)0x200000001780 = 0x200000000180;
+ *(uint64_t*)0x200000001788 = 0x1b133353141e377d;
+ syscall(SYS_preadv, /*fd=*/r[1], /*vec=*/0x200000001780ul,
+ /*vlen=*/0x10000000000000d1ul, /*off=*/0ul);
+ break;
+ case 5:
+ memcpy((void*)0x200000000040, "./file0\000", 8);
+ syscall(
+ SYS_open, /*file=*/0x200000000040ul,
+ /*flags=O_TRUNC|O_NONBLOCK|O_NOFOLLOW|O_CREAT|O_APPEND|0x2*/ 0x70eul,
+ /*mode=*/0ul);
+ break;
+ case 6:
+ memcpy((void*)0x200000000480, "./file0\000", 8);
+ res = syscall(
+ SYS_open, /*file=*/0x200000000480ul,
+ /*flags=O_NONBLOCK|O_CREAT|O_RDWR|0x80400000000000*/ 0x80400000000206ul,
+ /*mode=*/0ul);
+ if (res != -1)
+ r[2] = res;
+ break;
+ case 7:
+ syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x200000ul,
+ /*prot=PROT_WRITE|PROT_READ*/ 3ul,
+ /*flags=MAP_FIXED|MAP_SHARED|0x20000*/ 0x20011ul, /*fd=*/r[2],
+ /*offset=*/0ul);
+ break;
+ case 8:
+ memcpy((void*)0x200000000040, "./file0\000", 8);
+ syscall(SYS_truncate, /*file=*/0x200000000040ul, /*len=*/0xaa480ul);
+ break;
+ case 9:
+ memcpy((void*)0x200000000480, "./file0\000", 8);
+ res = syscall(SYS_open, /*file=*/0x200000000480ul, /*flags=*/0ul,
+ /*mode=*/0ul);
+ if (res != -1)
+ r[3] = res;
+ break;
+ case 10:
+ syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x200000ul,
+ /*prot=PROT_WRITE|PROT_READ*/ 3ul,
+ /*flags=MAP_FIXED|MAP_PRIVATE*/ 0x12ul, /*fd=*/r[3],
+ /*offset=*/0ul);
+ break;
+ }
+}
+int main(void)
+{
+ syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
+ /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
+ /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul,
+ /*fd=*/(intptr_t)-1, /*offset=*/0ul);
+ const char* reason;
+ (void)reason;
+ loop();
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+(cd ../testcases/swap; ./swap -t 3m -i 30 -l 100 > /dev/null 2>&1) &
+sleep 5
+
+work=/tmp/$prog.dir
+rm -rf $work
+mkdir $work
+cd /tmp/$prog.dir
+for i in `jot 30`; do
+ (
+ mkdir d$i
+ cd d$i
+ timeout 3m /tmp/$prog > /dev/null 2>&1 &
+ )
+done
+while pgrep -q $prog; do sleep 2; done
+while pkill swap; do :; done
+wait
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller76.sh b/tools/test/stress2/misc/syzkaller76.sh
new file mode 100755
index 000000000000..67a566cbfa00
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller76.sh
@@ -0,0 +1,235 @@
+#!/bin/sh
+
+# panic: aio_process_rw: opcode 70
+# cpuid = 7
+# time = 1746175480
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe010844ccb0
+# vpanic() at vpanic+0x136/frame 0xfffffe010844cde0
+# panic() at panic+0x43/frame 0xfffffe010844ce40
+# aio_process_rw() at aio_process_rw+0x28e/frame 0xfffffe010844cea0
+# aio_daemon() at aio_daemon+0x286/frame 0xfffffe010844cef0
+# fork_exit() at fork_exit+0x82/frame 0xfffffe010844cf30
+# fork_trampoline() at fork_trampoline+0xe/frame 0xfffffe010844cf30
+# --- trap 0xc, rip = 0x2020f02a472a, rsp = 0x2020ec9bb8d8, rbp = 0x2020ec9bb9d0 ---
+# KDB: enter: panic
+# [ thread pid 71553 tid 100216 ]
+# Stopped at kdb_enter+0x33: movq $0,0x122f9c2(%rip)
+# db> x/s version
+# version: FreeBSD 15.0-CURRENT #0 main-n276945-2735c20d114f-dirty: Fri May 2 07:17:00 CEST 2025
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO
+# db>
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=0549d8c089382a2593078734cc8166a0fc9049f1
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// syzbot+b6e15476c91852bb2264@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+int main(void)
+{
+ syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
+ /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
+ /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul,
+ /*fd=*/(intptr_t)-1, /*offset=*/0ul);
+ const char* reason;
+ (void)reason;
+ intptr_t res = 0;
+ if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
+ }
+ res = syscall(SYS_freebsd10_pipe, /*pipefd=*/0x2000000005c0ul);
+ if (res != -1)
+ r[0] = *(uint32_t*)0x2000000005c4;
+ syscall(SYS_close, /*fd=*/r[0]);
+ memcpy((void*)0x200000000080, ".\000", 2);
+ syscall(SYS_open, /*file=*/0x200000000080ul, /*flags=*/0ul, /*mode=*/0ul);
+ *(uint32_t*)0x200000000080 = 0;
+ *(uint32_t*)0x200000000084 = 0;
+ *(uint32_t*)0x200000000088 = 4;
+ *(uint64_t*)0x200000000090 = 0;
+ *(uint64_t*)0x200000000098 = 0;
+ *(uint32_t*)0x2000000000a0 = 0;
+ *(uint32_t*)0x2000000000a4 = 8;
+ *(uint64_t*)0x2000000000a8 = 0x7fffffffffffffff;
+ *(uint32_t*)0x2000000000b0 = 0;
+ *(uint32_t*)0x2000000000b4 = 0x100;
+ *(uint64_t*)0x2000000000b8 = 0;
+ *(uint32_t*)0x2000000000c0 = 0;
+ *(uint32_t*)0x2000000000c4 = 0;
+ *(uint32_t*)0x2000000000c8 = 0;
+ *(uint32_t*)0x2000000000cc = 3;
+ *(uint32_t*)0x2000000000d0 = 0;
+ *(uint32_t*)0x2000000000d4 = 0;
+ *(uint32_t*)0x2000000000d8 = 0x400008;
+ *(uint32_t*)0x2000000000dc = 0x8e;
+ *(uint32_t*)0x2000000000e0 = 0xfffffffd;
+ *(uint32_t*)0x2000000000e4 = 0xf;
+ *(uint32_t*)0x2000000000e8 = 0xfffffffc;
+ *(uint32_t*)0x2000000000ec = 0;
+ *(uint32_t*)0x2000000000f0 = 0;
+ *(uint32_t*)0x2000000000f4 = 0;
+ *(uint32_t*)0x2000000000f8 = 0xff;
+ *(uint32_t*)0x2000000000fc = 0;
+ *(uint32_t*)0x200000000100 = 0;
+ *(uint32_t*)0x200000000104 = 2;
+ *(uint32_t*)0x200000000108 = 0;
+ *(uint32_t*)0x20000000010c = 2;
+ *(uint32_t*)0x200000000110 = 2;
+ *(uint32_t*)0x200000000114 = 0x5bee;
+ *(uint32_t*)0x200000000118 = 0;
+ *(uint32_t*)0x20000000011c = 0xc;
+ *(uint32_t*)0x200000000120 = 3;
+ *(uint32_t*)0x200000000124 = 2;
+ *(uint32_t*)0x200000000128 = 0;
+ *(uint32_t*)0x20000000012c = 0x10000000;
+ *(uint32_t*)0x200000000130 = 0;
+ *(uint32_t*)0x200000000134 = 1;
+ *(uint32_t*)0x200000000138 = 0;
+ *(uint32_t*)0x20000000013c = 0x83;
+ *(uint32_t*)0x200000000140 = 0;
+ *(uint32_t*)0x200000000144 = 0;
+ *(uint32_t*)0x200000000148 = 0;
+ *(uint32_t*)0x20000000014c = 0;
+ *(uint32_t*)0x200000000150 = 0;
+ *(uint32_t*)0x200000000154 = 0xfff;
+ *(uint32_t*)0x200000000158 = 1;
+ *(uint32_t*)0x20000000015c = 0x4c;
+ *(uint32_t*)0x200000000160 = 0x1fffffc;
+ *(uint32_t*)0x200000000164 = 4;
+ *(uint32_t*)0x200000000168 = 0x40000001;
+ *(uint32_t*)0x20000000016c = 0;
+ *(uint32_t*)0x200000000170 = 8;
+ *(uint32_t*)0x200000000174 = 0;
+ *(uint32_t*)0x200000000178 = 0;
+ *(uint32_t*)0x20000000017c = 0x100001;
+ *(uint32_t*)0x200000000180 = 0;
+ *(uint32_t*)0x200000000184 = 0x1ff;
+ *(uint32_t*)0x200000000188 = 0xe;
+ *(uint32_t*)0x20000000018c = 8;
+ *(uint32_t*)0x200000000190 = 0;
+ *(uint32_t*)0x200000000194 = 0;
+ *(uint32_t*)0x200000000198 = 0;
+ *(uint32_t*)0x20000000019c = 0xc;
+ *(uint32_t*)0x2000000001a0 = 9;
+ *(uint32_t*)0x2000000001a4 = 2;
+ *(uint32_t*)0x2000000001a8 = 0x10000002;
+ *(uint32_t*)0x2000000001ac = 0x100000;
+ *(uint32_t*)0x2000000001b0 = 0x46;
+ *(uint32_t*)0x2000000001b4 = 6;
+ *(uint32_t*)0x2000000001b8 = 0x3ff;
+ *(uint32_t*)0x2000000001bc = 2;
+ *(uint32_t*)0x2000000001c0 = 0;
+ *(uint32_t*)0x2000000001c4 = 0xfffffffa;
+ *(uint32_t*)0x2000000001c8 = 0x200;
+ *(uint32_t*)0x2000000001cc = 0;
+ *(uint32_t*)0x2000000001d0 = 1;
+ *(uint32_t*)0x2000000001d4 = 3;
+ *(uint32_t*)0x2000000001d8 = 0;
+ *(uint32_t*)0x2000000001dc = 0x100;
+ *(uint32_t*)0x2000000001e0 = 0;
+ *(uint32_t*)0x2000000001e4 = 8;
+ *(uint32_t*)0x2000000001e8 = 0x108c6b2;
+ *(uint32_t*)0x2000000001ec = 0xfffffffa;
+ *(uint32_t*)0x2000000001f0 = 0;
+ *(uint32_t*)0x2000000001f4 = 5;
+ *(uint32_t*)0x2000000001f8 = 0;
+ *(uint32_t*)0x2000000001fc = 0;
+ *(uint32_t*)0x200000000200 = 0;
+ *(uint32_t*)0x200000000204 = 0;
+ *(uint32_t*)0x200000000208 = 0;
+ *(uint32_t*)0x20000000020c = 0x80;
+ *(uint32_t*)0x200000000210 = 0;
+ *(uint32_t*)0x200000000214 = 1;
+ *(uint32_t*)0x200000000218 = 0;
+ *(uint32_t*)0x20000000021c = 6;
+ *(uint32_t*)0x200000000220 = 0;
+ *(uint32_t*)0x200000000224 = 0;
+ *(uint32_t*)0x200000000228 = 0;
+ *(uint32_t*)0x20000000022c = 6;
+ *(uint32_t*)0x200000000230 = 0;
+ *(uint32_t*)0x200000000234 = 0;
+ *(uint32_t*)0x200000000238 = 0;
+ *(uint32_t*)0x20000000023c = 0xa9f;
+ syscall(SYS_ioctl, /*fd=*/(intptr_t)-1, /*cmd=*/0xc1c06d02ul,
+ /*arg=*/0x200000000080ul);
+ *(uint32_t*)0x200000000580 = -1;
+ *(uint64_t*)0x200000000588 = 0;
+ *(uint64_t*)0x200000000590 = 0x200000000180;
+ *(uint64_t*)0x200000000598 = 0;
+ *(uint32_t*)0x2000000005a0 = 0xfffff000;
+ *(uint32_t*)0x2000000005a4 = 3;
+ *(uint64_t*)0x2000000005a8 = 0;
+ *(uint32_t*)0x2000000005b0 = 0;
+ *(uint32_t*)0x2000000005b4 = 0;
+ *(uint64_t*)0x2000000005b8 = 0;
+ *(uint64_t*)0x2000000005c0 = 0;
+ *(uint64_t*)0x2000000005c8 = 0;
+ *(uint32_t*)0x2000000005d0 = 0;
+ *(uint32_t*)0x2000000005d4 = 0;
+ *(uint64_t*)0x2000000005d8 = 0;
+ *(uint16_t*)0x2000000005e0 = 0x4043;
+ *(uint32_t*)0x200000000620 = -1;
+ *(uint64_t*)0x200000000628 = 0;
+ *(uint64_t*)0x200000000630 = 0;
+ *(uint64_t*)0x200000000638 = 0;
+ *(uint32_t*)0x200000000640 = 0x10;
+ *(uint32_t*)0x200000000644 = 0;
+ *(uint64_t*)0x200000000648 = 0;
+ *(uint32_t*)0x200000000650 = 0;
+ *(uint32_t*)0x200000000654 = 0;
+ *(uint64_t*)0x200000000658 = 8;
+ *(uint64_t*)0x200000000660 = 0x3ff;
+ *(uint64_t*)0x200000000668 = 0;
+ *(uint32_t*)0x200000000670 = 1;
+ *(uint32_t*)0x200000000674 = 0;
+ *(uint32_t*)0x200000000678 = 3;
+ *(uint16_t*)0x200000000680 = 0;
+ *(uint32_t*)0x2000000006c0 = -1;
+ *(uint64_t*)0x2000000006c8 = 0;
+ *(uint64_t*)0x2000000006d0 = 0;
+ *(uint64_t*)0x2000000006d8 = 0;
+ *(uint32_t*)0x2000000006e0 = 0;
+ *(uint32_t*)0x2000000006e4 = 0;
+ *(uint64_t*)0x2000000006e8 = 2;
+ *(uint32_t*)0x2000000006f0 = 0;
+ *(uint32_t*)0x2000000006f4 = 0;
+ *(uint64_t*)0x2000000006f8 = 0x101;
+ *(uint64_t*)0x200000000700 = 0xb3;
+ *(uint64_t*)0x200000000708 = 0;
+ *(uint32_t*)0x200000000710 = 0;
+ *(uint32_t*)0x200000000714 = 0xa;
+ *(uint64_t*)0x200000000718 = 3;
+ *(uint32_t*)0x200000000720 = 0;
+ syscall(SYS_lio_listio, /*mode=*/0ul, /*list=*/0x200000000580ul, /*nent=*/3ul,
+ /*sig=*/0ul);
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+work=/tmp/$prog.dir
+rm -rf $work
+mkdir $work
+cd /tmp/$prog.dir
+timeout 3m /tmp/$prog > /dev/null 2>&1
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller77.sh b/tools/test/stress2/misc/syzkaller77.sh
new file mode 100755
index 000000000000..c77a3fd2dd22
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller77.sh
@@ -0,0 +1,290 @@
+#!/bin/sh
+
+# panic: sofree:1883 curvnet is NULL, so=0xfffff8017ca59000
+# cpuid = 8
+# time = 1746559098
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0182b5c8d0
+# vpanic() at vpanic+0x136/frame 0xfffffe0182b5ca00
+# panic() at panic+0x43/frame 0xfffffe0182b5ca60
+# sorele_locked() at sorele_locked+0x25f/frame 0xfffffe0182b5ca90
+# uipc_sendfile_wait() at uipc_sendfile_wait+0x1df/frame 0xfffffe0182b5caf0
+# vn_sendfile() at vn_sendfile+0x59b/frame 0xfffffe0182b5cd70
+# sendfile() at sendfile+0x129/frame 0xfffffe0182b5ce00
+# amd64_syscall() at amd64_syscall+0x15a/frame 0xfffffe0182b5cf30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe0182b5cf30
+# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x8223fb72a, rsp = 0x824baaf58, rbp = 0x824baaf90 ---
+# KDB: enter: panic
+# [ thread pid 6382 tid 103296 ]
+# Stopped at kdb_enter+0x33: movq $0,0x122f202(%rip)
+# db> x/s version
+# version: FreeBSD 15.0-CURRENT #0 main-n277057-794e792121ba-dirty: Tue May 6 18:34:20 CEST 2025
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO
+# db>
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=f04b36c4f2b84533225a1bd695a0aed2efa559e5
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// syzbot+7b0b20cf2c672c181d98@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <errno.h>
+#include <pthread.h>
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <time.h>
+#include <unistd.h>
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void thread_start(void* (*fn)(void*), void* arg)
+{
+ pthread_t th;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 128 << 10);
+ int i = 0;
+ for (; i < 100; i++) {
+ if (pthread_create(&th, &attr, fn, arg) == 0) {
+ pthread_attr_destroy(&attr);
+ return;
+ }
+ if (errno == EAGAIN) {
+ usleep(50);
+ continue;
+ }
+ break;
+ }
+ exit(1);
+}
+
+typedef struct {
+ pthread_mutex_t mu;
+ pthread_cond_t cv;
+ int state;
+} event_t;
+
+static void event_init(event_t* ev)
+{
+ if (pthread_mutex_init(&ev->mu, 0))
+ exit(1);
+ if (pthread_cond_init(&ev->cv, 0))
+ exit(1);
+ ev->state = 0;
+}
+
+static void event_reset(event_t* ev)
+{
+ ev->state = 0;
+}
+
+static void event_set(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ if (ev->state)
+ exit(1);
+ ev->state = 1;
+ pthread_mutex_unlock(&ev->mu);
+ pthread_cond_broadcast(&ev->cv);
+}
+
+static void event_wait(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ while (!ev->state)
+ pthread_cond_wait(&ev->cv, &ev->mu);
+ pthread_mutex_unlock(&ev->mu);
+}
+
+static int event_isset(event_t* ev)
+{
+ pthread_mutex_lock(&ev->mu);
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+static int event_timedwait(event_t* ev, uint64_t timeout)
+{
+ uint64_t start = current_time_ms();
+ uint64_t now = start;
+ pthread_mutex_lock(&ev->mu);
+ for (;;) {
+ if (ev->state)
+ break;
+ uint64_t remain = timeout - (now - start);
+ struct timespec ts;
+ ts.tv_sec = remain / 1000;
+ ts.tv_nsec = (remain % 1000) * 1000 * 1000;
+ pthread_cond_timedwait(&ev->cv, &ev->mu, &ts);
+ now = current_time_ms();
+ if (now - start > timeout)
+ break;
+ }
+ int res = ev->state;
+ pthread_mutex_unlock(&ev->mu);
+ return res;
+}
+
+struct thread_t {
+ int created, call;
+ event_t ready, done;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+
+static void* thr(void* arg)
+{
+ struct thread_t* th = (struct thread_t*)arg;
+ for (;;) {
+ event_wait(&th->ready);
+ event_reset(&th->ready);
+ execute_call(th->call);
+ __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->done);
+ }
+ return 0;
+}
+
+static void loop(void)
+{
+ if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
+ }
+ int i, call, thread;
+ for (call = 0; call < 8; call++) {
+ for (thread = 0; thread < (int)(sizeof(threads) / sizeof(threads[0]));
+ thread++) {
+ struct thread_t* th = &threads[thread];
+ if (!th->created) {
+ th->created = 1;
+ event_init(&th->ready);
+ event_init(&th->done);
+ event_set(&th->done);
+ thread_start(thr, th);
+ }
+ if (!event_isset(&th->done))
+ continue;
+ event_reset(&th->done);
+ th->call = call;
+ __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+ event_set(&th->ready);
+ event_timedwait(&th->done, 50);
+ break;
+ }
+ }
+ for (i = 0; i < 100 && __atomic_load_n(&running, __ATOMIC_RELAXED); i++)
+ sleep_ms(1);
+}
+
+uint64_t r[5] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
+ 0xffffffffffffffff, 0xffffffffffffffff};
+
+void execute_call(int call)
+{
+ intptr_t res = 0;
+ switch (call) {
+ case 0:
+ memcpy((void*)0x200000000480, "./file0\000", 8);
+ res = syscall(
+ SYS_open, /*file=*/0x200000000480ul,
+ /*flags=O_NONBLOCK|O_CREAT|O_RDWR|0x80000000000000*/ 0x80000000000206ul,
+ /*mode=*/0ul);
+ if (res != -1)
+ r[0] = res;
+ break;
+ case 1:
+ syscall(SYS_ftruncate, /*fd=*/r[0], /*len=*/0x3862ul);
+ break;
+ case 2:
+ res = syscall(SYS_socket, /*domain=*/2ul, /*type=*/2ul, /*proto=*/0x88);
+ if (res != -1)
+ r[1] = res;
+ break;
+ case 3:
+ res = syscall(SYS_socketpair, /*domain=*/1ul, /*type=SOCK_STREAM*/ 1ul,
+ /*proto=*/0, /*fds=*/0x200000000180ul);
+ if (res != -1) {
+ r[2] = *(uint32_t*)0x200000000180;
+ r[3] = *(uint32_t*)0x200000000184;
+ }
+ break;
+ case 4:
+ syscall(SYS_dup2, /*oldfd=*/r[2], /*newfd=*/r[1]);
+ break;
+ case 5:
+ memcpy((void*)0x200000000140, "./file0\000", 8);
+ res = syscall(SYS_open, /*file=*/0x200000000140ul, /*flags=*/0ul,
+ /*mode=*/0ul);
+ if (res != -1)
+ r[4] = res;
+ break;
+ case 6:
+ syscall(SYS_sendfile, /*fd=*/r[4], /*s=*/r[1], /*offset=*/0ul,
+ /*nbytes=*/0ul, /*hdtr=*/0ul, /*sbytes=*/0ul,
+ /*flags=SF_SYNC|SF_NOCACHE*/ 0x14ul);
+ break;
+ case 7:
+ syscall(SYS_dup2, /*oldfd=*/r[4], /*newfd=*/r[3]);
+ break;
+ }
+}
+int main(void)
+{
+ syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
+ /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
+ /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul,
+ /*fd=*/(intptr_t)-1, /*offset=*/0ul);
+ const char* reason;
+ (void)reason;
+ loop();
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+(cd ../testcases/swap; ./swap -t 3m -i 30 -l 100 > /dev/null 2>&1) &
+sleep 5
+
+work=/tmp/$prog.dir
+rm -rf $work
+mkdir $work
+cd /tmp/$prog.dir
+for i in `jot 30`; do
+ (
+ mkdir d$i
+ cd d$i
+ timeout 3m /tmp/$prog > /dev/null 2>&1 &
+ )
+done
+while pgrep -q $prog; do sleep 2; done
+while pkill swap; do :; done
+wait
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller78.sh b/tools/test/stress2/misc/syzkaller78.sh
new file mode 100755
index 000000000000..1858129d4c81
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller78.sh
@@ -0,0 +1,282 @@
+#!/bin/sh
+
+# Fatal trap 12: page fault while in kernel mode
+# cpuid = 10; apic id = 07
+# fault virtual address = 0x0
+# fault code = supervisor read data, page not present
+# instruction pointer = 0x20:0xffffffff80c3c276
+# stack pointer = 0x28:0xfffffe017273eb00
+# frame pointer = 0x28:0xfffffe017273eb30
+# code segment = base 0x0, limit 0xfffff, type 0x1b
+# = DPL 0, pres 1, long 1, def32 0, gran 1
+# processor eflags = interrupt enabled, resume, IOPL = 0
+# current process = 43905 (syzkaller78)
+# rdi: fffff8005b5d55e0 rsi: 0000000000000008 rdx: ffffffff81249e88
+# rcx: fffff8001b9aed00 r8: 0000000000000000 r9: fffff80003396000
+# rax: 0000000000000000 rbx: fffff8005b5d5400 rbp: fffffe017273eb30
+# r10: 0000000000000000 r11: fffff804d84e9c60 r12: fffff8005b5d55f8
+# r13: 0000000000000000 r14: fffff80497171700 r15: fffff8005b5d55c0
+# trap number = 12
+# panic: page fault
+# cpuid = 7
+# time = 1746555157
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe017273e830
+# vpanic() at vpanic+0x136/frame 0xfffffe017273e960
+# panic() at panic+0x43/frame 0xfffffe017273e9c0
+# trap_pfault() at trap_pfault+0x48d/frame 0xfffffe017273ea30
+# calltrap() at calltrap+0x8/frame 0xfffffe017273ea30
+# --- trap 0xc, rip = 0xffffffff80c3c276, rsp = 0xfffffe017273eb00, rbp = 0xfffffe017273eb30 ---
+# unp_dispose() at unp_dispose+0x3b6/frame 0xfffffe017273eb30
+# uipc_detach() at uipc_detach+0x35/frame 0xfffffe017273eb80
+# sorele_locked() at sorele_locked+0x107/frame 0xfffffe017273ebb0
+# soclose() at soclose+0x17d/frame 0xfffffe017273ec10
+# _fdrop() at _fdrop+0x1b/frame 0xfffffe017273ec30
+# closef() at closef+0x1e3/frame 0xfffffe017273ecc0
+# fdescfree() at fdescfree+0x41e/frame 0xfffffe017273ed80
+# exit1() at exit1+0x4a4/frame 0xfffffe017273edf0
+# sys_exit() at sys_exit+0xd/frameamd64_syscall() at amd64_syscall+0x15a/frame 0xfffffe017273ef30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe017273ef30
+# --- syscall (1, FreeBSD ELF64, exit), rip = 0x823ab472a, rsp = 0x8208e3ea8, rbp = 0x8208e3ec0 ---
+# KDB: enter: panic
+# [ thread pid 43905 tid 103344 ]
+# Stopped at kdb_enter+0x33: movq $0,0x122f202(%rip)
+# db>
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=46eb92ee6e2f6acbd4250d0f2065b1f93296bd82
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// syzbot+0e99ffc200638909ca1c@syzkaller.appspotmail.com
+
+#define _GNU_SOURCE
+
+#include <sys/types.h>
+
+#include <dirent.h>
+#include <errno.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/stat.h>
+#include <sys/syscall.h>
+#include <sys/wait.h>
+#include <time.h>
+#include <unistd.h>
+
+static unsigned long long procid;
+
+static void kill_and_wait(int pid, int* status)
+{
+ kill(pid, SIGKILL);
+ while (waitpid(-1, status, 0) != pid) {
+ }
+}
+
+static void sleep_ms(uint64_t ms)
+{
+ usleep(ms * 1000);
+}
+
+static uint64_t current_time_ms(void)
+{
+ struct timespec ts;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts))
+ exit(1);
+ return (uint64_t)ts.tv_sec * 1000 + (uint64_t)ts.tv_nsec / 1000000;
+}
+
+static void use_temporary_dir(void)
+{
+ char tmpdir_template[] = "./syzkaller.XXXXXX";
+ char* tmpdir = mkdtemp(tmpdir_template);
+ if (!tmpdir)
+ exit(1);
+ if (chmod(tmpdir, 0777))
+ exit(1);
+ if (chdir(tmpdir))
+ exit(1);
+}
+
+static void reset_flags(const char* filename)
+{
+ struct stat st;
+ if (lstat(filename, &st))
+ exit(1);
+ st.st_flags &= ~(SF_NOUNLINK | UF_NOUNLINK | SF_IMMUTABLE | UF_IMMUTABLE |
+ SF_APPEND | UF_APPEND);
+ if (lchflags(filename, st.st_flags))
+ exit(1);
+}
+static void __attribute__((noinline)) remove_dir(const char* dir)
+{
+ DIR* dp = opendir(dir);
+ if (dp == NULL) {
+ if (errno == EACCES) {
+ if (rmdir(dir))
+ exit(1);
+ return;
+ }
+ exit(1);
+ }
+ struct dirent* ep = 0;
+ while ((ep = readdir(dp))) {
+ if (strcmp(ep->d_name, ".") == 0 || strcmp(ep->d_name, "..") == 0)
+ continue;
+ char filename[FILENAME_MAX];
+ snprintf(filename, sizeof(filename), "%s/%s", dir, ep->d_name);
+ struct stat st;
+ if (lstat(filename, &st))
+ exit(1);
+ if (S_ISDIR(st.st_mode)) {
+ remove_dir(filename);
+ continue;
+ }
+ if (unlink(filename)) {
+ if (errno == EPERM) {
+ reset_flags(filename);
+ reset_flags(dir);
+ if (unlink(filename) == 0)
+ continue;
+ }
+ exit(1);
+ }
+ }
+ closedir(dp);
+ while (rmdir(dir)) {
+ if (errno == EPERM) {
+ reset_flags(dir);
+ if (rmdir(dir) == 0)
+ break;
+ }
+ exit(1);
+ }
+}
+
+static void execute_one(void);
+
+#define WAIT_FLAGS 0
+
+static void loop(void)
+{
+ int iter = 0;
+ for (;; iter++) {
+ char cwdbuf[32];
+ sprintf(cwdbuf, "./%d", iter);
+ if (mkdir(cwdbuf, 0777))
+ exit(1);
+ int pid = fork();
+ if (pid < 0)
+ exit(1);
+ if (pid == 0) {
+ if (chdir(cwdbuf))
+ exit(1);
+ execute_one();
+ exit(0);
+ }
+ int status = 0;
+ uint64_t start = current_time_ms();
+ for (;;) {
+ sleep_ms(10);
+ if (waitpid(-1, &status, WNOHANG | WAIT_FLAGS) == pid)
+ break;
+ if (current_time_ms() - start < 5000)
+ continue;
+ kill_and_wait(pid, &status);
+ break;
+ }
+ remove_dir(cwdbuf);
+ }
+}
+
+uint64_t r[5] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
+ 0xffffffffffffffff, 0xffffffffffffffff};
+
+void execute_one(void)
+{
+ intptr_t res = 0;
+ if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
+ }
+ memcpy((void*)0x200000000480, "./file0\000", 8);
+ res = syscall(
+ SYS_open, /*file=*/0x200000000480ul,
+ /*flags=O_NONBLOCK|O_CREAT|O_RDWR|0x80000000000000*/ 0x80000000000206ul,
+ /*mode=*/0ul);
+ if (res != -1)
+ r[0] = res;
+ syscall(SYS_ftruncate, /*fd=*/r[0], /*len=*/0x3862ul);
+ memcpy((void*)0x200000000100, "./file0\000", 8);
+ res = syscall(SYS_open, /*file=*/0x200000000100ul,
+ /*flags=O_DIRECT*/ 0x10000ul, /*mode=*/0ul);
+ if (res != -1)
+ r[1] = res;
+ *(uint64_t*)0x2000000000c0 = 0x200000000340;
+ *(uint64_t*)0x2000000000c8 = 0x41;
+ syscall(SYS_readv, /*fd=*/r[1], /*vec=*/0x2000000000c0ul, /*vlen=*/1ul);
+ res = syscall(SYS_socket, /*domain=*/2ul, /*type=*/2ul, /*proto=*/0x88);
+ if (res != -1)
+ r[2] = res;
+ res = syscall(SYS_socketpair, /*domain=*/1ul, /*type=SOCK_STREAM*/ 1ul,
+ /*proto=*/0, /*fds=*/0x200000000180ul);
+ if (res != -1)
+ r[3] = *(uint32_t*)0x200000000180;
+ syscall(SYS_dup2, /*oldfd=*/r[3], /*newfd=*/r[2]);
+ memcpy((void*)0x200000000140, "./file0\000", 8);
+ res =
+ syscall(SYS_open, /*file=*/0x200000000140ul, /*flags=*/0ul, /*mode=*/0ul);
+ if (res != -1)
+ r[4] = res;
+ syscall(SYS_sendfile, /*fd=*/r[4], /*s=*/r[2], /*offset=*/0xcbul,
+ /*nbytes=*/0x2000ul, /*hdtr=*/0ul, /*sbytes=*/0ul,
+ /*flags=SF_USER_READAHEAD|SF_NODISKIO|0x2*/ 0xbul);
+}
+int main(void)
+{
+ syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
+ /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
+ /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul,
+ /*fd=*/(intptr_t)-1, /*offset=*/0ul);
+ const char* reason;
+ (void)reason;
+ for (procid = 0; procid < 4; procid++) {
+ if (fork() == 0) {
+ use_temporary_dir();
+ loop();
+ }
+ }
+ sleep(1000000);
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+(cd ../testcases/swap; ./swap -t 3m -i 30 -l 100 > /dev/null 2>&1) &
+sleep 5
+
+work=/tmp/$prog.dir
+rm -rf $work
+mkdir $work
+cd /tmp/$prog.dir
+for i in `jot 30`; do
+ (
+ mkdir d$i
+ cd d$i
+ timeout 3m /tmp/$prog > /dev/null 2>&1 &
+ )
+done
+while pgrep -q $prog; do sleep 2; done
+while pkill swap; do :; done
+wait
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work
+exit 0
diff --git a/tools/test/stress2/misc/syzkaller79.sh b/tools/test/stress2/misc/syzkaller79.sh
new file mode 100755
index 000000000000..7413a2034a3d
--- /dev/null
+++ b/tools/test/stress2/misc/syzkaller79.sh
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+# panic: mutex so_rcv not owned at ../../../kern/uipc_usrreq.c:1750
+# cpuid = 5
+# time = 1746938647
+# KDB: stack backtrace:
+# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe01e75c5b40
+# vpanic() at vpanic+0x136/frame 0xfffffe01e75c5c70
+# panic() at panic+0x43/frame 0xfffffe01e75c5cd0
+# __mtx_assert() at __mtx_assert+0xa9/frame 0xfffffe01e75c5ce0
+# knote() at knote+0x45/frame 0xfffffe01e75c5d30
+# sowwakeup_locked() at sowwakeup_locked+0xc8/frame 0xfffffe01e75c5d50
+# socantsendmore() at socantsendmore+0x4f/frame 0xfffffe01e75c5d70
+# uipc_shutdown() at uipc_shutdown+0x113/frame 0xfffffe01e75c5db0
+# soshutdown() at soshutdown+0x3e/frame 0xfffffe01e75c5dd0
+# kern_shutdown() at kern_shutdown+0x5e/frame 0xfffffe01e75c5e00
+# amd64_syscall() at amd64_syscall+0x15a/frame 0xfffffe01e75c5f30
+# fast_syscall_common() at fast_syscall_common+0xf8/frame 0xfffffe01e75c5f30
+# --- syscall (0, FreeBSD ELF64, syscall), rip = 0x82281772a, rsp = 0x82092efd8, rbp = 0x82092f000 ---
+# KDB: enter: panic
+# [ thread pid 54792 tid 1014483 ]
+# Stopped at kdb_enter+0x33: movq $0,0x122f192(%rip)
+# db> x/s version
+# version: FreeBSD 15.0-CURRENT #0 main-n277201-48578dcb6b7e-dirty: Sat May 10 13:10:42 CEST 2025
+# pho@mercat1.netperf.freebsd.org:/usr/src/sys/amd64/compile/PHO
+# db>
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+set -u
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+// https://syzkaller.appspot.com/bug?id=ac94349a29f2efc40e9274239e4ca9b2c473a4e7
+// autogenerated by syzkaller (https://github.com/google/syzkaller)
+// syzkaller.appspot.com/x/repro.c?x=16c074d4580000
+
+#define _GNU_SOURCE
+
+#include <pwd.h>
+#include <stdarg.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/endian.h>
+#include <sys/syscall.h>
+#include <unistd.h>
+
+uint64_t r[1] = {0xffffffffffffffff};
+
+int main(void)
+{
+ syscall(SYS_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul,
+ /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/ 7ul,
+ /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/ 0x1012ul,
+ /*fd=*/(intptr_t)-1, /*offset=*/0ul);
+ const char* reason;
+ (void)reason;
+ intptr_t res = 0;
+ if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {
+ }
+ res = syscall(SYS_socketpair, /*domain=*/1ul, /*type=SOCK_SEQPACKET*/ 5ul,
+ /*proto=*/0, /*fds=*/0x200000000040ul);
+ if (res != -1)
+ r[0] = *(uint32_t*)0x200000000044;
+ syscall(SYS_fcntl, /*fd=*/r[0], /*cmd=*/4ul, /*flags=FASYNC*/ 0x40ul);
+ syscall(SYS_shutdown, /*fd=*/r[0], /*how=*/2ul);
+ return 0;
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c -lpthread || exit 1
+
+work=/tmp/$prog.dir
+rm -rf $work
+mkdir $work
+cd /tmp/$prog.dir
+timeout 3m /tmp/$prog > /dev/null 2>&1
+
+rm -rf /tmp/$prog /tmp/$prog.c /tmp/$prog.core /tmp/$prog.?????? $work
+exit 0
diff --git a/tools/test/stress2/misc/tcp4.sh b/tools/test/stress2/misc/tcp4.sh
index cc98a4e3d51f..da0b7c07283d 100755
--- a/tools/test/stress2/misc/tcp4.sh
+++ b/tools/test/stress2/misc/tcp4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/timeout.sh b/tools/test/stress2/misc/timeout.sh
index 079efe3006b5..90d160f6b771 100755
--- a/tools/test/stress2/misc/timeout.sh
+++ b/tools/test/stress2/misc/timeout.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/tmpfs10.sh b/tools/test/stress2/misc/tmpfs10.sh
index 870530c57ea7..6388f59959a4 100755
--- a/tools/test/stress2/misc/tmpfs10.sh
+++ b/tools/test/stress2/misc/tmpfs10.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# tmpfs(5) name lookup problem seen:
+# tmpfs(4) name lookup problem seen:
# $ ./tmpfs10.sh
# tmpfs10: unlink(p01193.14729) at loop #2: No such file or directory
diff --git a/tools/test/stress2/misc/tmpfs11.sh b/tools/test/stress2/misc/tmpfs11.sh
index efb535b8ea94..629ca8ae3d31 100755
--- a/tools/test/stress2/misc/tmpfs11.sh
+++ b/tools/test/stress2/misc/tmpfs11.sh
@@ -28,7 +28,7 @@
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
-# Test with two tmpfs(5) file systems mounted.
+# Test with two tmpfs(4) file systems mounted.
. ../default.cfg
diff --git a/tools/test/stress2/misc/tmpfs13.sh b/tools/test/stress2/misc/tmpfs13.sh
index 29b44cbc9ad4..231c42033f9d 100755
--- a/tools/test/stress2/misc/tmpfs13.sh
+++ b/tools/test/stress2/misc/tmpfs13.sh
@@ -40,6 +40,7 @@
. ../default.cfg
N=`sysctl -n hw.ncpu`
+[ $N -gt 32 ] && N=32 # Arbitrary cap
usermem=`sysctl -n hw.usermem`
[ `swapinfo | wc -l` -eq 1 ] && usermem=$((usermem/100*80))
size=$((usermem / 1024 / 1024 / 2))
diff --git a/tools/test/stress2/misc/tmpfs17.sh b/tools/test/stress2/misc/tmpfs17.sh
index 878fcf6c95d1..d5f6c50d2e48 100755
--- a/tools/test/stress2/misc/tmpfs17.sh
+++ b/tools/test/stress2/misc/tmpfs17.sh
@@ -26,7 +26,7 @@
# SUCH DAMAGE.
#
-# tmpfs(5) option nonc test scenario
+# tmpfs(4) option nonc test scenario
. ../default.cfg
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
diff --git a/tools/test/stress2/misc/tmpfs19.sh b/tools/test/stress2/misc/tmpfs19.sh
index ab1e96835955..4c8843ae1522 100755
--- a/tools/test/stress2/misc/tmpfs19.sh
+++ b/tools/test/stress2/misc/tmpfs19.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/tmpfs2.sh b/tools/test/stress2/misc/tmpfs2.sh
index 80885c331e14..09a2cfd68266 100755
--- a/tools/test/stress2/misc/tmpfs2.sh
+++ b/tools/test/stress2/misc/tmpfs2.sh
@@ -45,13 +45,15 @@ if [ $# -eq 0 ]; then
else
if [ $1 = find ]; then
- for i in `jot 1024`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
find ${mntpoint}* -type f > /dev/null 2>&1
done
else
# The test: Parallel mount and unmounts
- for i in `jot 1024`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
m=$1
opt=`[ $(( m % 2 )) -eq 0 ] && echo -f`
mount -t tmpfs tmpfs ${mntpoint}$m
diff --git a/tools/test/stress2/misc/tmpfs20.sh b/tools/test/stress2/misc/tmpfs20.sh
index 763d70a49ae8..80fa04936c4f 100755
--- a/tools/test/stress2/misc/tmpfs20.sh
+++ b/tools/test/stress2/misc/tmpfs20.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/tmpfs21.sh b/tools/test/stress2/misc/tmpfs21.sh
index 295ba0bd20c0..936f2c125564 100755
--- a/tools/test/stress2/misc/tmpfs21.sh
+++ b/tools/test/stress2/misc/tmpfs21.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Peter Holm
#
diff --git a/tools/test/stress2/misc/tmpfs22.sh b/tools/test/stress2/misc/tmpfs22.sh
index 4439ad1bf1d5..0912b03b5848 100755
--- a/tools/test/stress2/misc/tmpfs22.sh
+++ b/tools/test/stress2/misc/tmpfs22.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/tmpfs23.sh b/tools/test/stress2/misc/tmpfs23.sh
index 2f956d512dda..170f4c10cb8b 100755
--- a/tools/test/stress2/misc/tmpfs23.sh
+++ b/tools/test/stress2/misc/tmpfs23.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/tmpfs24.sh b/tools/test/stress2/misc/tmpfs24.sh
new file mode 100755
index 000000000000..eb366cddc127
--- /dev/null
+++ b/tools/test/stress2/misc/tmpfs24.sh
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# A SEEK_HOLE / SEEK_DATA test scenario
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+exp=/tmp/$prog.exp
+here=`pwd`
+log=/tmp/$prog.log
+
+cc -o /tmp/lsholes -Wall -Wextra -O2 $here/../tools/lsholes.c | exit 1
+cat > $exp <<EXP
+Min hole size is 4096, file size is 524288000.
+data #1 @ 0, size=4096)
+hole #2 @ 4096, size=4096
+data #3 @ 8192, size=4096)
+hole #4 @ 12288, size=4096
+data #5 @ 16384, size=4096)
+hole #6 @ 20480, size=524267520
+EXP
+
+set -eu
+mount -t tmpfs dummy $mntpoint
+set +e
+
+file=$mntpoint/file
+truncate -s 500m $file
+bs=`getconf MIN_HOLE_SIZE $file`
+printf "\001" | dd of=$file seek=$((0*bs)) bs=1 count=1 conv=notrunc status=none
+printf "\002" | dd of=$file seek=$((2*bs)) bs=1 count=1 conv=notrunc status=none
+printf "\003" | dd of=$file seek=$((4*bs)) bs=1 count=1 conv=notrunc status=none
+s1=0
+s2=0
+/tmp/lsholes $file > $log 2>&1; s1=$?
+
+cat $log
+diff -u $exp $log || s2=1
+
+umount $mntpoint
+rm -f /tmp/lsholes $exp $log
+exit $((s1 + s2))
diff --git a/tools/test/stress2/misc/tmpfs25.sh b/tools/test/stress2/misc/tmpfs25.sh
new file mode 100755
index 000000000000..b4ee7bdeef34
--- /dev/null
+++ b/tools/test/stress2/misc/tmpfs25.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+# Regression test for:
+# Bug 223015 - [tmpfs] [patch] tmpfs does not support sparse files
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+set -eu
+prog=$(basename "$0" .sh)
+cont=/tmp/$prog.cont
+sync=/tmp/$prog.sync
+mount | grep -q "on $mntpoint " && umount $mntpoint
+mount -t tmpfs -o size=100m dummy $mntpoint
+iused=`df $mntpoint | tail -1 | awk '{print $3}'`
+
+list="1m 10m 40m 45m 49m 50m 60m 100m 1g 4g"
+r=0
+for s in $list; do
+ truncate -s $s $mntpoint/sparse || {
+ echo "truncate -s $s failed"
+ r=1; break 2
+ }
+ rm $mntpoint/sparse || break
+ used=`df $mntpoint | tail -1 | awk '{print $3}'`
+ [ $used -ne $iused ] && {
+ echo "truncate -s $s test: $iused / $used"; r=1; break; }
+done
+
+touch $cont
+for i in `jot 1000`; do
+ [ $r -ne 0 ] && break
+ file=$mntpoint/sparse.$i
+ for s in $list; do
+ [ ! -f $cont ] && break
+ for n in `jot 300`; do [ -f $sync ] && break; sleep .2; done
+ truncate -s $s $file || {
+ echo "truncate -s $s failed"
+ rm -f $cont
+ break
+ }
+ [ -f $file ] || { echo "No file $file"; break; }
+ rm $file || break
+ done &
+done
+touch $sync
+wait
+
+used=`df $mntpoint | tail -1 | awk '{print $3}'`
+if [ $used -ne $iused ]; then
+ [ `ls -al $mntpoint | wc -l` -gt 3 ] &&
+ ls -al $mntpoint | head -10
+ df -i $mntpoint
+ fstat -f $mntpoint
+fi
+umount $mntpoint
+rm -f $cont $sync
+
+exit $r
diff --git a/tools/test/stress2/misc/tmpfs26.sh b/tools/test/stress2/misc/tmpfs26.sh
new file mode 100755
index 000000000000..25fa59ff37c3
--- /dev/null
+++ b/tools/test/stress2/misc/tmpfs26.sh
@@ -0,0 +1,179 @@
+#!/bin/sh
+
+# Bug 272678 - VFS: Incorrect data in read from concurrent write
+
+# Test scenario by: Kristian Nielsen <knielsen@knielsen-hq.org>
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+#include <stdio.h>
+#include <pthread.h>
+#include <sys/select.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MAGIC 0x42
+
+const char *filename = "testfile.bin";
+
+static FILE *write_file;
+static FILE *read_file;
+static pthread_mutex_t write_mutex;
+static pthread_cond_t write_cond;
+static pthread_mutex_t read_mutex;
+static pthread_cond_t read_cond;
+static pthread_mutex_t state_mutex;
+static pthread_cond_t state_cond;
+static int write_state;
+static int read_state;
+
+void *
+writer_routine(void *arg __unused)
+{
+ unsigned char data[44];
+
+ memset(data, MAGIC, sizeof(data));
+ pthread_mutex_lock(&write_mutex);
+
+ for (;;) {
+
+ while (write_state != 1)
+ pthread_cond_wait(&write_cond, &write_mutex);
+
+ fwrite(data, 1, sizeof(data), write_file);
+ fflush(write_file);
+
+ pthread_mutex_lock(&state_mutex);
+ write_state = 2;
+ pthread_cond_signal(&state_cond);
+ pthread_mutex_unlock(&state_mutex);
+ }
+}
+
+void *
+reader_routine(void *arg __unused)
+{
+
+ for (;;) {
+ unsigned char buf[387];
+ int len;
+
+ while (read_state != 1)
+ pthread_cond_wait(&read_cond, &read_mutex);
+
+ len = fread(buf, 1, sizeof(buf), read_file);
+ if (len < (int)sizeof(buf) && ferror(read_file)) {
+ perror(" read file");
+ exit(1);
+ }
+ for (int i = 0; i < len; ++i) {
+ if (buf[i] != MAGIC) {
+ fprintf(stderr, "ERROR! invalid value read 0x%2x at %d of %d, pos %ld\n",
+ buf[i], i, len, ftell(read_file));
+ exit(126);
+ }
+ }
+
+ pthread_mutex_lock(&state_mutex);
+ read_state = 2;
+ pthread_cond_signal(&state_cond);
+ pthread_mutex_unlock(&state_mutex);
+ }
+}
+
+void
+create_threads(void)
+{
+ pthread_t write_thread_id, read_thread_id;
+ pthread_attr_t attr;
+
+ pthread_mutex_init(&write_mutex, NULL);
+ pthread_mutex_init(&read_mutex, NULL);
+ pthread_mutex_init(&state_mutex, NULL);
+ pthread_cond_init(&write_cond, NULL);
+ pthread_cond_init(&read_cond, NULL);
+ pthread_cond_init(&state_cond, NULL);
+
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+ pthread_create(&write_thread_id, &attr, writer_routine, NULL);
+ pthread_create(&read_thread_id, &attr, reader_routine, NULL);
+}
+
+int
+main(int argc, char *argv[])
+{
+ int num_iter = 1000;
+ int i;
+ unsigned char buf[343];
+
+ if (argc >= 2)
+ num_iter = atoi(argv[1]);
+
+ write_state = 0;
+ read_state = 0;
+
+ create_threads();
+ memset(buf, MAGIC, sizeof(buf));
+
+ for (i = 0; i < num_iter; ++i) {
+ /* Write the first part of the file. */
+ pthread_mutex_lock(&write_mutex);
+ write_file = fopen(filename, "wb");
+ if (!write_file) {
+ perror(" open file");
+ exit(1);
+ }
+ fwrite(buf, 1, sizeof(buf), write_file);
+ fflush(write_file);
+
+ /* Open a read handle on the file. */
+ pthread_mutex_lock(&read_mutex);
+ read_file = fopen(filename, "rb");
+ if (!read_file) {
+ perror(" open read file");
+ exit(1);
+ }
+
+ write_state = 1;
+ read_state = 1;
+ pthread_cond_signal(&write_cond);
+ pthread_mutex_unlock(&write_mutex);
+ pthread_cond_signal(&read_cond);
+ pthread_mutex_unlock(&read_mutex);
+
+ pthread_mutex_lock(&state_mutex);
+ while (write_state != 2 || read_state != 2)
+ pthread_cond_wait(&state_cond, &state_mutex);
+ pthread_mutex_unlock(&state_mutex);
+
+ /* Close and remove the file, ready for another iteration. */
+ pthread_mutex_lock(&write_mutex);
+ fclose(write_file);
+ write_state = 0;
+ pthread_mutex_unlock(&write_mutex);
+
+ pthread_mutex_lock(&read_mutex);
+ fclose(read_file);
+ read_state = 0;
+ pthread_mutex_unlock(&read_mutex);
+
+ unlink(filename);
+ }
+
+ return (0);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O2 /tmp/$prog.c -lpthread || exit 1
+
+mount -t tmpfs dummy $mntpoint
+cd $mntpoint
+/tmp/$prog; s=$?
+cd -
+umount $mntpoint
+
+rm /tmp/$prog /tmp/$prog.c
+exit $s
diff --git a/tools/test/stress2/misc/tmpfs27.sh b/tools/test/stress2/misc/tmpfs27.sh
new file mode 100755
index 000000000000..5479dcd9188a
--- /dev/null
+++ b/tools/test/stress2/misc/tmpfs27.sh
@@ -0,0 +1,49 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# umount FS with memory mapped file. tmpfs version.
+
+# "panic: object with writable mappings does not have a reference" seen:
+# https://people.freebsd.org/~pho/stress/log/log0518.txt
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+set -eu
+prog=$(basename "$0" .sh)
+here=`pwd`
+mp1=$mntpoint
+
+mount -t tmpfs dummy $mp1
+
+export RUNDIR=$mp1/stressX
+export runRUNTIME=2m
+export LOAD=70
+export mmapLOAD=100
+export TESTPROGS="testcases/mmap/mmap testcases/swap/swap"
+set +e
+
+(cd ..; ./testcases/run/run $TESTPROGS > /dev/null 2>&1) & rpid=$!
+sleep 5
+
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 120 ]; do
+ umount -f $mp1 &&
+ mount -t tmpfs dummy $mp1
+ mount | grep -q "on $mp1 " || break
+ pgrep -q mmap || break
+done
+pkill run swap mmap
+while pgrep -q swap; do pkill swap; done
+wait $rpid
+
+while mount | grep -q "on $mp1 "; do
+ umount $mp1
+done
+exit 0
diff --git a/tools/test/stress2/misc/tmpfs28.sh b/tools/test/stress2/misc/tmpfs28.sh
new file mode 100755
index 000000000000..d73e957b7f28
--- /dev/null
+++ b/tools/test/stress2/misc/tmpfs28.sh
@@ -0,0 +1,61 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# A SEEK_HOLE / SEEK_DATA test scenario, variation of tmpfs24.sh
+
+# A regression test for "40c1672e886b - main - swap_pager: fix
+# seek_data with invalid first page"
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+exp=/tmp/$prog.exp
+here=`pwd`
+log=/tmp/$prog.log
+
+cc -o /tmp/lsholes -Wall -Wextra -O2 $here/../tools/lsholes.c | exit 1
+cat > $exp <<EXP
+Min hole size is 4096, file size is 524288000.
+data #1 @ 0, size=4096)
+hole #2 @ 4096, size=4096
+data #3 @ 8192, size=4096)
+hole #4 @ 12288, size=4096
+data #5 @ 16384, size=4096)
+hole #6 @ 20480, size=524267520
+EXP
+
+set -eu
+mount -t tmpfs dummy $mntpoint
+set +e
+
+file=$mntpoint/file
+copy=$mntpoint/copy
+truncate -s 500m $file
+bs=`getconf MIN_HOLE_SIZE $file`
+printf "\001" | dd of=$file seek=$((0*bs)) bs=1 count=1 conv=notrunc status=none
+printf "\002" | dd of=$file seek=$((2*bs)) bs=1 count=1 conv=notrunc status=none
+printf "\003" | dd of=$file seek=$((4*bs)) bs=1 count=1 conv=notrunc status=none
+s1=0
+s2=0
+s3=0
+/tmp/lsholes $file > $log 2>&1 || s1=1
+
+cmp -s $exp $log || { s2=2; sdiff $exp $log; }
+
+$here/../testcases/swap/swap -t 2m -i 20 -h > /dev/null &
+sleep 10
+cp $file $copy
+while pkill swap; do :; done
+wait
+cmp $file $copy || { echo "copy error"; s3=4; }
+
+umount $mntpoint
+rm -f /tmp/lsholes $exp $log
+exit $((s1 + s2 + s3))
diff --git a/tools/test/stress2/misc/tmpfs8.sh b/tools/test/stress2/misc/tmpfs8.sh
index b17a329f69e7..b78f0e74562b 100755
--- a/tools/test/stress2/misc/tmpfs8.sh
+++ b/tools/test/stress2/misc/tmpfs8.sh
@@ -28,7 +28,7 @@
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
-# Demonstrate rename(2) cache problem for tmpfs(5). Fixed in r226987.
+# Demonstrate rename(2) cache problem for tmpfs(4). Fixed in r226987.
# Variation of rename6.sh
. ../default.cfg
diff --git a/tools/test/stress2/misc/trim8.sh b/tools/test/stress2/misc/trim8.sh
index f31a10b5be25..2aafac7cf5ab 100755
--- a/tools/test/stress2/misc/trim8.sh
+++ b/tools/test/stress2/misc/trim8.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/truncate8.sh b/tools/test/stress2/misc/truncate8.sh
index 132468b3ca78..e3192262e4f3 100755
--- a/tools/test/stress2/misc/truncate8.sh
+++ b/tools/test/stress2/misc/truncate8.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/truncate9.sh b/tools/test/stress2/misc/truncate9.sh
index c199605e70a8..75526dcabf19 100755
--- a/tools/test/stress2/misc/truncate9.sh
+++ b/tools/test/stress2/misc/truncate9.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/truss2.sh b/tools/test/stress2/misc/truss2.sh
index 6a5743550b04..0bf769a485ab 100755
--- a/tools/test/stress2/misc/truss2.sh
+++ b/tools/test/stress2/misc/truss2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
diff --git a/tools/test/stress2/misc/udp2.sh b/tools/test/stress2/misc/udp2.sh
index 3cd72d82734b..f305fc554c24 100755
--- a/tools/test/stress2/misc/udp2.sh
+++ b/tools/test/stress2/misc/udp2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/ufsbench.sh b/tools/test/stress2/misc/ufsbench.sh
index 03e8ba64e2f6..58abba0971c8 100755
--- a/tools/test/stress2/misc/ufsbench.sh
+++ b/tools/test/stress2/misc/ufsbench.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/umount3.sh b/tools/test/stress2/misc/umount3.sh
index c6920b80f99d..b28230d8b3af 100755
--- a/tools/test/stress2/misc/umount3.sh
+++ b/tools/test/stress2/misc/umount3.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/umount4.sh b/tools/test/stress2/misc/umount4.sh
index e46f319959a0..bcd062bb8106 100755
--- a/tools/test/stress2/misc/umount4.sh
+++ b/tools/test/stress2/misc/umount4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Peter Holm
#
diff --git a/tools/test/stress2/misc/umountf11.sh b/tools/test/stress2/misc/umountf11.sh
index b2a694037420..b41ec6bc5737 100755
--- a/tools/test/stress2/misc/umountf11.sh
+++ b/tools/test/stress2/misc/umountf11.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/umountf12.sh b/tools/test/stress2/misc/umountf12.sh
index 8a13f8fd480a..af74cf37a0b8 100755
--- a/tools/test/stress2/misc/umountf12.sh
+++ b/tools/test/stress2/misc/umountf12.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/umountf4.sh b/tools/test/stress2/misc/umountf4.sh
index 4f5ea0fff660..e26555e7c6f3 100755
--- a/tools/test/stress2/misc/umountf4.sh
+++ b/tools/test/stress2/misc/umountf4.sh
@@ -65,13 +65,15 @@ if [ $# -eq 0 ]; then
else
if [ $1 = find ]; then
- for i in `jot 100`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
find ${mntpoint}* -type f > /dev/null 2>&1
done
else
# The test: Parallel mount and unmounts
- for i in `jot 100`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
m=$1
opt=`[ $(( m % 2 )) -eq 0 ] && echo -f`
mount $opt /dev/md${m} ${mntpoint}$m
diff --git a/tools/test/stress2/misc/umountf6.sh b/tools/test/stress2/misc/umountf6.sh
index aeb4454ea69c..628342689b38 100755
--- a/tools/test/stress2/misc/umountf6.sh
+++ b/tools/test/stress2/misc/umountf6.sh
@@ -65,13 +65,15 @@ if [ $# -eq 0 ]; then
else
if [ $1 = find ]; then
- for i in `jot 100`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
find ${mntpoint}* -type f > /dev/null 2>&1
done
else
# The test: Parallel mount and unmounts
- for i in `jot 100`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
m=$1
opt=`[ $(( m % 2 )) -eq 0 ] && echo -f`
mount $opt /dev/md${m} ${mntpoint}$m
diff --git a/tools/test/stress2/misc/unionfs13.sh b/tools/test/stress2/misc/unionfs13.sh
index 9c2d57425053..0202e782a11c 100755
--- a/tools/test/stress2/misc/unionfs13.sh
+++ b/tools/test/stress2/misc/unionfs13.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm
#
diff --git a/tools/test/stress2/misc/unionfs14.sh b/tools/test/stress2/misc/unionfs14.sh
index ca9fa3a5b274..054e76e4b476 100755
--- a/tools/test/stress2/misc/unionfs14.sh
+++ b/tools/test/stress2/misc/unionfs14.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/unionfs15.sh b/tools/test/stress2/misc/unionfs15.sh
new file mode 100755
index 000000000000..87cea7c0b15d
--- /dev/null
+++ b/tools/test/stress2/misc/unionfs15.sh
@@ -0,0 +1,86 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# O_PATH test scenario. Variation of nullfs29.sh
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+md1=$mdstart
+md2=$((md1 + 1))
+mp1=/mnt$md1
+mp2=/mnt$md2
+mkdir -p $mp1 $mp2
+set -e
+for i in $mp1 $mp2; do
+ mount | grep -q "on $i " && umount -f $i
+done
+for i in $md1 $md2; do
+ mdconfig -l | grep -q md$i && mdconfig -d -u $i
+done
+
+mdconfig -a -t swap -s 2g -u $md1
+mdconfig -a -t swap -s 2g -u $md2
+newfs $newfs_flags -n md$md1 > /dev/null
+newfs $newfs_flags -n md$md2 > /dev/null
+mount /dev/md$md1 $mp1
+mount /dev/md$md2 $mp2
+mount -t unionfs -o noatime $mp1 $mp2
+set +e
+
+cat > /tmp/unionfs15.c <<EOF
+#include <sys/stat.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main(void) {
+ int new_dir, new_file, ret;
+ struct stat sb;
+ char *dir = "test2";
+ char *path= "test2/what2";
+
+ if (mkdir(dir, 0755) == -1)
+ err(1, "mkdir(test2)");
+ new_dir = openat(AT_FDCWD, dir, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_PATH, 0700);
+ if (new_dir == -1)
+ err(1, "openat(%s)", dir);
+
+ ret = fstatat(new_dir, "what2", &sb, AT_SYMLINK_NOFOLLOW);
+ if (ret == 0)
+ errx(1, "Expected fstatat() to fail");
+ if (ret == -1 && errno != ENOENT)
+ err(1, "fstatat(%s)", dir);
+
+ close(new_dir);
+ new_file = openat(AT_FDCWD, path, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC, 0644);
+ if (new_file== -1)
+ err(1, "openat(%s)", path);
+}
+
+EOF
+mycc -o /tmp/unionfs15 -Wall -Wextra -O2 /tmp/unionfs15.c || exit 1
+cd $mp2
+/tmp/unionfs15; s=$?
+cd $here
+umount $mp2
+
+while mount | grep -Eq "on $mp2 .*unionfs"; do
+ umount $mp2 && break
+ sleep 5
+done
+umount $mp2
+umount $mp1
+mdconfig -d -u $md2
+mdconfig -d -u $md1
+rm -f /tmp/unionfs15.c /tmp/unionfs15
+exit $s
diff --git a/tools/test/stress2/misc/unionfs16.sh b/tools/test/stress2/misc/unionfs16.sh
new file mode 100755
index 000000000000..c1c65f7d8313
--- /dev/null
+++ b/tools/test/stress2/misc/unionfs16.sh
@@ -0,0 +1,65 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# No problems seen with this test scenario
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+[ -d /usr/src/tools/test/stress2 ] || exit 0
+prog=$(basename "$0" .sh)
+log=/tmp/$prog.log
+md1=$mdstart
+md2=$((md1 + 1))
+mp1=/mnt$md1
+mp2=/mnt$md2
+s=0
+
+mkdir -p $mp1 $mp2
+set -e
+for i in $mp1 $mp2; do
+ mount | grep -q "on $i " && umount -f $i
+done
+for i in $md1 $md2; do
+ mdconfig -l | grep -q md$i && mdconfig -d -u $i
+done
+
+mdconfig -a -t swap -s 3g -u $md1
+mdconfig -a -t swap -s 3g -u $md2
+newfs $newfs_flags -n md$md1 > /dev/null
+newfs $newfs_flags -n md$md2 > /dev/null
+mount /dev/md$md1 $mp1
+mount /dev/md$md2 $mp2
+(cd $mp1; cp -a /usr/src/tools/test/stress2 .)
+(cd $mp2; cp -a /usr/src/tools/test/stress2 .)
+rm $mp1/stress2/testcases/run/run
+rm $mp2/stress2/testcases/swap/swap
+mount -u -o ro $mp1
+mount -t unionfs -o below $mp1 $mp2
+rm $mp2/stress2/testcases/mkdir/mkdir
+chmod 777 $mp2
+set +e
+
+(cd $mp2/stress2; make > /dev/null 2>&1)
+export RUNDIR=$mp2/stressX
+export runRUNTIME=1m
+su $testuser -c "cd $mp2/stress2; ./run.sh vfs.cfg" > /dev/null 2>&1
+umount $mp2
+
+while mount | grep -Eq "unionfs.* on $mp2 "; do
+ umount $mp2 && break
+ sleep 5
+done
+fsck_ffs -fy /dev/md$md2 > $log 2>&1
+grep -Eq "WAS MODIFIED" $log && { cat $log; s=1; }
+umount $mp2
+umount $mp1
+mdconfig -d -u $md1
+mdconfig -d -u $md2
+rm -f $log
+exit $s
diff --git a/tools/test/stress2/misc/unionfs17.sh b/tools/test/stress2/misc/unionfs17.sh
new file mode 100755
index 000000000000..9ddbd1cab8cb
--- /dev/null
+++ b/tools/test/stress2/misc/unionfs17.sh
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# unionfs(4) test
+# Variation of unionfs7.sh, but with tmpfs
+
+# "mkdir: rmdir(d17) Directory not empty" seen.
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+mp1=/mnt$mdstart
+mp2=/mnt$((mdstart + 1))
+mkdir -p $mp1 $mp2
+set -e
+for i in $mp1 $mp2; do
+ mount | grep -q "on $i " && umount -f $i
+done
+
+mount -o size=4g -t tmpfs dummy $mp1
+mount -o size=4g -t tmpfs dummy $mp2
+
+mount -t unionfs -o noatime $mp1 $mp2
+set +e
+export 'INODES=100000'
+
+export CTRLDIR=$mp2/stressX.control
+export INCARNATIONS=10
+export LOAD=80
+export RUNDIR=$mp2/stressX
+export runRUNTIME=5m
+export rwLOAD=80
+export symlinkLOAD=80
+
+export TESTPROGS="
+testcases/lockf2/lockf2
+testcases/symlink/symlink
+testcases/openat/openat
+testcases/rw/rw
+testcases/fts/fts
+testcases/link/link
+testcases/lockf/lockf
+testcases/creat/creat
+testcases/mkdir/mkdir
+testcases/rename/rename
+testcases/mkfifo/mkfifo
+testcases/dirnprename/dirnprename
+testcases/dirrename/dirrename
+testcases/swap/swap
+"
+
+cp -r ../../stress2 $mp2
+export TESTPROGS=`echo $TESTPROGS | sed 's/\n/ /g'`
+
+set +e
+chmod 777 $mp2
+su $testuser -c \
+ "(cd $mp2/stress2; ./testcases/run/run $TESTPROGS)"
+
+while mount | grep -Eq "on $mp2 .*unionfs"; do
+ umount $mp2 && break
+ sleep 5
+done
+umount $mp2
+n=`find $mp1/stressX | wc -l`
+[ $n -eq 1 ] && s=0 || { find $mp1/stressX -ls | head -12; s=1; }
+umount $mp1
+exit $s
diff --git a/tools/test/stress2/misc/unionfs18.sh b/tools/test/stress2/misc/unionfs18.sh
new file mode 100755
index 000000000000..a7840db263e1
--- /dev/null
+++ b/tools/test/stress2/misc/unionfs18.sh
@@ -0,0 +1,73 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Simple unionfs(4) + tmpfs(4) test
+
+# "rmdir: d2: Directory not empty" seen.
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+. ../default.cfg
+
+mp1=/mnt$mdstart
+mp2=/mnt$((mdstart + 1))
+mkdir -p $mp1 $mp2
+set -e
+for i in $mp1 $mp2; do
+ mount | grep -q "on $i " && umount -f $i
+done
+
+md1=$mdstart
+md2=$((md1 + 1))
+mp1=/mnt$md1
+mp2=/mnt$md2
+mkdir -p $mp1 $mp2
+for i in $mp1 $mp2; do
+ mount | grep -q "on $i " && umount -f $i
+done
+
+if [ $# -eq 0 ]; then
+ echo "tmpfs version"
+ mount -o size=4g -t tmpfs dummy $mp1
+ mount -o size=4g -t tmpfs dummy $mp2
+else
+ echo "UFS version"
+ for i in $md1 $md2; do
+ mdconfig -l | grep -q md$i && mdconfig -d -u $i
+ done
+ mdconfig -a -t swap -s 4g -u $md1
+ mdconfig -a -t swap -s 4g -u $md2
+ newfs $newfs_flags -n md$md1 > /dev/null
+ newfs $newfs_flags -n md$md2 > /dev/null
+ mount /dev/md$md1 $mp1
+ mount /dev/md$md2 $mp2
+fi
+
+mount -t unionfs -o noatime $mp1 $mp2
+set +e
+
+N=3 # Tree depth
+here=`pwd`
+cd $mp2
+mkdir dir; cd dir
+for j in `seq 1 $N`; do
+ mkdir d$j && cd d$j
+done
+for j in `seq $N 1`; do
+ cd .. && rmdir d$j
+done
+cd ..
+rmdir dir || { s=1; find dir -ls; }
+cd $here
+
+while mount | grep -Eq "on $mp2 .*unionfs"; do
+ umount $mp2 && break
+ sleep 5
+done
+umount $mp2
+umount $mp1
+exit $s
diff --git a/tools/test/stress2/misc/unionfs19.sh b/tools/test/stress2/misc/unionfs19.sh
new file mode 100755
index 000000000000..a4e31ad0857e
--- /dev/null
+++ b/tools/test/stress2/misc/unionfs19.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# umount FS with memory mapped file
+# "panic: general protection fault" seen:
+# https://people.freebsd.org/~pho/stress/log/log0519.txt
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+here=`pwd`
+log=/tmp/$prog.log
+md1=$mdstart
+md2=$((md1 + 1))
+mp1=/mnt$md1
+mp2=/mnt$md2
+
+set -e
+mdconfig -l | grep -q md$md && mdconfig -d -u $md1
+mdconfig -l | grep -q md$u2 && mdconfig -d -u $md2
+
+mdconfig -s 2g -u $md1
+newfs $newfs_flags /dev/md$md1 > /dev/null
+mdconfig -s 2g -u $md2
+newfs $newfs_flags /dev/md$md2 > /dev/null
+
+mkdir -p $mp1 $mp2
+mount /dev/md$md1 $mp1
+mount /dev/md$md2 $mp2
+mount -t unionfs -o noatime $mp1 $mp2
+mount | grep -E "$mp1|$mp2"
+set +e
+
+export RUNDIR=$mp2/stressX
+export runRUNTIME=2m
+export LOAD=70
+export mmapLOAD=100
+export TESTPROGS="testcases/mmap/mmap testcases/swap/swap"
+
+(cd ..; ./testcases/run/run $TESTPROGS > /dev/null 2>&1) & rpid=$!
+sleep 5
+
+tail -F -n 0 /var/log/messages > $log & lpid=$!
+
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 120 ]; do
+ umount -f $mp2 &&
+ mount -t unionfs -o noatime $mp1 $mp2
+ sleep 5
+ mount | grep -q unionfs || break
+ pgrep -q mmap || break
+done
+pkill run swap mmap
+while pgrep -q swap; do pkill swap; done
+wait $rpid
+
+umount $mp2 # The unionfs mount
+umount $mp2
+umount $mp1
+
+mdconfig -d -u $md1
+mdconfig -d -u $md2
+
+kill $lpid && wait $lpid
+grep -m 1 "pager read error" $log && s=1 || s=0
+rm $log
+exit $s
diff --git a/tools/test/stress2/misc/unionfs4.sh b/tools/test/stress2/misc/unionfs4.sh
index 2355005c1f8b..e23f90004a88 100755
--- a/tools/test/stress2/misc/unionfs4.sh
+++ b/tools/test/stress2/misc/unionfs4.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
@@ -52,6 +52,8 @@ done
mdconfig -a -t swap -s 2g -u $md1
mdconfig -a -t swap -s 2g -u $md2
+[ "$newfs_flags" = "-U" ] &&
+ newfs_flags="-j" # "out of inodes" work around
newfs $newfs_flags -n md$md1 > /dev/null
newfs $newfs_flags -n md$md2 > /dev/null
mount /dev/md$md1 $mp1
diff --git a/tools/test/stress2/misc/unionfs5.sh b/tools/test/stress2/misc/unionfs5.sh
index 5e12ffbf5abd..a45ffde5c0b2 100755
--- a/tools/test/stress2/misc/unionfs5.sh
+++ b/tools/test/stress2/misc/unionfs5.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
@@ -50,8 +50,8 @@ for i in $md1 $md2; do
mdconfig -l | grep -q md$i && mdconfig -d -u $i
done
-mdconfig -a -t swap -s 2g -u $md1
-mdconfig -a -t swap -s 2g -u $md2
+mdconfig -a -t swap -s 5g -u $md1
+mdconfig -a -t swap -s 5g -u $md2
newfs $newfs_flags -n md$md1 > /dev/null
newfs $newfs_flags -n md$md2 > /dev/null
mount /dev/md$md1 $mp1
@@ -68,11 +68,12 @@ else
echo "Using FFS"
export RUNDIR=$mp1/stressX
fi
-export runRUNTIME=2m
+export CTRLDIR=$mp2/stressX.control
+export runRUNTIME=2m
-(cd ../testcases/mkdir; ./mkdir -t 2m -i 20)
+(cd ../testcases/mkdir; ./mkdir -t 2m -i 20 -l 100)
-find $RUNDIR -ls | head -5
+find $RUNDIR -ls | grep -v 'stressX$' | head -5
while mount | grep -Eq "on $mp2 .*unionfs"; do
umount $mp2 && break
sleep 5
diff --git a/tools/test/stress2/misc/unionfs6.sh b/tools/test/stress2/misc/unionfs6.sh
index 7291a6f61fd8..cae1995a2e0d 100755
--- a/tools/test/stress2/misc/unionfs6.sh
+++ b/tools/test/stress2/misc/unionfs6.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
@@ -27,7 +27,7 @@
# SUCH DAMAGE.
#
-# unionfs(8) test
+# unionfs(4) test
# "panic: ufs dir vp 0xfffffe0157351068 ip 0xfffffe016a63d488 flags 0x3c06" seen
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
@@ -57,6 +57,10 @@ mount -t unionfs -o noatime $mp1 $mp2
set +e
mount | grep -E "$mp1|$mp2"
+set `df -ik $mp2 | tail -1 | awk '{print $4,$7}'`
+export KBLOCKS=$(($1 / 4))
+export INODES=$(($2 / 4))
+
export CTRLDIR=$mp2/stressX.control
export INCARNATIONS=10
export LOAD=80
diff --git a/tools/test/stress2/misc/unionfs7.sh b/tools/test/stress2/misc/unionfs7.sh
index ad4514c60532..6adcd01a5f83 100755
--- a/tools/test/stress2/misc/unionfs7.sh
+++ b/tools/test/stress2/misc/unionfs7.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
@@ -27,7 +27,7 @@
# SUCH DAMAGE.
#
-# unionfs(8) test
+# unionfs(4) test
# "unionfs_get_node_status: 0xfffffe018f356770 is not exclusive locked but
# should be" seen.
@@ -60,6 +60,10 @@ mount -t unionfs -o noatime $mp1 $mp2
set +e
mount | grep -E "$mp1|$mp2"
+set `df -ik $mp2 | tail -1 | awk '{print $4,$7}'`
+export KBLOCKS=$(($1 / 4))
+export INODES=$(($2 / 4))
+
export CTRLDIR=$mp2/stressX.control
export INCARNATIONS=10
export LOAD=80
diff --git a/tools/test/stress2/misc/unionfs8.sh b/tools/test/stress2/misc/unionfs8.sh
index b0d9deb354d2..fdc37b16ff03 100755
--- a/tools/test/stress2/misc/unionfs8.sh
+++ b/tools/test/stress2/misc/unionfs8.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
@@ -27,7 +27,7 @@
# SUCH DAMAGE.
#
-# unionfs(8) test with a cd9660 file system
+# unionfs(4) test with a cd9660(4) file system
# "panic: unionfs_noderem: vnode 0xfffffe014f9259c8 locked recursively" seen
# https://people.freebsd.org/~pho/stress/log/log0233.txt
@@ -51,8 +51,8 @@ for i in $md1 $md2; do
mdconfig -l | grep -q md$i && mdconfig -d -u $i
done
-mdconfig -a -t swap -s 4g -u $md1
-mdconfig -a -t swap -s 4g -u $md2
+mdconfig -a -t swap -s 5g -u $md1
+mdconfig -a -t swap -s 5g -u $md2
newfs $newfs_flags -n md$md1 > /dev/null
newfs $newfs_flags -n md$md2 > /dev/null
mount /dev/md$md1 $mp1
@@ -69,6 +69,10 @@ mount -t unionfs -o below $mp1 $mp2
set +e
mount | grep -E "$mp1|$mp2"
+set `df -ik $mp2 | tail -1 | awk '{print $4,$7}'`
+export KBLOCKS=$(($1 / 6))
+export INODES=$(($2 / 6))
+
export CTRLDIR=$mp2/stressX.control
export INCARNATIONS=10
export LOAD=80
diff --git a/tools/test/stress2/misc/unionfs9.sh b/tools/test/stress2/misc/unionfs9.sh
index 80ab45e38f88..700eed13aeb5 100755
--- a/tools/test/stress2/misc/unionfs9.sh
+++ b/tools/test/stress2/misc/unionfs9.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
@@ -33,6 +33,7 @@
# https://people.freebsd.org/~pho/stress/log/log0205.txt
# https://people.freebsd.org/~pho/stress/log/log0226.txt
+# https://people.freebsd.org/~pho/stress/log/log0404.txt
[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
. ../default.cfg
diff --git a/tools/test/stress2/misc/unix_socket.sh b/tools/test/stress2/misc/unix_socket.sh
index a5486dd7d4f0..c4283f30de0d 100755
--- a/tools/test/stress2/misc/unix_socket.sh
+++ b/tools/test/stress2/misc/unix_socket.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/unix_socket_detach.sh b/tools/test/stress2/misc/unix_socket_detach.sh
index 66670daf5639..6d201273ac05 100755
--- a/tools/test/stress2/misc/unix_socket_detach.sh
+++ b/tools/test/stress2/misc/unix_socket_detach.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2016 Mark Johnston <markj@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/vfork.sh b/tools/test/stress2/misc/vfork.sh
index 20db95c2b9be..cabc30ebaa6c 100755
--- a/tools/test/stress2/misc/vfork.sh
+++ b/tools/test/stress2/misc/vfork.sh
@@ -31,6 +31,9 @@
# "panic: failed to set signal flags for ast p ... fl 4" seen.
# Fixed in r302999.
+# Test scenario updated after commit:
+# ecc662c749b1 - main - PT_ATTACH: do not interrupt interruptible sleeps
+
. ../default.cfg
cd /tmp
@@ -46,38 +49,32 @@ main(void)
fprintf(stderr, "%d\n", getpid());
if ((pid = vfork()) == 0) {
-#if 0
- if (ptrace(PT_TRACE_ME, 0, 0, 0) == -1)
- err(1, "PT_TRACEME");
-#endif
sleep(30);
_exit(0);
}
if (pid == -1)
err(1, "vfork");
-
- return (0);
}
EOF
-mycc -o vfork1 -Wall -Wextra -g vfork1.c
-rm vfork1.c
+mycc -o vfork1 -Wall -Wextra -g vfork1.c || exit 1
+rm vfork1.c
cat > vfork2.c <<- EOF
#include <sys/types.h>
+#include <sys/ptrace.h>
+#include <sys/resource.h>
+#include <sys/time.h>
+#include <sys/wait.h>
#include <err.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
-#include <sys/ptrace.h>
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <sys/wait.h>
#include <unistd.h>
int
-main(int argc, char **argv)
+main(int argc, char *argv[])
{
pid_t pid, rpid;
struct rusage ru;
@@ -86,6 +83,7 @@ main(int argc, char **argv)
if (argc != 2)
errx(1, "Usage: %s <pid>", argv[0]);
pid = atoi(argv[1]);
+ status = 0;
if (pid == -1)
err(1, "fork()");
@@ -99,24 +97,17 @@ main(int argc, char **argv)
err(0, "OK wait4");
}
if (rpid == 0) {
-// fprintf(stderr, "No rusage info.\n");
if (ptrace(PT_DETACH, pid, NULL, 0) == -1)
err(1, "ptrace(%d) detach", pid);
- if (wait(&status) == -1)
- err(1, "wait");
} else {
fprintf(stderr, "FAIL Got unexpected rusage.\n");
if (ru.ru_utime.tv_sec != 0)
fprintf(stderr, "FAIL tv_sec\n");
}
- if (status != 0x4000)
- fprintf(stderr, "FAIL Child exit status 0x%x\n", status);
-
- return (0);
}
EOF
-mycc -o vfork2 -Wall -Wextra -g vfork2.c
-rm vfork2.c
+mycc -o vfork2 -Wall -Wextra -g vfork2.c || exit 1
+rm vfork2.c
./vfork1 &
sleep .2
@@ -127,5 +118,6 @@ childpid=`ps -lx | grep -v grep | grep vfork1 |
./vfork2 $childpid
s=$?
+pkill vfork1
rm -f vfork1 vfork2
exit $s
diff --git a/tools/test/stress2/misc/vm_map.sh b/tools/test/stress2/misc/vm_map.sh
index fb2a2b75b5a5..e209d8aacb2c 100755
--- a/tools/test/stress2/misc/vm_map.sh
+++ b/tools/test/stress2/misc/vm_map.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/vunref.sh b/tools/test/stress2/misc/vunref.sh
index f844a0dd3625..f08035a95694 100755
--- a/tools/test/stress2/misc/vunref.sh
+++ b/tools/test/stress2/misc/vunref.sh
@@ -82,7 +82,8 @@ if [ $# -eq 0 ]; then
else
if [ $1 = mmap ]; then
touch $RUNDIR/active.$2
- for i in `jot 500`; do
+ start=`date +%s`
+ while [ $((`date +%s`- start)) -lt 300 ]; do
cd ${mntpoint}$2
/tmp/vunref > /dev/null 2>&1
cd /
diff --git a/tools/test/stress2/misc/write2.sh b/tools/test/stress2/misc/write2.sh
index 82d7e1c988d7..f1f9deeef374 100755
--- a/tools/test/stress2/misc/write2.sh
+++ b/tools/test/stress2/misc/write2.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2022 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/zfs10.sh b/tools/test/stress2/misc/zfs10.sh
index 3f3fdd2622d7..9d8ae717dffa 100755
--- a/tools/test/stress2/misc/zfs10.sh
+++ b/tools/test/stress2/misc/zfs10.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/zfs11.sh b/tools/test/stress2/misc/zfs11.sh
index 97e71a5a13f7..84300aed0c0c 100755
--- a/tools/test/stress2/misc/zfs11.sh
+++ b/tools/test/stress2/misc/zfs11.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/zfs12.sh b/tools/test/stress2/misc/zfs12.sh
index cfabca2b9f6f..e8f82efc9b9b 100755
--- a/tools/test/stress2/misc/zfs12.sh
+++ b/tools/test/stress2/misc/zfs12.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
diff --git a/tools/test/stress2/misc/zfs13.sh b/tools/test/stress2/misc/zfs13.sh
index 2ccd4388270d..33630e0f1d75 100755
--- a/tools/test/stress2/misc/zfs13.sh
+++ b/tools/test/stress2/misc/zfs13.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm
#
diff --git a/tools/test/stress2/misc/zfs14.sh b/tools/test/stress2/misc/zfs14.sh
index 750119aff941..70b97e950dff 100755
--- a/tools/test/stress2/misc/zfs14.sh
+++ b/tools/test/stress2/misc/zfs14.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/misc/zfs15.sh b/tools/test/stress2/misc/zfs15.sh
new file mode 100755
index 000000000000..b40474507517
--- /dev/null
+++ b/tools/test/stress2/misc/zfs15.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+
+# Test scenario suggestion by: markj@
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+kldstat -v | grep -q zfs.ko || { kldload zfs.ko; loaded=1; } ||
+ exit 0
+
+. ../default.cfg
+
+here=`pwd`
+level=`jot -r 1 1 3` # Redundancy levels
+mp1=/stress2_tank/test
+s=0
+u1=$mdstart
+u2=$((u1 + 1))
+u3=$((u1 + 2))
+u4=$((u1 + 3))
+u5=$((u1 + 4))
+
+set -e
+mdconfig -l | grep -q md$u1 && mdconfig -d -u $u1
+mdconfig -l | grep -q md$u2 && mdconfig -d -u $u2
+mdconfig -l | grep -q md$u3 && mdconfig -d -u $u3
+mdconfig -l | grep -q md$u4 && mdconfig -d -u $u4
+mdconfig -l | grep -q md$u5 && mdconfig -d -u $u5
+
+mdconfig -s 512m -u $u1
+mdconfig -s 512m -u $u2
+mdconfig -s 512m -u $u3
+mdconfig -s 512m -u $u4
+mdconfig -s 512m -u $u5
+
+zpool list | egrep -q "^stress2_tank" && zpool destroy stress2_tank
+[ -d /stress2_tank ] && rm -rf /stress2_tank
+zpool create stress2_tank raidz$level md$u1 md$u2 md$u3 md$u4
+zfs create stress2_tank/test
+set +e
+
+export RUNDIR=/stress2_tank/test/stressX
+export runRUNTIME=5m
+export LOAD=80
+export symlinkLOAD=80
+export rwLOAD=80
+export TESTPROGS="
+testcases/lockf2/lockf2
+testcases/symlink/symlink
+testcases/openat/openat
+testcases/rw/rw
+testcases/fts/fts
+testcases/link/link
+testcases/lockf/lockf
+testcases/creat/creat
+testcases/mkdir/mkdir
+testcases/rename/rename
+testcases/mkfifo/mkfifo
+testcases/dirnprename/dirnprename
+testcases/dirrename/dirrename
+testcases/swap/swap
+"
+
+(cd ..; ./testcases/run/run $TESTPROGS > /dev/null 2>&1) &
+
+sleep 60
+echo "zpool attach stress2_tank raidz$level-0 md$u5"
+zpool attach stress2_tank raidz$level-0 md$u5
+sleep 30
+zfs snapshot stress2_tank/test@1
+wait
+
+while zpool status | grep -q "in progress"; do
+ sleep 5
+done
+zpool scrub stress2_tank
+zpool status | grep -q "errors: No known data errors" ||
+ { zpool status; s=1; }
+
+zfs umount stress2_tank/test
+zfs destroy -r stress2_tank
+zpool destroy stress2_tank
+
+mdconfig -d -u $u1
+mdconfig -d -u $u2
+mdconfig -d -u $u3
+mdconfig -d -u $u4
+mdconfig -d -u $u5
+[ -n "$loaded" ] && kldunload zfs.ko
+exit $s
diff --git a/tools/test/stress2/misc/zfs16.sh b/tools/test/stress2/misc/zfs16.sh
new file mode 100755
index 000000000000..258bf9ea4799
--- /dev/null
+++ b/tools/test/stress2/misc/zfs16.sh
@@ -0,0 +1,105 @@
+#!/bin/sh
+
+# No problems seen
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+kldstat -v | grep -q zfs.ko || { kldload zfs.ko; loaded=1; } ||
+ exit 0
+
+. ../default.cfg
+
+here=`pwd`
+cd /tmp
+sed '1,/^EOF/d' < $here/datamove.sh > zfs16.c
+mycc -o zfs16 -Wall -O0 -g zfs16.c || exit 1
+rm -f zfs16.c
+
+mp1=/stress2_tank/test
+u1=$mdstart
+u2=$((u1 + 1))
+
+set -eu
+mdconfig -l | grep -q md$u1 && mdconfig -d -u $u1
+mdconfig -l | grep -q md$u2 && mdconfig -d -u $u2
+
+mdconfig -s 2g -u $u1
+mdconfig -s 2g -u $u2
+
+zpool list | egrep -q "^stress2_tank" && zpool destroy stress2_tank
+[ -d /stress2_tank ] && rm -rf /stress2_tank
+zpool create stress2_tank md$u1 md$u2
+zfs create stress2_tank/test
+set +e
+
+(cd $here/../testcases/swap; ./swap -t 2m -i 20 -l 100 -h > /dev/null) &
+sleep 2
+cd $mp1
+while pgrep -q swap; do
+ /tmp/zfs16; s=$?
+ rm -f /stress2_tank/test/*
+done
+cd $here
+while pkill swap; do sleep 1; done
+wait
+
+zfs umount stress2_tank/test
+zfs destroy -r stress2_tank
+zpool destroy stress2_tank
+mdconfig -d -u $u1
+mdconfig -d -u $u2
+rm -f /tmp/zfs16
+set +u
+[ $loaded ] && kldunload zfs.ko
+exit $s
+EOF
+#include <sys/types.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/param.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define SIZ (500UL * 1024 * 1024)
+
+int
+main(int argc __unused, char *argv[])
+{
+ off_t hole;
+ size_t len;
+ int fd;
+ char *p, *path;
+
+ len = SIZ;
+
+ path = argv[1];
+ if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == -1)
+ err(1,"open()");
+ if (ftruncate(fd, len) == -1)
+ err(1, "ftruncate");
+ if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) ==
+ MAP_FAILED) {
+ if (errno == ENOMEM)
+ return (1);
+ err(1, "mmap(1)");
+ }
+ p[1 * 1024] = 1;
+ p[2 * 1024] = 1;
+ p[4 * 1024] = 1;
+
+ if (msync(p, len, MS_SYNC | MS_INVALIDATE) == -1)
+ err(1, "msync()");
+
+ if ((hole = lseek(fd, 0, SEEK_HOLE)) == -1)
+ err(1, "lseek(SEEK_HOLE)");
+ if (hole != SIZ)
+ printf("--> hole = %jd, file size=%jd\n",
+ (intmax_t)hole, (intmax_t)SIZ);
+ close(fd);
+
+ return (hole == SIZ ? 0 : 1);
+}
diff --git a/tools/test/stress2/misc/zfs17.sh b/tools/test/stress2/misc/zfs17.sh
new file mode 100755
index 000000000000..d20e39765afa
--- /dev/null
+++ b/tools/test/stress2/misc/zfs17.sh
@@ -0,0 +1,74 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Copy from nullfs over zfs to nullfs over ufs
+# Test scenario description by: mjguzik
+
+# Page fault seen:
+# https://people.freebsd.org/~pho/stress/log/log0498.txt
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+[ `sysctl -n kern.kstack_pages` -lt 4 ] && exit 0
+
+. ../default.cfg
+
+set -u
+kldstat -v | grep -q zfs.ko || { kldload zfs.ko ||
+ exit 0; loaded=1; }
+
+u1=$mdstart
+u2=$((u1 + 1))
+u3=$((u2 + 1))
+mp0=/stress2_tank/test # zfs mount
+mp1=$mntpoint # nullfs of zfs
+mp2=$mntpoint$mdstart # ufs
+mp3=$mntpoint$((mdstart + 1)) # nullfs of ufs
+mkdir -p $mp2 $mp3
+
+mdconfig -l | grep -q md$u1 && mdconfig -d -u $u1
+mdconfig -l | grep -q md$u2 && mdconfig -d -u $u2
+
+mdconfig -s 2g -u $u1
+mdconfig -s 2g -u $u2
+
+zpool list | egrep -q "^stress2_tank" && zpool destroy stress2_tank
+[ -d /stress2_tank ] && rm -rf /stress2_tank
+zpool create stress2_tank raidz md$u1 md$u2
+zfs create ${mp0#/}
+
+mount | grep -q $mp1 && umount -f $mp1
+mount -t nullfs $mp0 $mp1
+
+mdconfig -a -t swap -s 1g -u $u3
+newfs $newfs_flags /dev/md$u3 > /dev/null
+mount /dev/md$u3 $mp2
+mount -t nullfs $mp2 $mp3
+
+dd if=/dev/zero of=$diskimage bs=1m count=50 status=none
+cp $diskimage $mp1
+cp $mp1/diskimage $mp3
+rm -f $diskimage
+
+umount $mp3
+umount $mp2
+mdconfig -d -u $u3
+
+while mount | grep -q "on $mntpoint "; do
+ umount $mntpoint && break
+ sleep 1
+done
+
+zfs umount ${mp0#/}
+zfs destroy -r stress2_tank
+zpool destroy stress2_tank
+
+mdconfig -d -u $u2
+mdconfig -d -u $u1
+set +u
+[ -n "$loaded" ] && kldunload zfs.ko
+exit 0
diff --git a/tools/test/stress2/misc/zfs18.sh b/tools/test/stress2/misc/zfs18.sh
new file mode 100755
index 000000000000..fb4f301f43c9
--- /dev/null
+++ b/tools/test/stress2/misc/zfs18.sh
@@ -0,0 +1,134 @@
+#!/bin/sh
+
+# File corruption scenario.
+# Test program obtained from Kyle Evans <kevans@FreeBSD.org>
+
+# "panic: VERIFY3(rc->rc_count == number) failed (4849664 == 0)" seen.
+
+# Page fault seen:
+# https://people.freebsd.org/~pho/stress/log/log0560.txt
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+[ `sysctl -n kern.kstack_pages` -lt 4 ] && exit 0
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+cat > /tmp/$prog.c <<EOF
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <assert.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+
+//#define FILE "2"
+#define FILE "file"
+
+int
+main(void)
+{
+ struct stat sb;
+ ssize_t wsz;
+ size_t bufsz;
+ void *buf, *obuf;
+ int mfd, fd;
+ int done = 0;
+
+ mfd = open(FILE, O_RDONLY);
+ assert(mfd >= 0);
+
+ assert(fstat(mfd, &sb) == 0);
+ bufsz = sb.st_size;
+ buf = obuf = mmap(NULL, bufsz, PROT_READ, MAP_SHARED, mfd, 0);
+ assert(buf != MAP_FAILED);
+
+ /* O_RDWR */
+ fd = open(FILE, O_RDWR);
+ if (fd < 0)
+ err(1, "open");
+ assert(fd >= 0);
+
+again:
+ while (bufsz > 0) {
+ wsz = write(fd, buf, bufsz);
+ if (wsz < 0)
+ err(1, "write");
+ else if (wsz == 0)
+ fprintf(stderr, "Huh?\n");
+ bufsz -= wsz;
+ buf += wsz;
+ }
+
+ bufsz = sb.st_size;
+ buf = obuf;
+
+ if (++done < 2)
+ goto again;
+
+ close(fd);
+ munmap(obuf, sb.st_size);
+ close(mfd);
+ return (0);
+}
+EOF
+mycc -o /tmp/$prog -Wall -Wextra -O0 /tmp/$prog.c || exit 1
+set -u
+kldstat -v | grep -q zfs.ko || { kldload zfs.ko ||
+ exit 0; loaded=1; }
+
+u1=$mdstart
+u2=$((u1 + 1))
+mp0=/stress2_tank/test # zfs mount
+
+mdconfig -l | grep -q md$u1 && mdconfig -d -u $u1
+mdconfig -l | grep -q md$u2 && mdconfig -d -u $u2
+
+mdconfig -s 4g -u $u1
+mdconfig -s 4g -u $u2
+
+zpool list | egrep -q "^stress2_tank" && zpool destroy stress2_tank
+[ -d /stress2_tank ] && rm -rf /stress2_tank
+zpool create stress2_tank raidz md$u1 md$u2
+zfs create ${mp0#/}
+
+here=`pwd`
+cd /stress2_tank
+# Optimized file creation:
+#jot -b 'A' -s '' 875998989 > file
+dd if=/dev/random of=file bs=1m count=$(((875998990/1024/1024)+1)) status=none
+truncate -s 875998990 file
+cat file file > file.post
+mv file file.orig
+
+counter=1
+s=0
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 300 ]; do
+ cp file.orig file
+ /tmp/$prog
+ if ! cmp file file.post; then
+ echo "Iteration #$counter"
+ od -t x8 file | head -1000 > /tmp/$prog.file1
+ od -t x8 file.post | head -1000 > /tmp/$prog.file2
+ diff /tmp/$prog.file1 /tmp/$prog.file2 | head -15
+ rm /tmp/$prog.file1 /tmp/$prog.file2
+ s=1
+ break
+ fi
+ counter=$((counter + 1))
+done
+cd $here
+
+zfs umount ${mp0#/}
+zfs destroy -r stress2_tank
+zpool destroy stress2_tank
+
+mdconfig -d -u $u2
+mdconfig -d -u $u1
+set +u
+[ $loaded ] && kldunload zfs.ko
+rm /tmp/$prog /tmp/$prog.c
+exit $s
diff --git a/tools/test/stress2/misc/zfs19.sh b/tools/test/stress2/misc/zfs19.sh
new file mode 100755
index 000000000000..a3bb19c8be07
--- /dev/null
+++ b/tools/test/stress2/misc/zfs19.sh
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+#
+# Copyright (c) 2024 Peter Holm <pho@FreeBSD.org>
+#
+# SPDX-License-Identifier: BSD-2-Clause
+#
+
+# Hunt for "vm_fault: pager read error, pid 99058 (mmap)"
+
+[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
+kldstat -v | grep -q zfs.ko || { kldload zfs.ko; loaded=1; } ||
+ exit 0
+
+. ../default.cfg
+
+prog=$(basename "$0" .sh)
+here=`pwd`
+log=/tmp/$prog.log
+mp1=/stress2_tank/test
+u1=$mdstart
+u2=$((u1 + 1))
+
+set -e
+mdconfig -l | grep -q md$u1 && mdconfig -d -u $u1
+mdconfig -l | grep -q md$u2 && mdconfig -d -u $u2
+
+mdconfig -s 2g -u $u1
+mdconfig -s 2g -u $u2
+
+zpool list | egrep -q "^stress2_tank" && zpool destroy stress2_tank
+[ -d /stress2_tank ] && rm -rf /stress2_tank
+zpool create stress2_tank md$u1 md$u2
+zfs create stress2_tank/test
+set +e
+
+export RUNDIR=/stress2_tank/test/stressX
+export runRUNTIME=2m
+export LOAD=70
+export mmapLOAD=100
+export TESTPROGS="testcases/mmap/mmap testcases/swap/swap"
+
+(cd ..; ./testcases/run/run $TESTPROGS > /dev/null 2>&1) & rpid=$!
+sleep 5
+
+tail -F -n 0 /var/log/messages > $log & lpid=$!
+
+start=`date +%s`
+while [ $((`date +%s` - start)) -lt 120 ]; do
+ zfs umount -f stress2_tank/test &&
+ zfs mount stress2_tank/test
+ sleep 5
+ zfs list | grep -q /stress2_tank/test || break
+ pgrep -q mmap || break
+done
+pkill run swap mmap
+while pgrep -q swap; do pkill swap; done
+wait $rpid
+
+zfs umount stress2_tank/test
+zfs destroy -r stress2_tank
+zpool destroy stress2_tank
+
+mdconfig -d -u $u1
+mdconfig -d -u $u2
+[ -n "$loaded" ] && kldunload zfs.ko
+
+kill $lpid && wait $lpid
+grep -m 1 "pager read error" $log && s=1 || s=0
+rm $log
+s=0 # This is an expected behavior for zfs
+exit $s
diff --git a/tools/test/stress2/misc/zfs8.sh b/tools/test/stress2/misc/zfs8.sh
index 7d1d9887ce29..5eb53cd78ead 100755
--- a/tools/test/stress2/misc/zfs8.sh
+++ b/tools/test/stress2/misc/zfs8.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2018 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/zfs9.sh b/tools/test/stress2/misc/zfs9.sh
index 274a42f18bdb..2b051c8cd3c3 100755
--- a/tools/test/stress2/misc/zfs9.sh
+++ b/tools/test/stress2/misc/zfs9.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/zz-combo01.sh b/tools/test/stress2/misc/zz-combo01.sh
index 8899ade3441f..19c102288c79 100755
--- a/tools/test/stress2/misc/zz-combo01.sh
+++ b/tools/test/stress2/misc/zz-combo01.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/zz-combo02.sh b/tools/test/stress2/misc/zz-combo02.sh
index 2d866858bb8f..d65caf2f3c22 100755
--- a/tools/test/stress2/misc/zz-combo02.sh
+++ b/tools/test/stress2/misc/zz-combo02.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/zz-combo03.sh b/tools/test/stress2/misc/zz-combo03.sh
index 7afaec11e861..1bc3424f9de3 100755
--- a/tools/test/stress2/misc/zz-combo03.sh
+++ b/tools/test/stress2/misc/zz-combo03.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
diff --git a/tools/test/stress2/misc/zz-combo04.sh b/tools/test/stress2/misc/zz-combo04.sh
index 69003ec73371..1cbe19b6d518 100755
--- a/tools/test/stress2/misc/zz-combo04.sh
+++ b/tools/test/stress2/misc/zz-combo04.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm
#
diff --git a/tools/test/stress2/misc/zzbuildworld.sh b/tools/test/stress2/misc/zzbuildworld.sh
index ae0956239648..e1bf867d8d5f 100755
--- a/tools/test/stress2/misc/zzbuildworld.sh
+++ b/tools/test/stress2/misc/zzbuildworld.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2019 Dell EMC Isilon
#
@@ -44,6 +44,7 @@ top=$mntpoint
export MAKEOBJDIRPREFIX=$top/obj
export log=$top/buildworld.`date +%Y%m%dT%H%M`
n=$((`sysctl -n hw.ncpu` + 1))
+[ $n -gt 32 ] && n=32 # Arbitrary cap
cd $src
make -j$n buildworld > $log 2>&1 && s=0 ||s=1
grep '\*\*\*' $log && s=2
diff --git a/tools/test/stress2/testcases/swap/swap.c b/tools/test/stress2/testcases/swap/swap.c
index 75bfe7856aed..c54605a4b0fe 100644
--- a/tools/test/stress2/testcases/swap/swap.c
+++ b/tools/test/stress2/testcases/swap/swap.c
@@ -155,10 +155,8 @@ test(void)
c[i] = 0;
i += page;
}
-#if 0
- if (op->hog != 1)
- usleep(1000);
-#endif
+ if (arc4random() % 100 < 10)
+ usleep(10000);
}
free((void *)c);
diff --git a/tools/test/stress2/tools/bench.c b/tools/test/stress2/tools/bench.c
index 606c8e6ed726..71918b7b0684 100644
--- a/tools/test/stress2/tools/bench.c
+++ b/tools/test/stress2/tools/bench.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2018 Dell EMC Isilon
*
diff --git a/tools/test/stress2/tools/fail.sh b/tools/test/stress2/tools/fail.sh
index 6d83d8fe0d22..a7b9c769892a 100755
--- a/tools/test/stress2/tools/fail.sh
+++ b/tools/test/stress2/tools/fail.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/tools/fast.sh b/tools/test/stress2/tools/fast.sh
index ce33eaa4c103..83809c8baf55 100755
--- a/tools/test/stress2/tools/fast.sh
+++ b/tools/test/stress2/tools/fast.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/tools/flip.c b/tools/test/stress2/tools/flip.c
index 8d01e9d78ea1..f2a4d86e115b 100644
--- a/tools/test/stress2/tools/flip.c
+++ b/tools/test/stress2/tools/flip.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
* All rights reserved.
@@ -57,7 +57,7 @@ flip(void *ap, size_t len)
unsigned char bit, buf, mask, old __unused;
cp = (unsigned char *)ap;
- byte = random_long(0, len);
+ byte = random_long(0, len - 1);
bit = random_long(0,7);
mask = ~(1 << bit);
buf = cp[byte];
@@ -70,14 +70,22 @@ flip(void *ap, size_t len)
#endif
}
+static void
+trash(char *c)
+{
+ if (arc4random() % 2 == 1)
+ *c = 0;
+ else
+ arc4random_buf(c, sizeof(c));
+}
+
int
main(int argc, char *argv[])
{
struct stat st;
off_t pos;
size_t size;
- int fd, i, times;
- char c;
+ int c, fd, i, times;
times = 1;
size = 0;
@@ -111,19 +119,26 @@ main(int argc, char *argv[])
if (size == 0) {
if (fstat(fd, &st) == -1)
err(1, "stat %s", argv[0]);
+ if ((st.st_mode & S_IFREG) == 0)
+ errx(1, "%s must be a regular file\n", argv[0]);
size = st.st_size;
}
for (i = 0; i < times; i++) {
+ char ch;
+
pos = arc4random() % size;
if (lseek(fd, pos, SEEK_SET) == -1)
err(1, "lseek()");
- if (read(fd, &c, 1) != 1)
+ if (read(fd, &ch, 1) != 1)
err(1, "read()");
- flip(&c, 1);
+ if (arc4random() % 100 < 98)
+ flip(&ch, 1);
+ else
+ trash(&ch);
if (lseek(fd, pos, SEEK_SET) == -1)
err(1, "lseek()");
- if (write(fd, &c, 1) != 1)
+ if (write(fd, &ch, 1) != 1)
err(1, "write()");
}
diff --git a/tools/test/stress2/tools/lsholes.c b/tools/test/stress2/tools/lsholes.c
index a583c1315093..736ae92a41c8 100644
--- a/tools/test/stress2/tools/lsholes.c
+++ b/tools/test/stress2/tools/lsholes.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2021 Peter Holm <pho@FreeBSD.org>
*
@@ -40,7 +40,8 @@ main(int argc, char *argv[])
{
struct stat st;
off_t data, hole, pos;
- long mx;
+ long mn;
+ intmax_t siz;
int fd, n;
char *name;
@@ -54,33 +55,47 @@ main(int argc, char *argv[])
err(1, "open(%s)", name);
if (fstat(fd, &st))
err(1, "fstat()");
- if ((mx = fpathconf(fd, _PC_MIN_HOLE_SIZE)) == -1)
+ if ((mn = fpathconf(fd, _PC_MIN_HOLE_SIZE)) == -1)
err(1, "fpathconf()");
- fprintf(stderr, "file \"%s\" size = %jd, _PC_MIN_HOLE_SIZE = %ld\n",
- name, (intmax_t)st.st_size, mx);
+ fprintf(stderr, "Min hole size is %ld, file size is %jd.\n",
+ mn, (intmax_t)st.st_size);
n = 1;
pos = 0;
+
while (pos < st.st_size) {
- if ((hole = lseek(fd, pos, SEEK_HOLE)) == -1)
+ hole = lseek(fd, pos, SEEK_HOLE);
+ if (hole == -1 && errno != ENXIO)
err(1, "lseek(SEEK_HOLE)");
- if ((data = lseek(fd, hole, SEEK_DATA)) == -1) {
- if (errno == ENXIO) {
- if (hole == st.st_size)
- break;
- fprintf(stderr,
- "No data after hole @ %jd\n",
- (intmax_t)hole);
- break;
- }
- err(1, "lseek(SEEK_DATA)");
+ data = lseek(fd, pos, SEEK_DATA);
+ if (data == -1 && errno != ENXIO)
+ err(1, "lseek(SEEK_data)");
+
+ if (hole >= 0 && data >= 0 && hole > data) {
+ siz = hole - data;
+ printf("data #%d @ %ld, size=%jd)\n",
+ n, (intmax_t)data, siz);
+ n++;
+ pos += siz;
+ }
+ if (hole >= 0 && data >= 0 && hole < data) {
+ siz = data - hole;
+ printf("hole #%d @ %ld, size=%jd\n",
+ n, (intmax_t)hole, siz);
+ n++;
+ pos += siz;
+ }
+ if (hole >= 0 && data == -1) {
+ siz = st.st_size - hole;
+ printf("hole #%d @ %ld, size=%jd\n",
+ n, (intmax_t)hole, siz);
+ n++;
+ pos += siz;
}
- pos = data;
- printf("hole #%d @ %jd (0x%jx), size=%jd (0x%jx)\n",
- n, (intmax_t)hole, (intmax_t)hole, (intmax_t)(data - hole),
- (intmax_t)(data - hole));
- n++;
}
+ if (hole == st.st_size) {
+ /* EOF */
+ printf("hole #%d @ %ld, size=%jd\n",
+ n, (intmax_t)hole, 0L);
+ }
close(fd);
- if (hole != st.st_size)
- errx(1, "No implicit hole at EOF");
}
diff --git a/tools/test/stress2/tools/ministat.sh b/tools/test/stress2/tools/ministat.sh
index 552828e97e59..d219122a0c42 100755
--- a/tools/test/stress2/tools/ministat.sh
+++ b/tools/test/stress2/tools/ministat.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/tools/ps.sh b/tools/test/stress2/tools/ps.sh
index 238192db1b0e..c8ed7d66ecac 100755
--- a/tools/test/stress2/tools/ps.sh
+++ b/tools/test/stress2/tools/ps.sh
@@ -1,7 +1,7 @@
#!/bin/sh
#
-# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
#
diff --git a/tools/test/stress2/tools/serial.c b/tools/test/stress2/tools/serial.c
new file mode 100644
index 000000000000..8dcf9c5da3a8
--- /dev/null
+++ b/tools/test/stress2/tools/serial.c
@@ -0,0 +1,44 @@
+/* Fill a file with a sequence of byte values from 0 - 0xff */
+
+#include <sys/param.h>
+#include <sys/mman.h>
+#include <err.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int
+main(int argc, char *argv[])
+{
+ size_t i, size;
+ int fd;
+ char *cp, *file;
+
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s <file> <file length in bytes>\n", argv[0]);
+ exit(1);
+ }
+ file = argv[1];
+ size = atol(argv[2]);
+
+ if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0)
+ err(1, "%s", file);
+
+ if (lseek(fd, size - 1, SEEK_SET) == -1)
+ err(1, "lseek error");
+
+ /* write a dummy byte at the last location */
+ if (write(fd, "\0", 1) != 1)
+ err(1, "write error");
+
+ if ((cp = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED)
+ err(1, "mmap()");
+
+ for (i = 0; i < size; i++)
+ cp[i] = i & 0xff;
+
+ if (munmap(cp, size) == -1)
+ err(1, "munmap");
+ close(fd);
+}
diff --git a/tools/test/stress2/tools/swap.c b/tools/test/stress2/tools/swap.c
index ce272b794ea7..9e07a8c46d1f 100644
--- a/tools/test/stress2/tools/swap.c
+++ b/tools/test/stress2/tools/swap.c
@@ -1,5 +1,5 @@
/*-
- * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ * SPDX-License-Identifier: BSD-2-Clause
*
* Copyright (c) 2020 Peter Holm <pho@FreeBSD.org>
* All rights reserved.
diff --git a/tools/test/stress2/tools/vmstat.sh b/tools/test/stress2/tools/vmstat.sh
index 89ff1e331fc5..f7006669a7c0 100755
--- a/tools/test/stress2/tools/vmstat.sh
+++ b/tools/test/stress2/tools/vmstat.sh
@@ -45,34 +45,28 @@ OIFS=$IFS
while true; do
# Type InUse MemUse
[ -z "$optm" ] && vmstat -m | sed 1d |
- sed 's/\(.* \)\([0-9][0-9]*\) *\(.*\)K .*/\1:\2:\3/' |
- while IFS=: read -r p1 p2 p3; do
- name=`echo $p1 | sed 's/^ *//;s/ *$//'`
- memuse=$p3
+ while read l; do
+ name=`echo $l | sed -E 's/ [0-9]+ .*//; s/^ *//'`
+ memuse=`echo $l | sed -E "s#$name##" | \
+ awk '{print int(($2 + 1023) / 1024)}'`
[ "$memuse" -ne 0 ] && echo "vmstat -m $name,$memuse"
- done
+ done
# ITEM SIZE LIMIT USED
- [ -z "$optz" ] && vmstat -z |
- grep -vE '(rl_entry):' |
- sed "1,2d;/^$/d;s/: /, /" |
- sed -E 's/[^[:print:]\r\t]/ /g' |
+ [ -z "$optz" ] && vmstat -z | sed 1d |
while read l; do
- IFS=','
- set $l
- [ $# -lt 8 ] &&
- { echo "# args must be >= 8, but is $# in $l" 1>&2;
- continue; }
- size=$2
- used=$4
+ name=`echo $l | sed 's/:.*//'`
+ l=`echo $l | sed 's/.*://'`
+ size=`echo $l | awk -F ',' '{print $1}'`
+ used=`echo $l | awk -F ',' '{print $3}'`
[ -z "$used" -o -z "$size" ] &&
{ echo "used/size not set $l" 1>&2; continue; }
echo $used | egrep -q '^ *[0-9]{1,10}$' ||
{ echo "Bad used: $used. l=$l" 1>&2; continue; }
tot=$((((size * used) + 1023) / 1024))
[ $tot -ne 0 ] &&
- echo "vmstat -z $1,$tot"
- done
+ echo "vmstat -z $name,$tot"
+ done
r=`sysctl -n vm.stats.vm.v_wire_count`
[ -n "$r" ] &&
@@ -98,6 +92,7 @@ done | awk $debug -F, '
close(cmd);
printf "%s \"%s\" %'\''dK\r\n", t,
name, size;
+ fflush
n[name] = 0;
}
s[name] = size;