From 8a272653d9fbd9fc37691c9aad6a05089b4ecb4d Mon Sep 17 00:00:00 2001 From: Peter Holm Date: Wed, 3 Mar 2021 13:56:56 +0100 Subject: [PATCH] stress2: Initial import Discussed with: kib --- tools/test/README | 1 + tools/test/stress2/Makefile | 11 + tools/test/stress2/README | 20 + tools/test/stress2/all.cfg | 8 + tools/test/stress2/creat.cfg | 8 + tools/test/stress2/ddb.conf | 6 + tools/test/stress2/default.cfg | 122 ++ tools/test/stress2/df.cfg | 8 + tools/test/stress2/disk.cfg | 8 + tools/test/stress2/doc/README | 3 + tools/test/stress2/doc/linuxforum06.pdf | Bin 0 -> 523790 bytes tools/test/stress2/doc/stress.pdf | Bin 0 -> 39840 bytes tools/test/stress2/include/stress.h | 64 + tools/test/stress2/io.cfg | 9 + tools/test/stress2/jeff.cfg | 8 + tools/test/stress2/lib/Makefile | 9 + tools/test/stress2/lib/main.c | 212 +++ tools/test/stress2/lib/options.c | 268 ++++ tools/test/stress2/lib/random_int.c | 56 + tools/test/stress2/lib/resources.c | 248 ++++ tools/test/stress2/link.cfg | 9 + tools/test/stress2/load.cfg | 18 + tools/test/stress2/lockf.cfg | 9 + tools/test/stress2/marcus.cfg | 24 + tools/test/stress2/misc/1st.sh | 73 + tools/test/stress2/misc/256m.sh | 45 + tools/test/stress2/misc/README | 4 + tools/test/stress2/misc/advlock.sh | 245 ++++ tools/test/stress2/misc/aesni.sh | 38 + tools/test/stress2/misc/all.debug.inc | 95 ++ tools/test/stress2/misc/all.exclude | 111 ++ tools/test/stress2/misc/all.exclude.pae | 11 + tools/test/stress2/misc/all.sh | 255 ++++ tools/test/stress2/misc/altbufferflushes.sh | 98 ++ .../test/stress2/misc/alternativeFlushPath.sh | 131 ++ tools/test/stress2/misc/arp.sh | 57 + tools/test/stress2/misc/aslr.sh | 46 + tools/test/stress2/misc/audit.sh | 58 + tools/test/stress2/misc/audit2.sh | 59 + tools/test/stress2/misc/backingstore.sh | 81 ++ tools/test/stress2/misc/backingstore2.sh | 72 + tools/test/stress2/misc/backingstore3.sh | 73 + tools/test/stress2/misc/badcode.sh | 65 + tools/test/stress2/misc/badcode2.sh | 57 + tools/test/stress2/misc/badcode3.sh | 57 + tools/test/stress2/misc/bench.sh | 300 ++++ tools/test/stress2/misc/beneath.sh | 110 ++ tools/test/stress2/misc/beneath2.sh | 101 ++ tools/test/stress2/misc/beneath3.sh | 92 ++ tools/test/stress2/misc/beneath4.sh | 133 ++ tools/test/stress2/misc/bio.sh | 225 +++ tools/test/stress2/misc/buildkernel.sh | 63 + tools/test/stress2/misc/buildworld.sh | 67 + tools/test/stress2/misc/buildworld2.sh | 57 + tools/test/stress2/misc/buildworld3.sh | 95 ++ tools/test/stress2/misc/buildworld4.sh | 74 + tools/test/stress2/misc/burnin.sh | 210 +++ tools/test/stress2/misc/callout_reset_on.sh | 331 +++++ tools/test/stress2/misc/callout_reset_on2.sh | 303 ++++ tools/test/stress2/misc/chain.sh | 77 + tools/test/stress2/misc/churn.sh | 211 +++ tools/test/stress2/misc/cleanup.sh | 105 ++ tools/test/stress2/misc/cluster.sh | 269 ++++ tools/test/stress2/misc/cmp.sh | 187 +++ tools/test/stress2/misc/collapse.sh | 153 ++ tools/test/stress2/misc/compare.sh | 44 + tools/test/stress2/misc/context.sh | 130 ++ tools/test/stress2/misc/context2.sh | 131 ++ tools/test/stress2/misc/contigmalloc.sh | 255 ++++ tools/test/stress2/misc/contigmalloc2.sh | 223 +++ tools/test/stress2/misc/contigmalloc3.sh | 225 +++ tools/test/stress2/misc/core.sh | 77 + tools/test/stress2/misc/core2.sh | 95 ++ tools/test/stress2/misc/core3.sh | 171 +++ tools/test/stress2/misc/core4.sh | 89 ++ tools/test/stress2/misc/core5.sh | 199 +++ tools/test/stress2/misc/cpuset.sh | 49 + tools/test/stress2/misc/credleak.sh | 162 +++ tools/test/stress2/misc/crossmp.sh | 89 ++ tools/test/stress2/misc/crossmp10.sh | 104 ++ tools/test/stress2/misc/crossmp11.sh | 121 ++ tools/test/stress2/misc/crossmp2.sh | 86 ++ tools/test/stress2/misc/crossmp3.sh | 108 ++ tools/test/stress2/misc/crossmp4.sh | 107 ++ tools/test/stress2/misc/crossmp5.sh | 95 ++ tools/test/stress2/misc/crossmp6.sh | 103 ++ tools/test/stress2/misc/crossmp7.sh | 100 ++ tools/test/stress2/misc/crossmp8.sh | 125 ++ tools/test/stress2/misc/crossmp9.sh | 90 ++ tools/test/stress2/misc/dangling.sh | 87 ++ tools/test/stress2/misc/datagram.sh | 96 ++ tools/test/stress2/misc/datagram2.sh | 104 ++ tools/test/stress2/misc/datagram3.sh | 106 ++ tools/test/stress2/misc/datamove.sh | 230 +++ tools/test/stress2/misc/datamove2.sh | 244 ++++ tools/test/stress2/misc/datamove3.sh | 241 ++++ tools/test/stress2/misc/datamove4.sh | 251 ++++ tools/test/stress2/misc/datamove5.sh | 262 ++++ tools/test/stress2/misc/db.sh | 178 +++ tools/test/stress2/misc/dd.sh | 64 + tools/test/stress2/misc/dev.sh | 137 ++ tools/test/stress2/misc/dev2.sh | 144 ++ tools/test/stress2/misc/dev3.sh | 160 +++ tools/test/stress2/misc/devfd.sh | 130 ++ tools/test/stress2/misc/devfs.sh | 72 + tools/test/stress2/misc/devfs2.sh | 107 ++ tools/test/stress2/misc/devfs3.sh | 45 + tools/test/stress2/misc/devfs4.sh | 35 + tools/test/stress2/misc/devfs5.sh | 68 + tools/test/stress2/misc/dfull.sh | 56 + tools/test/stress2/misc/dtrace.sh | 68 + tools/test/stress2/misc/dtrace_fault.sh | 65 + tools/test/stress2/misc/dumpfs.sh | 73 + tools/test/stress2/misc/dup.sh | 122 ++ tools/test/stress2/misc/dup2.sh | 71 + tools/test/stress2/misc/execi386.sh | 86 ++ tools/test/stress2/misc/execve.sh | 130 ++ tools/test/stress2/misc/exlock.sh | 122 ++ tools/test/stress2/misc/exlock2.sh | 210 +++ tools/test/stress2/misc/ext2fs.sh | 57 + tools/test/stress2/misc/ext2fs2.sh | 55 + tools/test/stress2/misc/ext2fs3.sh | 68 + tools/test/stress2/misc/ext3fs.sh | 61 + tools/test/stress2/misc/ext4fs.sh | 64 + tools/test/stress2/misc/extattr.sh | 95 ++ tools/test/stress2/misc/extattr2.sh | 94 ++ tools/test/stress2/misc/extattr3.sh | 62 + tools/test/stress2/misc/extattr_set_fd.sh | 79 + tools/test/stress2/misc/extattrctl.sh | 73 + tools/test/stress2/misc/f_offset.sh | 160 +++ tools/test/stress2/misc/fcntl.sh | 234 +++ tools/test/stress2/misc/fcntl2.sh | 188 +++ tools/test/stress2/misc/fcntl3.sh | 56 + tools/test/stress2/misc/fdatasync.sh | 197 +++ tools/test/stress2/misc/fdatasync2.sh | 196 +++ tools/test/stress2/misc/fdescfs.sh | 74 + tools/test/stress2/misc/fdgrowtable.sh | 105 ++ tools/test/stress2/misc/fexecve.sh | 94 ++ tools/test/stress2/misc/ffs_blkfree.sh | 76 + tools/test/stress2/misc/ffs_sync.sh | 254 ++++ tools/test/stress2/misc/ffs_syncvnode.sh | 59 + tools/test/stress2/misc/ffs_syncvnode2.sh | 63 + tools/test/stress2/misc/fifo.sh | 87 ++ tools/test/stress2/misc/fifo2.sh | 206 +++ tools/test/stress2/misc/fifo3.sh | 209 +++ tools/test/stress2/misc/fifo4.sh | 80 ++ tools/test/stress2/misc/flock.sh | 191 +++ tools/test/stress2/misc/flock_open_close.sh | 174 +++ tools/test/stress2/misc/force.sh | 70 + tools/test/stress2/misc/force2.sh | 79 + tools/test/stress2/misc/force3.sh | 65 + tools/test/stress2/misc/force4.sh | 91 ++ tools/test/stress2/misc/force5.sh | 74 + tools/test/stress2/misc/force6.sh | 79 + tools/test/stress2/misc/fork.sh | 129 ++ tools/test/stress2/misc/forkbomb.sh | 148 ++ tools/test/stress2/misc/fpclone.sh | 192 +++ tools/test/stress2/misc/fpclone2.sh | 117 ++ tools/test/stress2/misc/fpu.sh | 103 ++ tools/test/stress2/misc/fragments.sh | 275 ++++ tools/test/stress2/misc/freepages.sh | 130 ++ tools/test/stress2/misc/fs.sh | 91 ++ tools/test/stress2/misc/fsck.sh | 149 ++ tools/test/stress2/misc/fsck2.sh | 38 + tools/test/stress2/misc/fsck3.sh | 88 ++ tools/test/stress2/misc/fsck4.sh | 67 + tools/test/stress2/misc/fsck5.sh | 72 + tools/test/stress2/misc/fsck6.sh | 80 ++ tools/test/stress2/misc/fsgs.sh | 135 ++ tools/test/stress2/misc/fstat.sh | 178 +++ tools/test/stress2/misc/fsync.sh | 91 ++ tools/test/stress2/misc/fsync2.sh | 138 ++ tools/test/stress2/misc/ftruncate.sh | 189 +++ tools/test/stress2/misc/ftruncate2.sh | 205 +++ tools/test/stress2/misc/fts.sh | 144 ++ tools/test/stress2/misc/fts2.sh | 285 ++++ tools/test/stress2/misc/fts3.sh | 133 ++ tools/test/stress2/misc/full.sh | 67 + tools/test/stress2/misc/fullpath.sh | 111 ++ tools/test/stress2/misc/fullpath2.sh | 214 +++ tools/test/stress2/misc/fuse.sh | 57 + tools/test/stress2/misc/fuse2.sh | 89 ++ tools/test/stress2/misc/fuse3.sh | 42 + tools/test/stress2/misc/fuzz.sh | 180 +++ tools/test/stress2/misc/gbde.sh | 55 + tools/test/stress2/misc/geli.sh | 68 + tools/test/stress2/misc/geomleak.sh | 52 + tools/test/stress2/misc/geomleak2.sh | 57 + tools/test/stress2/misc/getrandom.sh | 142 ++ tools/test/stress2/misc/getrandom2.sh | 188 +++ tools/test/stress2/misc/gjournal.sh | 76 + tools/test/stress2/misc/gjournal2.sh | 63 + tools/test/stress2/misc/gjournal3.sh | 85 ++ tools/test/stress2/misc/gjournal4.sh | 65 + tools/test/stress2/misc/gnop.sh | 77 + tools/test/stress2/misc/gnop10.sh | 139 ++ tools/test/stress2/misc/gnop2.sh | 80 ++ tools/test/stress2/misc/gnop3.sh | 73 + tools/test/stress2/misc/gnop4.sh | 79 + tools/test/stress2/misc/gnop5.sh | 69 + tools/test/stress2/misc/gnop6.sh | 68 + tools/test/stress2/misc/gnop7.sh | 80 ++ tools/test/stress2/misc/gnop8.sh | 68 + tools/test/stress2/misc/gnop9.sh | 139 ++ tools/test/stress2/misc/gpt.sh | 51 + tools/test/stress2/misc/graid0.sh | 71 + tools/test/stress2/misc/graid1.sh | 80 ++ tools/test/stress2/misc/graid1_10.sh | 96 ++ tools/test/stress2/misc/graid1_2.sh | 131 ++ tools/test/stress2/misc/graid1_3.sh | 93 ++ tools/test/stress2/misc/graid1_4.sh | 97 ++ tools/test/stress2/misc/graid1_5.sh | 116 ++ tools/test/stress2/misc/graid1_6.sh | 106 ++ tools/test/stress2/misc/graid1_7.sh | 127 ++ tools/test/stress2/misc/graid1_8.sh | 102 ++ tools/test/stress2/misc/graid1_9.sh | 114 ++ tools/test/stress2/misc/graid3.sh | 71 + tools/test/stress2/misc/growfs.sh | 63 + tools/test/stress2/misc/holdcnt0.sh | 261 ++++ tools/test/stress2/misc/holdcnt02.sh | 238 +++ tools/test/stress2/misc/holdcnt03.sh | 237 +++ tools/test/stress2/misc/holdcnt04.sh | 248 ++++ tools/test/stress2/misc/holdcnt05.sh | 249 ++++ tools/test/stress2/misc/ifconfig.sh | 60 + tools/test/stress2/misc/ifconfig2.sh | 67 + tools/test/stress2/misc/indir.sh | 201 +++ tools/test/stress2/misc/indir_trunc.sh | 231 +++ tools/test/stress2/misc/inversion.sh | 97 ++ tools/test/stress2/misc/isofs.sh | 60 + tools/test/stress2/misc/isofs2.sh | 58 + tools/test/stress2/misc/isofs3.sh | 66 + tools/test/stress2/misc/jail.sh | 66 + tools/test/stress2/misc/jail2.sh | 76 + tools/test/stress2/misc/jail3.sh | 76 + tools/test/stress2/misc/jail4.sh | 78 + tools/test/stress2/misc/jexec.sh | 67 + tools/test/stress2/misc/jumbo.sh | 221 +++ tools/test/stress2/misc/kern_umtx_inf_loop.sh | 148 ++ tools/test/stress2/misc/kevent.sh | 174 +++ tools/test/stress2/misc/kevent10.sh | 96 ++ tools/test/stress2/misc/kevent11.sh | 178 +++ tools/test/stress2/misc/kevent12.sh | 233 +++ tools/test/stress2/misc/kevent13.sh | 141 ++ tools/test/stress2/misc/kevent14.sh | 77 + tools/test/stress2/misc/kevent15.sh | 161 +++ tools/test/stress2/misc/kevent2.sh | 170 +++ tools/test/stress2/misc/kevent3.sh | 74 + tools/test/stress2/misc/kevent4.sh | 174 +++ tools/test/stress2/misc/kevent5.sh | 183 +++ tools/test/stress2/misc/kevent6.sh | 168 +++ tools/test/stress2/misc/kevent7.sh | 281 ++++ tools/test/stress2/misc/kevent8.sh | 163 +++ tools/test/stress2/misc/kevent9.sh | 206 +++ tools/test/stress2/misc/killpg.sh | 155 ++ tools/test/stress2/misc/kinfo.sh | 162 +++ tools/test/stress2/misc/kinfo2.sh | 186 +++ tools/test/stress2/misc/kinfo3.sh | 197 +++ tools/test/stress2/misc/kpti.sh | 50 + tools/test/stress2/misc/largepage.sh | 152 ++ tools/test/stress2/misc/laundry.sh | 177 +++ tools/test/stress2/misc/ldt.sh | 370 +++++ tools/test/stress2/misc/ldt2.sh | 99 ++ tools/test/stress2/misc/libMicro.sh | 53 + tools/test/stress2/misc/linger.sh | 168 +++ tools/test/stress2/misc/linger2.sh | 172 +++ tools/test/stress2/misc/linger3.sh | 134 ++ tools/test/stress2/misc/linger4.sh | 155 ++ tools/test/stress2/misc/link.sh | 193 +++ tools/test/stress2/misc/link2.sh | 78 + tools/test/stress2/misc/linux.sh | 55 + tools/test/stress2/misc/lockd.sh | 70 + tools/test/stress2/misc/lockf.sh | 73 + tools/test/stress2/misc/lockf2.sh | 43 + tools/test/stress2/misc/lockf3.sh | 163 +++ tools/test/stress2/misc/lockf4.sh | 183 +++ tools/test/stress2/misc/lockf5.sh | 61 + tools/test/stress2/misc/lookup_shared.sh | 38 + tools/test/stress2/misc/lstat.sh | 236 +++ tools/test/stress2/misc/mac.sh | 38 + tools/test/stress2/misc/mac_chkexec.sh | 57 + tools/test/stress2/misc/machipc.sh | 184 +++ tools/test/stress2/misc/machipc2.sh | 292 ++++ tools/test/stress2/misc/marcus.sh | 55 + tools/test/stress2/misc/marcus2.sh | 73 + tools/test/stress2/misc/marcus3.sh | 52 + tools/test/stress2/misc/marcus4.sh | 86 ++ tools/test/stress2/misc/marcus5.sh | 85 ++ tools/test/stress2/misc/marcus6.sh | 83 ++ tools/test/stress2/misc/marcus7.sh | 90 ++ tools/test/stress2/misc/maxmemdom.sh | 52 + tools/test/stress2/misc/maxproc.sh | 167 +++ tools/test/stress2/misc/maxvnodes.sh | 70 + tools/test/stress2/misc/maxvnodes2.sh | 42 + tools/test/stress2/misc/md.sh | 58 + tools/test/stress2/misc/md2.sh | 57 + tools/test/stress2/misc/md3.sh | 56 + tools/test/stress2/misc/md4.sh | 43 + tools/test/stress2/misc/md5.sh | 48 + tools/test/stress2/misc/md6.sh | 44 + tools/test/stress2/misc/md7.sh | 39 + tools/test/stress2/misc/md8.sh | 121 ++ tools/test/stress2/misc/md9.sh | 59 + tools/test/stress2/misc/mdconfig.sh | 39 + tools/test/stress2/misc/mdconfig2.sh | 53 + tools/test/stress2/misc/mdconfig3.sh | 46 + tools/test/stress2/misc/memguard.sh | 65 + tools/test/stress2/misc/memguard2.sh | 68 + tools/test/stress2/misc/memguard3.sh | 63 + tools/test/stress2/misc/memguard4.sh | 61 + tools/test/stress2/misc/midi.sh | 94 ++ tools/test/stress2/misc/midi2.sh | 114 ++ tools/test/stress2/misc/mincore.sh | 157 ++ tools/test/stress2/misc/minherit.sh | 176 +++ tools/test/stress2/misc/mkfifo.sh | 86 ++ tools/test/stress2/misc/mkfifo2c.sh | 89 ++ tools/test/stress2/misc/mkfifo2d.sh | 81 ++ tools/test/stress2/misc/mkfifo3.sh | 139 ++ tools/test/stress2/misc/mkfifo4.sh | 186 +++ tools/test/stress2/misc/mkfifo5.sh | 214 +++ tools/test/stress2/misc/mkfifo6.sh | 183 +++ tools/test/stress2/misc/mkfifo7.sh | 203 +++ tools/test/stress2/misc/mkfifo8.sh | 200 +++ tools/test/stress2/misc/mknod.sh | 163 +++ tools/test/stress2/misc/mlockall.sh | 80 ++ tools/test/stress2/misc/mlockall2.sh | 165 +++ tools/test/stress2/misc/mlockall3.sh | 167 +++ tools/test/stress2/misc/mlockall4.sh | 66 + tools/test/stress2/misc/mlockall5.sh | 162 +++ tools/test/stress2/misc/mlockall6.sh | 203 +++ tools/test/stress2/misc/mlockall7.sh | 262 ++++ tools/test/stress2/misc/mmap.sh | 63 + tools/test/stress2/misc/mmap10.sh | 273 ++++ tools/test/stress2/misc/mmap11.sh | 301 ++++ tools/test/stress2/misc/mmap12.sh | 81 ++ tools/test/stress2/misc/mmap13.sh | 81 ++ tools/test/stress2/misc/mmap14.sh | 252 ++++ tools/test/stress2/misc/mmap15.sh | 223 +++ tools/test/stress2/misc/mmap16.sh | 145 ++ tools/test/stress2/misc/mmap17.sh | 86 ++ tools/test/stress2/misc/mmap18.sh | 308 ++++ tools/test/stress2/misc/mmap19.sh | 241 ++++ tools/test/stress2/misc/mmap2.sh | 177 +++ tools/test/stress2/misc/mmap20.sh | 83 ++ tools/test/stress2/misc/mmap21.sh | 165 +++ tools/test/stress2/misc/mmap22.sh | 130 ++ tools/test/stress2/misc/mmap23.sh | 108 ++ tools/test/stress2/misc/mmap24.sh | 99 ++ tools/test/stress2/misc/mmap25.sh | 120 ++ tools/test/stress2/misc/mmap26.sh | 123 ++ tools/test/stress2/misc/mmap27.sh | 126 ++ tools/test/stress2/misc/mmap28.sh | 131 ++ tools/test/stress2/misc/mmap29.sh | 71 + tools/test/stress2/misc/mmap3.sh | 167 +++ tools/test/stress2/misc/mmap30.sh | 77 + tools/test/stress2/misc/mmap31.sh | 174 +++ tools/test/stress2/misc/mmap32.sh | 202 +++ tools/test/stress2/misc/mmap33.sh | 121 ++ tools/test/stress2/misc/mmap34.sh | 230 +++ tools/test/stress2/misc/mmap35.sh | 112 ++ tools/test/stress2/misc/mmap36.sh | 80 ++ tools/test/stress2/misc/mmap37.sh | 153 ++ tools/test/stress2/misc/mmap38.sh | 42 + tools/test/stress2/misc/mmap39.sh | 131 ++ tools/test/stress2/misc/mmap4.sh | 116 ++ tools/test/stress2/misc/mmap40.sh | 159 ++ tools/test/stress2/misc/mmap5.sh | 129 ++ tools/test/stress2/misc/mmap6.sh | 179 +++ tools/test/stress2/misc/mmap7.sh | 147 ++ tools/test/stress2/misc/mmap8.sh | 89 ++ tools/test/stress2/misc/mmap9.sh | 95 ++ tools/test/stress2/misc/mount.sh | 82 ++ tools/test/stress2/misc/mount2.sh | 73 + tools/test/stress2/misc/mountro.sh | 67 + tools/test/stress2/misc/mountro2.sh | 54 + tools/test/stress2/misc/mountro3.sh | 56 + tools/test/stress2/misc/mountro4.sh | 100 ++ tools/test/stress2/misc/mountro5.sh | 63 + tools/test/stress2/misc/mountro6.sh | 57 + tools/test/stress2/misc/mountu.sh | 284 ++++ tools/test/stress2/misc/mprotect.sh | 75 + tools/test/stress2/misc/mprotect2.sh | 97 ++ tools/test/stress2/misc/msdos.sh | 60 + tools/test/stress2/misc/msdos10.sh | 89 ++ tools/test/stress2/misc/msdos2.sh | 58 + tools/test/stress2/misc/msdos3.sh | 52 + tools/test/stress2/misc/msdos4.sh | 76 + tools/test/stress2/misc/msdos5.sh | 59 + tools/test/stress2/misc/msdos6.sh | 93 ++ tools/test/stress2/misc/msdos7.sh | 57 + tools/test/stress2/misc/msdos8.sh | 157 ++ tools/test/stress2/misc/msdos9.sh | 77 + tools/test/stress2/misc/msetdomain.sh | 144 ++ tools/test/stress2/misc/msync.sh | 201 +++ tools/test/stress2/misc/msync2.sh | 131 ++ tools/test/stress2/misc/multicast.sh | 118 ++ tools/test/stress2/misc/multicast2.sh | 26 + tools/test/stress2/misc/namecache.sh | 214 +++ tools/test/stress2/misc/namecache2.sh | 192 +++ tools/test/stress2/misc/nanosleep.sh | 87 ++ tools/test/stress2/misc/nbufkv.sh | 156 ++ tools/test/stress2/misc/newfs.sh | 94 ++ tools/test/stress2/misc/newfs2.sh | 69 + tools/test/stress2/misc/newfs3.sh | 81 ++ tools/test/stress2/misc/newfs4.sh | 128 ++ tools/test/stress2/misc/newfs5.sh | 116 ++ tools/test/stress2/misc/nfs.sh | 55 + tools/test/stress2/misc/nfs10.sh | 73 + tools/test/stress2/misc/nfs11.sh | 67 + tools/test/stress2/misc/nfs12.sh | 160 +++ tools/test/stress2/misc/nfs13.sh | 66 + tools/test/stress2/misc/nfs14.sh | 74 + tools/test/stress2/misc/nfs15.sh | 212 +++ tools/test/stress2/misc/nfs15lockd.sh | 240 ++++ tools/test/stress2/misc/nfs15lockd2.sh | 41 + tools/test/stress2/misc/nfs15lockd3.sh | 250 ++++ tools/test/stress2/misc/nfs16.sh | 196 +++ tools/test/stress2/misc/nfs17.sh | 76 + tools/test/stress2/misc/nfs2.sh | 69 + tools/test/stress2/misc/nfs3.sh | 60 + tools/test/stress2/misc/nfs4.sh | 70 + tools/test/stress2/misc/nfs5.sh | 68 + tools/test/stress2/misc/nfs6.sh | 81 ++ tools/test/stress2/misc/nfs7.sh | 68 + tools/test/stress2/misc/nfs8.sh | 66 + tools/test/stress2/misc/nfs9.sh | 88 ++ tools/test/stress2/misc/nfs_halfpage.sh | 99 ++ tools/test/stress2/misc/nfs_halfpage2.sh | 103 ++ tools/test/stress2/misc/nfsdelegation.sh | 169 +++ tools/test/stress2/misc/nfsdepth.sh | 239 ++++ tools/test/stress2/misc/nfsrename.sh | 224 +++ tools/test/stress2/misc/nfssillyrename.sh | 67 + tools/test/stress2/misc/nullfs.sh | 72 + tools/test/stress2/misc/nullfs10.sh | 71 + tools/test/stress2/misc/nullfs11.sh | 89 ++ tools/test/stress2/misc/nullfs12.sh | 64 + tools/test/stress2/misc/nullfs13.sh | 77 + tools/test/stress2/misc/nullfs14.sh | 58 + tools/test/stress2/misc/nullfs15.sh | 64 + tools/test/stress2/misc/nullfs16.sh | 61 + tools/test/stress2/misc/nullfs17.sh | 84 ++ tools/test/stress2/misc/nullfs18.sh | 133 ++ tools/test/stress2/misc/nullfs19.sh | 90 ++ tools/test/stress2/misc/nullfs2.sh | 54 + tools/test/stress2/misc/nullfs20.sh | 74 + tools/test/stress2/misc/nullfs21.sh | 71 + tools/test/stress2/misc/nullfs22.sh | 247 ++++ tools/test/stress2/misc/nullfs23.sh | 50 + tools/test/stress2/misc/nullfs24.sh | 69 + tools/test/stress2/misc/nullfs25.sh | 90 ++ tools/test/stress2/misc/nullfs26.sh | 47 + tools/test/stress2/misc/nullfs27.sh | 91 ++ tools/test/stress2/misc/nullfs3.sh | 56 + tools/test/stress2/misc/nullfs4.sh | 50 + tools/test/stress2/misc/nullfs5.sh | 79 + tools/test/stress2/misc/nullfs6.sh | 50 + tools/test/stress2/misc/nullfs7.sh | 63 + tools/test/stress2/misc/nullfs8.sh | 67 + tools/test/stress2/misc/nullfs9.sh | 82 ++ tools/test/stress2/misc/numa.sh | 46 + tools/test/stress2/misc/oom.sh | 47 + tools/test/stress2/misc/oom2.sh | 49 + tools/test/stress2/misc/oovm.sh | 134 ++ tools/test/stress2/misc/oovm2.sh | 136 ++ tools/test/stress2/misc/open.sh | 84 ++ tools/test/stress2/misc/openlock.sh | 94 ++ tools/test/stress2/misc/overcommit.sh | 62 + tools/test/stress2/misc/overcommit2.sh | 65 + tools/test/stress2/misc/overflow3.sh | 96 ++ tools/test/stress2/misc/overlap.sh | 160 +++ tools/test/stress2/misc/pageout.sh | 144 ++ tools/test/stress2/misc/parallelmount.sh | 68 + tools/test/stress2/misc/parallelmount2.sh | 84 ++ tools/test/stress2/misc/pathconf.sh | 56 + tools/test/stress2/misc/pathconf2.sh | 37 + tools/test/stress2/misc/pause.sh | 159 ++ tools/test/stress2/misc/pcatch.sh | 154 ++ tools/test/stress2/misc/pcatch2.sh | 44 + tools/test/stress2/misc/pdfork.sh | 58 + tools/test/stress2/misc/perf.sh | 151 ++ tools/test/stress2/misc/pfl.sh | 188 +++ tools/test/stress2/misc/pfl2.sh | 104 ++ tools/test/stress2/misc/pfl3.sh | 47 + tools/test/stress2/misc/pfl4.sh | 95 ++ tools/test/stress2/misc/ping.sh | 53 + tools/test/stress2/misc/pipe.sh | 132 ++ tools/test/stress2/misc/pipe2.sh | 163 +++ tools/test/stress2/misc/pipe3.sh | 148 ++ tools/test/stress2/misc/pipe_enomem.sh | 102 ++ tools/test/stress2/misc/pkru.sh | 512 +++++++ tools/test/stress2/misc/pkru2.sh | 108 ++ tools/test/stress2/misc/pmc.sh | 55 + tools/test/stress2/misc/pmc2.sh | 51 + tools/test/stress2/misc/pmc3.sh | 44 + tools/test/stress2/misc/pmc4.sh | 124 ++ tools/test/stress2/misc/pmc5.sh | 138 ++ tools/test/stress2/misc/pmc6.sh | 41 + tools/test/stress2/misc/pmc7.sh | 12 + tools/test/stress2/misc/poll.sh | 57 + tools/test/stress2/misc/poll2.sh | 212 +++ tools/test/stress2/misc/posix_fadvise.sh | 72 + tools/test/stress2/misc/posix_fadvise2.sh | 78 + tools/test/stress2/misc/posix_fadvise3.sh | 120 ++ tools/test/stress2/misc/posix_openpt.sh | 79 + tools/test/stress2/misc/posix_openpt2.sh | 152 ++ tools/test/stress2/misc/pread.sh | 190 +++ tools/test/stress2/misc/proccontrol.sh | 54 + tools/test/stress2/misc/procfs.sh | 69 + tools/test/stress2/misc/procfs2.sh | 37 + tools/test/stress2/misc/procfs3.sh | 154 ++ tools/test/stress2/misc/procfs4.sh | 156 ++ tools/test/stress2/misc/procfs5.sh | 84 ++ tools/test/stress2/misc/procfs6.sh | 42 + tools/test/stress2/misc/procstat.sh | 44 + tools/test/stress2/misc/procstat2.sh | 44 + tools/test/stress2/misc/pthread.sh | 137 ++ tools/test/stress2/misc/pthread2.sh | 296 ++++ tools/test/stress2/misc/pthread3.sh | 304 ++++ tools/test/stress2/misc/pthread4.sh | 296 ++++ tools/test/stress2/misc/pthread5.sh | 121 ++ tools/test/stress2/misc/pthread6.sh | 308 ++++ tools/test/stress2/misc/pthread7.sh | 285 ++++ tools/test/stress2/misc/pthread8.sh | 137 ++ tools/test/stress2/misc/pthread9.sh | 185 +++ tools/test/stress2/misc/ptrace.sh | 106 ++ tools/test/stress2/misc/ptrace10.sh | 161 +++ tools/test/stress2/misc/ptrace11.sh | 124 ++ tools/test/stress2/misc/ptrace2.sh | 143 ++ tools/test/stress2/misc/ptrace3.sh | 130 ++ tools/test/stress2/misc/ptrace4.sh | 58 + tools/test/stress2/misc/ptrace5.sh | 200 +++ tools/test/stress2/misc/ptrace6.sh | 204 +++ tools/test/stress2/misc/ptrace7.sh | 238 +++ tools/test/stress2/misc/ptrace8.sh | 122 ++ tools/test/stress2/misc/ptrace9.sh | 133 ++ tools/test/stress2/misc/pts.sh | 154 ++ tools/test/stress2/misc/pts2.sh | 79 + tools/test/stress2/misc/pts3.sh | 102 ++ tools/test/stress2/misc/pty.sh | 161 +++ tools/test/stress2/misc/pty2.sh | 101 ++ tools/test/stress2/misc/quota1.sh | 57 + tools/test/stress2/misc/quota10.sh | 105 ++ tools/test/stress2/misc/quota11.sh | 67 + tools/test/stress2/misc/quota12.sh | 80 ++ tools/test/stress2/misc/quota2.sh | 57 + tools/test/stress2/misc/quota3.sh | 57 + tools/test/stress2/misc/quota4.sh | 65 + tools/test/stress2/misc/quota5.sh | 44 + tools/test/stress2/misc/quota6.sh | 69 + tools/test/stress2/misc/quota7.sh | 79 + tools/test/stress2/misc/quota8.sh | 89 ++ tools/test/stress2/misc/quota9.sh | 93 ++ tools/test/stress2/misc/r335171.sh | 158 ++ tools/test/stress2/misc/racct.sh | 57 + tools/test/stress2/misc/radix.sh | 271 ++++ tools/test/stress2/misc/random.sh | 37 + tools/test/stress2/misc/rdgsbase.sh | 182 +++ tools/test/stress2/misc/rdwr.sh | 118 ++ tools/test/stress2/misc/readdir.sh | 179 +++ tools/test/stress2/misc/recursiveflushes.sh | 75 + tools/test/stress2/misc/rename.sh | 130 ++ tools/test/stress2/misc/rename10.sh | 184 +++ tools/test/stress2/misc/rename11.sh | 139 ++ tools/test/stress2/misc/rename12.sh | 192 +++ tools/test/stress2/misc/rename13.sh | 60 + tools/test/stress2/misc/rename14.sh | 198 +++ tools/test/stress2/misc/rename15.sh | 82 ++ tools/test/stress2/misc/rename2.sh | 103 ++ tools/test/stress2/misc/rename3.sh | 51 + tools/test/stress2/misc/rename4.sh | 62 + tools/test/stress2/misc/rename5.sh | 137 ++ tools/test/stress2/misc/rename6.sh | 149 ++ tools/test/stress2/misc/rename7.sh | 150 ++ tools/test/stress2/misc/rename8.sh | 173 +++ tools/test/stress2/misc/rename9.sh | 169 +++ tools/test/stress2/misc/revoke.sh | 116 ++ tools/test/stress2/misc/rot.sh | 142 ++ tools/test/stress2/misc/routetbl.sh | 61 + tools/test/stress2/misc/ruby.sh | 38 + tools/test/stress2/misc/rw.sh | 65 + tools/test/stress2/misc/rwlock_ronly.sh | 82 ++ tools/test/stress2/misc/sched.sh | 161 +++ tools/test/stress2/misc/schedfuzz.sh | 79 + tools/test/stress2/misc/sctp.sh | 158 ++ tools/test/stress2/misc/sctp2.sh | 169 +++ tools/test/stress2/misc/sctp3.sh | 172 +++ tools/test/stress2/misc/seekdir.sh | 157 ++ tools/test/stress2/misc/segnp.sh | 57 + tools/test/stress2/misc/segregs.sh | 144 ++ tools/test/stress2/misc/select.sh | 168 +++ tools/test/stress2/misc/select3.sh | 39 + tools/test/stress2/misc/selfd.sh | 152 ++ tools/test/stress2/misc/sem.sh | 142 ++ tools/test/stress2/misc/sem_post.sh | 107 ++ tools/test/stress2/misc/sem_timedwait.sh | 161 +++ tools/test/stress2/misc/sem_wait.sh | 109 ++ tools/test/stress2/misc/sendfile.sh | 213 +++ tools/test/stress2/misc/sendfile10.sh | 313 ++++ tools/test/stress2/misc/sendfile11.sh | 235 +++ tools/test/stress2/misc/sendfile12.sh | 241 ++++ tools/test/stress2/misc/sendfile13.sh | 371 +++++ tools/test/stress2/misc/sendfile14.sh | 382 +++++ tools/test/stress2/misc/sendfile15.sh | 218 +++ tools/test/stress2/misc/sendfile16.sh | 224 +++ tools/test/stress2/misc/sendfile17.sh | 225 +++ tools/test/stress2/misc/sendfile18.sh | 125 ++ tools/test/stress2/misc/sendfile19.sh | 246 ++++ tools/test/stress2/misc/sendfile2.sh | 142 ++ tools/test/stress2/misc/sendfile20.sh | 247 ++++ tools/test/stress2/misc/sendfile21.sh | 243 ++++ tools/test/stress2/misc/sendfile22.sh | 282 ++++ tools/test/stress2/misc/sendfile23.sh | 207 +++ tools/test/stress2/misc/sendfile24.sh | 235 +++ tools/test/stress2/misc/sendfile25.sh | 237 +++ tools/test/stress2/misc/sendfile26.sh | 308 ++++ tools/test/stress2/misc/sendfile3.sh | 210 +++ tools/test/stress2/misc/sendfile4.sh | 141 ++ tools/test/stress2/misc/sendfile5.sh | 165 +++ tools/test/stress2/misc/sendfile6.sh | 255 ++++ tools/test/stress2/misc/sendfile7.sh | 42 + tools/test/stress2/misc/sendfile8.sh | 267 ++++ tools/test/stress2/misc/sendfile9.sh | 266 ++++ tools/test/stress2/misc/sendfile_shm.sh | 200 +++ tools/test/stress2/misc/sendmsg.sh | 224 +++ tools/test/stress2/misc/sendmsg2.sh | 142 ++ tools/test/stress2/misc/sethostname.sh | 36 + tools/test/stress2/misc/setsockopt.sh | 152 ++ tools/test/stress2/misc/setsockopt2.sh | 208 +++ tools/test/stress2/misc/setuid.sh | 122 ++ tools/test/stress2/misc/shm.sh | 201 +++ tools/test/stress2/misc/shm2.sh | 167 +++ tools/test/stress2/misc/shm_open.sh | 85 ++ tools/test/stress2/misc/shm_super.sh | 87 ++ tools/test/stress2/misc/sigaltstack.sh | 128 ++ tools/test/stress2/misc/sigfastblock.sh | 141 ++ tools/test/stress2/misc/sigfastblock2.sh | 132 ++ tools/test/stress2/misc/signal.sh | 247 ++++ tools/test/stress2/misc/signal0.sh | 102 ++ tools/test/stress2/misc/sigreturn.sh | 121 ++ tools/test/stress2/misc/sigstop.sh | 98 ++ tools/test/stress2/misc/sigstop2.sh | 144 ++ tools/test/stress2/misc/sigxcpu.sh | 155 ++ tools/test/stress2/misc/smrstress.sh | 56 + tools/test/stress2/misc/smrstress2.sh | 80 ++ tools/test/stress2/misc/snap.sh | 55 + tools/test/stress2/misc/snap10.sh | 68 + tools/test/stress2/misc/snap11.sh | 87 ++ tools/test/stress2/misc/snap12.sh | 72 + tools/test/stress2/misc/snap2-1.sh | 60 + tools/test/stress2/misc/snap2.sh | 60 + tools/test/stress2/misc/snap3.sh | 64 + tools/test/stress2/misc/snap4.sh | 57 + tools/test/stress2/misc/snap5-1.sh | 61 + tools/test/stress2/misc/snap5.sh | 55 + tools/test/stress2/misc/snap6.sh | 48 + tools/test/stress2/misc/snap7.sh | 59 + tools/test/stress2/misc/snap8.sh | 92 ++ tools/test/stress2/misc/snap9.sh | 62 + tools/test/stress2/misc/sndstat.sh | 138 ++ tools/test/stress2/misc/socketpair.sh | 104 ++ tools/test/stress2/misc/socketpair2.sh | 273 ++++ tools/test/stress2/misc/socketpair3.sh | 144 ++ tools/test/stress2/misc/socketpair4.sh | 207 +++ tools/test/stress2/misc/softupdate.sh | 58 + tools/test/stress2/misc/sort.sh | 50 + tools/test/stress2/misc/sort2.sh | 52 + tools/test/stress2/misc/sparse.sh | 74 + tools/test/stress2/misc/spin.sh | 124 ++ tools/test/stress2/misc/split.sh | 99 ++ tools/test/stress2/misc/stack_guard_page.sh | 50 + tools/test/stress2/misc/statfs.sh | 126 ++ tools/test/stress2/misc/stealer.sh | 133 ++ tools/test/stress2/misc/su.sh | 54 + tools/test/stress2/misc/suj.sh | 52 + tools/test/stress2/misc/suj10.sh | 180 +++ tools/test/stress2/misc/suj11.sh | 58 + tools/test/stress2/misc/suj12.sh | 60 + tools/test/stress2/misc/suj13.sh | 60 + tools/test/stress2/misc/suj14.sh | 56 + tools/test/stress2/misc/suj15.sh | 66 + tools/test/stress2/misc/suj16.sh | 82 ++ tools/test/stress2/misc/suj17.sh | 136 ++ tools/test/stress2/misc/suj18.sh | 68 + tools/test/stress2/misc/suj19.sh | 77 + tools/test/stress2/misc/suj2.sh | 78 + tools/test/stress2/misc/suj20.sh | 177 +++ tools/test/stress2/misc/suj21.sh | 178 +++ tools/test/stress2/misc/suj22.sh | 195 +++ tools/test/stress2/misc/suj23.sh | 440 ++++++ tools/test/stress2/misc/suj24.sh | 52 + tools/test/stress2/misc/suj25.sh | 67 + tools/test/stress2/misc/suj26.sh | 85 ++ tools/test/stress2/misc/suj27.sh | 84 ++ tools/test/stress2/misc/suj28.sh | 87 ++ tools/test/stress2/misc/suj29.sh | 74 + tools/test/stress2/misc/suj3.sh | 64 + tools/test/stress2/misc/suj30.sh | 278 ++++ tools/test/stress2/misc/suj31.sh | 65 + tools/test/stress2/misc/suj32.sh | 92 ++ tools/test/stress2/misc/suj33.sh | 66 + tools/test/stress2/misc/suj34.sh | 61 + tools/test/stress2/misc/suj35.sh | 61 + tools/test/stress2/misc/suj4.sh | 56 + tools/test/stress2/misc/suj5.sh | 180 +++ tools/test/stress2/misc/suj6.sh | 183 +++ tools/test/stress2/misc/suj7.sh | 60 + tools/test/stress2/misc/suj8.sh | 61 + tools/test/stress2/misc/suj9.sh | 64 + tools/test/stress2/misc/swap.sh | 157 ++ tools/test/stress2/misc/swap2.sh | 176 +++ tools/test/stress2/misc/swap3.sh | 38 + tools/test/stress2/misc/swap4.sh | 152 ++ tools/test/stress2/misc/swap5.sh | 50 + tools/test/stress2/misc/swap6.sh | 52 + tools/test/stress2/misc/swapoff.sh | 69 + tools/test/stress2/misc/swapoff2.sh | 76 + tools/test/stress2/misc/swapoff3.sh | 144 ++ tools/test/stress2/misc/swapoff4.sh | 82 ++ tools/test/stress2/misc/swapoff5.sh | 182 +++ tools/test/stress2/misc/swappedout.sh | 52 + tools/test/stress2/misc/symlink.sh | 128 ++ tools/test/stress2/misc/symlink2.sh | 121 ++ tools/test/stress2/misc/symlink3.sh | 69 + tools/test/stress2/misc/symlink4.sh | 125 ++ tools/test/stress2/misc/symlink5.sh | 137 ++ tools/test/stress2/misc/syscall4.sh | 386 +++++ tools/test/stress2/misc/syscall5.sh | 99 ++ tools/test/stress2/misc/syscall6.sh | 46 + tools/test/stress2/misc/sysctl.sh | 44 + tools/test/stress2/misc/sysctl2.sh | 43 + tools/test/stress2/misc/sysctl3.sh | 56 + tools/test/stress2/misc/sysctl4.sh | 54 + tools/test/stress2/misc/systrace.sh | 62 + tools/test/stress2/misc/systrace2.sh | 48 + tools/test/stress2/misc/syzkaller1.sh | 246 ++++ tools/test/stress2/misc/syzkaller10.sh | 93 ++ tools/test/stress2/misc/syzkaller11.sh | 299 ++++ tools/test/stress2/misc/syzkaller12.sh | 176 +++ tools/test/stress2/misc/syzkaller13.sh | 249 ++++ tools/test/stress2/misc/syzkaller14.sh | 295 ++++ tools/test/stress2/misc/syzkaller15.sh | 190 +++ tools/test/stress2/misc/syzkaller16.sh | 417 ++++++ tools/test/stress2/misc/syzkaller17.sh | 131 ++ tools/test/stress2/misc/syzkaller18.sh | 128 ++ tools/test/stress2/misc/syzkaller19.sh | 171 +++ tools/test/stress2/misc/syzkaller2.sh | 89 ++ tools/test/stress2/misc/syzkaller20.sh | 108 ++ tools/test/stress2/misc/syzkaller21.sh | 403 ++++++ tools/test/stress2/misc/syzkaller22.sh | 69 + tools/test/stress2/misc/syzkaller23.sh | 400 ++++++ tools/test/stress2/misc/syzkaller24.sh | 133 ++ tools/test/stress2/misc/syzkaller25.sh | 476 ++++++ tools/test/stress2/misc/syzkaller26.sh | 166 +++ tools/test/stress2/misc/syzkaller27.sh | 150 ++ tools/test/stress2/misc/syzkaller28.sh | 356 +++++ tools/test/stress2/misc/syzkaller29.sh | 128 ++ tools/test/stress2/misc/syzkaller3.sh | 49 + tools/test/stress2/misc/syzkaller30.sh | 67 + tools/test/stress2/misc/syzkaller4.sh | 382 +++++ tools/test/stress2/misc/syzkaller5.sh | 83 ++ tools/test/stress2/misc/syzkaller6.sh | 84 ++ tools/test/stress2/misc/syzkaller7.sh | 161 +++ tools/test/stress2/misc/syzkaller8.sh | 111 ++ tools/test/stress2/misc/syzkaller9.sh | 102 ++ tools/test/stress2/misc/tar.sh | 132 ++ tools/test/stress2/misc/tcp.sh | 59 + tools/test/stress2/misc/tcp2.sh | 62 + tools/test/stress2/misc/tcp3.sh | 288 ++++ tools/test/stress2/misc/tcp4.sh | 249 ++++ tools/test/stress2/misc/temp.sh | 167 +++ tools/test/stress2/misc/thr.sh | 99 ++ tools/test/stress2/misc/thr2.sh | 42 + tools/test/stress2/misc/thr3.sh | 104 ++ tools/test/stress2/misc/timeout.sh | 51 + tools/test/stress2/misc/tmpfs.sh | 48 + tools/test/stress2/misc/tmpfs10.sh | 155 ++ tools/test/stress2/misc/tmpfs11.sh | 81 ++ tools/test/stress2/misc/tmpfs12.sh | 95 ++ tools/test/stress2/misc/tmpfs13.sh | 95 ++ tools/test/stress2/misc/tmpfs14.sh | 112 ++ tools/test/stress2/misc/tmpfs15.sh | 48 + tools/test/stress2/misc/tmpfs16.sh | 200 +++ tools/test/stress2/misc/tmpfs17.sh | 144 ++ tools/test/stress2/misc/tmpfs18.sh | 58 + tools/test/stress2/misc/tmpfs19.sh | 56 + tools/test/stress2/misc/tmpfs2.sh | 64 + tools/test/stress2/misc/tmpfs20.sh | 60 + tools/test/stress2/misc/tmpfs21.sh | 59 + tools/test/stress2/misc/tmpfs22.sh | 117 ++ tools/test/stress2/misc/tmpfs23.sh | 52 + tools/test/stress2/misc/tmpfs3.sh | 45 + tools/test/stress2/misc/tmpfs4.sh | 46 + tools/test/stress2/misc/tmpfs5.sh | 53 + tools/test/stress2/misc/tmpfs6.sh | 110 ++ tools/test/stress2/misc/tmpfs7.sh | 249 ++++ tools/test/stress2/misc/tmpfs8.sh | 178 +++ tools/test/stress2/misc/tmpfs9.sh | 110 ++ tools/test/stress2/misc/trim.sh | 72 + tools/test/stress2/misc/trim2.sh | 59 + tools/test/stress2/misc/trim3.sh | 71 + tools/test/stress2/misc/trim4.sh | 68 + tools/test/stress2/misc/trim5.sh | 49 + tools/test/stress2/misc/trim6.sh | 57 + tools/test/stress2/misc/trim7.sh | 62 + tools/test/stress2/misc/trim8.sh | 62 + tools/test/stress2/misc/truncate.sh | 99 ++ tools/test/stress2/misc/truncate2.sh | 99 ++ tools/test/stress2/misc/truncate3.sh | 119 ++ tools/test/stress2/misc/truncate4.sh | 54 + tools/test/stress2/misc/truncate5.sh | 105 ++ tools/test/stress2/misc/truncate6.sh | 122 ++ tools/test/stress2/misc/truncate7.sh | 124 ++ tools/test/stress2/misc/truncate8.sh | 212 +++ tools/test/stress2/misc/truncate9.sh | 119 ++ tools/test/stress2/misc/truss.sh | 129 ++ tools/test/stress2/misc/truss3.sh | 36 + tools/test/stress2/misc/tvnlru.sh | 251 ++++ tools/test/stress2/misc/udp.sh | 48 + tools/test/stress2/misc/udp2.sh | 57 + tools/test/stress2/misc/ufsbench.sh | 58 + tools/test/stress2/misc/ufssuspend.sh | 131 ++ tools/test/stress2/misc/uma_zalloc_arg.sh | 302 ++++ tools/test/stress2/misc/umount.sh | 50 + tools/test/stress2/misc/umount2.sh | 90 ++ tools/test/stress2/misc/umount3.sh | 66 + tools/test/stress2/misc/umount4.sh | 71 + tools/test/stress2/misc/umountf.sh | 69 + tools/test/stress2/misc/umountf10.sh | 133 ++ tools/test/stress2/misc/umountf11.sh | 50 + tools/test/stress2/misc/umountf12.sh | 68 + tools/test/stress2/misc/umountf2.sh | 1273 +++++++++++++++++ tools/test/stress2/misc/umountf3.sh | 118 ++ tools/test/stress2/misc/umountf4.sh | 85 ++ tools/test/stress2/misc/umountf5.sh | 69 + tools/test/stress2/misc/umountf6.sh | 85 ++ tools/test/stress2/misc/umountf7.sh | 168 +++ tools/test/stress2/misc/umountf8.sh | 42 + tools/test/stress2/misc/umountf9.sh | 45 + tools/test/stress2/misc/umtx_suspend.sh | 88 ++ tools/test/stress2/misc/union.sh | 65 + tools/test/stress2/misc/unionfs.sh | 52 + tools/test/stress2/misc/unionfs2.sh | 46 + tools/test/stress2/misc/unionfs3.sh | 52 + tools/test/stress2/misc/unix_socket.sh | 161 +++ tools/test/stress2/misc/unix_socket_detach.sh | 124 ++ .../test/stress2/misc/unix_socket_detach2.sh | 157 ++ tools/test/stress2/misc/unlink.sh | 69 + tools/test/stress2/misc/vfork.sh | 131 ++ tools/test/stress2/misc/vm_fault_dontneed.sh | 99 ++ tools/test/stress2/misc/vm_map.sh | 117 ++ tools/test/stress2/misc/vm_reserv_populate.sh | 278 ++++ tools/test/stress2/misc/vmio.sh | 56 + tools/test/stress2/misc/vmstat.sh | 47 + tools/test/stress2/misc/vmstat2.sh | 41 + tools/test/stress2/misc/vmtotal.sh | 42 + tools/test/stress2/misc/vnodes.sh | 87 ++ tools/test/stress2/misc/vunref.sh | 212 +++ tools/test/stress2/misc/vunref2.sh | 72 + tools/test/stress2/misc/watchman.sh | 43 + tools/test/stress2/misc/wire_no_page.sh | 104 ++ tools/test/stress2/misc/write.sh | 231 +++ tools/test/stress2/misc/zfs.sh | 68 + tools/test/stress2/misc/zfs10.sh | 142 ++ tools/test/stress2/misc/zfs11.sh | 77 + tools/test/stress2/misc/zfs2.sh | 71 + tools/test/stress2/misc/zfs3.sh | 83 ++ tools/test/stress2/misc/zfs4.sh | 91 ++ tools/test/stress2/misc/zfs5.sh | 71 + tools/test/stress2/misc/zfs6.sh | 80 ++ tools/test/stress2/misc/zfs7.sh | 72 + tools/test/stress2/misc/zfs8.sh | 73 + tools/test/stress2/misc/zfs9.sh | 73 + tools/test/stress2/misc/zz-combo01.sh | 44 + tools/test/stress2/misc/zz-combo02.sh | 34 + tools/test/stress2/misc/zz-combo03.sh | 39 + tools/test/stress2/misc/zz-combo04.sh | 37 + tools/test/stress2/misc/zzbuildworld.sh | 54 + tools/test/stress2/mkdir.cfg | 9 + tools/test/stress2/mkfifo.cfg | 8 + tools/test/stress2/norw.cfg | 6 + tools/test/stress2/noswap.cfg | 6 + tools/test/stress2/pty.cfg | 8 + tools/test/stress2/run.sh | 84 ++ tools/test/stress2/rw.cfg | 8 + tools/test/stress2/syscall.cfg | 11 + tools/test/stress2/sysctl.cfg | 12 + tools/test/stress2/testcases/Makefile | 28 + tools/test/stress2/testcases/Makefile.inc | 6 + tools/test/stress2/testcases/README | 9 + tools/test/stress2/testcases/badcode/Makefile | 3 + .../test/stress2/testcases/badcode/badcode.c | 133 ++ tools/test/stress2/testcases/creat/Makefile | 3 + tools/test/stress2/testcases/creat/creat.c | 136 ++ .../stress2/testcases/dirnprename/Makefile | 3 + .../testcases/dirnprename/dirnprename.c | 172 +++ .../test/stress2/testcases/dirrename/Makefile | 3 + .../stress2/testcases/dirrename/dirrename.c | 144 ++ tools/test/stress2/testcases/fts/Makefile | 3 + tools/test/stress2/testcases/fts/fts.c | 102 ++ tools/test/stress2/testcases/link/Makefile | 3 + tools/test/stress2/testcases/link/link.c | 144 ++ tools/test/stress2/testcases/lockf/Makefile | 3 + tools/test/stress2/testcases/lockf/lockf.c | 184 +++ tools/test/stress2/testcases/lockf2/Makefile | 3 + tools/test/stress2/testcases/lockf2/lockf2.c | 130 ++ tools/test/stress2/testcases/mkdir/Makefile | 3 + tools/test/stress2/testcases/mkdir/mkdir.c | 135 ++ tools/test/stress2/testcases/mkfifo/Makefile | 4 + tools/test/stress2/testcases/mkfifo/mkfifo.c | 183 +++ tools/test/stress2/testcases/mmap/Makefile | 3 + tools/test/stress2/testcases/mmap/mmap.c | 148 ++ tools/test/stress2/testcases/openat/Makefile | 3 + tools/test/stress2/testcases/openat/doat.c | 688 +++++++++ tools/test/stress2/testcases/openat/openat.c | 187 +++ tools/test/stress2/testcases/pty/Makefile | 4 + tools/test/stress2/testcases/pty/pty.c | 111 ++ tools/test/stress2/testcases/rename/Makefile | 3 + tools/test/stress2/testcases/rename/rename.c | 134 ++ tools/test/stress2/testcases/run/Makefile | 3 + tools/test/stress2/testcases/run/run.c | 117 ++ tools/test/stress2/testcases/rw/Makefile | 3 + tools/test/stress2/testcases/rw/rw.c | 180 +++ tools/test/stress2/testcases/shm/Makefile | 4 + tools/test/stress2/testcases/shm/shm.c | 182 +++ tools/test/stress2/testcases/socket/Makefile | 3 + tools/test/stress2/testcases/socket/socket.c | 118 ++ tools/test/stress2/testcases/swap/Makefile | 3 + tools/test/stress2/testcases/swap/swap.c | 166 +++ tools/test/stress2/testcases/symlink/Makefile | 3 + .../test/stress2/testcases/symlink/symlink.c | 138 ++ tools/test/stress2/testcases/sysctl/Makefile | 3 + tools/test/stress2/testcases/sysctl/sysctl.c | 63 + tools/test/stress2/testcases/tcp/Makefile | 3 + tools/test/stress2/testcases/tcp/tcp.c | 188 +++ tools/test/stress2/testcases/thr1/Makefile | 5 + tools/test/stress2/testcases/thr1/thr1.c | 75 + tools/test/stress2/testcases/thr2/Makefile | 5 + tools/test/stress2/testcases/thr2/thr2.c | 93 ++ tools/test/stress2/testcases/udp/Makefile | 3 + tools/test/stress2/testcases/udp/udp.c | 112 ++ tools/test/stress2/tools/bench.c | 356 +++++ tools/test/stress2/tools/calc_mem_use.pl | 61 + tools/test/stress2/tools/df.sh | 42 + tools/test/stress2/tools/fail.sh | 74 + tools/test/stress2/tools/fast.sh | 59 + tools/test/stress2/tools/flip.c | 121 ++ tools/test/stress2/tools/freeze.sh | 42 + tools/test/stress2/tools/freeze2.sh | 43 + tools/test/stress2/tools/fstool.c | 236 +++ tools/test/stress2/tools/iwatch.sh | 47 + tools/test/stress2/tools/killall.sh | 50 + tools/test/stress2/tools/kldload.sh | 71 + tools/test/stress2/tools/leaks.sh | 112 ++ tools/test/stress2/tools/leaks2.sh | 113 ++ tools/test/stress2/tools/maxvnodes.sh | 43 + tools/test/stress2/tools/ministat.sh | 52 + tools/test/stress2/tools/monitor.sh | 40 + tools/test/stress2/tools/ps.sh | 50 + tools/test/stress2/tools/ptsleak.sh | 39 + tools/test/stress2/tools/ptyleak.sh | 40 + tools/test/stress2/tools/rwatch.sh | 57 + tools/test/stress2/tools/setup.sh | 45 + tools/test/stress2/tools/shuffle | 47 + tools/test/stress2/tools/splitall.sh | 60 + tools/test/stress2/tools/swap.c | 225 +++ tools/test/stress2/tools/uleak.sh | 71 + tools/test/stress2/tools/vmstat.sh | 113 ++ tools/test/stress2/udp.cfg | 9 + tools/test/stress2/vfs.cfg | 8 + 968 files changed, 111344 insertions(+) create mode 100644 tools/test/stress2/Makefile create mode 100644 tools/test/stress2/README create mode 100644 tools/test/stress2/all.cfg create mode 100644 tools/test/stress2/creat.cfg create mode 100644 tools/test/stress2/ddb.conf create mode 100644 tools/test/stress2/default.cfg create mode 100644 tools/test/stress2/df.cfg create mode 100644 tools/test/stress2/disk.cfg create mode 100644 tools/test/stress2/doc/README create mode 100644 tools/test/stress2/doc/linuxforum06.pdf create mode 100644 tools/test/stress2/doc/stress.pdf create mode 100644 tools/test/stress2/include/stress.h create mode 100644 tools/test/stress2/io.cfg create mode 100644 tools/test/stress2/jeff.cfg create mode 100644 tools/test/stress2/lib/Makefile create mode 100644 tools/test/stress2/lib/main.c create mode 100644 tools/test/stress2/lib/options.c create mode 100644 tools/test/stress2/lib/random_int.c create mode 100644 tools/test/stress2/lib/resources.c create mode 100644 tools/test/stress2/link.cfg create mode 100644 tools/test/stress2/load.cfg create mode 100644 tools/test/stress2/lockf.cfg create mode 100644 tools/test/stress2/marcus.cfg create mode 100755 tools/test/stress2/misc/1st.sh create mode 100755 tools/test/stress2/misc/256m.sh create mode 100644 tools/test/stress2/misc/README create mode 100755 tools/test/stress2/misc/advlock.sh create mode 100755 tools/test/stress2/misc/aesni.sh create mode 100644 tools/test/stress2/misc/all.debug.inc create mode 100644 tools/test/stress2/misc/all.exclude create mode 100644 tools/test/stress2/misc/all.exclude.pae create mode 100755 tools/test/stress2/misc/all.sh create mode 100755 tools/test/stress2/misc/altbufferflushes.sh create mode 100755 tools/test/stress2/misc/alternativeFlushPath.sh create mode 100755 tools/test/stress2/misc/arp.sh create mode 100755 tools/test/stress2/misc/aslr.sh create mode 100755 tools/test/stress2/misc/audit.sh create mode 100755 tools/test/stress2/misc/audit2.sh create mode 100755 tools/test/stress2/misc/backingstore.sh create mode 100755 tools/test/stress2/misc/backingstore2.sh create mode 100755 tools/test/stress2/misc/backingstore3.sh create mode 100755 tools/test/stress2/misc/badcode.sh create mode 100755 tools/test/stress2/misc/badcode2.sh create mode 100755 tools/test/stress2/misc/badcode3.sh create mode 100755 tools/test/stress2/misc/bench.sh create mode 100755 tools/test/stress2/misc/beneath.sh create mode 100755 tools/test/stress2/misc/beneath2.sh create mode 100755 tools/test/stress2/misc/beneath3.sh create mode 100755 tools/test/stress2/misc/beneath4.sh create mode 100755 tools/test/stress2/misc/bio.sh create mode 100755 tools/test/stress2/misc/buildkernel.sh create mode 100755 tools/test/stress2/misc/buildworld.sh create mode 100755 tools/test/stress2/misc/buildworld2.sh create mode 100755 tools/test/stress2/misc/buildworld3.sh create mode 100755 tools/test/stress2/misc/buildworld4.sh create mode 100755 tools/test/stress2/misc/burnin.sh create mode 100755 tools/test/stress2/misc/callout_reset_on.sh create mode 100755 tools/test/stress2/misc/callout_reset_on2.sh create mode 100755 tools/test/stress2/misc/chain.sh create mode 100755 tools/test/stress2/misc/churn.sh create mode 100755 tools/test/stress2/misc/cleanup.sh create mode 100755 tools/test/stress2/misc/cluster.sh create mode 100755 tools/test/stress2/misc/cmp.sh create mode 100755 tools/test/stress2/misc/collapse.sh create mode 100755 tools/test/stress2/misc/compare.sh create mode 100755 tools/test/stress2/misc/context.sh create mode 100755 tools/test/stress2/misc/context2.sh create mode 100755 tools/test/stress2/misc/contigmalloc.sh create mode 100755 tools/test/stress2/misc/contigmalloc2.sh create mode 100755 tools/test/stress2/misc/contigmalloc3.sh create mode 100755 tools/test/stress2/misc/core.sh create mode 100755 tools/test/stress2/misc/core2.sh create mode 100755 tools/test/stress2/misc/core3.sh create mode 100755 tools/test/stress2/misc/core4.sh create mode 100755 tools/test/stress2/misc/core5.sh create mode 100755 tools/test/stress2/misc/cpuset.sh create mode 100755 tools/test/stress2/misc/credleak.sh create mode 100755 tools/test/stress2/misc/crossmp.sh create mode 100755 tools/test/stress2/misc/crossmp10.sh create mode 100755 tools/test/stress2/misc/crossmp11.sh create mode 100755 tools/test/stress2/misc/crossmp2.sh create mode 100755 tools/test/stress2/misc/crossmp3.sh create mode 100755 tools/test/stress2/misc/crossmp4.sh create mode 100755 tools/test/stress2/misc/crossmp5.sh create mode 100755 tools/test/stress2/misc/crossmp6.sh create mode 100755 tools/test/stress2/misc/crossmp7.sh create mode 100755 tools/test/stress2/misc/crossmp8.sh create mode 100755 tools/test/stress2/misc/crossmp9.sh create mode 100755 tools/test/stress2/misc/dangling.sh create mode 100755 tools/test/stress2/misc/datagram.sh create mode 100755 tools/test/stress2/misc/datagram2.sh create mode 100755 tools/test/stress2/misc/datagram3.sh create mode 100755 tools/test/stress2/misc/datamove.sh create mode 100755 tools/test/stress2/misc/datamove2.sh create mode 100755 tools/test/stress2/misc/datamove3.sh create mode 100755 tools/test/stress2/misc/datamove4.sh create mode 100755 tools/test/stress2/misc/datamove5.sh create mode 100755 tools/test/stress2/misc/db.sh create mode 100755 tools/test/stress2/misc/dd.sh create mode 100755 tools/test/stress2/misc/dev.sh create mode 100755 tools/test/stress2/misc/dev2.sh create mode 100755 tools/test/stress2/misc/dev3.sh create mode 100755 tools/test/stress2/misc/devfd.sh create mode 100755 tools/test/stress2/misc/devfs.sh create mode 100755 tools/test/stress2/misc/devfs2.sh create mode 100755 tools/test/stress2/misc/devfs3.sh create mode 100755 tools/test/stress2/misc/devfs4.sh create mode 100755 tools/test/stress2/misc/devfs5.sh create mode 100755 tools/test/stress2/misc/dfull.sh create mode 100755 tools/test/stress2/misc/dtrace.sh create mode 100755 tools/test/stress2/misc/dtrace_fault.sh create mode 100755 tools/test/stress2/misc/dumpfs.sh create mode 100755 tools/test/stress2/misc/dup.sh create mode 100755 tools/test/stress2/misc/dup2.sh create mode 100755 tools/test/stress2/misc/execi386.sh create mode 100755 tools/test/stress2/misc/execve.sh create mode 100755 tools/test/stress2/misc/exlock.sh create mode 100755 tools/test/stress2/misc/exlock2.sh create mode 100755 tools/test/stress2/misc/ext2fs.sh create mode 100755 tools/test/stress2/misc/ext2fs2.sh create mode 100755 tools/test/stress2/misc/ext2fs3.sh create mode 100755 tools/test/stress2/misc/ext3fs.sh create mode 100755 tools/test/stress2/misc/ext4fs.sh create mode 100755 tools/test/stress2/misc/extattr.sh create mode 100755 tools/test/stress2/misc/extattr2.sh create mode 100755 tools/test/stress2/misc/extattr3.sh create mode 100755 tools/test/stress2/misc/extattr_set_fd.sh create mode 100755 tools/test/stress2/misc/extattrctl.sh create mode 100755 tools/test/stress2/misc/f_offset.sh create mode 100755 tools/test/stress2/misc/fcntl.sh create mode 100755 tools/test/stress2/misc/fcntl2.sh create mode 100755 tools/test/stress2/misc/fcntl3.sh create mode 100755 tools/test/stress2/misc/fdatasync.sh create mode 100755 tools/test/stress2/misc/fdatasync2.sh create mode 100755 tools/test/stress2/misc/fdescfs.sh create mode 100755 tools/test/stress2/misc/fdgrowtable.sh create mode 100755 tools/test/stress2/misc/fexecve.sh create mode 100755 tools/test/stress2/misc/ffs_blkfree.sh create mode 100755 tools/test/stress2/misc/ffs_sync.sh create mode 100755 tools/test/stress2/misc/ffs_syncvnode.sh create mode 100755 tools/test/stress2/misc/ffs_syncvnode2.sh create mode 100755 tools/test/stress2/misc/fifo.sh create mode 100755 tools/test/stress2/misc/fifo2.sh create mode 100755 tools/test/stress2/misc/fifo3.sh create mode 100755 tools/test/stress2/misc/fifo4.sh create mode 100755 tools/test/stress2/misc/flock.sh create mode 100755 tools/test/stress2/misc/flock_open_close.sh create mode 100755 tools/test/stress2/misc/force.sh create mode 100755 tools/test/stress2/misc/force2.sh create mode 100755 tools/test/stress2/misc/force3.sh create mode 100755 tools/test/stress2/misc/force4.sh create mode 100755 tools/test/stress2/misc/force5.sh create mode 100755 tools/test/stress2/misc/force6.sh create mode 100755 tools/test/stress2/misc/fork.sh create mode 100755 tools/test/stress2/misc/forkbomb.sh create mode 100755 tools/test/stress2/misc/fpclone.sh create mode 100755 tools/test/stress2/misc/fpclone2.sh create mode 100755 tools/test/stress2/misc/fpu.sh create mode 100755 tools/test/stress2/misc/fragments.sh create mode 100755 tools/test/stress2/misc/freepages.sh create mode 100755 tools/test/stress2/misc/fs.sh create mode 100755 tools/test/stress2/misc/fsck.sh create mode 100755 tools/test/stress2/misc/fsck2.sh create mode 100755 tools/test/stress2/misc/fsck3.sh create mode 100755 tools/test/stress2/misc/fsck4.sh create mode 100755 tools/test/stress2/misc/fsck5.sh create mode 100755 tools/test/stress2/misc/fsck6.sh create mode 100755 tools/test/stress2/misc/fsgs.sh create mode 100755 tools/test/stress2/misc/fstat.sh create mode 100755 tools/test/stress2/misc/fsync.sh create mode 100755 tools/test/stress2/misc/fsync2.sh create mode 100755 tools/test/stress2/misc/ftruncate.sh create mode 100755 tools/test/stress2/misc/ftruncate2.sh create mode 100755 tools/test/stress2/misc/fts.sh create mode 100755 tools/test/stress2/misc/fts2.sh create mode 100755 tools/test/stress2/misc/fts3.sh create mode 100755 tools/test/stress2/misc/full.sh create mode 100755 tools/test/stress2/misc/fullpath.sh create mode 100755 tools/test/stress2/misc/fullpath2.sh create mode 100755 tools/test/stress2/misc/fuse.sh create mode 100755 tools/test/stress2/misc/fuse2.sh create mode 100755 tools/test/stress2/misc/fuse3.sh create mode 100755 tools/test/stress2/misc/fuzz.sh create mode 100755 tools/test/stress2/misc/gbde.sh create mode 100755 tools/test/stress2/misc/geli.sh create mode 100755 tools/test/stress2/misc/geomleak.sh create mode 100755 tools/test/stress2/misc/geomleak2.sh create mode 100755 tools/test/stress2/misc/getrandom.sh create mode 100755 tools/test/stress2/misc/getrandom2.sh create mode 100755 tools/test/stress2/misc/gjournal.sh create mode 100755 tools/test/stress2/misc/gjournal2.sh create mode 100755 tools/test/stress2/misc/gjournal3.sh create mode 100755 tools/test/stress2/misc/gjournal4.sh create mode 100755 tools/test/stress2/misc/gnop.sh create mode 100755 tools/test/stress2/misc/gnop10.sh create mode 100755 tools/test/stress2/misc/gnop2.sh create mode 100755 tools/test/stress2/misc/gnop3.sh create mode 100755 tools/test/stress2/misc/gnop4.sh create mode 100755 tools/test/stress2/misc/gnop5.sh create mode 100755 tools/test/stress2/misc/gnop6.sh create mode 100755 tools/test/stress2/misc/gnop7.sh create mode 100755 tools/test/stress2/misc/gnop8.sh create mode 100755 tools/test/stress2/misc/gnop9.sh create mode 100755 tools/test/stress2/misc/gpt.sh create mode 100755 tools/test/stress2/misc/graid0.sh create mode 100755 tools/test/stress2/misc/graid1.sh create mode 100755 tools/test/stress2/misc/graid1_10.sh create mode 100755 tools/test/stress2/misc/graid1_2.sh create mode 100755 tools/test/stress2/misc/graid1_3.sh create mode 100755 tools/test/stress2/misc/graid1_4.sh create mode 100755 tools/test/stress2/misc/graid1_5.sh create mode 100755 tools/test/stress2/misc/graid1_6.sh create mode 100755 tools/test/stress2/misc/graid1_7.sh create mode 100755 tools/test/stress2/misc/graid1_8.sh create mode 100755 tools/test/stress2/misc/graid1_9.sh create mode 100755 tools/test/stress2/misc/graid3.sh create mode 100755 tools/test/stress2/misc/growfs.sh create mode 100755 tools/test/stress2/misc/holdcnt0.sh create mode 100755 tools/test/stress2/misc/holdcnt02.sh create mode 100755 tools/test/stress2/misc/holdcnt03.sh create mode 100755 tools/test/stress2/misc/holdcnt04.sh create mode 100755 tools/test/stress2/misc/holdcnt05.sh create mode 100755 tools/test/stress2/misc/ifconfig.sh create mode 100755 tools/test/stress2/misc/ifconfig2.sh create mode 100755 tools/test/stress2/misc/indir.sh create mode 100755 tools/test/stress2/misc/indir_trunc.sh create mode 100755 tools/test/stress2/misc/inversion.sh create mode 100755 tools/test/stress2/misc/isofs.sh create mode 100755 tools/test/stress2/misc/isofs2.sh create mode 100755 tools/test/stress2/misc/isofs3.sh create mode 100755 tools/test/stress2/misc/jail.sh create mode 100755 tools/test/stress2/misc/jail2.sh create mode 100755 tools/test/stress2/misc/jail3.sh create mode 100755 tools/test/stress2/misc/jail4.sh create mode 100755 tools/test/stress2/misc/jexec.sh create mode 100755 tools/test/stress2/misc/jumbo.sh create mode 100755 tools/test/stress2/misc/kern_umtx_inf_loop.sh create mode 100755 tools/test/stress2/misc/kevent.sh create mode 100755 tools/test/stress2/misc/kevent10.sh create mode 100755 tools/test/stress2/misc/kevent11.sh create mode 100755 tools/test/stress2/misc/kevent12.sh create mode 100755 tools/test/stress2/misc/kevent13.sh create mode 100755 tools/test/stress2/misc/kevent14.sh create mode 100755 tools/test/stress2/misc/kevent15.sh create mode 100755 tools/test/stress2/misc/kevent2.sh create mode 100755 tools/test/stress2/misc/kevent3.sh create mode 100755 tools/test/stress2/misc/kevent4.sh create mode 100755 tools/test/stress2/misc/kevent5.sh create mode 100755 tools/test/stress2/misc/kevent6.sh create mode 100755 tools/test/stress2/misc/kevent7.sh create mode 100755 tools/test/stress2/misc/kevent8.sh create mode 100755 tools/test/stress2/misc/kevent9.sh create mode 100755 tools/test/stress2/misc/killpg.sh create mode 100755 tools/test/stress2/misc/kinfo.sh create mode 100755 tools/test/stress2/misc/kinfo2.sh create mode 100755 tools/test/stress2/misc/kinfo3.sh create mode 100755 tools/test/stress2/misc/kpti.sh create mode 100755 tools/test/stress2/misc/largepage.sh create mode 100755 tools/test/stress2/misc/laundry.sh create mode 100755 tools/test/stress2/misc/ldt.sh create mode 100755 tools/test/stress2/misc/ldt2.sh create mode 100755 tools/test/stress2/misc/libMicro.sh create mode 100755 tools/test/stress2/misc/linger.sh create mode 100755 tools/test/stress2/misc/linger2.sh create mode 100755 tools/test/stress2/misc/linger3.sh create mode 100755 tools/test/stress2/misc/linger4.sh create mode 100755 tools/test/stress2/misc/link.sh create mode 100755 tools/test/stress2/misc/link2.sh create mode 100755 tools/test/stress2/misc/linux.sh create mode 100755 tools/test/stress2/misc/lockd.sh create mode 100755 tools/test/stress2/misc/lockf.sh create mode 100755 tools/test/stress2/misc/lockf2.sh create mode 100755 tools/test/stress2/misc/lockf3.sh create mode 100755 tools/test/stress2/misc/lockf4.sh create mode 100755 tools/test/stress2/misc/lockf5.sh create mode 100755 tools/test/stress2/misc/lookup_shared.sh create mode 100755 tools/test/stress2/misc/lstat.sh create mode 100755 tools/test/stress2/misc/mac.sh create mode 100755 tools/test/stress2/misc/mac_chkexec.sh create mode 100755 tools/test/stress2/misc/machipc.sh create mode 100755 tools/test/stress2/misc/machipc2.sh create mode 100755 tools/test/stress2/misc/marcus.sh create mode 100755 tools/test/stress2/misc/marcus2.sh create mode 100755 tools/test/stress2/misc/marcus3.sh create mode 100755 tools/test/stress2/misc/marcus4.sh create mode 100755 tools/test/stress2/misc/marcus5.sh create mode 100755 tools/test/stress2/misc/marcus6.sh create mode 100755 tools/test/stress2/misc/marcus7.sh create mode 100755 tools/test/stress2/misc/maxmemdom.sh create mode 100755 tools/test/stress2/misc/maxproc.sh create mode 100755 tools/test/stress2/misc/maxvnodes.sh create mode 100755 tools/test/stress2/misc/maxvnodes2.sh create mode 100755 tools/test/stress2/misc/md.sh create mode 100755 tools/test/stress2/misc/md2.sh create mode 100755 tools/test/stress2/misc/md3.sh create mode 100755 tools/test/stress2/misc/md4.sh create mode 100755 tools/test/stress2/misc/md5.sh create mode 100755 tools/test/stress2/misc/md6.sh create mode 100755 tools/test/stress2/misc/md7.sh create mode 100755 tools/test/stress2/misc/md8.sh create mode 100755 tools/test/stress2/misc/md9.sh create mode 100755 tools/test/stress2/misc/mdconfig.sh create mode 100755 tools/test/stress2/misc/mdconfig2.sh create mode 100755 tools/test/stress2/misc/mdconfig3.sh create mode 100755 tools/test/stress2/misc/memguard.sh create mode 100755 tools/test/stress2/misc/memguard2.sh create mode 100755 tools/test/stress2/misc/memguard3.sh create mode 100755 tools/test/stress2/misc/memguard4.sh create mode 100755 tools/test/stress2/misc/midi.sh create mode 100755 tools/test/stress2/misc/midi2.sh create mode 100755 tools/test/stress2/misc/mincore.sh create mode 100755 tools/test/stress2/misc/minherit.sh create mode 100755 tools/test/stress2/misc/mkfifo.sh create mode 100755 tools/test/stress2/misc/mkfifo2c.sh create mode 100755 tools/test/stress2/misc/mkfifo2d.sh create mode 100755 tools/test/stress2/misc/mkfifo3.sh create mode 100755 tools/test/stress2/misc/mkfifo4.sh create mode 100755 tools/test/stress2/misc/mkfifo5.sh create mode 100755 tools/test/stress2/misc/mkfifo6.sh create mode 100755 tools/test/stress2/misc/mkfifo7.sh create mode 100755 tools/test/stress2/misc/mkfifo8.sh create mode 100755 tools/test/stress2/misc/mknod.sh create mode 100755 tools/test/stress2/misc/mlockall.sh create mode 100755 tools/test/stress2/misc/mlockall2.sh create mode 100755 tools/test/stress2/misc/mlockall3.sh create mode 100755 tools/test/stress2/misc/mlockall4.sh create mode 100755 tools/test/stress2/misc/mlockall5.sh create mode 100755 tools/test/stress2/misc/mlockall6.sh create mode 100755 tools/test/stress2/misc/mlockall7.sh create mode 100755 tools/test/stress2/misc/mmap.sh create mode 100755 tools/test/stress2/misc/mmap10.sh create mode 100755 tools/test/stress2/misc/mmap11.sh create mode 100755 tools/test/stress2/misc/mmap12.sh create mode 100755 tools/test/stress2/misc/mmap13.sh create mode 100755 tools/test/stress2/misc/mmap14.sh create mode 100755 tools/test/stress2/misc/mmap15.sh create mode 100755 tools/test/stress2/misc/mmap16.sh create mode 100755 tools/test/stress2/misc/mmap17.sh create mode 100755 tools/test/stress2/misc/mmap18.sh create mode 100755 tools/test/stress2/misc/mmap19.sh create mode 100755 tools/test/stress2/misc/mmap2.sh create mode 100755 tools/test/stress2/misc/mmap20.sh create mode 100755 tools/test/stress2/misc/mmap21.sh create mode 100755 tools/test/stress2/misc/mmap22.sh create mode 100755 tools/test/stress2/misc/mmap23.sh create mode 100755 tools/test/stress2/misc/mmap24.sh create mode 100755 tools/test/stress2/misc/mmap25.sh create mode 100755 tools/test/stress2/misc/mmap26.sh create mode 100755 tools/test/stress2/misc/mmap27.sh create mode 100755 tools/test/stress2/misc/mmap28.sh create mode 100755 tools/test/stress2/misc/mmap29.sh create mode 100755 tools/test/stress2/misc/mmap3.sh create mode 100755 tools/test/stress2/misc/mmap30.sh create mode 100755 tools/test/stress2/misc/mmap31.sh create mode 100755 tools/test/stress2/misc/mmap32.sh create mode 100755 tools/test/stress2/misc/mmap33.sh create mode 100755 tools/test/stress2/misc/mmap34.sh create mode 100755 tools/test/stress2/misc/mmap35.sh create mode 100755 tools/test/stress2/misc/mmap36.sh create mode 100755 tools/test/stress2/misc/mmap37.sh create mode 100755 tools/test/stress2/misc/mmap38.sh create mode 100755 tools/test/stress2/misc/mmap39.sh create mode 100755 tools/test/stress2/misc/mmap4.sh create mode 100755 tools/test/stress2/misc/mmap40.sh create mode 100755 tools/test/stress2/misc/mmap5.sh create mode 100755 tools/test/stress2/misc/mmap6.sh create mode 100755 tools/test/stress2/misc/mmap7.sh create mode 100755 tools/test/stress2/misc/mmap8.sh create mode 100755 tools/test/stress2/misc/mmap9.sh create mode 100755 tools/test/stress2/misc/mount.sh create mode 100755 tools/test/stress2/misc/mount2.sh create mode 100755 tools/test/stress2/misc/mountro.sh create mode 100755 tools/test/stress2/misc/mountro2.sh create mode 100755 tools/test/stress2/misc/mountro3.sh create mode 100755 tools/test/stress2/misc/mountro4.sh create mode 100755 tools/test/stress2/misc/mountro5.sh create mode 100755 tools/test/stress2/misc/mountro6.sh create mode 100755 tools/test/stress2/misc/mountu.sh create mode 100755 tools/test/stress2/misc/mprotect.sh create mode 100755 tools/test/stress2/misc/mprotect2.sh create mode 100755 tools/test/stress2/misc/msdos.sh create mode 100755 tools/test/stress2/misc/msdos10.sh create mode 100755 tools/test/stress2/misc/msdos2.sh create mode 100755 tools/test/stress2/misc/msdos3.sh create mode 100755 tools/test/stress2/misc/msdos4.sh create mode 100755 tools/test/stress2/misc/msdos5.sh create mode 100755 tools/test/stress2/misc/msdos6.sh create mode 100755 tools/test/stress2/misc/msdos7.sh create mode 100755 tools/test/stress2/misc/msdos8.sh create mode 100755 tools/test/stress2/misc/msdos9.sh create mode 100755 tools/test/stress2/misc/msetdomain.sh create mode 100755 tools/test/stress2/misc/msync.sh create mode 100755 tools/test/stress2/misc/msync2.sh create mode 100755 tools/test/stress2/misc/multicast.sh create mode 100755 tools/test/stress2/misc/multicast2.sh create mode 100755 tools/test/stress2/misc/namecache.sh create mode 100755 tools/test/stress2/misc/namecache2.sh create mode 100755 tools/test/stress2/misc/nanosleep.sh create mode 100755 tools/test/stress2/misc/nbufkv.sh create mode 100755 tools/test/stress2/misc/newfs.sh create mode 100755 tools/test/stress2/misc/newfs2.sh create mode 100755 tools/test/stress2/misc/newfs3.sh create mode 100755 tools/test/stress2/misc/newfs4.sh create mode 100755 tools/test/stress2/misc/newfs5.sh create mode 100755 tools/test/stress2/misc/nfs.sh create mode 100755 tools/test/stress2/misc/nfs10.sh create mode 100755 tools/test/stress2/misc/nfs11.sh create mode 100755 tools/test/stress2/misc/nfs12.sh create mode 100755 tools/test/stress2/misc/nfs13.sh create mode 100755 tools/test/stress2/misc/nfs14.sh create mode 100755 tools/test/stress2/misc/nfs15.sh create mode 100755 tools/test/stress2/misc/nfs15lockd.sh create mode 100755 tools/test/stress2/misc/nfs15lockd2.sh create mode 100755 tools/test/stress2/misc/nfs15lockd3.sh create mode 100755 tools/test/stress2/misc/nfs16.sh create mode 100755 tools/test/stress2/misc/nfs17.sh create mode 100755 tools/test/stress2/misc/nfs2.sh create mode 100755 tools/test/stress2/misc/nfs3.sh create mode 100755 tools/test/stress2/misc/nfs4.sh create mode 100755 tools/test/stress2/misc/nfs5.sh create mode 100755 tools/test/stress2/misc/nfs6.sh create mode 100755 tools/test/stress2/misc/nfs7.sh create mode 100755 tools/test/stress2/misc/nfs8.sh create mode 100755 tools/test/stress2/misc/nfs9.sh create mode 100755 tools/test/stress2/misc/nfs_halfpage.sh create mode 100755 tools/test/stress2/misc/nfs_halfpage2.sh create mode 100755 tools/test/stress2/misc/nfsdelegation.sh create mode 100755 tools/test/stress2/misc/nfsdepth.sh create mode 100755 tools/test/stress2/misc/nfsrename.sh create mode 100755 tools/test/stress2/misc/nfssillyrename.sh create mode 100755 tools/test/stress2/misc/nullfs.sh create mode 100755 tools/test/stress2/misc/nullfs10.sh create mode 100755 tools/test/stress2/misc/nullfs11.sh create mode 100755 tools/test/stress2/misc/nullfs12.sh create mode 100755 tools/test/stress2/misc/nullfs13.sh create mode 100755 tools/test/stress2/misc/nullfs14.sh create mode 100755 tools/test/stress2/misc/nullfs15.sh create mode 100755 tools/test/stress2/misc/nullfs16.sh create mode 100755 tools/test/stress2/misc/nullfs17.sh create mode 100755 tools/test/stress2/misc/nullfs18.sh create mode 100755 tools/test/stress2/misc/nullfs19.sh create mode 100755 tools/test/stress2/misc/nullfs2.sh create mode 100755 tools/test/stress2/misc/nullfs20.sh create mode 100755 tools/test/stress2/misc/nullfs21.sh create mode 100755 tools/test/stress2/misc/nullfs22.sh create mode 100755 tools/test/stress2/misc/nullfs23.sh create mode 100755 tools/test/stress2/misc/nullfs24.sh create mode 100755 tools/test/stress2/misc/nullfs25.sh create mode 100755 tools/test/stress2/misc/nullfs26.sh create mode 100755 tools/test/stress2/misc/nullfs27.sh create mode 100755 tools/test/stress2/misc/nullfs3.sh create mode 100755 tools/test/stress2/misc/nullfs4.sh create mode 100755 tools/test/stress2/misc/nullfs5.sh create mode 100755 tools/test/stress2/misc/nullfs6.sh create mode 100755 tools/test/stress2/misc/nullfs7.sh create mode 100755 tools/test/stress2/misc/nullfs8.sh create mode 100755 tools/test/stress2/misc/nullfs9.sh create mode 100755 tools/test/stress2/misc/numa.sh create mode 100755 tools/test/stress2/misc/oom.sh create mode 100755 tools/test/stress2/misc/oom2.sh create mode 100755 tools/test/stress2/misc/oovm.sh create mode 100755 tools/test/stress2/misc/oovm2.sh create mode 100755 tools/test/stress2/misc/open.sh create mode 100755 tools/test/stress2/misc/openlock.sh create mode 100755 tools/test/stress2/misc/overcommit.sh create mode 100755 tools/test/stress2/misc/overcommit2.sh create mode 100755 tools/test/stress2/misc/overflow3.sh create mode 100755 tools/test/stress2/misc/overlap.sh create mode 100755 tools/test/stress2/misc/pageout.sh create mode 100755 tools/test/stress2/misc/parallelmount.sh create mode 100755 tools/test/stress2/misc/parallelmount2.sh create mode 100755 tools/test/stress2/misc/pathconf.sh create mode 100755 tools/test/stress2/misc/pathconf2.sh create mode 100755 tools/test/stress2/misc/pause.sh create mode 100755 tools/test/stress2/misc/pcatch.sh create mode 100755 tools/test/stress2/misc/pcatch2.sh create mode 100755 tools/test/stress2/misc/pdfork.sh create mode 100755 tools/test/stress2/misc/perf.sh create mode 100755 tools/test/stress2/misc/pfl.sh create mode 100755 tools/test/stress2/misc/pfl2.sh create mode 100755 tools/test/stress2/misc/pfl3.sh create mode 100755 tools/test/stress2/misc/pfl4.sh create mode 100755 tools/test/stress2/misc/ping.sh create mode 100755 tools/test/stress2/misc/pipe.sh create mode 100755 tools/test/stress2/misc/pipe2.sh create mode 100755 tools/test/stress2/misc/pipe3.sh create mode 100755 tools/test/stress2/misc/pipe_enomem.sh create mode 100755 tools/test/stress2/misc/pkru.sh create mode 100755 tools/test/stress2/misc/pkru2.sh create mode 100755 tools/test/stress2/misc/pmc.sh create mode 100755 tools/test/stress2/misc/pmc2.sh create mode 100755 tools/test/stress2/misc/pmc3.sh create mode 100755 tools/test/stress2/misc/pmc4.sh create mode 100755 tools/test/stress2/misc/pmc5.sh create mode 100755 tools/test/stress2/misc/pmc6.sh create mode 100755 tools/test/stress2/misc/pmc7.sh create mode 100755 tools/test/stress2/misc/poll.sh create mode 100755 tools/test/stress2/misc/poll2.sh create mode 100755 tools/test/stress2/misc/posix_fadvise.sh create mode 100755 tools/test/stress2/misc/posix_fadvise2.sh create mode 100755 tools/test/stress2/misc/posix_fadvise3.sh create mode 100755 tools/test/stress2/misc/posix_openpt.sh create mode 100755 tools/test/stress2/misc/posix_openpt2.sh create mode 100755 tools/test/stress2/misc/pread.sh create mode 100755 tools/test/stress2/misc/proccontrol.sh create mode 100755 tools/test/stress2/misc/procfs.sh create mode 100755 tools/test/stress2/misc/procfs2.sh create mode 100755 tools/test/stress2/misc/procfs3.sh create mode 100755 tools/test/stress2/misc/procfs4.sh create mode 100755 tools/test/stress2/misc/procfs5.sh create mode 100755 tools/test/stress2/misc/procfs6.sh create mode 100755 tools/test/stress2/misc/procstat.sh create mode 100755 tools/test/stress2/misc/procstat2.sh create mode 100755 tools/test/stress2/misc/pthread.sh create mode 100755 tools/test/stress2/misc/pthread2.sh create mode 100755 tools/test/stress2/misc/pthread3.sh create mode 100755 tools/test/stress2/misc/pthread4.sh create mode 100755 tools/test/stress2/misc/pthread5.sh create mode 100755 tools/test/stress2/misc/pthread6.sh create mode 100755 tools/test/stress2/misc/pthread7.sh create mode 100755 tools/test/stress2/misc/pthread8.sh create mode 100755 tools/test/stress2/misc/pthread9.sh create mode 100755 tools/test/stress2/misc/ptrace.sh create mode 100755 tools/test/stress2/misc/ptrace10.sh create mode 100755 tools/test/stress2/misc/ptrace11.sh create mode 100755 tools/test/stress2/misc/ptrace2.sh create mode 100755 tools/test/stress2/misc/ptrace3.sh create mode 100755 tools/test/stress2/misc/ptrace4.sh create mode 100755 tools/test/stress2/misc/ptrace5.sh create mode 100755 tools/test/stress2/misc/ptrace6.sh create mode 100755 tools/test/stress2/misc/ptrace7.sh create mode 100755 tools/test/stress2/misc/ptrace8.sh create mode 100755 tools/test/stress2/misc/ptrace9.sh create mode 100755 tools/test/stress2/misc/pts.sh create mode 100755 tools/test/stress2/misc/pts2.sh create mode 100755 tools/test/stress2/misc/pts3.sh create mode 100755 tools/test/stress2/misc/pty.sh create mode 100755 tools/test/stress2/misc/pty2.sh create mode 100755 tools/test/stress2/misc/quota1.sh create mode 100755 tools/test/stress2/misc/quota10.sh create mode 100755 tools/test/stress2/misc/quota11.sh create mode 100755 tools/test/stress2/misc/quota12.sh create mode 100755 tools/test/stress2/misc/quota2.sh create mode 100755 tools/test/stress2/misc/quota3.sh create mode 100755 tools/test/stress2/misc/quota4.sh create mode 100755 tools/test/stress2/misc/quota5.sh create mode 100755 tools/test/stress2/misc/quota6.sh create mode 100755 tools/test/stress2/misc/quota7.sh create mode 100755 tools/test/stress2/misc/quota8.sh create mode 100755 tools/test/stress2/misc/quota9.sh create mode 100755 tools/test/stress2/misc/r335171.sh create mode 100755 tools/test/stress2/misc/racct.sh create mode 100755 tools/test/stress2/misc/radix.sh create mode 100755 tools/test/stress2/misc/random.sh create mode 100755 tools/test/stress2/misc/rdgsbase.sh create mode 100755 tools/test/stress2/misc/rdwr.sh create mode 100755 tools/test/stress2/misc/readdir.sh create mode 100755 tools/test/stress2/misc/recursiveflushes.sh create mode 100755 tools/test/stress2/misc/rename.sh create mode 100755 tools/test/stress2/misc/rename10.sh create mode 100755 tools/test/stress2/misc/rename11.sh create mode 100755 tools/test/stress2/misc/rename12.sh create mode 100755 tools/test/stress2/misc/rename13.sh create mode 100755 tools/test/stress2/misc/rename14.sh create mode 100755 tools/test/stress2/misc/rename15.sh create mode 100755 tools/test/stress2/misc/rename2.sh create mode 100755 tools/test/stress2/misc/rename3.sh create mode 100755 tools/test/stress2/misc/rename4.sh create mode 100755 tools/test/stress2/misc/rename5.sh create mode 100755 tools/test/stress2/misc/rename6.sh create mode 100755 tools/test/stress2/misc/rename7.sh create mode 100755 tools/test/stress2/misc/rename8.sh create mode 100755 tools/test/stress2/misc/rename9.sh create mode 100755 tools/test/stress2/misc/revoke.sh create mode 100755 tools/test/stress2/misc/rot.sh create mode 100755 tools/test/stress2/misc/routetbl.sh create mode 100755 tools/test/stress2/misc/ruby.sh create mode 100755 tools/test/stress2/misc/rw.sh create mode 100755 tools/test/stress2/misc/rwlock_ronly.sh create mode 100755 tools/test/stress2/misc/sched.sh create mode 100755 tools/test/stress2/misc/schedfuzz.sh create mode 100755 tools/test/stress2/misc/sctp.sh create mode 100755 tools/test/stress2/misc/sctp2.sh create mode 100755 tools/test/stress2/misc/sctp3.sh create mode 100755 tools/test/stress2/misc/seekdir.sh create mode 100755 tools/test/stress2/misc/segnp.sh create mode 100755 tools/test/stress2/misc/segregs.sh create mode 100755 tools/test/stress2/misc/select.sh create mode 100755 tools/test/stress2/misc/select3.sh create mode 100755 tools/test/stress2/misc/selfd.sh create mode 100755 tools/test/stress2/misc/sem.sh create mode 100755 tools/test/stress2/misc/sem_post.sh create mode 100755 tools/test/stress2/misc/sem_timedwait.sh create mode 100755 tools/test/stress2/misc/sem_wait.sh create mode 100755 tools/test/stress2/misc/sendfile.sh create mode 100755 tools/test/stress2/misc/sendfile10.sh create mode 100755 tools/test/stress2/misc/sendfile11.sh create mode 100755 tools/test/stress2/misc/sendfile12.sh create mode 100755 tools/test/stress2/misc/sendfile13.sh create mode 100755 tools/test/stress2/misc/sendfile14.sh create mode 100755 tools/test/stress2/misc/sendfile15.sh create mode 100755 tools/test/stress2/misc/sendfile16.sh create mode 100755 tools/test/stress2/misc/sendfile17.sh create mode 100755 tools/test/stress2/misc/sendfile18.sh create mode 100755 tools/test/stress2/misc/sendfile19.sh create mode 100755 tools/test/stress2/misc/sendfile2.sh create mode 100755 tools/test/stress2/misc/sendfile20.sh create mode 100755 tools/test/stress2/misc/sendfile21.sh create mode 100755 tools/test/stress2/misc/sendfile22.sh create mode 100755 tools/test/stress2/misc/sendfile23.sh create mode 100755 tools/test/stress2/misc/sendfile24.sh create mode 100755 tools/test/stress2/misc/sendfile25.sh create mode 100755 tools/test/stress2/misc/sendfile26.sh create mode 100755 tools/test/stress2/misc/sendfile3.sh create mode 100755 tools/test/stress2/misc/sendfile4.sh create mode 100755 tools/test/stress2/misc/sendfile5.sh create mode 100755 tools/test/stress2/misc/sendfile6.sh create mode 100755 tools/test/stress2/misc/sendfile7.sh create mode 100755 tools/test/stress2/misc/sendfile8.sh create mode 100755 tools/test/stress2/misc/sendfile9.sh create mode 100755 tools/test/stress2/misc/sendfile_shm.sh create mode 100755 tools/test/stress2/misc/sendmsg.sh create mode 100755 tools/test/stress2/misc/sendmsg2.sh create mode 100755 tools/test/stress2/misc/sethostname.sh create mode 100755 tools/test/stress2/misc/setsockopt.sh create mode 100755 tools/test/stress2/misc/setsockopt2.sh create mode 100755 tools/test/stress2/misc/setuid.sh create mode 100755 tools/test/stress2/misc/shm.sh create mode 100755 tools/test/stress2/misc/shm2.sh create mode 100755 tools/test/stress2/misc/shm_open.sh create mode 100755 tools/test/stress2/misc/shm_super.sh create mode 100755 tools/test/stress2/misc/sigaltstack.sh create mode 100755 tools/test/stress2/misc/sigfastblock.sh create mode 100755 tools/test/stress2/misc/sigfastblock2.sh create mode 100755 tools/test/stress2/misc/signal.sh create mode 100755 tools/test/stress2/misc/signal0.sh create mode 100755 tools/test/stress2/misc/sigreturn.sh create mode 100755 tools/test/stress2/misc/sigstop.sh create mode 100755 tools/test/stress2/misc/sigstop2.sh create mode 100755 tools/test/stress2/misc/sigxcpu.sh create mode 100755 tools/test/stress2/misc/smrstress.sh create mode 100755 tools/test/stress2/misc/smrstress2.sh create mode 100755 tools/test/stress2/misc/snap.sh create mode 100755 tools/test/stress2/misc/snap10.sh create mode 100755 tools/test/stress2/misc/snap11.sh create mode 100755 tools/test/stress2/misc/snap12.sh create mode 100755 tools/test/stress2/misc/snap2-1.sh create mode 100755 tools/test/stress2/misc/snap2.sh create mode 100755 tools/test/stress2/misc/snap3.sh create mode 100755 tools/test/stress2/misc/snap4.sh create mode 100755 tools/test/stress2/misc/snap5-1.sh create mode 100755 tools/test/stress2/misc/snap5.sh create mode 100755 tools/test/stress2/misc/snap6.sh create mode 100755 tools/test/stress2/misc/snap7.sh create mode 100755 tools/test/stress2/misc/snap8.sh create mode 100755 tools/test/stress2/misc/snap9.sh create mode 100755 tools/test/stress2/misc/sndstat.sh create mode 100755 tools/test/stress2/misc/socketpair.sh create mode 100755 tools/test/stress2/misc/socketpair2.sh create mode 100755 tools/test/stress2/misc/socketpair3.sh create mode 100755 tools/test/stress2/misc/socketpair4.sh create mode 100755 tools/test/stress2/misc/softupdate.sh create mode 100755 tools/test/stress2/misc/sort.sh create mode 100755 tools/test/stress2/misc/sort2.sh create mode 100755 tools/test/stress2/misc/sparse.sh create mode 100755 tools/test/stress2/misc/spin.sh create mode 100755 tools/test/stress2/misc/split.sh create mode 100755 tools/test/stress2/misc/stack_guard_page.sh create mode 100755 tools/test/stress2/misc/statfs.sh create mode 100755 tools/test/stress2/misc/stealer.sh create mode 100755 tools/test/stress2/misc/su.sh create mode 100755 tools/test/stress2/misc/suj.sh create mode 100755 tools/test/stress2/misc/suj10.sh create mode 100755 tools/test/stress2/misc/suj11.sh create mode 100755 tools/test/stress2/misc/suj12.sh create mode 100755 tools/test/stress2/misc/suj13.sh create mode 100755 tools/test/stress2/misc/suj14.sh create mode 100755 tools/test/stress2/misc/suj15.sh create mode 100755 tools/test/stress2/misc/suj16.sh create mode 100755 tools/test/stress2/misc/suj17.sh create mode 100755 tools/test/stress2/misc/suj18.sh create mode 100755 tools/test/stress2/misc/suj19.sh create mode 100755 tools/test/stress2/misc/suj2.sh create mode 100755 tools/test/stress2/misc/suj20.sh create mode 100755 tools/test/stress2/misc/suj21.sh create mode 100755 tools/test/stress2/misc/suj22.sh create mode 100755 tools/test/stress2/misc/suj23.sh create mode 100755 tools/test/stress2/misc/suj24.sh create mode 100755 tools/test/stress2/misc/suj25.sh create mode 100755 tools/test/stress2/misc/suj26.sh create mode 100755 tools/test/stress2/misc/suj27.sh create mode 100755 tools/test/stress2/misc/suj28.sh create mode 100755 tools/test/stress2/misc/suj29.sh create mode 100755 tools/test/stress2/misc/suj3.sh create mode 100755 tools/test/stress2/misc/suj30.sh create mode 100755 tools/test/stress2/misc/suj31.sh create mode 100755 tools/test/stress2/misc/suj32.sh create mode 100755 tools/test/stress2/misc/suj33.sh create mode 100755 tools/test/stress2/misc/suj34.sh create mode 100755 tools/test/stress2/misc/suj35.sh create mode 100755 tools/test/stress2/misc/suj4.sh create mode 100755 tools/test/stress2/misc/suj5.sh create mode 100755 tools/test/stress2/misc/suj6.sh create mode 100755 tools/test/stress2/misc/suj7.sh create mode 100755 tools/test/stress2/misc/suj8.sh create mode 100755 tools/test/stress2/misc/suj9.sh create mode 100755 tools/test/stress2/misc/swap.sh create mode 100755 tools/test/stress2/misc/swap2.sh create mode 100755 tools/test/stress2/misc/swap3.sh create mode 100755 tools/test/stress2/misc/swap4.sh create mode 100755 tools/test/stress2/misc/swap5.sh create mode 100755 tools/test/stress2/misc/swap6.sh create mode 100755 tools/test/stress2/misc/swapoff.sh create mode 100755 tools/test/stress2/misc/swapoff2.sh create mode 100755 tools/test/stress2/misc/swapoff3.sh create mode 100755 tools/test/stress2/misc/swapoff4.sh create mode 100755 tools/test/stress2/misc/swapoff5.sh create mode 100755 tools/test/stress2/misc/swappedout.sh create mode 100755 tools/test/stress2/misc/symlink.sh create mode 100755 tools/test/stress2/misc/symlink2.sh create mode 100755 tools/test/stress2/misc/symlink3.sh create mode 100755 tools/test/stress2/misc/symlink4.sh create mode 100755 tools/test/stress2/misc/symlink5.sh create mode 100755 tools/test/stress2/misc/syscall4.sh create mode 100755 tools/test/stress2/misc/syscall5.sh create mode 100755 tools/test/stress2/misc/syscall6.sh create mode 100755 tools/test/stress2/misc/sysctl.sh create mode 100755 tools/test/stress2/misc/sysctl2.sh create mode 100755 tools/test/stress2/misc/sysctl3.sh create mode 100755 tools/test/stress2/misc/sysctl4.sh create mode 100755 tools/test/stress2/misc/systrace.sh create mode 100755 tools/test/stress2/misc/systrace2.sh create mode 100755 tools/test/stress2/misc/syzkaller1.sh create mode 100755 tools/test/stress2/misc/syzkaller10.sh create mode 100755 tools/test/stress2/misc/syzkaller11.sh create mode 100755 tools/test/stress2/misc/syzkaller12.sh create mode 100755 tools/test/stress2/misc/syzkaller13.sh create mode 100755 tools/test/stress2/misc/syzkaller14.sh create mode 100755 tools/test/stress2/misc/syzkaller15.sh create mode 100755 tools/test/stress2/misc/syzkaller16.sh create mode 100755 tools/test/stress2/misc/syzkaller17.sh create mode 100755 tools/test/stress2/misc/syzkaller18.sh create mode 100755 tools/test/stress2/misc/syzkaller19.sh create mode 100755 tools/test/stress2/misc/syzkaller2.sh create mode 100755 tools/test/stress2/misc/syzkaller20.sh create mode 100755 tools/test/stress2/misc/syzkaller21.sh create mode 100755 tools/test/stress2/misc/syzkaller22.sh create mode 100755 tools/test/stress2/misc/syzkaller23.sh create mode 100755 tools/test/stress2/misc/syzkaller24.sh create mode 100755 tools/test/stress2/misc/syzkaller25.sh create mode 100755 tools/test/stress2/misc/syzkaller26.sh create mode 100755 tools/test/stress2/misc/syzkaller27.sh create mode 100755 tools/test/stress2/misc/syzkaller28.sh create mode 100755 tools/test/stress2/misc/syzkaller29.sh create mode 100755 tools/test/stress2/misc/syzkaller3.sh create mode 100755 tools/test/stress2/misc/syzkaller30.sh create mode 100755 tools/test/stress2/misc/syzkaller4.sh create mode 100755 tools/test/stress2/misc/syzkaller5.sh create mode 100755 tools/test/stress2/misc/syzkaller6.sh create mode 100755 tools/test/stress2/misc/syzkaller7.sh create mode 100755 tools/test/stress2/misc/syzkaller8.sh create mode 100755 tools/test/stress2/misc/syzkaller9.sh create mode 100755 tools/test/stress2/misc/tar.sh create mode 100755 tools/test/stress2/misc/tcp.sh create mode 100755 tools/test/stress2/misc/tcp2.sh create mode 100755 tools/test/stress2/misc/tcp3.sh create mode 100755 tools/test/stress2/misc/tcp4.sh create mode 100755 tools/test/stress2/misc/temp.sh create mode 100755 tools/test/stress2/misc/thr.sh create mode 100755 tools/test/stress2/misc/thr2.sh create mode 100755 tools/test/stress2/misc/thr3.sh create mode 100755 tools/test/stress2/misc/timeout.sh create mode 100755 tools/test/stress2/misc/tmpfs.sh create mode 100755 tools/test/stress2/misc/tmpfs10.sh create mode 100755 tools/test/stress2/misc/tmpfs11.sh create mode 100755 tools/test/stress2/misc/tmpfs12.sh create mode 100755 tools/test/stress2/misc/tmpfs13.sh create mode 100755 tools/test/stress2/misc/tmpfs14.sh create mode 100755 tools/test/stress2/misc/tmpfs15.sh create mode 100755 tools/test/stress2/misc/tmpfs16.sh create mode 100755 tools/test/stress2/misc/tmpfs17.sh create mode 100755 tools/test/stress2/misc/tmpfs18.sh create mode 100755 tools/test/stress2/misc/tmpfs19.sh create mode 100755 tools/test/stress2/misc/tmpfs2.sh create mode 100755 tools/test/stress2/misc/tmpfs20.sh create mode 100755 tools/test/stress2/misc/tmpfs21.sh create mode 100755 tools/test/stress2/misc/tmpfs22.sh create mode 100755 tools/test/stress2/misc/tmpfs23.sh create mode 100755 tools/test/stress2/misc/tmpfs3.sh create mode 100755 tools/test/stress2/misc/tmpfs4.sh create mode 100755 tools/test/stress2/misc/tmpfs5.sh create mode 100755 tools/test/stress2/misc/tmpfs6.sh create mode 100755 tools/test/stress2/misc/tmpfs7.sh create mode 100755 tools/test/stress2/misc/tmpfs8.sh create mode 100755 tools/test/stress2/misc/tmpfs9.sh create mode 100755 tools/test/stress2/misc/trim.sh create mode 100755 tools/test/stress2/misc/trim2.sh create mode 100755 tools/test/stress2/misc/trim3.sh create mode 100755 tools/test/stress2/misc/trim4.sh create mode 100755 tools/test/stress2/misc/trim5.sh create mode 100755 tools/test/stress2/misc/trim6.sh create mode 100755 tools/test/stress2/misc/trim7.sh create mode 100755 tools/test/stress2/misc/trim8.sh create mode 100755 tools/test/stress2/misc/truncate.sh create mode 100755 tools/test/stress2/misc/truncate2.sh create mode 100755 tools/test/stress2/misc/truncate3.sh create mode 100755 tools/test/stress2/misc/truncate4.sh create mode 100755 tools/test/stress2/misc/truncate5.sh create mode 100755 tools/test/stress2/misc/truncate6.sh create mode 100755 tools/test/stress2/misc/truncate7.sh create mode 100755 tools/test/stress2/misc/truncate8.sh create mode 100755 tools/test/stress2/misc/truncate9.sh create mode 100755 tools/test/stress2/misc/truss.sh create mode 100755 tools/test/stress2/misc/truss3.sh create mode 100755 tools/test/stress2/misc/tvnlru.sh create mode 100755 tools/test/stress2/misc/udp.sh create mode 100755 tools/test/stress2/misc/udp2.sh create mode 100755 tools/test/stress2/misc/ufsbench.sh create mode 100755 tools/test/stress2/misc/ufssuspend.sh create mode 100755 tools/test/stress2/misc/uma_zalloc_arg.sh create mode 100755 tools/test/stress2/misc/umount.sh create mode 100755 tools/test/stress2/misc/umount2.sh create mode 100755 tools/test/stress2/misc/umount3.sh create mode 100755 tools/test/stress2/misc/umount4.sh create mode 100755 tools/test/stress2/misc/umountf.sh create mode 100755 tools/test/stress2/misc/umountf10.sh create mode 100755 tools/test/stress2/misc/umountf11.sh create mode 100755 tools/test/stress2/misc/umountf12.sh create mode 100755 tools/test/stress2/misc/umountf2.sh create mode 100755 tools/test/stress2/misc/umountf3.sh create mode 100755 tools/test/stress2/misc/umountf4.sh create mode 100755 tools/test/stress2/misc/umountf5.sh create mode 100755 tools/test/stress2/misc/umountf6.sh create mode 100755 tools/test/stress2/misc/umountf7.sh create mode 100755 tools/test/stress2/misc/umountf8.sh create mode 100755 tools/test/stress2/misc/umountf9.sh create mode 100755 tools/test/stress2/misc/umtx_suspend.sh create mode 100755 tools/test/stress2/misc/union.sh create mode 100755 tools/test/stress2/misc/unionfs.sh create mode 100755 tools/test/stress2/misc/unionfs2.sh create mode 100755 tools/test/stress2/misc/unionfs3.sh create mode 100755 tools/test/stress2/misc/unix_socket.sh create mode 100755 tools/test/stress2/misc/unix_socket_detach.sh create mode 100755 tools/test/stress2/misc/unix_socket_detach2.sh create mode 100755 tools/test/stress2/misc/unlink.sh create mode 100755 tools/test/stress2/misc/vfork.sh create mode 100755 tools/test/stress2/misc/vm_fault_dontneed.sh create mode 100755 tools/test/stress2/misc/vm_map.sh create mode 100755 tools/test/stress2/misc/vm_reserv_populate.sh create mode 100755 tools/test/stress2/misc/vmio.sh create mode 100755 tools/test/stress2/misc/vmstat.sh create mode 100755 tools/test/stress2/misc/vmstat2.sh create mode 100755 tools/test/stress2/misc/vmtotal.sh create mode 100755 tools/test/stress2/misc/vnodes.sh create mode 100755 tools/test/stress2/misc/vunref.sh create mode 100755 tools/test/stress2/misc/vunref2.sh create mode 100755 tools/test/stress2/misc/watchman.sh create mode 100755 tools/test/stress2/misc/wire_no_page.sh create mode 100755 tools/test/stress2/misc/write.sh create mode 100755 tools/test/stress2/misc/zfs.sh create mode 100755 tools/test/stress2/misc/zfs10.sh create mode 100755 tools/test/stress2/misc/zfs11.sh create mode 100755 tools/test/stress2/misc/zfs2.sh create mode 100755 tools/test/stress2/misc/zfs3.sh create mode 100755 tools/test/stress2/misc/zfs4.sh create mode 100755 tools/test/stress2/misc/zfs5.sh create mode 100755 tools/test/stress2/misc/zfs6.sh create mode 100755 tools/test/stress2/misc/zfs7.sh create mode 100755 tools/test/stress2/misc/zfs8.sh create mode 100755 tools/test/stress2/misc/zfs9.sh create mode 100755 tools/test/stress2/misc/zz-combo01.sh create mode 100755 tools/test/stress2/misc/zz-combo02.sh create mode 100755 tools/test/stress2/misc/zz-combo03.sh create mode 100755 tools/test/stress2/misc/zz-combo04.sh create mode 100755 tools/test/stress2/misc/zzbuildworld.sh create mode 100644 tools/test/stress2/mkdir.cfg create mode 100644 tools/test/stress2/mkfifo.cfg create mode 100644 tools/test/stress2/norw.cfg create mode 100644 tools/test/stress2/noswap.cfg create mode 100644 tools/test/stress2/pty.cfg create mode 100755 tools/test/stress2/run.sh create mode 100644 tools/test/stress2/rw.cfg create mode 100644 tools/test/stress2/syscall.cfg create mode 100644 tools/test/stress2/sysctl.cfg create mode 100644 tools/test/stress2/testcases/Makefile create mode 100644 tools/test/stress2/testcases/Makefile.inc create mode 100644 tools/test/stress2/testcases/README create mode 100644 tools/test/stress2/testcases/badcode/Makefile create mode 100644 tools/test/stress2/testcases/badcode/badcode.c create mode 100644 tools/test/stress2/testcases/creat/Makefile create mode 100644 tools/test/stress2/testcases/creat/creat.c create mode 100644 tools/test/stress2/testcases/dirnprename/Makefile create mode 100644 tools/test/stress2/testcases/dirnprename/dirnprename.c create mode 100644 tools/test/stress2/testcases/dirrename/Makefile create mode 100644 tools/test/stress2/testcases/dirrename/dirrename.c create mode 100644 tools/test/stress2/testcases/fts/Makefile create mode 100644 tools/test/stress2/testcases/fts/fts.c create mode 100644 tools/test/stress2/testcases/link/Makefile create mode 100644 tools/test/stress2/testcases/link/link.c create mode 100644 tools/test/stress2/testcases/lockf/Makefile create mode 100644 tools/test/stress2/testcases/lockf/lockf.c create mode 100644 tools/test/stress2/testcases/lockf2/Makefile create mode 100644 tools/test/stress2/testcases/lockf2/lockf2.c create mode 100644 tools/test/stress2/testcases/mkdir/Makefile create mode 100644 tools/test/stress2/testcases/mkdir/mkdir.c create mode 100644 tools/test/stress2/testcases/mkfifo/Makefile create mode 100644 tools/test/stress2/testcases/mkfifo/mkfifo.c create mode 100644 tools/test/stress2/testcases/mmap/Makefile create mode 100644 tools/test/stress2/testcases/mmap/mmap.c create mode 100644 tools/test/stress2/testcases/openat/Makefile create mode 100644 tools/test/stress2/testcases/openat/doat.c create mode 100644 tools/test/stress2/testcases/openat/openat.c create mode 100644 tools/test/stress2/testcases/pty/Makefile create mode 100644 tools/test/stress2/testcases/pty/pty.c create mode 100644 tools/test/stress2/testcases/rename/Makefile create mode 100644 tools/test/stress2/testcases/rename/rename.c create mode 100644 tools/test/stress2/testcases/run/Makefile create mode 100644 tools/test/stress2/testcases/run/run.c create mode 100644 tools/test/stress2/testcases/rw/Makefile create mode 100644 tools/test/stress2/testcases/rw/rw.c create mode 100644 tools/test/stress2/testcases/shm/Makefile create mode 100644 tools/test/stress2/testcases/shm/shm.c create mode 100644 tools/test/stress2/testcases/socket/Makefile create mode 100644 tools/test/stress2/testcases/socket/socket.c create mode 100644 tools/test/stress2/testcases/swap/Makefile create mode 100644 tools/test/stress2/testcases/swap/swap.c create mode 100644 tools/test/stress2/testcases/symlink/Makefile create mode 100644 tools/test/stress2/testcases/symlink/symlink.c create mode 100644 tools/test/stress2/testcases/sysctl/Makefile create mode 100644 tools/test/stress2/testcases/sysctl/sysctl.c create mode 100644 tools/test/stress2/testcases/tcp/Makefile create mode 100644 tools/test/stress2/testcases/tcp/tcp.c create mode 100644 tools/test/stress2/testcases/thr1/Makefile create mode 100644 tools/test/stress2/testcases/thr1/thr1.c create mode 100644 tools/test/stress2/testcases/thr2/Makefile create mode 100644 tools/test/stress2/testcases/thr2/thr2.c create mode 100644 tools/test/stress2/testcases/udp/Makefile create mode 100644 tools/test/stress2/testcases/udp/udp.c create mode 100644 tools/test/stress2/tools/bench.c create mode 100644 tools/test/stress2/tools/calc_mem_use.pl create mode 100755 tools/test/stress2/tools/df.sh create mode 100755 tools/test/stress2/tools/fail.sh create mode 100755 tools/test/stress2/tools/fast.sh create mode 100644 tools/test/stress2/tools/flip.c create mode 100755 tools/test/stress2/tools/freeze.sh create mode 100755 tools/test/stress2/tools/freeze2.sh create mode 100644 tools/test/stress2/tools/fstool.c create mode 100755 tools/test/stress2/tools/iwatch.sh create mode 100755 tools/test/stress2/tools/killall.sh create mode 100755 tools/test/stress2/tools/kldload.sh create mode 100755 tools/test/stress2/tools/leaks.sh create mode 100755 tools/test/stress2/tools/leaks2.sh create mode 100755 tools/test/stress2/tools/maxvnodes.sh create mode 100755 tools/test/stress2/tools/ministat.sh create mode 100755 tools/test/stress2/tools/monitor.sh create mode 100755 tools/test/stress2/tools/ps.sh create mode 100755 tools/test/stress2/tools/ptsleak.sh create mode 100755 tools/test/stress2/tools/ptyleak.sh create mode 100755 tools/test/stress2/tools/rwatch.sh create mode 100755 tools/test/stress2/tools/setup.sh create mode 100755 tools/test/stress2/tools/shuffle create mode 100755 tools/test/stress2/tools/splitall.sh create mode 100644 tools/test/stress2/tools/swap.c create mode 100755 tools/test/stress2/tools/uleak.sh create mode 100755 tools/test/stress2/tools/vmstat.sh create mode 100644 tools/test/stress2/udp.cfg create mode 100644 tools/test/stress2/vfs.cfg diff --git a/tools/test/README b/tools/test/README index 2bafa48a9764..5512fd5203ba 100644 --- a/tools/test/README +++ b/tools/test/README @@ -21,5 +21,6 @@ ppsapi Test 1 Pulse Per Second (1PPS) input for time control. pthread_vfork Check that vfork and pthreads work together. ptrace Verify that ptrace works with syscalls, vfork etc. sort Tests for the sort command, including a full regression. +stress2 Kernel stress tool. testfloat Programs to test floating-point implementations upsdl Test of mmap functionality. diff --git a/tools/test/stress2/Makefile b/tools/test/stress2/Makefile new file mode 100644 index 000000000000..ce98559377b9 --- /dev/null +++ b/tools/test/stress2/Makefile @@ -0,0 +1,11 @@ +SUBDIR= lib testcases +MK_AUTO_OBJ= no + +.include + +all: setup + +setup: + @cd ${.CURDIR}; ./tools/setup.sh +test: + cd ${.CURDIR}/misc; pwd; ./all.sh -onc diff --git a/tools/test/stress2/README b/tools/test/stress2/README new file mode 100644 index 000000000000..ddc8db817ce2 --- /dev/null +++ b/tools/test/stress2/README @@ -0,0 +1,20 @@ +stress2 is a tool for finding problems in the kernel. + +It is composed of a large number of regression tests, tests that +stress various components of the kernel and a few validation tests. +There are currently some 700 different tests. + +The key idea behind stress2 is to randomize as much as possible in +a test, as a way of achieving better coverage. For example, varying +VM pressure, varying numbers of threads, varying delays, etc. +stress2 has found a large number of problems: +https://people.freebsd.org/~pho/stress/log/ + +To run the full test suite type "make test" in the stress2 directory. + +To run a subset of tests, go to the stress2/misc directory. + To run for example all tmpfs tests, type ./all.sh -o $(grep -l tmpfs *.sh) + To run fdatasync.sh for one hour, type ./all.sh -m 60 fdatasync.sh" + To run dup2.sh three times, type ./all.sh -l 3 dup2.sh + +Peter Holm diff --git a/tools/test/stress2/all.cfg b/tools/test/stress2/all.cfg new file mode 100644 index 000000000000..562ed767a110 --- /dev/null +++ b/tools/test/stress2/all.cfg @@ -0,0 +1,8 @@ +# Stress Test Suite Configuration: run all test programs + +# Default values +. ./default.cfg + +export TESTPROGS="" +export swapHOG=1 +export swapLOAD=100 diff --git a/tools/test/stress2/creat.cfg b/tools/test/stress2/creat.cfg new file mode 100644 index 000000000000..dc5931564ffd --- /dev/null +++ b/tools/test/stress2/creat.cfg @@ -0,0 +1,8 @@ +# Stress Test Suite Configuration + +# Default values +. ./default.cfg + +export TESTPROGS="testcases/creat/creat" +export creatNODELAY=1 +export creatLOAD=100 diff --git a/tools/test/stress2/ddb.conf b/tools/test/stress2/ddb.conf new file mode 100644 index 000000000000..d0805f5640b8 --- /dev/null +++ b/tools/test/stress2/ddb.conf @@ -0,0 +1,6 @@ +# ddb commands used for stress2 crash reports +# + +script pho1=bt; show allpcpu; show alllocks; show lockedvnods; show allchains; show mount; show bufqueues; show page; show pageq +script pho=set $lines 20000; run pho1; show freepages; acttrace; ps; allt; dump + diff --git a/tools/test/stress2/default.cfg b/tools/test/stress2/default.cfg new file mode 100644 index 000000000000..43b89dc7e160 --- /dev/null +++ b/tools/test/stress2/default.cfg @@ -0,0 +1,122 @@ +# Stress Test Suite Configuration. + +# Changes should be added to a `hostname` file in this directory. +# As a minimum you must updated "testuser". + +export SHELL=/bin/sh +: ${allconfig:=/tmp/stress2.d/`hostname`} +[ -f "$allconfig" ] && . $allconfig # Source in local configuration + +# Default values +export RUNDIR=${RUNDIR:-/tmp/stressX} +export RUNTIME=${RUNTIME:-2m} +export VERBOSE=${VERBOSE:-1} +export LOAD=${LOAD:-20} + +# The INCARNATIONS variable may be set to match the number of CPUs and +# the amount of RAM in the test box. +export INCARNATIONS=${INCARNATIONS:-20} + +export BLASTHOST=${BLASTHOST:-192.168.1.1} # host with udp discard enabled in inetd.conf +#export nfs_export=somehost:mount # Used by the NFS tests + +# Run all test cases: +export runRUNTIME=${runRUNTIME:-3d} # Run tests for three days +export runINCARNATIONS=1 +export runLOAD=100 + +export swapINCARNATIONS=${swapINCARNATIONS:-$((2 * INCARNATIONS))} +export swapLOAD=${swapLOAD:-80} + +export syscallKILL=1 +export swapKILL=1 # May takes a long time to stop + +export rwLOAD=${rwLOAD:-70} +export mkdirLOAD=${mkdirLOAD:-80} +export creatLOAD=${creatLOAD:-80} + +export symlinkLOAD=${symlinkLOAD:-20} + +export tcpKILL=1 +export shmINCARNATIONS=${shmINCARNATIONS:-5} + +[ -z "$TESTPROGS" ] && export TESTPROGS=" +testcases/rw/rw +testcases/swap/swap +testcases/creat/creat +testcases/mkdir/mkdir +testcases/thr1/thr1 +testcases/udp/udp +testcases/tcp/tcp +" + +# +# Defaults for ./misc tests +# + +export diskimage=${diskimage:-/tmp/diskimage} # Location of 1G disk image +export mntpoint=${mntpoint:-/mnt} # Disk image mount point +export testuser=${testuser:-TBD} # Name of non root test user +export mdstart=${mdstart:-10} # Start of free md units +export part=${part:-a} # Partition to use on a md FS +export newfs_flags=${newfs_flags:-"-U"} # Default file system flags +export stress2origin=${stress2origin:-`pwd`} +export stress2tools=`dirname $stress2origin`/tools + +# fsck wrapper +checkfs () { + local s + + fsck -t ufs -fy $1 > /tmp/fsck.log 2>&1 + if grep -v "IS CLEAN" /tmp/fsck.log | \ + LANG=C egrep -q "[A-Z][A-Z]"; then + echo "fsck -t ufs -fy $1" + cat /tmp/fsck.log + s=1 + else + rm -f /tmp/fsck.log + s=0 + fi + return $s +} + +# Support for pre-build binaries for stress2/misc tests +# Build modes: +# 1 Build and copy binary to $STRESS2BIN +# 2 Do not compile; use binary from $STRESS2BIN + +# Examples: +# BMODE=1 ./all.sh -on `grep -lw mycc *.sh` +# BMODE=2 STRESS2BIN=/home/pho/stress2/bin.i386.r276368 ./all.sh + +CC=${CC:-cc} +top=`dirname $(pwd)` # cwd for the all.sh script +STRESS2BIN=${STRESS2BIN:-$top/bin} +mycc () { # "-o" must be first argument + local file + + [ "$1" = "-o" ] && file=`basename $2` + if [ "$BMODE" = "1" ]; then + $CC $@ || return + [ -z "$file" ] && return # "-c" + [ -d $STRESS2BIN ] || mkdir $STRESS2BIN + [ -x $STRESS2BIN/$file ] && + echo "Overwriting $STRESS2BIN/$file" + echo "cp $2 $STRESS2BIN" + cp $2 $STRESS2BIN + exit 0 # Build but do not run the test + elif [ "$BMODE" = "2" ]; then + [ -z "$file" ] && return + if [ ! -x $STRESS2BIN/$file ]; then + echo "$STRESS2BIN/$file not found" + exit 1 + fi + echo "Using binary $STRESS2BIN/$file" + cp $STRESS2BIN/$file /tmp + else + $CC $@ # default "build and run" mode + fi +} + +id $testuser > /dev/null 2>&1 || + { echo "Non-root \$testuser \"$testuser\" not found."; exit 1; } diff --git a/tools/test/stress2/df.cfg b/tools/test/stress2/df.cfg new file mode 100644 index 000000000000..933f52aa5896 --- /dev/null +++ b/tools/test/stress2/df.cfg @@ -0,0 +1,8 @@ +# Stress Test Suite Configuration + +# Default values +. ./default.cfg + +# Only run these two test programs for VFS tests + +export TESTPROGS="testcases/creat/creat testcases/rw/rw" diff --git a/tools/test/stress2/disk.cfg b/tools/test/stress2/disk.cfg new file mode 100644 index 000000000000..557dcc913202 --- /dev/null +++ b/tools/test/stress2/disk.cfg @@ -0,0 +1,8 @@ +# Stress Test Suite Configuration + +# Default values +. ./default.cfg + +export TESTPROGS="testcases/rw/rw testcases/creat/creat testcases/mkdir/mkdir" +export rwNODELAY=1 +export rwLOAD=100 diff --git a/tools/test/stress2/doc/README b/tools/test/stress2/doc/README new file mode 100644 index 000000000000..cd932e4da01f --- /dev/null +++ b/tools/test/stress2/doc/README @@ -0,0 +1,3 @@ +stress.pdf An old (and out of date) document describing the first + generation of the test suite. +linuxforum06.pdf The slides from a presentation at Linux Forum 2006 diff --git a/tools/test/stress2/doc/linuxforum06.pdf b/tools/test/stress2/doc/linuxforum06.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ab9d685b36c383fe63baf10362a76b8c7a42fe99 GIT binary patch literal 523790 zcmeFYcT`i|_9z+!M0!VhP(YC0J48g92uPP26%YXd>7hnJdhgPugOo_`gx(RPMSAZ7 z2{k|nFW))8bML!%j5}T%D<7Dgpfn5xDPLGV3ot<4s)$XIajVtc^<6C!|=QdW();46s zii%{!Ztku&Zym{qA(_bu^Dpp3C_|3$yhCqIg-74I20nT{AD9|U0DM};ZcruF-ahFh zX|`x!N}qz%+RA{|{6?p&kuWuw%Jlp-2pr2sTnl77A%7cFjA6ARRJenOc>}?B7D?Va z;3@A|iXgVg7h7ogmTK(kE=igtdEV}Dl4emT$LH&f3|&}~JP7cvFiyL0bE$NUeQDtN zv@%beoj1B?E6`6Vq(4(FxAAY-JCES~)98}YJqN4GWd=fbux_&;;@zJ8bH_%uqRL@y zkLTjwZIoQ5q_FGuVM^S#Rh1Q&Icd?>(aM>UOgG!Eav3oyWEm73j^pJUHa#cW#Ba_U zIru>?ty7>npQ;ZwPS*b+2JY}*v?L?`hlKw+WM>zZkR~Jk?<3;>8Tp6c2Hu}+*o9u} zytB8la{o8Q^*!FX|Ld%V<6B!CvH#(Mv7I%JEt0~*|L&^W*x7z?XO|NBul_STcehtI zuFB4ipPZd+oZQ)Q6aI6Xvhzo0SN%_Kt#ETZxAC;Ive8p}_V1zp@b$T}!GE~=&mI4@ z03;-3WF-GbKHvViT>((OP}NWc+_?h)+`+v7xAOpH0N&lZ|GaSxANMA>Pe6c=Pe4pa zc<(+bF)1ktF$oD7IW;92ITbkx2_-!x6%8#N9UUpf0|t6p25MS5+JAoJ4j%3vd;%f@ z0wP*65;EHV$L+QQKz09a-`&@EcOC)mQr*F$x^vqD0OFpL;Lg7q;J@0PySQh(M|huz zm;`r09VOuI9X!0d_;~+3HSTJE+&BQAih%l|h|)b8-M55~TxdnV#OL1UcvjU(r}rDl zDfZ4akcgQ60Rtlw*JEy;C%obkl2Xz#vdYg@RMpfqUg#Sb8X3PfF}1R`d2jo{&fd-4 z!_y1m?GyAhI3zSIJR%`6DLEzeTUvTvenDYTaY^Zq>YCcR`i91)=C1CZ-oE~U!J&!C zsp%QSpV_(9we^k7t?ixNJ=F2Z>Dl=O`ts@@yzT(-{*4yy^WTX5Pk2$`@VbkSkB3kA z4_=5T+^2mOpIg;Q#381KqCLXEObIIubsp?=TK~ zgF?eu;HNpT*&da5eFK$w@1&m~D^x@uv0;3mbq#{Vp0gsvDS&=tsF>1~EJD*Mea)$l z**n9IcKn(B57kK7`1!1*-xaFLqK>f4H|6jTM_>Q`#JoViE%sBLuo_G>MN0IidX^A^ zs|SPl*czV(rH4l4(y@7$oH%+pMqafU2fS`@JSe@WqdRd9gs{B%e+x@=seHS!9vSp`kBH1pao{&<#)(Uu!>=Uw2`EeXY9% zpn0YGVay{FXi!Hx6EYy-I!dSfvcVYNc5~a6Jm++baOQ_d(qdkv`NJnID&{xVdGLqs zM`)g$1LeF0f!^tcKo7LqQjLQQ2fqRyUlGN+W%0@pny<2>ncx052ZzS6YZ!Fa-rHJ6a;m&JU8i%ix0c+}E-xus3SaMIf%Y7qf)|_%r z!%pesg-wrR$@=|_Y;FM5nT@i%i!7HV7er+FwE z-U0%DLOftlD;TA@YGF)H$)82md}%hHJ{|0Hn8_ptblyhaWsxt0@7T|3z;p~lKWVR= zOa1$6i78}#uo0!$R`db2a;$02hm}`#n5hM_?FJ4lA$aI{W+Y@fI{@T$Czp#aIrCr8 z**G+rA)EF#fA&1lHkdwez;cVMQ+&Omh$`o-Le$EUy`SzE2G11?UkY=a!ic8eZ^tM; z_+;$CDg2bybb_y1Kp9(TTfGDxO)GS+48yrOIp5#=5?ZoIvT7lP=oeQut-DF=w}57c z?p)$2iOy*|Zw18zINn5=tcQD#KK#dxm!ig`pU$SzSt= zeswriU?O&s#_S4;p*;uU4>~%c5?8q+u&k}oRcCSr7Row=RVT)FGN-Tl_rcH2(Jm}j zfNQGPbD>`!HHGJ;5Trb2;C=cqG?y^q{E6-BJtpJ8^y{3<07CrZzg!k}gS|KVm|Fmi z=Bn*MB+_bK%&d1+C(K7;^Q`}>O?C@fy_h)3_Oitsd$$=Fy$r+<^fmY0`p6aGxm&jYo0(*18?90gNB1+()5BZ9N-c;iw@I`YdEMu_v-DPFiiyu- zK`bixL?pY_=?AzLjG-IudIh=LHMUZ1?tqm*JbJ>CIup%g$C&_^mAV?NxiECiBI5L` zK&kbB8O+c$-L4h`fp!~;T6IkWa8Y(8dn*Z`sdW*L3vg^c@a@O%Si0mj3!kyBX0DmyfK7plNtZd%5g!8Gg~ZQ_P11}K z75vWvYjqmDJy_@-I6i8CmWg5X*Bqs~n5>rV-7ZDQ=?t8_nXgM)t+7u%ILRHNt3rF0 zY4qgs#j$kAjUabBCv;njauoG)$5-nZ8T?P{q)*T^T@5(aOBkZOBJvmC72E>e+r@}6 zRR&z@Py34v$0v5&X^W2A=1k1i;Fc+tw<@`G&fR=_yqEUXzwP~y?dK~mx_(HgPBZdXAtAGdORIG zqT-F1i3K^}B+9IQa3Pu5H?ECuV-aXlKmGS@OHE_U;fxJ=!gJShiU9AkmCs7}l=s<9 zTk1j%m(&ZRxf{|vTlILXU3P{b9Dfk0fqnd%=WY`pPHV8F`Oiom1ZM3H8yt<)&0CJ; zH(l$m3Nh?hDvUdNz{&RMWzS>XrIh`P&H0f73TYa^Q2SX}mouTx8axooo(M*pthL+% z2J%T2~Z$ROEB*vuxDCg4hCf>dg81-9hV?VkCZ_s?M}??zTUis<0gL z|7~WbTI1&C@>u$nhQ;@dWIT>XE#RPAK)qLwx}q@J7bmKy1Wq+aX?hZFVuoM+cHI0r zznCDIAI{9B?J|k}GDb?+xh{+@eP=%%-BRdps+p%aNunjsV(%(NV7=+=A@v)+pSuIE zpJ`o^L~kRRS22$5R6j=7%;Wvg2#gKLV8XM9+CG0ubJKkKD zgkl6v&_~}BbV+9Sz<0ya9UGtwOEA0(EMjFS=2M8_nEbJw{(J-W|2GlHdEJI#E@%M=obPzUsDMnq*gB z=r1APJo}!mckqK>{I#;5vd$d$dFsrWI~3GqNgTJ+%JydGSi<1W8Xc5lR79w*58=r|PNK4P)wE|&F5FhR8CwgEaCg{N=R zH(y($oVoGP29);%<1qDwW2wpIby1n?vI8`2@6*y<31PQht_qF8e<(k%YClFSKK9IG*AwxCU*nN5q~K1_6MRbF zKv^tpb762wP4U9(r2;Sdn%tPznaClZSm#%2?4Q-xjWf~2$JO6J&ea3(L}u_Vha;DEL^VfpHqUejXJW5zhrxO>Jk_&jQP_7*_e?3r3I z_Pi<9mg6w{>=z`Xdxq`tWcKi@FScKr7_SEw({!wk(C!kGxuk{6x#jbJqFx$c=`I-A zWErk3e?h4iy%f14MNKx7vyyj*osZ?fv$p35RO(-kl3BD>Z?y#kzDire?=s+e;Uk(j zBV;g$-v^Pt^h{8?2}VMr+;zg(7$*HxR!6m$O~%g{o}V|T*kx*)7#38Y{TypPX> z5t?#**xryp5|;9TQxC=*6+&1=Hx)1ptW$+wQ$vpVDe#)yis$^y=Q*X^8 zHRs z;D${Mozmc=&k8RhFed15oJ@a#zCrys-@MHS?Ao%<5{rNk}D%hr*FoR7MxWFjdw;p5G69-Li~ z8rrEJAc6t5*VUkhSAVbF0w{p-XL8b3foBx&*hC-3-2$qgCEo1aD5Jrs;f`AXLpy8t zdMpVfaN?pnCU~E4nNEkzv+1q#yQ-OwaDGn?bRx-ltOf^qo^%Zxx8b#lieF zX!k0!o(A(8xzZRuq&S?gbASJ&gg4+j;yYSsJ+vDhcEl1uheCw()zj1VQsO%&F|$eH}wIJ(Z%OKZ;BX0&mVNd2%85z>%HH%XFd0w)9y`P$SYm-OkvN?E<}c|_5~p)yODNmY?Bjxzr9^$ z5^S-U=;@3FEJFncp}@;R304ZeTR<@PwE@O24Y)?pw|hz=>P4a@xZ1(EM{2ajDSh#{ zrA-V=)PlOVf>(^4SQ4rpSOM0uL06=nwI?By7;V?QaKOyW2a!|G>|i#=R$Q0rt$1y{w9h65}@%Y2dtg!6~|&(njK?u4+k; zj6_ZlumKqQhT<)1|HV|+J-?=iN}VFhKijDCYl=DF^Lg~s3c_#iUoEk74 zv(7$0(B^XsC_4gspaaeM+$?q1N-urNsN6bhbI|;{$n8Xm9%$gwBjiG1{h&nV{M5;` zo^|XzI(DWF)&WEs+yZ8|`@MAMHPopUDx2t~Fkjr+F%3r8Ss;iX%Fq7{|gEtsi9|) zWNtc%hl_TIC-Q3WrDrM*#wUXgxscG6^YW{lZaDLPHeC}bkiNm0!BzGi&(pVmI}i;R zaU2b6F(1)ZUSz3J-zO9w*;OHrL`lr**(Q1b>o+B1Gr2{PT4Lwb5tmlyzPO9yFihwh zy0-5K!XQ5lj*r+r6iqql!7bor;aDoW^oq6A^`rJeBl6s&5IxcRJ9eZVw7O3T{;$A~ z;QC|0l59v~1=x=tE#u3G5(hOS{0xN8uY}oSdBpw_79$e**4Ia*y`Cn_+eBH&KXfU$uNtnq%lu)<7z+_{78c(rSD0)Y4N6`vBQi z`2{}&B)WG`MRCI8%PApgm{Q zlBn0#tofnBB#+aG7GoCDXZGFQOk_tsxK}<675m;YV>( z*2*E!K@X;o_kRER+i2ltUyd8k=_94hK&X(OYQj-;H+tHACLg9$XW3>$;X4nfGv z{MemkUozFaH?w<^YYC6`rq8&xz=$`uGC39hScJSoM@53EUTayaDa@w6!D#t_LfRif zta`@}f6J>C?hO>j{si|bQsfdtvmkV?Bc9~uXCHY0Tc(NL?}o0V9{koPP(2#ZUQ*D&rIgc8fMMtQ5aZr-MA=+txF1h~g%k~%;;W{f7GEz`t9Fh=K4~GoD&)zqiKT-e;(BfsU z_-lC|T!ee%ur3Tbuli0+x_@}xD_K7tZtBIVH_HqNKHP|DrRu{(L)V~b@9!peEzM5CjF!WXm=LbwFZHJ1 z3Q>gNmG7PWE@n2#6*HddqJzwBd%*V`ELqKjXgVt`_lEQ0AJ)T3_}fk1z^ zQGkAhGQz$NjH;z zR=<`tPo{1)O@fWo86zxw7n42;aloq^nu0HSMft;S0ZV$K6l=mzrtCFP-BUFb>``NE z(1``K>j6R5nq%Y71Wl>2R|9_~bH2}kcn|aaV<_w+==N+H+aaLfo1H7;7pXMXKeJRS z)VX*09Gum1$8`D$E3Eg@{o9M}Bnn3~#i>h;RavO8z6j;A`LIeNphpv3wD1Pv)beh* zh=G+vxiwr2eInjHMq=r1n;+S*;0wjjM4o45oI}tBiqw#XS8-_Oo(8~9YO27oiKR$~ zp3WU>Y5kpfv(J6-Hx8G7Q4PWCDD6m2j*ZsHi~1V8zy$KlE4I*+Jp%urYe{IQk-Wz( z;J&pdn*iFR46-Cd(M?vA3xjwMFX9E3aU$tB-0)=_hlmJ^99B-ED5m&!kqYqPO{^Lh zV{`loNcYS_d;a;vkp%PXb9&FXww{TG=PG(5I^%fYF{uMWRI$lTE!<8s`kl9J{e&R* zwP30($6fx99D^(F3kG62xY!>9Y!WBikh<`|Wd^9NP=u*!;u>ECNzVzy^=gR>Xjbo_ znZ^ZS#dpcp&ERGr%dyAg-eg!Aqi(t-MN_Ehu8yLhj~ur5G!w|x&qWu+UB1mpdmlXE zykVZYQda+6-U=#Kep_tDRZ+lK_sDWte<6G0On$nmmyhZxD_>VkbIp}T7j0fHfpx8h z`@`1iAlSspw%*?xT);CWO60taAnXGednH+3qOx)NQ^+S&I(itOwW&uvNdFds7IcD54(GmIn z7w!!V#%9MNeX?!ruElo3?FnW|OSD{KELr1=po_fyXXRPo^N-oTd;5Yasl=^ixh80B zIO3j%FN6L@oLAgmkPIrUo2#~z$ZF9p7k(bXCDec2GhH*$!ahG;)0?81GE-2lgk^E4-4MbTkkJ z@5-qa>TZ+k3!s2szfbj)Y;}?xb>z854#B(jbjG77)!7ki7cufw#pok72jpHZ4 z>ZpT1?{mzi(;5bcZL+ok0;&ZAlFu7L->mX&QT&@$tU?j%Z%5+F|Tyh*b>BMvt z#RGG{v0r=$zqc;f>Q?36$#s7d3bz4yTeqH86j&Zz4VBWBznQxbVm3d}aP>7FyP9fu z%6)h$UA|#Q-K;J9BGB+c+PMQUz6=04!6TPz7JJJTfhdbU*!Sn%&`^&VDf(XNq5j4# z#e1T`0U_;fc{LIsoF#8FhJFI=rkG=O6puDq^&?u>5DwLtet(xaoLssga}~^;S3h&E z;IKc3HO8O+Y(n@A(7}1En0!@;i@J5+w6^NNAT26rvGwb!vbn{%W;E2S>75{LUqPfd z!!4kkKsT`J@{2{&8&v?v;6q*nfaiY!d}|;ykIq4b7t(c3D0rEC;{?mIKTf)+s${`7 zTa)%W8$Vc?ZjAVQ(~6+~I?g34sCAyTU0EtySJ0w9#z6CSO&v69mll7@ah%Nwn}qHB zSVV#2WChx*D)wa&QGOOu^R13+nnAul%$wt^7L)~=gDwn(n=E^u-2#S1vgM5)OWXU6 z1%yr^x0KDoM25+9)GKTRf8PS6sx2^yG@b1f^~mHPCE8doFZpbb#nagnr$Pmb@NGtc zTDH$QYwx+si66!?_Pg5iy}n%XAy2E+T$^cfD}=nzv`~CvJMCd&tX&g9sac!g@|jSk z&*doMa)h5dtn`4p%=YxXBbX$9^A=#--Jg=h^A}z*zj)@XzY9Y@PVJmk6!Ei}!3ynr zR)B&ryhp_lyZ3}c31^?F7uY$->If}+5zQ`FIhMB9l74J;Xdv0= zb)ye-W*lz;+bOyBiLi~82&53(Eud2dZVLEA=HNF}6D zghy7vSKmZu`)c1Pxj2f(u{wYn3WU9XR=9UOyNG69%L#M$jg~*GszVW8`AKdE)l2F{ zGjNh3mzBY?kjV3oH~D^e-jCBtFdU62&AxdW1LVP9S2J_+kp~2+%b(1Bh|kEZuq1rz zzOyE^6koRZToqMY+p}H$e+?KIOGshpZUO6&W8VU(cfucBu>HEsI5{CauC#BoH=Ho! zfbI`m9Jelu4Q@Vp!z=CPTsV1 zS%E<2e5c{e7||%{KE8?jm3ZehH$UVZuU~8Cf+4Z1ZN;H=6_nL;dvh-zXh=`C@!pfpRJVYZuN)_Wpk!kpZR^|h z0tYAw+N0uK+_%xwgEpE5(r0-&RxN*wlUZ6Qmwqgj-#mh`Y`DZ8+BYZos){5pFC}2K zfBbrlF}v3B6Z_46cf;-~%GfQKxjxw={tMgieQsRbho`x&W{Q2*%Yk6TI)PpVKR^xR za58-EG+BrySo2rw@!1a9MtPRH+)+OguTUbbA6gi|7rQ?a)8oJS&LxhJGpE!&XYLlT z+7t3iz-iqO>EAp4@F9vmRibL(EDjI2-rO!1A&PPInQAY4p%*MYhnlWmT#7UZ&?5CI z3xh?BJgCVs0jFq`ah4~~Y3#%@-uw`kvk*IvL0XsEv1Vna6U>>F6Vs8FZC$4I--x*^ zPyF2f4R=t$Epw@_ej@9OB(Epye4WYdd7ZWh#}((4X1 zz!Y4?>Mr;iSA0&|vpMC`6<^D=IPxvJzR(gojUg&~!S^5}$aq`-OfLc)6sgkU-W98_ z(mNvgsr5qienqZ6=RZ~u<9o%9yHMhI;r#f|1m4hIGSmHDslgS0x*+p~1Apxe_u9{t zpP+M2(x)BU-u)AA*i+#G)Z%OAZuwe29MWActms-2XNC509t(cL4w~b@%Ucw@q~jyq zheug_!lSds2mjIhK8HN9c-~~bIF+E)fm+Zl_!VFq4sbIn8-nT2O($K~{5|%gIDZdT zzPGsWDDiCnxb3h048rv}Hm~V2RN}V-#|;~>&~4HKw!_Adkz%3I-hXV&H2Lb62(iLI znf|#m>IUB7JeTuqM(8l0f7O|m&(1V)13!G3ne!tO5U1MPCO_u0(Wh-sNBElz7u)j$Pd(6_8Smo;$e(2!{Us<3v@) z8{f0e=Q?ViB<_G+@()lWDxURwp8R^*-jtvruhWsg;Kp@`aNB|{n!W)~c-pDFa_VN% z;p2Gx*>F8nr>`!fg5h3+_67t&d`IAzoTx=0Y5WiVCmTnb0jDCVlUkd)U?-MyLqo^I5q0bMvj$*n2%^ zc5<}{ULulk3(!R#L|u^k)P@i&Kxq;!v%q(uodR%20jag4&!@{@=N5$R0tAtLnQ^bZ z!TdhaQ7=l$zh`qPMGwiweuGki+xIz+SN=%>!p3j`z~v~LpJ=jGiur4> zt)EnTK7*DMcyI2(24m4rKw;oDp@ZMZ?v5h!-7A75 z`>uH-VWW_XNZZv*m>%l+G9OlAJzKEx`s|0OZ9KZmk3V@$Q7GpKQ3>hu<2yk}tXblE zCkATzeSTgZ^)jlyOvsjo6G2X=rpIk=YjopOT8VS5{xPr9hg5%4NAQ&J^VOiiYZg}B zSZQQTZk`UO>936Pd7a|s!NBUvh^PJL^tuOw>*?!!vmk2_A$K&~4j#-TpD$vLj+ild zP-zvR5)Z#i6%2r?Yh(p|x>Gg4R=f82i*Zis zTk?|Qsg4Tc^@uOephB=;+qE^cQ?*s#TEb#<6-YK4%jEaM24MH8O7fh)d-GaZXvB=+ z5!Yqd-YZI-Enp;0v%SMkC~|{o{VY%tO9j_y6}1J4A0_v+Js$}TQeO*=s2LHaZ&z4m z-9It#R46Zd+;1z<7DJqoxOXLFT#Z@Q%yICu!^I%GOwBEH^86@~9{mv#fO*x1isz`g z672EQ0yzq=52zR=SdyRHI&Q0jfrB7wESJ6TuHMZ7g_?`Ab4+IfdsTwiRH)*amB#OK zcRumj$%A*b_1f`0-ziGZ6t~k`X4+lr9rR4~jKJa7?fR>gB;-jaPnr|{*2XTQK$z6= z^;(@EHnQKJL9=;RuK=Q!Rf%5hlgHTPITO2cdMf23diuXgwQ;d(J!C-D8?sEsmTln&mLvg$evnROx2jiEwUJ*-)HFrf+6RTb7khQ zRX!DHFsT=p*x(!fIh6X;%{`@$j1tTF)z-||W0P;&Zw0ZhkXw>cV=VC#MgGc*srlgf z6u$H!kE&s-QDSr$3B6`bcP80y&Ivt~{Ti{F{s=l}z7aIO5r1I$V|;~L*4NND8IRIo zHbyYo(2jE~yk|p1`;Z>$vMCC=?pwO^NnWd{8)o+ggSdiF4FoBu0|Wto4XoF<_bnq= z#@KcPgsU8)DPCFC-1~4xM3ZVAS6SeCZ#9|wb6=urv!;o|pI zZ+Rk)>++_Zdtwa&Usj!Cm|$VG>MJ$K#b2ecB97$sdDbGA9$Xf^JA1d|^lco$H8{i= z%QH=5glaps*Xz>=dRaF#|CDI=Pj=9Lt#uuQZc$pPoAUGkvEeTX=51`%;s=xeu02n5 z*(@Hqh+0Z@P;GKLtmSM)omZ`2r~X8~lPJo$c#k6Ju`zHvxlg&080FWGZ<|NS)Er9; zQS9!L6d=p18Rhd%To~%zOuMcT+4Baaoyq)ZXo#4g4Plt!iE}h~dbi{+fR(UL(~|Y0 zW+~8?V3=)rE1)!aL$`ApvS5Bw`S7NwJTFIG?Qi9g7viTbqL6kcbTo0?&HQIjDHp@x zSV4u6_>-aXrEv573OG+tRz6)PdcF4(L|HB2&|H4>SeYC;145JIYM8<*yY(B%I1@zf zsJV?3qjV_dfl;^(x|=lk-3|^)S>XE);*H17yQ*1ykHX}^T_J@DHgSRIidz6V&QTn} zN{-|k%a3j{y*MuA6UxA}T(YWl!9rcp5gw?}2;&1|F)FU)g8Yr=dzA*~+q|+?*{&i7 znw`JwB@CnKXbE)t0KG5jF1bFcynMO%BG&Ed0soNjtR$1PpDdzmpL-dT`uqtCvE5eI zxc=*tQ3LXbC|ms(K6*YA@dK4R`J*L-m&DHYUKLUj^LRr)`lL)9*z9JvzAYf!DFpNR z_8uVZJjE;)+6Uh1jkqL!*^y2Bb7!V?ze|y<9Yq-7)M~Nj0Oqx2GYrX+BnsrGBq1LS zgq*!s@bP&Ih*5PJ6Ax+OU_OLMr&GbChn)6g=f_%3cl`F(IA`Ft@Q5o=B!r$gjonk4Wq3W)?A|dmaD3O36!68%F zG041?YaK?0zIYj_i=2TMK?1uB7gA+y7QCo_o()m+dBPRsb#bQjHriXVL;^}^;Q%L> zNS3!iTj@cdsF`1c)yYM6iWD~$?W8(15b)YkDvIyL*8}V@sv?6Ui4~CMB_}C87-yWU zDb-~#p|=@ezZ|n1KBzAQBTK#kmF474ql*RW18`-nN{YgeIzYm(c5`~yW48oS8-X}j z)oT{4;@LR`M(U^+bl2{J67%9F8>8glQm+!JkNi4ZYDQ0TT*E%7lw&OKc>o4r`?12v zEu1bPV!?8t2nu5(JRF~<Yx#j7>kWfc+it8s$QSvuiuBc>E<~ixXaK+WVsH% z1&lvxo>mHVQ+{eScBVd1I<2%5tK_m!LVl|RTBe3n_8a)|`SS&$@EgfA$g-W+(vB-e zA&5xZ>$AP~CmC}4eez(J6NL{^vm2JeIda#=;gBvr=cAc6=iUp(6B!r{D!NZ9J&$TN zhf46cQUL;!tQ_mVV6G(2ZmJZmO4&mF!3BpB0^0|1E9n(P*H8J{7VWgA{=6)IH?=uj z;aLu6PX(GW6$OiKM(oC7sQ9}2_SbNAj8yk^60Hi&Uh_xEG8PHNRtoIko&C>+0spa* z?r&$yec((tew`Ps+0xYU>YfJo1f0~*8TA-Cr+glQ8tZi^7AltL-dO^M9Y3mxa^zPa ziVjh$=m|wToWilhI;a?M5V+bn;_#!BCE_*0^MjG7>ZhT}?NRpg9zMzYJ1*dFiiF5Z zBs^HWO(1bNWp2^P=4h+l()>Eq6P!nUT*Lb-nM7bIbXOiPSxw{@hf!WDPbD<_H^$?n zs!b2)4wrM!<&{?WB<_N_RNM?APCz9h)f?RgsquW7q((Yn?hejWI|v`gwHhRG5Y}lnFgP>+1~=RzTLy`6&Na0UHTqKoYUjd zIk1+49A4cDUo|6wi4Vt@4!dexzu$CT+z!@jedD26yd!Lt&(Fne#C8U!&|h)Qj9@IX zB?Z>$2Kltt|7~3wNbSs_SRLnVoT_8on8qmkj0$WOdiH79#K)K)e$3X^;7&}?F(>bf z&`!RbHm#`;^lquSLI@2bo8GfYn{(2>fdeJ48WtmHn>z4w>`Q+*$i5HEs8i6M=wJ??kc}XI@=FEF-mU`H;+{>a|CcUGB%qFLJRG)^_>^5q#frmK0 zKgCR#FO6)p_^eQZT%T*KP+n>HDq-!xWH)(uzsub8 z#lWlchi(n0mG8Vzww;$rds5Ws)ULF-_jqDvq)2V=8}(a&*Q1svZ$C8_+Uwa}W()Fx zejUqjr@x9Sy#+`}{%zCOfa%Y~&lnD6UPX9V@61JKHxzf5+BJ~4*$FRHX18^+DzOSX zXmF7}ix2eiMPz`4>a_ zK|N*nvc>kKAD^_mCKAoWwosHh?rz0uS${&_skNyt;*(xkePU8qx=8;*%@IG0!Wd|o&6C~rc}C+C|>(WjEPOT>{Eh42LVleP0&cW3-%QE81z5vR1HM$Dg! z`Q}PL0CMO<_PrQX5=oXu)Zw2E9xh#-@w>Qkrb*>p^VkEjhZck{wLc-a!ml3U%AqaC zR(-8&k-rjYtu{5K4O|dZCBW}=dng4v*@zr15FfU9%a1HL*nFb$k?&+ob~Ua9#{)4k zby^HldU>Qrp#*+FbDsX$F0`pQQ8)eI%a*~rJL%@u6BL`8`xaGd8M1A}Js5A|_mCu!g1&b=gji(7&FcxdrUhmw}NlglHQ= zu!@jyldy(HTz8HJFsg;y)cJUwDuxuj zf^ROA`>M=@({|7SZd4sc+aF>_+X3kGSe$y33Odbtr+f<#*s9kRzEZ!3LNnRK_Ap<+ zYPa9M>BELJD}dI%iUI_6*T;aeD9a_FOvjX0R3_I2o5#z0k9kL*aBM}ZVTm?Zk0=&M zaze9(QQ+>u>EUuF&+n6S3D7p$Gy!y-+O-Hq17#cf1P2-aQ@Y1eLGGs75Rx>ODk`pU)V8@lO|%n zDLR9(ZT{z4F?e2-MqOsdiELmsWgNVI;qSvzca#s3gzdj|O zO(+J)F{IaiQ{8I4=+RpNNi6JBztw=rpjiG;M10Vb@9)(|aZ9XW1sgZ_XXK4#a7rN> z0*gEp2B-gKtQqjLaLEx%M+q_N)PXb4VCE>t{;Oa94&4|>w_}a53Q^tF0MVS$DfLR9 z+Eyi@tdar$eaWA`StM_8`-ar-p{W5`LK7oiCEvL*_C9Q7uom`3Q53~LSnJ?(luW`_ z!9v9|c5}uN+ksd&7pNNiC0yK42Ym`gzFfXPh^rd^Q?t6E4|oiZSl9aq^>hel1);i< z?wry6FAAK1X;7rmEr1qC<)?`jK(72yNX?Oi2gLr))1wT~VC~-qOXhk$onW147}>b6 z8U$rKz;ECl8L@QG&Zmb5*(#I}t8U?W-fJxy;F$joNXeYluhLm=D$1ARO0Jt!Gz5<- zyrEYDh#>&q0-T7`|9l4SzM4we-r|@tP7L*|02&0qzNuvp848XtVCy>em@Kw?vW(Vd zkGOs!>uSDPQ?gcr2gq5R4w&MM7ecOLRVOMQ=uZV#$yG5ASrL*BH4?JTTH~KDD5!kw zUXAqSdBxCY_>>Ap+#c9oCNYvi%o{9qqySC;u?)FJ$h4^$)8e-KgZC-NK5`%~-}Wnk z%1@qPQa>&m`;zo~Ih#ClOlBVOvC|oxH*UJ~5YhSW=5ntk;PJ;d@m))=xhY4oqkXqYmhDP8ojBtqrkh{=-uR@SYI9e z!ZpZK%S?-{El1UQH~poo!dH6FD(_FvS`6J1&$yd7|Ebkbu-{Htnzl7=oy5qzL8K>- zc>c8gU^}?bpH~7%v6?lY_U9`@E_Z^XvSq6^mq{@|M5X%$XT`4uc_wKOmb;~L&To8e zj05@dl8Mn7Lz!l{cxvESdLN2hH-Tro$M99PhRWkP3-Jg~i+brqX7XvV0^|B4M-Qe! z+6dj`KEqB1_6P)OEEtz?$;t&%VpxBmd7pfH1YXM1dh>dnl_xB^@%g1wna*|X3So`Dg9DtwxP-9lT1=u+ScPmm5G7*-w4EN8J-EExD-x!a+kdN*?1zAR`m?qh)m4fUI zrT5h-)}L1FiuF|nE4aN{;(5pbw9?Pab{Q4@aPghB*TX1QL9R0NG4YT5F!OoQELu8V zZ53`y0`E{nq@LOXloa0NOhE)7-;Ff8E1Ws~{F5}$k&8DYz_x#zae4a9?pv(jO_;6! zI%^wm(xP-(0(qUbCvhuc_YXrKkt**1hC?{>M}tgDy*IqCjdE{^xG|X)7dUF*U<-N( z=XwVvK6NJ8Bl-c+S8LRcwIu?91>CM~0lX*BsHKNYIzdivW3*~4g&WM>I&rB@vhT4y zhGUNdP4kF~6qlk(wirLPLUrh;| zw(vy`ml}~kC|eUmR-abxu-TY!X4uAJf46g)`3v?dN5g$T-2y%&QCw~{5mQXZKv(FF zfK}i?tPq4`l?s&_5mcy&$1xHze|MNUmhZL+b%7XLY1UPRKV|xgeSj#rQs>2T0l~KT*wk;pv$-WbTvp z@DG&QVWrBPBGqUns*rHs1HF&V9u?&3?S4_EhXJk@uR!1#^($`z?+-;K+xv`hDu3cH zIEnMYtrW~QTEwOVU9%?CL$jj8h_i4lDJMM`ImUDA+kL~H3vgze4kTD>giRBT$s^i# zEeX)m6$*6~7kxZ=lld}se``q~hXsW7F2RaljekwAkb*_eCGys{(xI;KEuX5jR*4Fu z44t7dOl(mvGJNjoygK88G-w+IW4VbCPg9h@PApSn#h2i7?gyeeXjO4~tDNMgC!Cgl zc<=nux!U?M$NkqT7m{~qjEaqJbzGOT3lp#^*(Z$ynwP%`_-gzo=bj=9+IKZJ#8Do! z>iC$9S?x>O#0+VCQ;bPCXM)C_2CR1VkP+LRxi?ih_Jq&Ty5-EPJ*!^PP4ZWY4a4MD z89jvWGEyN!E!J9j*OVqx)xJGF<1HQ6`a4m+zq2R9R%tT@9THpFTp6LTr-;H1XZsTh zTCMJrQPan2Dd_6;O&^pFgATU3&7l{8=Wt@ly-pGfA2t0aZBf4-&ew(Ua5a(vF`a`R zEW8D$Bb|YZ2N6oyAKt{WPH~Y^3pxAO4+VC_BQ z+5Z23f2yj~R(nKCYg2nmTeXX#q-Kh$Rn%S~TB~M^q9|!=&$Nh5Y*j_=qDJi9#E6i@ z=j3z#zjMy_cFzA?I~U%!gqsT)Z?D($`FK7a_t)tjdCF*Nm zr#^mI!D_{_=`I#p&^MOD?Xi02iRfOMCl9`Byj7nadO7Y<7cowfMQ6Es`{XZ15 zI)EP8iI7y>*!{`E3(}l3JqxR%jBuT7&ma$@{qM9ZsRoL(?iZ3gfmz6uY9|R>w`{I7 zM)sQ&MMqaU>T!~IJ+HMfW;=-GjF;7x;nzYV8QNY^23|SV%w0ie>fC4@wxCBrfIWF5 zCf(3ZIg8B6AY!Y~kz|lNBj@m~>z-x@TO!rP#M-}SLNRzp!VQQazQ~mkv07ubj1Edy zqZOPKLK>0m-ydm^+xeELHNahA#|*~nt2u){zfpb5S2S*whxAPLi>-lgxTo``n5b8= zBd4Tp(QM{I5Q{(GX}vUl_xtMG-}6vICocAN6!NfxCJyC-Na8$Wss2_L=d;Sv(o=6h zrTd9w9UGB9jH!gzKd~Z4lE#LF`p$d$Bu!^rB4^JcR3mvIu;CpAVw&!CjkjfjiLhrK zbr^U&*~_i-)5^-1`-Kp(>-J22oP4*-RdbHL7Uw7a zf73k2p)XBiB(P1m_@<;MO^JKmg;!JgK~EAcU$joGFXHt1oUiIuz7$d!f(eyClvtzt zSJ~O?7SDw)sMJUaT08}D?HK4pUQqW#+Yp3JmbL#KGjJ+CCIv!rx!;MX4;`##~s7n+vu*O?>sj?Qp!Qb8H%J@VG7DP#57 z@^wV*Rf{>kVVU?l{zqBP8MvQ=d`HD^GV~WOkim=(Y9$67xF?BbpLcn*5H5^GCCgp7 zS*x5It*Xw?wI!GyG6ak<7;zg+lqX|Cvn53O^*Cd)iaR&kw6=-4g*UTRwqj@WKhhX5 zA6i*_7d)exX-06mUmNZV10)=9o;4oTq^vj~d?dWKNQ2_b#?#vZs(5E#f-=OR9q;Qe zIf)0G=}tk!!u{r)8KI$WBa3UA>gi*=QPq0{%igNm?LX`;r`J$g?>#m?o0!rnX-G?vC@BMY?xZ4W9 z^Um~>ptW4t+c0xs30{spW2)wgo9q5FA2Aq|oQ~PRjKQSec#7t(n98V!-D{7IpKaH| zLC9DwTfkJ@OS;mQMQ5vL%u%6b9v8n8p1lAuRPMg?`#C}VAj3M9f`156+cTVH56^$8 z_})9c3!>lLf`uiY6wu8w$hT^9iNNHnC|nnKP1nFC?yV7>S!LbsZr2;%3cr;+JsN*l z8i6Yx>wp|%jEsHQAqG>5TMRhQJ1>(nCk!a{XLs4cnJ%`#`pz5dnDc>KGYFr5Q}%PO zIcNt`AU&SeotE23=-q?kcN;5{U)^s$H$Oq#rrAE_n$eh4%L`R41qCoE6>&DI|I#Ox z?^z->AM#6>w01NSR?YpT3xV!Lk9$i?J)I<94igP(dp0GGI2r{WQ_K;8W6k z^Zg>)qRD10lF80AVukm{!bjS}_2y)+=@MR%urziKqs5ogKX z4bE3Gbg!3uh&3A$iIRxMx(<+4bvq3Me^Oaki-1lpJteusz1$`a;cCC{wDczSnfDIn zRcGjVg$G}Qdr6J_thmY|7M!6SYqo0)IbHMN-UD#A>p7!kuJ4?MB`(@sKd6y%axJ`Y zSQh2(T7QEt{7Cj6({(aH>`09ehdiISh9RL}MIWR_PV$Q;Uvbv%0PxFz9=Smc3WmtO z%kTeCd@YNDzE~9V4)_giYIoIeu-{6MaTai=`Kw2FbQ|{D@3k_UrP!i1px~u-eZNDN zln@?;ry+|tSIqfO9G1?JWfK99wE@X85YkV9*K@TO!>3H^z;&l=5`MAyt z$TsLhhodidur!C&;BRPM@7Ilxf+TmNQFf}$OCa|D0Tu5!s+Gf()W-n zB93ednKPlg=mZ?;2W%ip3qVSO07(Uywu6!cFT)G#Z^>Ra-gOaw!3R29F@J!5?WQZx zc&4~cfe@d^Av0pn>ykz+4{q_o|Dh1L+p*RA?R9BeMuSBHYAd}^|!Ji52e637*?ru<-39pW8FYs#N5kl z#WB)R9n%2H?f**Mp*r@wyrGOae1VDYMI@>PXdiR}rWs<6qQ~!Cd6poMBrF{90+D@C z`?=$-dXf(wmuuw)-OG$3PZd(@X7^185z!Z*K~#*E2x+ZRbx|~x+x8j+AdtDAf{uzRfp7e^!@wD*UX)$ZOtzNNc84Z%Z_+b*={5X zUF*!J|&(`O;kg4f8VDVx>7~t9*3e8@EcWouMECnYAWX*9AReVsoJ-uL4NR0 z<;WTiz_esTjogg7x~oexQA8ft}7_^~w~&c|&B?Xp)RxhK0-uY_8uR}EfdDJASGDL+2OA?whd zdq>GK(_ekPJf*-pc)%#1!3T|AxdM0_Qy`>?2z@vafFPGlDNV&n?V_tw6EkIZC)NKdM3GLRG=^yxv;p`>&<4`=(pCYqoj-c2-m+Z?{cJDW& zhYFx|7QY^A{IB5h!Iq zhff+{RZcj4IE2hF%Cbro2<`I?b&n=Zc8yA`p^|uR;D=2oAOJ?Ja*|>dKh2rm)=_Bz z&z}nX&UsTSP#F^?> z5toV7_>76bk}sX*#Qhq%7d+il2S=r?2G?|4JXl$E=j~2BA$k-LCi=j1BJi zv2mvuroO=6AeVDX?ommhU<5xU*Vxii&8pP`dCR1J0p3Yu2y-!LW=BPP`UWEiqY8+P ztlPtVd6dqrEpg?#kl^h4g&P*nI~b{j4`Fc<;GQm4dY3yd=}lX>sMlH@Yx)ZW>-!KH zcCT+RV4uW&VH&4e)Uz3Qk1g^*CvX=@MBuqIrDx7|%%ZLSI{zN1ob4HW3boc*q!d1_ zx~H^0SYlPyMF3=WSDE}AZBShq_cfLXC|$dG`K80=F}@XBe_P~Q?4CBAN!Iou>{h2W zBmbU+P0nysVOCY*0G4%g`kOu8o_lQ*NadQhdp2PG+x3lId}<(78Qx<(IzfcggN1i| zB%5(RSA~(@wZ6KTrCEF0f|W@KfHD0R&E5n(8>e!X``-N&@c6a=_VkHK*&U^^{%_NE zEp7YZGF?neS_zoT8wsFStsfB~e$DFg8v{&;KS2T$bSL$*?6#)gnkK71A?yF4fISn^ zza@M${w3yN1g>(khS2~qTKN=*yrZ>sk_~!$IWoMBRvQq%L|8{k!7Tc(B|nLfc*gV8 znJLVz#F@CwzIZhh$rX%H!Jn;C7KL2dTm-*5J8ayhDI**D2Oj`Z!hkiQeVyz%YkCKo z?b5Bzwgu$^mdSDY(PleL>xdg9? zoVhKjU!KT*^SLM&g+qY~p7rq?im=`=M>&7}u1YabZBKY1 zPZocJQ1?YkUmKd|Z)Ud1Yp9}A0NwMNotd9@g2I$?yp?)g9Iy1!JI~#ukT6LU75=xY zlsF=HbJ$g()#YS3btG@E$_s|OWx+nP2`>8MuyLpSW5iS*(UtTCV)73K2WqAGQmpxC zy1HHHmBMd*)xj(--7!?Y0xAcoP`m%QAk(!r#81Ft^4DwyJ`B+E*C7zy9Jw?231Lpo zXp{uY$9jkP#5^AzT~pkT$sN1 zmygB%J}dH%!_xmzR$N~ahv#f|$oKg>+6tVmJ4iHlMf(05&j2Qsq4)aQ!M;DU_Q=k_ zRnx(mkR0;Nn>d{|CWOrz;4nO28{`yl!OfqU^4K{FZ+3=bH9EbEm!?@266MIB!S^Y# z@zQg4KTcu#!ngV6woxuuanvn1?oUiJ2>fm3*diEtK+6s>{+iP|C8e;vA%u4}5O(~B zB0c8>F{S702p)f zHY4~^xAW-G4&#t zL*)CER@d}ryaXm3lj~kU>ST(99N*)_#YL#irRC-dRP2oH_(PoB+DsS}h?A{Ax=Y!l z{AKzDH>L5+a!;EW9uK`js$98H{@34W080qu3BUMocOiFuy?vVdg>i;XVPg6~6x%ud zY=0yr23HLy??$ng{P;vFrIHnU-OHt;4HzebPqWTl%@{MvT?$PDL~W!(d?q>$QT8ZB zcz$7F+l?8Gn%FXO>YaKcrt&u#)a&e~GF23P`1h<$rW?>Otd{DoVG>aEqKKLAxbA8^(4H#Rm3#FPpA!qGVB?HLPHo%XuEFqK&#|A*kL? zE6hEFzqf5rgy9#RF+vDpO4CJ-0YWbQsYNF4)@Pz=5|O?=~vX?XzeWlqN@ z?hTsb@N{WMB6s>VuKC8-wi{E- zN6*&>A{RZTi{<;DOvhiygCYS20w$^sG_c)t8C>dsS0b1i=2&R#557{p+_%j7H?T#> zk^epG<4^wanarO?)ynEJl{flhq?1`H4EyW{OI!e;5FUD-ZTj}&5UQJmcRGg`2NG?JHp2#A%NiDG zY;_3k<@v3V2_jru&Irk)Q_x_PVky0`I@1w_Z#n9wux~ISJfc$Nrsf zMd0rM-_rC0=Jy5w%q6$>iSn+untp7_{qc^I4tEkJF9_oJvRXJJp5|Gb)rlXe=d>9u%Er;sxa*IHFmuI zNIkN_Xmp^kdLyiYgEX42t`>h!yC{5wx$04Dg=V#{=C>y9ZSfHubXHH@@2+6nS;}?)1 z`8-I4w9(Bht$8dBr6cx`G9gLndy1eSP|1*IG+Gg{XBX*%&&6%v{PN zQFTE{uYLca(6o)aD0j4Hb@%pvp#1GDCuRj5g0LE2TVS1C>#QQ*yN38GNKl9by0f69 zzilJuNox3v5awtK&{KDZykw?c&L|Hj*+yu65A5UN0~1s|HZwa1pIX?$k!Lh4c^iQh zubC!Lf=tAlRk&}+7|D6Bl!5WLTfOK6^1Cnr-ZEpti<=&BQw@?z(DodgiiA~Tx{xGT zd73kZ{d)b$USB;~kv(E!A3NJyCBIr~Cv0e7k{v$0xGm}`+_fcdvA$5Bo)=))1R&nb z@8!W-PDAcgy659v8=F(fE7&dCDr4@3F(+(9*R3PZKBBEw@H7E2?~0yH?3F5eSJdP` zy0BfyG#v-D**GOR%~~`mbAawGcJ)dKv(lJreQEd;S1=}w?H{`<$llqA;6zDTyrZeSg#r$+n*%TEP~@Cvr^QUPC@WjRpO3^=wyrCkP{BBUF$ z$*(rb`v|x{@P=kv!uRG>7g-MjFto5TaJ_60N(TMxi2yXJkk(w2Mkp5OuAx-4~r@|1Z zMV;;ge1(V&s_ZTt)0sgC$P;hPa80Awnj-^`4h1IF-bMhw6TVO3?BvY`tDt!#CREKG zBey1U0m^7lnSm!5AV26%CU0>cIJjahR_Sf{URx)`cqt??pMT3R5eLK6UJ2YJ!I2{l z(;QOTCUpdJ6SW*Jk@MMY##oi3*4eW*KvoaZrq=AUPjJ;PL14ISH|XNyZKKeuNxKY? zTLe3ApN0IcD8H%|+aA5L3+sO<_MXDOnI1SQrxNuz-c&TRJ-*kXX$-`bIm#Rip^@EM zroAn2t$ZXi&5 z;-3mM{2fOantAvV=0E8Pdd8>&ImdcFtHT8MNk}{mYzqI~zD}{0_S*9|glUx>doAf^ z%;qCXo5nu$mx@6aBQ*3)e{A0ruC5n^&mL=4Q$zUvnofKRZT0+VTUhmbGw}VnF~pwy zEsIXLw30p`3ry%kF9eDlD+UKbt!IE6V&s*vqKY&LmWo`=7I{L-ioElvs<}3I%b7I9 zGIkm5Frql3Yk+f&H*21a$q9fsR;LR}tEtda`}@K2qwTNOZ0^h?>n$~Dj}g9ny+as4 zahBG6zKmLN9n+ONOq;h{XDJjDrJ+guePXRxu?ysBpcSMmq3tVLs+HNZe=5+ZLH~oN zf{HE~SHW9yZx(6lyk7Z<>URBU+=BNs=IMb^Q6vR&$gr!`vkA3WvUzT5T)Dfy9=(9bC{dhk><9nN%{%4 z`V1H$)4Gb6Fz7}z_V&0WmRQNGUSn6@DOwY6&iUBqLzdf=|)k9CQa5=bfw(AAy%RdyZOza`%nrl{x zfCDMXPeTMd!FG3;-g%MMs3*p?E3fL0tzzuJdTYbEMicsNbZX%uP`rF-(8+~eYU~Nw z`5lNzXwo6-Rr~>4(=2ji*KAn#@4U;QgtZ-Nol2*db-N{|J-8{Va)XDO>ZrO(P)_3W zTBOjl8+lO|DI*Lan#;XzI? zI$z2}GbdYV){``c1_8=zwQcY>R=l36!h4lu>s_T@m6E++sVoji_75&QkDD9jnQrdW z{OG((N()eJADmG198n$mG5ESl!SjG9b&+>$?1~G+qM}{GQv`Noeg%K~&@U#i>wA91 z^Pp|Ted(Lk`Y=W;Mn9T5?q>%a*rH>n1~%zJ(m`M`B1G)@~RZ z2_HMm^kuZ~x`)-kgmyt@V5(`K@1?F@Sbu=*H!CioZ^g0_H&+Hmv!9G zLivOY&u+YF-z4@4gWiGWp%?=wt=_8Xf{0FQA$exVDkX4i_8=M3e^n4pyngwVl2G*@ zRn7mRNdK=^iDqM~&()3Gd;+-Eyio1q4NbhZB3I`B_;34pKxsU{bI_*v-WKk!nRr|C zcUaQmUwp*)vrCN(vc===d!mOsts^PDEM{o*rmYQqxPRWprFh6&vU7U^e2r+X+W3Ci z?I_K+VML&xf?EzLI-M7@?|$Tx^H!6#%> zhhh*tMz^D;b*jo+>e{AyMmhwp+(rRA1(r(l*ZA)q>dxKdydl(d_LML4oC<78yowE2 z(uf~GF(1A$&;YOUCVe;SJhIh$_eJ}JPOpp|`^U`8qWio9D0C2F%Ot7mYAjP9jE5G$ zav}d^c==hXCZxC!xEdM^CmbRrkq1V`39AjL=Ej6L?%VInfl-Qw=Dh=*Jb4|}u)Hb> z%Pd0u!Pr73?gN=9j@{Fb?p0nr9DbPeJ#UrmedrCBD4}xp)2;n1tQvrGM;4~+Kg2BT z+9`qc`RPO$x>KKFYC}L>(jH^4=|l9q%JetlRwxvA2#TknW;@Q``*f#o*?YrRB1@*j zqmS}FC_Mp~SxVbcD;}lW6gCvbUHeMpIZwhZv@5~u$nefVhcdlvElsXi;Ah2??0Vp} z&VLKcOnjrU`U(?KD5y3mVs+7BQV-_O{P4Wc^WLD(qBz_Y;lUA0`|qZtu)BKe`r*9R zt5$7>WLdtrR7H!zK6)$qqRo|=O@!bd-!YAsU;k{tR1y83Ys)TZ-<72oU|G9h&T4P{_3=hb~DyBu(_zNgZ3r#5Gx6S!E zH>H$_t2O@82P9BLDo*0=wrAp^rY?I|=5Et#FOKn1Fs|i@kQ-O3OX^dEHe<)}Mt$Wn zsB5ZfE>c~lubY$?;93|FZkJn743!?@PYq^WdKLc%CVdaOR}#M9Z^zWlaCIBXq)@Y$ z;2o1QcKSXFb6D0aLtp*|Cb6-vA{Um}L7QX1 zJd*nk+axlDsBj9w*5p zf^y)@k*qh!(MOED-J-kUBdgZ@BO|e$n|)`5TGNrYMxf1^q*X!<8@LrSmQ?NXOT)lf z7TMg?rY#_B@wOPyI(P63r}2xX(tR-9-Xt#!1Sm69sfC+-@Qr?Iq%Nh}3Nn7)^~TN{ z?wjmye<$TP1$h^mv1wg#&GVWwXOxiR{X=)R{SWfFIcnQ8cdC`=PiN~@o-IY%H+Mh3 z8Qp!h*%EO-Vs}T8oAPc;fzF^JeS=>Z4(?O2VBi%c7K2=VlU&DSyEWk3u)_&GX zTbM8M2;jWiNkYL}z+Z=I!%mJo47EaDh!RY%p~wQ^N`e5JvVaD@WEB)uH}~7d{hJ-j zz>D<7_kd!t3(yt{rl9}oMdIb+qvu~i54y&l+$Sb}%a>n{B5G_Mw^oIINWr5TutmbhJ<^ zXE5)ZjPdOcJ;$42HQy!UZRY1-*W3fI8!|y?Mj{Jh$1s*VVxwP7$Fz_6Oc^#mc+_Tm z77Ow z=&*=#eSloJb4WsY$bJwgV*n!7CKt<;6xenH#`aZ=UgmZBpjWf=`qI;SuQd${+JUgy z%EsoL^y1Imi4H8sM@{@NZ9J%F3xD=uD%l<38+bT2t0E+Lkyr3a+hNAWZ&4}xqGmFp z)wW|S7a7hzsR3Op&`|Mf&2+e{J}4&5w8E{o_GC5?>)8#mYHin&m=yASb5)mj@7aKj zCuBYA)MYdRqp6C%nr8nnha=$LiF5hy=cQxVHz$5`;El1XjAXfn@DWS z{K$`hrIxo8IpgTKf#XghwcW(Z*b}_D_|KG$o~pt`YDW)cE-OS{3FAvoD@b|ojCACg z;yH}qgx~2DznltFj+J_0&>%x;%RAioAkAl!B1WY2>GiMb%>Tmmp~%?-`Lf8dNcxo3 zWRJ*uGdFDA!qogGjgv!D)pcVkoR0QoUgoWss9N6)=P4L_mh=XP&c=5{o_%UAH!!)^L&h#b&iR(ft+>RF9ct#)r!Yw z-ctR&oL)KNS@HNm_P+LhR{E+B*Y?tlH^S4Ws5^7PdRIe3OQ~L;Kk-kl;LZ0~XK52m z#CtqbF&xL`;SB08GT91;sSRc-^s@8z#6%H;i1hXc{0{&&5@Uj-V#qBC$ycotw^U>l z-|OhL^z~gnZ1a)$#&Xw297K?md=90j%Nd>Rf>tZ1^Zh@Nc}(kZ8G66gghmXq)t?$K@0l~|QkE~| z;kMy7-dWM}mv)AbihN$QV;Pf*?sKm{`?)}aRY+#nn_VYQemX`X7`HrJ3sn(tBWRB+ z!LUtD-DZbVGKeZo=L;Xx^CLZSyCpICX-c&er%xm#+U=sZS1KTZFEcJXY&4GsO_K~8 zQ-4st^Ro0R>K-*$Wcf_Aq&A(dxUGFtv?PiBiCh>w>`7QUSh{v`j=));!X^InlB+o9 z%Xs9KGMh+QV-s@U9r);YSC+Q_-i5`&)k!A1)wWMCr6PJ~qUR4J@cIz87nh3<#T;Jc zWU*hiUHBueHS=u!^<)NFQe50~DF1mSbCRkf5Q;GbQW|0PaCO+=zJ$*P4Jd|reZkz! zH=5nD+D)3o_xYL^VY3x+DT`x2n+MtUF=?Ng@`;>84%qK-Tes?iFHNymU-!LL(AloM zMnSB!5k=?|A^*;R{`X5_3pF2)TkJ9pl)V~qQiji22?@2=)3ply{P;8^G()R>MU6fJO`ZgyQnk2I z=}yh9nTE|Y4E($76lc6~dRvK?QJ#I53Xua~nn=yT*O!tQUHILyd)(9eZ2L{0QsYNq z)SW5m2aokOuccJmdfbzoX_B?;3p2P8Z-GzTuJOU9dQL&ejrLV1m`P_gIn(dje}lv@ z>}{m!!MYO0q{UhWc&fNsC`igAqY7fHpKGzyVW;1}@(nHhqbDyHJviJVytPPMnyXP} zE%15J##)gcv4mhJFLRgD5TFV<-UVaXF_T#;IFJ@H?M^0})V5YgRRPz0`IoXPZB$eo zW1g3xuv8b8c2=$(_Fz|ynL7tdl$-4tWIq|^3)O~B`Pk(?9WbA6poLU=Ld!H%=Ha^g z4Mr-=8g!mQ)XEon7NGJ~H=6-?u+l~EhlXXQ-QXsMo=1sXnZF?|ic2BRDMJD_VJfn8yz9`rvXLd!5UN*;CzHCX6CT>DM=^)OVcA3UQHvm&3~#BLo2AHr=qy z1_2wi16DR9)V5dlr(`&z>s^Uo&DFBc3Do?0`%2ND-7h)EB^4s>j!FTIzP^$2@_KGx zL9hSW>}D7RMb*jweMt6iX9&(hVV(jLW|w)jG|ANM5De*1fnfb*O0k#rYQmzCs82}E znF0Am;V0LCUe1<{zZ&unOpZ*&M@MOzbFl^GiT_;`m%IG_)t+dJug9vdSyfLAY1NdE z`FPx2N93)70GO*sPnp(y`x*waqfW__d2Ub(MDe`^jVhK7(XeVva|3kG`@SDSHF?yspHvkVx?*iTtP(F zOf|HcFa8*mlIojKmpxT|<+?520}&k$*vyEaGg@Y}Z{aPSJhZpO__2>CSb=f+gLhl; zam;jSq+b$bn@Ejn_{6IPK*mNu(Xc54wRfc$u)`Co{((ogrDErB-n+$TOTWkuyij_p z*=*`yePFG^ZY8Q;pUQ1b!xa;|+6)I_iuBwAWkwW}qe(n#DAN^hlk01wKba0ND0klC zFV^A;K7l2;VYESemQ=F;6*|5bXY9y83rdyMdxx{CUz_QbB4P`{A1<-oggPjzDPhqj z!eRH%>>{2%?4ym>>Vs8vBLtJdNAA0^#j&VGGNLtI;Pk?WK#Pa3Al@{j2P*e1(@7)M zu6Wf3>OW79(47^W{lRtz`R7%}r{}%&9q-PnCH|qH2=V)eLhB{0tW6oDlzvFW&6YN2 z6r=ZdAK@XUvD2yxJ*#Z?s+m^jRV184{2nL)>Ir+>%6H8Om3YbYgi_sUre?z*rlTu- zX?gT_0Du>Bi1&4oF2IC8?8J6{lglD|ZjsqzhDgnVy!(i|s^|Bg`1XPZTV11x%3pL# zm$fI`PgPkXvXo(i+%?vtSI7bg$`&$!_sYI-5Na~{wNOevLBjODTH!U5z`WP*u9QF67O$7}aoiRa(I`Y7 z2YQUQFB+yEz?(MaOqj%b2XDl@O%}qRH%-4+BzZ8<=ygmX_>w%I*|^{P?LA41IH5J8-)cY`{6?sI_Wkh=8 zN6C67-6d9zgS)oIu^^#~g895tE)`#K66f{!_aBo_gQu)*_j=?OeW$e{0^Zq zYQvXdc6&7MZkY&pH+`{r!(T(H)jj*Iq6_ZG;%}mtdmGVfhwt~rpwAgm)f zt;^NZ*?gH~ANsfZFI_JhPW?=!*B;!Llc}UST)Pgq9}8rS@ci|OE1BnLci>(%njxJ; znd2n;>}O@R2)B!Bzv1u~ciYXga2woCu-uUt-K9fIiQQ^?M=Pkv@b9A#U%{({s%q4wnn5oB5w!EP8ktxko*+{oiFp0jXrG?HwD^bPtSSn|(o0>}j~g0%E9?DtyWj&I?HXP;&VaP5KS51D`R_Eaf|aX? z2S;kVqF-7~lm2t!_5b&rIXPKC=LI-K`To>$#AbZyBI>NHA!Te=!YPqr;|m_NQf}7} z$@I%CVaR1t@G6|JiO^nwG1>zDZ1dQG53O~988eGFDXo@`>KdN^vhJqkUrPX;(;@#i zh2lTeivM^{i3T>ACdz2=6K)YLr}nu914#)|bg(gFM~wJG3>Q?2?q7j{@fll#J~-nrcw zzfnc4g$2K7)fCKT{Zw`cF}l%0NWFO;zZRPL7{9a9Hpj*>n=L;l9RFtXN}uT2oixhJ zX^&E_WM;iB`?3KUif$}hPcV;@N&&=j*Lo9!$bnL_n5otxK*Jj}y*I;7bVv)? z>24)`uT0=g4_<9}-dVg#%&kK`;|W)4T%yF*SO?Wu$A9H~WxNA4%CBP1n_`C z+U~&Z@C$VgO(VJmxDvS9iaNLt@h2$Z{f#Gm*5Lh@w+i4v^L(_qNs9O6NqTW?-$*Y;S71crsd+nlD{ zpFDY6XJrti|5}42dN*C~T6RY(-FJMuQG0bL=zy)1g zdwWeAbN7vVbA3sSxl%ZHu$?pJ7>frLT>h#XF7N-cJ+s#tzK8inMmn)d{{ph95Ub{k zQdQ=4-fgl7NxG7v^i7EYbkFAee#L}0UaoEViAOHKll@Tm9?b>Wa3zyKz8REI2}g)A z-F@#jc!ZFnS)Otp^w6HjA&MT@za~=#oXw@^{hyvj7)tRPwxgO=-p+I8j>`AEH3h^5 zcZ0QmAXFxkJ~rB*(!n?j3^#s<0L43vtQj;QZYbkQetcJ!9)6{=wiKKK9hEo}N67$J z65&iPZH@SRtP+`@VDIp!zo=VYWF(zHh=%LR&`=SO7x4~6khuP(OFt-EynSytROu2& zKC{y7$N%etE7|c2!9~UdiOc0nWsK%8Papb_iI=EJ?(f$js}tRC!zFS*4Vrg>_Ot%Q zu2D;ovScFFA@}OBuo$TgAPa=c_#l4nLxQ(gHc?;m0$f&IxL}c56SGY&W!CLQK@GO&D*zl}3C{lj>YjyG+*@rdD z$5i4zt`mBcnb{7jCGUU55B|S--3E;7@702%TOwRSBGSEZl!ytPBAbI;I`;J}M(e={r zs|u1KSKjlNews3@Ngh2EN_kSR&PPq*XK;dWdS7!0=S@iIxQx#TDF9jHkt_PY51+{h zcLWYvCKty<-o7pITWU@A0S{Zo%_|X}eHs8?<%CY@x#c0BI~^&FSqhCM1N2yZ8%k;Q zD=sQyXFB1zJN+)Ht?zHmMV6)a*deo(xf#mLhtA9rn=aq?@#R@^7xPh>I7|<*?TgF) zUYQVx%W1lqGSRvMlP==&?+--{E(UCqPm%I=)OE?ee2O&hjF+6li5Ek=s>TVk1@<9k zol21t%k-DL4{!7bm-om}Zanfvmk2YqIiY-foWgMZ^FQ+K4E!E1JPWIAl>sgyzEq_3Wn+cSZV&Q^TIz7o z(NIwCm?B;fum11a)c>oWiC9uC)X|hV#Ask1K7fiE|Kd53ATkRPe9~Z(CK8ZwpOUa2 z=?w7y!5nFYfyOQKp8yj*6%z~;z-;qxn_BN|iz%2C$KOa(j(R{7rH7^LkL)S$+BKc& zd_^h&K8MAD8?x3sbFyazIIwk5j##C*CCh=82NvR_Io~L`$meSJ$U*TO^MR^i18LOO zpNq$E&Att`GtF(y)qf~V#xC69TppTxnNw?^(G`XOEoo8?${qgZNWh}+ckKWZ7(3Oh13T~mrKT`mCj-Sa49o~B~=WMX!&w|&f{oyHyoFqc@{ z-B794=oD~Sgl2CYhMID^s1(274Ob1yhNmvWz6U3^%a`F32aI^XkG=oN|01PP!yPqxuZ61Fprt)IcYdb>~doSS?R3r{bonH8!!Fl{u~1Y#n|SKsVnedt#Xcv36l@HvdpWD?xkI z#rJr`na;0*M;hI(g*+1xI!vXomXA^q{y3AJi{&)vY~uj2YGqdV<}+9U>mU2+^J?=W zKKgzmLp5!x^zveALj&-g&kW(9pF3*)_BbdyToHfH`~K;e!h>(O_kDD^fHlhZ_>M1T zHR`JEz}@~k?!MBtX7*Fx_{DEUM#F53suqkSg7U0cMSpR)3qP-)$Lkb5iSU0E;?Qb^V9XUQ3Ld} zjWK)Ns0x|i-#z=ZDIpBp#-uXdyT@cwpcx#9Fiqro<*2`w@>G=4Oqc!sHU+}IC(imt z2YIJQvyG^q4ypul}(smzw>?cwng*Wrfif=XHbn{b4w$R$Z`<} zV2VQjQ4q|^9~VZ5X^q=9kz>R2pqEST?&&$qgS?F^(Nr6jV-@Q6xwX2O9!%xTvRMV` zja$4gp%xp=>dfir^fYZV89BU(FPZD+zWGDcWd2JDyW+4^QdHc|Qf{Ct`#~{oR$ue~M#oO8-N{eSqKtExlS8`=0G+`FDz_)Zk6vdd~3CYy^@yAOPrp8GeAvTQ-z zBijt#T7=w#7?Wx>Jh6;A?vfg+PCFhOej0OQnVgy^zYMH{C6?2cyvK)kU5sG7YP0v# zGfB8}5IJ4w2#$ny-|l1+i2}O3gXn3<^;d*+UfMr2Rd7CI`4-1abEdENI{duw1Hy-v zpAR;GUtkY=|F!CiA5@cb{qp#L+`)EG9skFy^naSO{-6D>x(3?QDw8Co)7Vt>+moZW zSS_~B1fKa;!YYyCd}|PnF&&#bUcKcy)ycJu^Oybeay)ux1WtJVooSUJM1+j$NOPc1 zsrBjPBp(k8W;zwSvP$bhaLIqZT}@GnYuh_o zZRZBBk4+BFQpv7DHIcX>9%J6Y+mh+c;@^93z1h8v$cvlBzPxS>8Q*pS|N-A~P*oHC$RArdj7+X8=d-MBg6*gZv&R1XIvaPXA7L$!}r> zIMybx!NDr2eD{J+v=7;tQ!&KDK{j}Tp};H`JBTb+yaDcl9Yt_?Q+y1~*PDI4^@kE{ z6ta9tn}R(op$=s)Fe8pAp2M$7OZjmBHo(KO> z+~7rn-Vs%=2+DaV4dIex7vi{0yM7vjW@Mi>;5;Hz5L2g^V>Bcfdq+e40IRpYhFHGo z#|)v3yIfU89@tvUzOcjktIqq+wm9My!>+;5Bf#DnPcL^L{$hy<(WjKBT4jG`8C(eW zLriuxIyMff!t88V{-O9JKOK$j?cu(IB&UL-7Di3?xN61c;?&GGO7wEZg7I+IY!~94 z7&tOpN&Ym5c&d4Iq`~V!gJo!$zL5K!z*I%v+&?Rny9V2ud(q%TKTmz8xOU~Ly+pgR zd7E3F9_@khN@$o9+ujqIs6Yf)>)0BL~zL}3?!npqDq^#qZOK5Vu~#%s+e3d)zgrj3(Q zw~!5QB|P1pR+BkQER?G1|Bbizj%u>))_sGZCSNtNnWko#;a z<>~gWhTncjr=jx0O?2Kn!7Is;vGmGa7#O1o~>%d|apM8#-AgfF%T7Rwg85dhOw zbcGtEQW#liu{oObMm<{US@QfR2RyoWWQMt26hCqd$Xc-M&%chsI8d{Gv3{+oBzEML=aS{ecg{<@=fjl zd+Y<*ex7;5jT}0FU+01(@B@%#%q(5k$r&=zyG;BF;fN=|txi;qF@nA6^;NA8`Vkbd z9^`M9`HM?~q{=Dgk4;+)w~%A# zx&Tz)g*`{*T3L%kUFak0H3w=d?M2kMK_r5ca~^!n0r&-C%pQY=yV#KdUo z**7|Cg+9ocf(a^J$x`w!P-W2^&Pc}O{k;-DkKGuDqEQt_-1-sjpUv3kRq>Y}%SC_5 zfiuu6Mlrnc(#hA~KQnkcWT3DWYp4;gR9h6S6JqiV07Y=s7FB>~1ohIBtrw3W{n1Z~(@l;_`XZZVTkCbx0yhZGM=Bji2WKs_F!D|~8RDfJ=2fRwB z$dc*olb00f=T(F9>)`NeuN~_tTA7q{aGGbm&{#)j=(z_}1-&+U_Em+!wj{o504QOo^v#$aAU1+YcAUFT74lUGb<9oaET!Fd2Uw*^kitv< z7D!C?NFXE2pK`z0aL*{5gD&uT>HX~=h9QOH;g-76c{j#ZQJu-Hf?F=7R}Y-;6WWjR zM;KZROaP3>gpJ0-k>A$Ifa(B-=LlrpVZix;Q?jdrAyUC zaU&fb1VMp!d%Fedl4wS{KP6U;V2m=`rC=BV3jvf+G_%^^6wg*l1u5adKLhAiL_5S| zBRBd;x9^`X^#8A~bl(sJ5uGyT_ZTN2BADgdAQ#Go|FhREE(#C1v=QQ^nX>LzVm8JJ z$+uZw1!b=_L+ARsANZq5R3asFytaKg8zr{7Qv<(7E>2!w_Nv=&YQY4soPtN&n1ATE z1JdUYV}KvR=r7RmG9Z8LfH?kh$>Ri^V*KSGf6n`QJ#&jiwbASGDw1+v+m?7&nq2JqHnM6NfJ-{E0?3O*6wi=wSyFAiLQwh z;pj1)??5ZV{@)w={xj+OKYqpt1sHhVnd~uh+v%?5JF8Cijg1Lv9O`*@zxRcJSb2Y3 zjuu%HG3R4KdZ$a1n)B z{ygU7Wl9txY{D|E8{C=Z)bMU|ua@*5y^d0d42QkAc8#oAnmzRtRriwcwNuU`PBK99 zLX#7pZIcKmYR`N)hKzhhtA5D%LEt#yk9g5qrzkAm2joWlB4WIG675vH?Yv($ndvA~ ze!hZ&A|cf>JA+t{8L(j$j-d9<$e|{k%cRmrGs_OX)S_`3*q_>QvaF zoqPjRGyQ0eQ2|tz77G@Q{%dg|c0MmVC~hco)lI=wj6ZA)jTe_sKVASXWB>oQLx$!h zoSz#I+D4gz#O~Nh=)6GCrjv5_KSxVPX3M&k{NsrNYe*H`FrnsWeJZu*Q6QX&tyaq%B|MTO@mg>9cDzg|5bVAq!r*h+;&m-MUYXEo7d9KYUi zRP{dS-tU`F3aGeJJ0Yd@l}1D@az}2l%#Sv!s9lF5O+r@v!+NZ{Ys0y4UmfhXYiHpd z%@jsk(qA9~c(EYP$LFxNq*PDOimu)3y4$lsW|4bs!w_fvPrgK+%H;<{u8xk^vci_`^hP8$hU*bPL+E{ z>&LA}%V!3@l|QrHR4EH24}p(qAK+UXDEcFYK^t$U>hmdn5u?1rpx}`M$Y)LA zY-H)|_N;blk&R&Xw_}Q?P@@febA&Nb`AVfBMB$$s)PMLYG6)xkj{|i#oMJ``64&BV zuyMf63#3Z=%q2*Kzm-u(-1VAj<0jMqBdRBOBr-4a89`|IR8mAp$q4Tkov2KWYNh$o zuhbKB^jlS!PqxEar+>3+rR>#~@N@3p0;3`|dw+qVp)AB(IK!@rN`Ju6i-G1YG4s30EJIC{}zP?p``miwQL%F0fF{iIJC-by))FHXWFNKO#yrF2nwIixC z8Pc^C+-IdbM7K!=pCI~VHQWPgmz$6750%WT`k@f~S2%oVJg1{iy?WS|h&;2LLmT0h zg?cxsZ7FK^tEf3%&}!IozwioG--K2!RYN)=2{bsmP7?E1s@d(QJ~Z~80~sW*H64w; z2)7V``^?nZQW`0ll41}zvY19N9EB}n_~wrROLbd5$@f28?*D|0 z`L7;_Fe8?8;Ox3rfFZ+*G?&ZbJ67g*0ZuR*L3Z0mN@GUVNr@WC&4tXj{a~gqHF1eIh`q5eNTGG6sNwhDJrVHSARSUUl*CdAv z0WfbJORJ-z;2%Y8ici?)Wq{eccsNz$T_|I|_x9I>jYahS-Yi(hVgyt%Jl|R{ChPHN z#_%lhlCDiO-G=4 zyS@qzDt_hS*C|4#gZu=0HGdLeXK((kD){GN`%2^8SaP>l_gJnkpG~hh?0Df&$HUca zNn3;1D^;sVav?iMh3ioTTd(fup7rzS*+RTIV=o9C)0-6xH1gmP{zw6U&U)E-P0>$t zQqtoF@1d8thEB*;1<^H;d~@rM zbjPjVkf+=EY-Q07mJ4n_R&lKLo+=R(j zID0ys*_}@8qLS(p)K{)}Hf1^*as8Tp=EBp(b#si!UKqnEJn6PFY}MQncd_OUWHgEW zEOBemDqPr3V^ffElFsu0XG-4x-BOisulqHv`l%Pn`SjZacJ5eX2Ha#vh*e?p3`kKw z7@85>K+jk;2wYf{1b=vO_WY*M$XErvGF=F|M4$8Hj@gsbIR|># zt^ALH2UQ)LP;}h^Gx65au~*u0FoDw6Cml)T&ldEo*iQP^m|~ac#c>_6nemDK;yB?1 zUF5PSXz*O9)a5hLGjq+z3+7|#X0>+wr(Ww%`s2Qesg1z0-gGQbN#sMy zTbbJ48+y1#6D%=AT(UzAuzjG^2y`*D7%6n=^F#~v`iI44zRCtfpa#%+SOp$2K zr@F6Hww#uRGh|tdsA>ZyS&A@$IzMwpvsJv?fy#L`!+Ii&hozvhpJ%YRw`%RGwVAWFi_; z;agM}pti$WQGg7qs9kQ?4t}i!J-)SO1K{#piQ83<$jl*UVSmkvW0$@0BVi&(b?Dy8 z_j@B$+Sm8B+8#1I__7dt1D=wC6%Va8U*a!W5m_JixZ`>E^+z)**@ssiQVIu4oJQ}q zuofa-5iGQ-1?jO3%6HHXJmLVIjH%*>C)DML%I6*~&Ztytg7_^X7W)DDlmK+YFIxgq zQv>XD*Ai2$6U-&A=Y7v%dZd90EBialo7D!<0YIS`17o{rAzg*Je~GsO_sPMNi#a^T zd`^u!H-V+^s@YYOv)=ED+xw}Gw_D!kG)6pJ@r;One!X0=V|iMr6vlxo1hn}zZ9O7L zjKggtu4vGQiO}h(nWthX*U$UcP!n%=e2iz)^81es!+=Y^|=y@yq@8G`+9!mjzgRE#Ho{ zfU&wn2Ki$+!5Y^31S_3YX60~c>Cr-Q1NKLR3IIvChwcwTgtT!5d_PMWE+|)5gSa%y z0?wXCkP4q>@wWi5eLqrn^v}*O{kP&DxE?{4TpPCa#?>mGL{>>bF?`^@{l7pG+klk~ z*levbtsLqJX1F|Kz(_*B)pjS#b>|Bt#@T&dv7rQ=t;7%WB&_3)7qy`5{^un63o896 zNjl2UwNbrZQGC2#X+Pb6*<({u5O7m);g{W0{ict9gJ~7Z;`4w1I3v_f z?}B#s;4q<*P|BxDg^kz3DF$eG9@HrQ4{!q*^`r3kZgHngQr=YvEdEtzH^5jzed#`bt+kH6uHp4Lz z$0meMNgifB=6yLuQW0#8Qmwi*u%=NhWO>hiOZVDHEBs)3g)UTlZTg6gZTo~0Haikk z#}54G7nj5Z4rq*`-#M<#zo_tPUum%xkRB;9=@}a6`*)JCg) zZUCP!7V#w40<=Ge1I1hM%KN)O1j;kc*Kpg1;DvbIy=dT%a=OfRr!||rYvFMcD_PYJ zw5$74Q*X6T)5ngVYrD4mB0JjU==@j(&@AuG1TDwMEN|Oz_Li&7NyPvLz_hYy^6xKn zfnZl+BZPG*@q~?x`NSAEB!p0RFBm)>QB$RAKP#^6jRp}fVSr#fAPUD~Qi+Z* z@i}!EK}gvWrt0xzi1fB~$koW|f_M%JZE2ox{|XGE4;48yAyHjBXPzNVVrbyg`Mk!M z8{UG8R{Xz1E^T_I)+PXl-;o7@-FmvmGsMpXyVbHy4>1@Y)={7eZ=Am8aaYFK*zB2Y zgfS&b>VE%L`>m5O_tWo#mxHDYTM;9~kp)@m7)CM6JWg>xlGVT=X?q{xP%~cFDjfaj z2}qfO3!B>JND5_?n|zN`vkaP`KPef{!6t?)uNDaA7tyBV>&oT48@&)D3F{9KT}ml4 z^^v`F082X5v4_w1(f-!`cdL?N@rOkjm;IE1&JO1TC$-?zg`1n689z*Cfr;)NI5@{(Vk3n+9k6 zrD9fr{YtuaNR3|~l4S#dtB2jkt$ExeAi6~*x_EE(9=uO72sc*5KC`<=+m#jiwfJ1g zAIRT4I|Ea8r<^+W#`+~=0Dm$uuD~@|`&q^KSmOn>mn|){D1NRNegn_^&Yk50kKy>Q zxF@tTFY-y$#(&!G_`4q|Bh71AckX7JkRqcmXl!1mq&4Zop&xPHYpYEYB_)Yv{BxG$ zl_B@Gn5x%5$NRXFR4WVSpUEcb{+N<@9V8ieSX%k}$oZp=bK2}p!ItS4iHP8M=7Y`W zl?qn5rm-XCrYe6<)aia_>~HOh&MF4_ta8pY(@EX=G|dd@L0wlC?qVu9-j0-2zxz2L zYb0m(KB~7FL*s9O?d!f`ghO2_odl)eHABHAu{hBHura z|LlZ4p>m#hF?TSEfO?+p;nt>mFdTJ}V{J?Xh(7+^=ogK;I~cq1ifYe~0x+_8oyC0e z*y$O_HOO-6@$9?$=7!#-TVRH7;kHm}N0lA##<{R4aFjy_B`O)ucoGrwc@tpg?i?=g z=+=$ZZu`v8WPK31eqTH{Hw1J>)oN-6mX8_o^zRuofbZD>keRT9rsNgGwTR8gz4 zQbrj6WUs;P{{wz^OJoK8Q-E}Brr3GC3&H@GoO>vJqZOIr0 zk2)75^3>N}y{*LZCH>EawK|g;Bt{;fI`Ju}6(HRG5eDNmwF?#+S3Mqo1CCE{fQZ*2 zPLeQ(J-bM&)uq#xh2HcRm*dZ~-&OcI%5stQ?TE^z6X`$iTaf{gz{*Nl-`e=wRK1Kc zTiTq;s3@DWo_iAD3SbLaS83ypfGiqaEb8a^a$1}?*PbcC3?O-yT;cK_=Lw&iufEKC zKK*6X0G7Bv1t`HN`Y$ql>fDxSZK{1AF4>hVK34m2&GXEd0*ceX%=F4!hl!R9#E(>1 zuKopjg02GYi=?}lx9lQTi`bX-vv9VOu=OD=9HT+-^2Y?`y!$D$sOT0}d8iSB=N*^rr^>()(* zn$I53vJd(S_X6+gUCH(Qus(`QidPx!|0miCl$$K6cL_Kh{0EAN{(td%lkO#)F+9ya|D)x;OL0M_e`Z&HHM>9Wf}ee{=YFg$ z+OXj|i1k#)_G~GP#O;_Z{Z2Z~zeYQ5#JS6MLw49^K$i7)+8gAa$>np!0ngk4tS*)F zJ$APz+O76U%#a6-N*1xcv!icOhE{&DaQY3nc+~90K zu3XLYgvY{-zMZ2d5sBv~v=c+GPwhB#p!!DPbwx7v8NRUO%>{v6`KNY1*Yh7_zvBqg zk^1e%+>O5S2I;cu!q7*1-DK|3QNP$i^WYCpLsO#P*h|zO`0eo{y6e#5K@|kKT=C9< zaO40$&nqKeY*H#x+^pmKO|n4ga|v~L37h`>_U>F;vdzF;YVA*;2M+0_W1Y1vuR49W zNB^{X)9;J3(DVh9@@?>*;BR;=S;b{pGlVb8A$+45d?36i*04dY)sdT5lR%t+aBbGu|}a-3gVkCF`T)evr^55R_ARf7>crSo1rss?piM z89oebML@xEbLp0$*2(l z(2;;lx6M=9D%?DMa<`|xb1fN<+uhe?r;X$(;c5-OiuNS{29wJogbp0X<}9>3Sb7N? z8EN~`EqBswu7C21SBUy$TUYPvO|reDqYs;!Y=;oJp5K#S(vqiu;$WoeY*Pj9;2%Sx zg5t%o&(p+l+npIEp|y_o_k+S!zq-n{V^25K3LQ}JW>lgYSI9YI}$LT)BLF0BP9aG(; zH!;f=8TU~I!DP5T64gf>sz(OrNRnxoATbd_Re!#i&Rw#%m~_{3nb!z3gjZrMfildUBGRO%(~yx=8gp&V=$Fva|@4Rike^T06}oW6K?#knl$r!nba zb?v##JL2m&ACaexaqe%Jc65QnOEItQHRD&ZiR40;)%&@Bv0cbr)I;oJ5VM)fsue4y z-}U@MXCgl5E)2Fu?~rvS&sb^QKAfkMSAokB+3;>y>ZL0#cr6F4D6Lw367}0iYIaw_ zr5zqvez4quHIqZ+o9GIz%rkKLYkp4-MJKz-tPe*>LNhvJZpfl!i`OCafv|k0thifT zUAO*-tLpVz-2Nj(vbW#@tw&M^iODg|5ce`2#+(%?pP8*UY-ydk*PN4i_cx3azc+Tx z?ltr^(m$vS#_NG2l(fQ}u;^QJcTlOfN&^z<2-LSPG%Du`1jbqeeb)J$?$J-c7^AO2+)kW;bNfejEJ}|aqHoYhy9wyM ziVAY0?rlH(#r)!4kJrSD=@PaBabz32n@jti-=$>FB6TqnPG4_CKj#vT?Z`>>ma!99 zB14TnENA|8b%HqT#Y<1Bcq1T~a?+|H)+R1i+Qma8=DIpFWp)(hJo@Wn0*Pdb}l33>&T&+Qp5$_^y{ z1v(_Nx;6Fz`DtjYGoGqK<4^8x;Lh0IUG3+jJ{g5WM&Bo?WmBkofGo)Wz}Fny(Rfuj zg~9Cmf}=Kw&&zV}y(A~3d)76>y~eS@cqr>@?Zr(LI5|!^Ju}$U!CMC{xh9o9F>R!zV zy(_A8vb-0GD@(IrY|)>+;`i`-8g6*{D_jxAJ!?o?s|e^+M!G#IUwz>aeCwcF%izuy_uP7YHZALLz#kpT1v?IRQH$`uQD8-<3G1dD)OF|LDAOfyA>%^d<3gELgo6acAqmN zf8L2cd%Np0oaE^)?j3yBwt$hZMwIzd`Z!s(bIbyrdF4rtUy0zTOLiUmLeP}OQlOEO zcfl z8Jd=(mbC>of65+jxT#5MN$Ro}+rCgX{1N>DudXUG`&nYm^Lb^4LlR8#E1-vE?lo_C zyE~xe#EF(1;JEmuXs9?$xrVl`rqjeK2@oM3EI;Swe-0fhzUgS$mQV0Jp!H4OOrQ;- zM_Kma4zLFPAKDVjdL@@`ng153P5ymwm7_W^p0G1rB(^p8+RVjQ6(+zam(~%sLt=!-lDps90)(tPaTg7VtbJFuUZ!>&nF5>Fk`Fk#<&n3%sZHIxMd#^i>L7MLg(0EML;X)x z%Rtue_@?v?;$1?pr)Zbd;Z&7YP=Ig<*P8F3l2W-Z(v`|ID!+-Yo2WM2RuO7u%(+-K#Nup`V9k56(?c>shKlI$DpELV^gHE7M`# zoczb@{rIQ)ojz9frq=A-ZIO7Nk`*dhC6ub>|m=|tx*v; zB%<%Td3oSc7+Tb|#cn0oq9ZL$_c!3NaPBT#41hFocDs&B1d1*9eJMU-p-AM2K9d4O z!r(A22^_EWB|=S*K*Uj5+yfCSho^Y=G%ts!mM^?rEkSR-kp?Du2B(O}In{^1tMw;FN%B*D2>2kY1uAC`CHqfcF54-98G ziJ^WCKk1cwG~w-L-d?#^JEwJn>$f_%Qsj{C*c=Z-(If1kk%9Al!QB~8jSpl_@+0q6 z5ue$Tq;SI++8OQO0HAmx-fH-RSoX;>dYt(?#>1a9r!*G4jS)#UGT)cVM@J?dKmm0k zk41-AHqAv#IX{IOT`Y{=%keq=`Cz6<`tR#%7jF_Hf~%lrgMqq%r{Y+KvO>Vx2SN|J ziI#5FQ`i(|>U=l?$~q}@VL_untFg2~W0dKcWt)zvBeW3ZB|Z?eXS9gRK2k0$p4AOp zQM|Njb!#zKBH2i5EdkRC(iuyB_TYTNY@}7jZ!CoGfq{n<7aoOUSeW-F4uLc+&qkB= z!x}lF17nxsjvsgaY zPTslS1Cd?0Ui8aH@rzE-t*K^EM-!#g`R&!ENF`=M!OF}bnAwqu>(1!f?+PgvrstG3 zVgbgS=`Z4Y+oT9tz{Rb^5y!LxaGAYO$I#oCs#GC6n) zHj&kWoP4vWP^Lqb`cgN0$;pxA;y?g%8mePk1$w|$n4Me86d4*so;(6}m!!V%D&`X>#GZ%3->p^0bJZ!19{s@H zEn-1aeG{*3T^iAC%4{&~aq{3DSFciGOY`#z$pJ#B!viox5mqHhs}Za~27+$(aj58> zEy4DT>48Arms-Ew^R&hj3$SYMr%Ns}lP}Wzq??Os-RrCtmw;Tk&X-tdgrO)h z?r_t+_P1N2f9Q}_@8HjV&@xHw=TYUlDxND1E02IY!!)!ZF-glQ$1f+qHba37qvfM5 zZ@81BFPpL0-cx+PXKjQXnK@UU5(5s&Ly&MOm0^K#H~^>DqmTa!1t$1!V{X^g{b2ry2jYu z-_t%=$ZF>VP|yO)mC1P(60Im(Y0)M32YS<5W|HVxM1T)r)))(iep|{eul!E9M5p(d zuD5l(iwitTlqu+Q$(>VnvxmEOjHDx4EXr2G+{^|y)i!^u@SY1`VTwLpTGQy58Z@Kvz*551gg&$?HZ}sCru4vx z$=qYd1ka|(KSs^@U_^K9E(KF!xhHRoyJc=E?yLTI2qgL|G7M4MI^8isMmXu*DV~Mt z;SaL~TbgU9CF?0QTB034+qGt_C@H5cS_=*;9oe;0`UKd8XZ18&%|jQJiprMe2ZD>8 zZweYWHzoZ3#r--jhf3DSi2SWi?Q)5r=!nRDG|OVv?vl=ej#qbCtwf;7Pw*G*nmJNG zgpMMNhOhN|-o~`oy^E`8WQ*IqnlZFHlA1ysxNk#BAY*OI7f4BJBn^BJN^{r!39!%o z9JPGV%qYyquXj}`^pQx}T@nvm?K0naR3Lib6S^-HPxQFRj`iL&h zcXwF_$4b9KAQ3fZiJ$zF_5lYQ*|@vKnaOC9aU&2ihDrMse8sXN5(@eL(k8ohVg8_p zrdM0dI$)D_NuzO0{}CDQ-(5GoE7~C2@y^v~kRC)hg()K@qvpD81_(xPJ5^B5DLbU% zLRsfx-Vt&w=i1Ka*~^Zd>5L5YuPOxl7(h9OC2|Ho{>%OBf4~p^S7e=;5Kayl1Hf^=D}nNljE8SK@bCZyxebnSeOWxF3s8JQ(ihe9biy+#-h%b_@}y-;S5r4utrbo>vBhQZt;itk?WPHk2n zI0}tI*g=0HR-ijV!T7T7Hu*8}Js)bwd-Hmfn^fgzzUBboZ-m(*)&-t7!DBH9%}*=mWTQ)OHn8W1qq)3grC<6=GLOAh3L+&>T2`y*u+b$ z?-g!8RCL)4mIs1$OA+=W5s3G*VjuA_9mgwAXXBCe>_2(H0i@>!{=fEOO$Pth5}>y%wo2dsHLOMiq)u_uD^#sja{MO&E?5*9uWeq*$vZ7p z1z_K-6h3Z9#|%677UVgd9ieA@MA(BL&yfPGo>mK0g#ikqSvmoYDcDumxYJR*=6zaEFB^7DQ`s&^e)M5nK zmhHZbx!Wr-62`HLR1;N>D@i?ec7QG|FZEvEk|R2+MFvlXFYUYat>^eJ<*{(|6iD36Y&0-8g*4FOL~8Ce-;n|H25w#)+O3%P`F8~zLtf+i*YrvC=kwQTaAv^ zzgJtysM$m<-6A;uG0n`o?`jZ->kQz&WF0Qn(K=Srs9*k1t9dTi=8pb6%0PWcNq5tn z=^>R8YQ=2iDV!$l7610ZlLd?$bwcl#&cxmr4##`Nc_6w+@&*`9qx0Ihu_n6ldwzj6 zBW;p8t|SgZv|hnN`68pymbvai2!x5lWJ^4(mVRaF%7&alu~F6d&d%eIM`S!ky>yCY z2YzNhmU>8{gy0o#y;V!R4$AGpmyz9@P$fe^Ez=F)_g5s6t=Ft_la-o3Kwh`ZDftny z6#O7{ChgjHHO~7pEhiR5i*^g%##unj)QK(|tnwzqL6{Z33yf>7@dM=*573Z&>@PLN zNo)?wpJz^}LXnLIg^5>oL*~!UIPL~G_RvGXandRAo*I@#rvE6jWyO>*-$E{12XCoB zzlB4;6{;URqUH#Y`s{Y)wR)jN$0two`ufv84n2zc)C*b>1D4=Y+1tH}!iP?^dY5vS zpNG6kpz;CzE3?)A`Qz$3S9C9hFh%1KQK$yBcGSBx19Sf{tZIVCDy2_$`UpZevBUU= z$d2o=t4T6&-(Ob3)i=|_C~;^k6lry;A-Qw4{4QpZrtuS^-I08UN@NvDaNCPX?pre_ z4P+~Nzn}^@5xK>27Dj)k#2MPK*NvjPEZ6s^0M9lf5gDW+qp1{ryW>KT6ImzH2XO{+ zk-AXTn9j^SrtR1UnW4;J5e<_|7UxMy&$*(N4rJ^oOSr)wVK%_)c#D$>S9n+)gNd}3 z9#gPlQ2W!Y)L_F|`$p@hLgt|GiNH%)4yx1jW3G(8FsuJngAMY|-Cu$O4%}6;@*(ncGw0oyx{*I4xL$30aF{WdG;S|O>LEi@^hq!k~85WHdBNtIZdIV4 zt;ZA(26MJNq2>sBPtLOJ;Hy|=0&zq{WK096s+eZXpM&L*_YF$IIFU~yVa%X)6)R-Al=N~ z3Zxf|#MC;(DL`>S-De(Qwzy{gq_ef$wpS~YiAj9>`IqDSc$Z($k0@LidE#u2_i>>T zn@h|v@Txjwea@i%sn;R@1Y*Od*?LQDPgc%7o9PqRv6=;5{8*U4jul)pYh!nude*08 zpBiV|ejac)x9t+41V`5eB||tZQEX;2q4Zp+w=K%n>RLW%ijJh+0mX&9)&z88x=rYO zqRROr_$1_NZVE|=c%8I3w(3?(z3E*vW10qd1YmOM@gY{`xnTSj!OCW*NzoM zwiAnwy}sqiWNtT<2!68YQTcea6(~0_-IY@iWh%45vtw;25j#7kPI9n#S!rXJnl~KF zW#9G@ON>X6(MN+&YJaciQ)tv+)wmm9Ya?Q}kB!;pR0y5hsg{({bYl7GORPLkJHq}r ztQ(+l{{?c?WiCgwc+i^@-aMqUt*TY=;aapUM~G{l9B*55p5Jto2{ie$v@&F3$ajQf z81%vhZC>pN5a)M#j)E?vpB|%M+jOAibU!xCpR97379aDtH|7_3v^WWCQh|m9EysZ_ z*I6;yr8Btq5%gP%p_HVjeF#0z$XKQF74_9<9{>%avpDg|^U>vsI%kV^5JT!Qfm4{M z|3dFl57*^qm$@0v{uiwEf2B?EkLR>KCakVv-a~5<-EO+em`?UhfKs<0+RY_Jh@#b~ zdG%m6xbS{+aDiXSL#v;BuiuaroU6c>7Fh_oSSg(NTkjxD^j{zbdtYGnS|NTD{X`2p zy&*j&pBvgm={q_Uz*+RC;QR@ETBfWV2E!8p0uzi+npJ^vg|$BEW51cH1h=fB<+p_| zt!?EOz=03wyw@m&x+*Y#&S$R4u~@L*IBl5D_xi}Eu&S_QDfs7d-~z~BtrPMyXc^UE z;i5}WBa#=)J4>&|Ss1^wUX<|jc<{&UC z2TGSE1wNxH9nDSN@6c4D3um@c`^uT?HyQ{=C_A(tVf2BQxmyW@)AIDxK?y~KzIK-Q*QoeNqL}@+r z*qIEG+V?koEwsNykQY)3LE8NplktF|G?^8rjO*(Hx`x}$&|a6dAfZ|-cz?II0LUZt z@zUM&VZ#R2*Pz)YA7%l7N3+9zF6XbcsuSU(t%?=DPC#jfFZT6#hMUw{+LoVkYmt$7 zz2XZrvt1aipa#Nn*~8Y~=BIqyrZsUJv~; zjQQTr&nG77=<+57E&JrV!)RUN$B8eox?ukng2+lkgawu|#)eLB3&BK~6!n3`f$1xE@)9VMI~Q+t-_H?HvY6+H=z9{bH1cEG z>Kq(7zVdAKVfP4Q`hcO^)*@P4QY&}Uw|3W`whRwgS{Ocblx`n0NfZx6XuM4b`oQWj z)(BxHjkST(9<|luJ~WsQV;-I^ZIYueUK0GyDPflhFK!3(tQ5w1 z`LM8joy5w$%l``$B#{Q}5#ChC3o?(#CDl8fW_=1m$wKPC+tk0{5g@C}AYe-22A z&J`Bqy`G?R#bvQ}i6C;)9#p@7#6mRrtV7Gie!(_Hb z)$zK!N9T6=Z`S`FrRlq#t@9!i;F5?A12}^P>?Zz78E&b2yTX6Wl+;tOX)rTHG2kii zt>!_02*b0~TCjf%!32o10^E{ ziqV$gFkSdTC9RPni;D=$?DHH!uRSOP@G)OYwp-a#+FlXwrZMSyfE(S&09GORr)~u8 zYfduK$#=)3`f|c9@3-xBQ=`bPNxhn{+VWcUWwxzgoxZmabBrxq|FC@NhQD9$(sdvC zU@+Ds0%+TWce&PJLiLq0i^1wemf?sqTY@Wnh>K=FENs*ANE*UakoKzjJM>G>lN1u& zkP>Ec@SDzM&m|_Q?N)H7n?r%>!S?LLK)%!Kp261deXmwGu0bpVr(d-kR~8*Z2<{j* zh?D$ZAZF-e0pNXwpG&0%Xw*erF>5~f&Ak~GG3z3%x1OZ7#VQ4M(U+;7M0pTd2run$ zHY+mWuv;(dazYa={*R^5?`4z1n?*O&}wD3i!V@-YGq2}Nao7YyEEO4pRQ%wG8>PDIIqPoXa$zt z+srs|)=J7s`+R(uH)60iaS|+}S^q;ahEr_7*X-w9pVOr?HMVg5Q!;~_661^c2?x>0 z67K2r!2DpR4$s|Sp$^YKLf>jZ(U>^(C>`~!iF-_a3}hUy*U-u?pKPB`9XIY|jD?P~ z^ygf4+mSHWn_Iqahz*;q$X9kGtLlkPr_vLe_;1nZ{M*coY?!EmzrF~FNU_0h=5IHS zOAcoCcZZ2I%YN()u5Ovq?SMvRICL&Wm@`Knwx}mQ5@`G?;I(Kua6VAU*<3TgBasvw zEMkI%L;_g_qJ#i!9CbkKR-n~n>d{u4?cI;ylS%)jKdku9xmDDk@fEF;ukju?9H+K( zx9_=g+4|k16Zaw;|88VPc~0tmi+Td|LazS3NyUvw83f!D9z2v%UF9~&tktkH0}E6< z9y%S*_}Cyo-WniUe{^gAAvhYts33u}Xm3Wv5TPafX}PBSwuuqzi6aZ~Qd_%yA$f@*{_wu6y5lxL_IaW4c_OWYV4&JA}1KNT?8V+;S4?J zuVBV$Sb;ddMVK(I^0R2#I|V6z_)w|k;~xG=G3NaDwzP>t%cZulH^G0T^m0J=C_z-a z1sZ(cPlQA`JUWqK+1Cl+64}rzg)9_?oSyCbxRW zUTZJrgHe4PVbol~(L6UANUj!{*KN2{BPQ0gZD2JR`_}ADzef3e)09Z$$M4CRoV=%d z8Sk4E#x?TMAIf4&^cUAP3lpDow{eca9CDzJfybF{Wg90|>6NaPt8@&}K{pWh0z=6- zq6tgbr9T)*r`!EHt1G+fCb(a3qz@bA*T2Lz^p{`QDrbEiQJ|UmH9beJSSHgGI2^Sy zLhXEp0_dZEh!7{2|BJnM4AP|87KPikr)_)Mwr$&X_cPPB?P=S#ZQI7QrfuDR_d)FQ z#rxf}&yD-@W@N-uPgPV_RW9br1=6;_M{{ISV7d3Lm1#UV2hK{yr?!lZY860Qw6-*3 z{`qmfR`J*Fn09t@7SGZ>H@7Um$kk@M{!{k=yL932hp@+VcaB@cyd3T@9)$1u1=;o4 zJ@5PvKc0m1Jm`n?8>ek5dEcKQT@N=xTQOtPBYPMnhkn}5C0^Okh>R`jqOo( zV~=880ibbp5~kJb;|NsT&!KeGi5a>uTYm_8&*R~|vYW>A#=c67^C%utBAT!##$DB5 zZ|6ke%H9QSVZAespO8GYsN^%Z8*UZDt!+OQlamFOEJdeQ2~6+#O{8&Z5}2T7+(^-= z6Fk434pa_bOHquTZ*M&xUTbfDp@p=*|Fw8#)C#&#&kHG(L?eVrWhew9u3B?I%P~s+ z-xjd_@4~kJ_WE1pd$KpM$7TNq=HdsLC)^@k&R1Mlh^KnF1wQfBQZc7CBGS63V;9Ft z7IBhlkJ^qwK&u3Iw@UfG{i^f zs!y`W=M5KJyrkyU=8wKb{~2;kr@${emEiZQa^Lgmod)x?m>G)sGCQ7hk??|N_y&F5lBtYQVa;8cyv)q>+^M)qBFB)GU|4RI{NWWe`>ZI__WUeXwYWK0I zN116n!*ALi#lbGNq_wN!r8z*HS)B{_y0}|qKdcp%6ddAc$X97zsDB#Ao1Fbno)}cv z5+{{cv7`scI=3H|l2n1kH<3`pXTTYE**IbMQ z^OMJbHzxC)ZWxO-h)k4Ti z1Nbz@w=k^K(n6LE&D25DRtk+K+Stb*gdUIm{LpVyfIWN6GqyI22#ePE(~AfHpTr1N z$2qECS$!RA9xw?%(p#&73pXdbewjJ~0FLN|nH{#Y%cw09d!paW%y@u+NE7C|WWwya z?Jx2B@e*WhU%8+36+VHalX~@^WEk=YLl+#pM{$7Ty{|7aY=-M2_AuYjv_2@eh83P1 zU)c-#B(-b?%REX|4pof*2uK`*RkzpR@aQ&sdDq26ZQ1ud{^}7Y;)KR z9i6FO<8W4`iF0`YAku8Br|ey&jgK`S+})??axHn=tM=Y`N%I{q=HKY-%Z4GpO1bWO zs6p-zRb0iUYpHJXq59LZa$jjZ(L0|6uXYQsas5Am_7KD9aWt>_3I^!%*#dQS~T*fEN~it-bya0?q&1d!7>>rr+bMym?Q)${2K@ zmJz^u>Rr`C-{CoN!u{+a>zbxP+$D`iK!D~1*Yta_3kP~~-+6pP)BZrVHQN4C^e;$u zU#o+%c>F~4*OnE~=k9SGk3zm7A4dyXyu^<8Ew6pq=!>3Gqyv=ZSYdV5`Zdbsh&U1HIv&rgxiXJneVKzcTd5xI-}*jYhRR#|?eMi7pd-td6Vp*-3Nf zhj*o^)ZSqqB0zg%YKz7An8;EF7#(C>&?IqtZAe&rd;ChaRp74Q9MVT2l0M$E{q64e zGK7SQHccL6m8W0(Z|vMJpK^cyH`A-i{@(qVRp}wOUJrIIicD96kI?n6@XZ+vzM~e% zENk);FYEnp-8*GJL~BSCpNOvch6ESo5<>_c=jqgbeZTexTohd%0`3d^GN+yI)veukUGx zcEG>VKZT_ad$}@4HqseXv}22X!G^sB17MXiTeUA#=7**NgfiIYx)zQ^$qJzYK!JV}0~^gn$_`6`11x{srAFI_1v z*=+2%8?j78j`)qVK~o2{$EX!YoB9)|a2uYF{)u59-#>lY-&6hzMskE0@qG>#$h;UL zud~gNhYpC19$!HsKNXw5VkeB>QTw@~8kBXO+|CrPwo0v;AtOie1_E;-gCRJTInNR_ z2vEM9{*%8Lk7C($w_-(6%y_dKID29tq+r=-m!4WigBNp|)V@^m9DAKn+lf-EuUC-;0p))s23ge1|V zNwfNqh>uT2LHOQCh;!q4qOEr(nfE_nP)pe3c$@nt8Ik1Is$^^<-3DyleKt$%_z=Cf z`Iy~xh4&EyIvDI*;L}~(Orj5vExvqx@X;s?td2Kt*8W`RNnWczq&`VsDM)mEzdnk{ z-yD9d03Xf<%=4cTZ&Jv;I!<~{Y+uRRe+5LKf-zj1KO|m@wL!W2 zk5x-QS$=H<)jfe;{kdka^W^v1$2p+hvq#=aTVUjzPWD4OcrazvStg0YcXoXBern!t z99Sbb-@MA#xR%{#Pu!xoMiW|>spsr91Fmu41kOZ!rJH&1LF_gd-~M*C=KkgWZ?TOr zeJwxObaAY0A=uFgD@TzT2BeB&upf^u2cg=wyn=0)V47!nwQ|zr_TrUDVxzWHOY4|( z2a^LtZT1Z<_B?q|#g8z|C=7#RU!g3Nu`I^`2vUHTy7OX!jjdj1V-l~kfpSioWeS-@ zfO%rz3J54(*5MNf=j+J?z#r527+ybzwcfiD>;!MUR%xJcIfG2#4IGW?*{dSuyy*{~gwm2cm!O`=WN@p03Fa-FAN zV#gHBpNw7gA1px6*JySkwnO-vQ~E7QVg#S!b`it4Y_M*YRU4wW_7wPoZn3kxJmG4PkblKqePT z*0qlZ!KW7c_IatP(c1%7nU@#tug0hKlJ8NkO#OzaB{wOG@#-f07X-|VfN3nWVDA8> z@8DnwzMP~F)zjAHmrs=P1FxRF#ZL^op3DcpU64sCJ0|hVq{h_(fEP7VpDS7ZXnxd7 z&&vq@2D?&#IS0R0&D__9HV&_%aD!vXm!ZPsrvl`1_m@YeO-uj*1j??b@-?Jbb7zp# znr+73pG&?h8SPYjZeN;1do=GYA54Brb}!fm!zc4H)`Dn*UqfAlO)AX+?8#_Z}qlUoXa@Y~3Wc%_6u+fVt0?lazJoB=2t^d^2 z77jNDk~n;4hapLnK#!_o59o|C^0jy`!xII>FY`T)j-S`l1MCEtA4IJv%%{v9ZMO9w z5->3nE7QO|f~y>pUb*%L$ydW@iUo>dxhO0OWna}CfgFJD&^^V#IT#v&)TDo;83U>O zvJ@BuVxi-J(fYri@j36Gq`$zWZ`nTgj&`^R+sgaluX-&0aI68!e}B5YaZ!)Hg+E6Q-nHb zt9{2B0@2cNf7Bdop!du-VpEKn-ymxX;c@N$Ho-bZ^WZn7V*^a6CRlk8DLFPKKkVRm z;-_blbFZ0o+ta0EsU0>Kbp}p{A=Ld=7GJ@hg&1_!`2=$XL@}N5QfXL3pp?MX&%{(F z9jy7cajCLzCpiarVri7XDWrgE6v;}eGkXR^!}|jVbi7$-0Qr_vp<9F2b9N7wtoeuf z6Q{F_y%i)BCpVmia_{#UocX3 z&Il@~+NmpqFUk@lYmci zp3UI9uVa?K)XsgrRQ1`)f39h66P@6F57>C=aiE7_)yXa5*@j z`sdm$KS4!%xK0^Y!bm<8_%5}t3Y}aYM;HjqkfZ?3oXKFVp%ONbsHR=@xf;2m*&rTO zpXabDeU3p)veEAnDn4F0;^Djio(V@3Q#2meFercnxre%ATLHZad9W%inZB!kgzFjA z$(HV2j~sm<(WF0QkO-sZ^!dxa4#-G&r5wFho(Vwj@UTo^7w7UCh9{TMX|1JDBgHPR z@{mMX3TIs$CCuvg4cUK(#pvsKnL7IppE`VnZ!`97!T)m-=1i7N-aoVG# zY(kqAvBNHz#YIvf0HnF7Dv}Z?fQ5-zDk9cJM(U8#2_nBDkKsa0c-B)o^%MBZ$TMiA zMn1CuXOZ`Sn&};-#nflt5d&(*+z(k!$X7o)Ug%6-$Dy9NO~wVNIw*uB46TzoAn z61EiWDDf^Zmfyw{@X&SJ1aos()uABh?lfDhNo;k@BNDTC|M(72LBzX}U!gHkXQoOYn2W zAf+tD2c>PRy3mP0Qx!{=2|`SjPW){Hx$#HJTQY*dSr*Lf zO}Vo-nMU6EO(D?Gf@ffju-+{)2#Ah~t}}d#cPEeyex4ceu~SHlel-t)a02BI0694e zl)@m8x zO<0?YX#6J0up8!atphzI;nfSRw}vudwgxO8$aM6d_Q2jHJr z6%4Ph&M4y#w5zSnkwR2u1yaMu5>kyX_1o`iT3!nYir!4h3U-dy$IbSqoM0N}RvVtb4)i(owhRZOLjAQ2L$ zT6&0tS>5-0>N$j9s$S02O>d2vqA?j*IAbXTlhXnP7@xtlWfxt)*-63o@|2asOsr&Z z_#5*Da#(<%u@P>x`u0=Kd~hv$QYMhry^2AIcd#l*Sl!Sxbp%;C7(7_DAKBw&O32mJ za8L@3a^MD?t7zbY&&(7&&>S8Y%W9RDF+NY4Z5iW>G1%gAM%`IOQsl6oE@H`Q7yNde zx`?zmd3{IILTR@`fZ?L?vq?OQo8xh=riE)#VU7dmbR?E`G0*Go5ed<8k;p5@>K{YnD$4Av>BJ_DYVIpt zBm*MrIl1YhOp;>gbwKKg-y10i3Qm@th7%vNKWB7V%+?7(V6QYeF=o|_+`3d$?g+|N zMXf0(nYvX80C)ST)-MNCE&!_gR<^hgDIXkJ+UK7qs(Y)+cx_8Gq8hqC@0U+FVm_!~ zh^|_W@mc~EUNk->d%^l?z;iur=n32aSxj(}HgjH&l`KHxiW5QP&DEbg2njOY5(ic; zB}`!Iodl&U;NdQabk-CbYb{dl3WIBk2_lY-+_1Rq^uBJh5m}>xH#?o!uapkbhx~S> z6Y_-2+Y#Y|P?fUJ|28kE#rXMUsG!};Mu3TfqyT;#Rc-o2&=^Y4OQCVgsjBp(RWABQ zZGMkQP}ptp_hkAP+5J12axniFLC?hcAD8}F(*LF4{p-qHrn;^*4il0m`xF1~Rt44a zq(3f5Fpj4kIB@TvwxC{=EDZ0jNzN}EKaZDEkQfasb)(G8#p}L*KD2iarA<%OeWPd^ z9iTe;)b~lh%$~@8ULW5+8~1kSxOC@Pojr)@&G1QOm^PtIy=A!F`CZQWxpf&0n1n7I zgx91{?g<1>tw9LhaL`QT2hdNDC-y-eAI~wZP!%6k6Kw3`-WbCVa0>J)K|c#?CJ1P0 zi|PmkD3u1TthNyZX#;I*owVVo0ud2d;rYtA6mmrID(0ae{cf!YV+(J<-gzA`9fF-0 z!JF4Wd4@O$ml3Ml0((fSZT9{u8`~~vKysY1W4zTy>F1>=Bk}0a!}dT5W$` zd)73?P)}Jn0sVkhZS zT1(r$w1W{l90WpCrokEejapq|ML$F(Kk9`ee?j~|Z0dLj*krn=9h95DaoG4_%ULYq zZxgCxg50I1iYdt#)VHD11C-iW$yELHW-%Bs0Wm;(e#3p&)pZkR5~~IY6ohX(bD&`Y zQ#W&<%@8GBmT*8yEN3_I0^DQ05E0QhiP$ZhvbRxV_HCIn8d2(PoN1rpZicykPd)#++#w`nXJY#=LXP9_sOK-``F}t?YQ2By z$(@ilh+LRljif(q`s->e>mP#zd~z;?5QF{{c6VoKG*K82%B1ulvBbX>Jd(!v`3(2# zGhVIA!13Ln^@yf?biW5)X79**x4&)a#e~csdhBojBx1hN^Y4s*2hnPI^M?$Gad`IP z$w-)vz&LUf>GbujrD1&F!)mY#-B)|8@ zTJ8fH){{U=#All$ZSKp|ZO&z&!5_YF=PN9wFMawO-+Sdm<>=gpY60Ju@h`?e_+-Z~ za@;~_zRUcCgaya2{Ci~l&y^V=A?tU}e?~@TroTZ(=D*aie;pYsHDs-EzmSpP+~=xw zrqp!R7%@m!>`E?A7--9r#lNz+er-j(gquZ$b#(oY!WSC)GZC;_`6*`S||OqlFs}kpq7AK>urv#;%{$7)!(*0h zPDgtl`hyKT(!S@(mJ!-%$Y2=mDFZW#0dQHN%?!ye!%6JpX>5;~5V44a0r~_SKFW)c zoff#~s^77(Q)WqBB;v=GEC6#mNa3{7b(?q)nBiO*;pfPdb0|~#RB&n>fyhjSqD)>* ziWsF|%!k&x1Vnu3XBi}!uP*7eo|GcbxspG=#sk}H?g!r<_>F1!N#;|9EYL2jdXJ*||c(x7?{!7W%>Z+=4EPT9GBsePhW9k??XV-tOrJ(k)ZV}?hKp?`#GBQ<3^lUM~VS$5B-pOfJQbEyEFlTa2xbK`7F$O`N_f$=Ev%ASseVS zG9x{?U0Oh)VHFNI+Yu5bCizWFC0j4yK;J)-z6mD4P5Y^xdJOnh z%y8=sG*}HF*1T98N<01<%f(Bw#N#m(h!)K^LoqcRqZMugS(aDy#~$49;a}w&Wq;zB z&MmaTfOalX6;-OGvqPS$ev2#3#|Uj?ie5eJvE)XdC&2(Ry*!zYBTf;pH>)qZ_$8Ig zvPN~xp!VvHV4mxCGsX^gqt4ON;=EuFK1oKGLbB56V;wUr-eu69oMbkBVjC@0bs_5Y z+Ujr6%Dv2^zC*$gXexjl7@2`PGo;d4=*#yF~dDA5c#Y@cUUk7@BWj@;l0qKNPtt$5a^u@B5RUAC1b(=Z%Owb zr1&3N7|Var!kAh9j&%Q0&Hi=LjZz%90%d~x%cSN^zffy4swYgzLK=h*3j6NcMHriS zG`C&tb|EV@7ifTFR`4x~G={*sYuE8oSA>4nHJ12gyLtjA$)LxdBURYS@ zGk6u%59=NBC<}kazCzP-@`XQrqem-0ZI|EdsV+@Gu`^sATYMMFt`C-=tf7WRYW8k} zUybqrIu-_r+X|@=M)a}|EGf)QMT@nhy#nnpCvgf6_mysXAWYtt4Ris|qH9rMX%;83 zTF;joFEqg7S5q0*Y1u(wijy0&6DK?#85ISbIABu?bRw&n$nZJn+NfKt#Z~L?r}sZK zSwceQ@Bd{j%KV=a{4XU}1>j&x$e_pL`>Z*jZKxrh5o;$(sNx%9rWQPNb5X?OX;nMqrzVz#y5JW5oAnE zyi8$YQAM3lE23cMosSwQ?O&bJtaJ&lB&kFd=^;VbCCiYKp`o2!}J>vo{T@;S7G^34LWKDeT)ENM4=KV!H=TJp{FFp*d6oERr1 zN-(bf(D7(d_VG=67wP>FdeveWR!X%MS4*!i)kzeyqIq2t8Vr8qjI@$kQ>ZHLh>ohK zXOZdu>WDTg*jfEC3N|YPw!w%8`1|zR`A^7Goxrreoc@U4P~LLo%!zaO#2os9k%p9Z zjH+xJQAf1C$`;*Vg#41){Z+(BT19VEM(By>f%nP)BBkc497=SMilUJi6TWkB1qiEg z(t{qbECb6#zk!J@LZ%5QCzMwf-#pl**7U07wT-1()-TkhJyo_hq|NIhd=qk!2QI` zirP~A_He28G7VYVGRWkYjZvWt%vTGSqROsCMORn(Y?S+eO39+FPPnBk&-&c>Jrt$f zGc3mScmU85!!lg zogyJnOV1Iz#4J`MM+@8eCGZbKsw7FAzWeLQ;9BJ`FT;8_wtIrX@L#n7_l7}D2+xV#hhqtg#@&r86c;sNtnV4YmZ^XBLr;jHe7Qe%3eP53@8u);GsQjmBR-}#tBx6X zJ1iZzS<8-gT%iOf3$UW;e&zG*923kknDplh5v6T>6VKWM=%XxBPw4?c{^!Ax<-v5d zhSt4JLFki2vjdaCI`F2DCO&o01D|VV?1f8j`)i@Jo0Fx6<0!j)4J6>;;Dh?Gr~A_H z(U(e=p(N18FrQR26okh8884Jql=UPa1;;mf5b4K9#7}1&#RLxgvHL?#^;>T!e3&0{ zLijOKfk5qM@)F;T3^idQwZfP$?Z4)bXF{HA8B!4!xC1eO!t*CM6{*o zh5Xb#x96*trPCPZl9Ec4E@!}@9!J*d-qH@)I?4R2&w91IjDX0DE*@(C*&4>S1pDEr zKyTVImr87M67-P0mrD?SbVwNmWum#kbB?~_8j5t&QFSWiqA??J0Bw?Tkpyg2{=^L} z$#ce5(J^Y*RYI*Q6Ch%^@>0r)w}K*lh;l%+c-MSNpGX|dph~kj)_&hwA+1S0F}_Zz z-0J4qwmkT8bi20TpL`*`ACQRm+?yBvMNZHBXUW3o7Loc>>H~rh!Ft1gK%j0aK!rv z*xMLb)a0$DiJt{Y%;xi*?4t0pL?gn>~zWf z;l%~{%EXnK%8slelbrhO0t_p6749l}wLkqisYP!qeTCz{F2Xb=K9vLz29cOVe%y7s)cXl;PlCJ3{W1=&f#t)>ou zqs1Yeo*iv~IypABfFF*{d4LjXdafk5%uG5!k_OubW8Ep%ad34N1Jodxn3>3L3it@k)twGyD z&NVsU31neX83=a4IOr);T@&$X5H9DOyCbzJ*SUhoI`w(HI_sMNIu~x@FGiNNa+gQf zgDxq^iG=7cxwOOlzgi!zfkY5RQ@b)^?|e`T{HMTC)`2z(%dhL1NMDpxEJaf$Gm$=p zGr9s3aV0cpW0om0hY?*FQ($FHDEGT73IN)pqF=~-F(Zl~y`8Ea{~xIK^1An$&}FYE zKqiW?a#>gEvLPF#B&bV6Qb4~jF5%2t?=CVVyq2vwqhsKLb{bO9_E z83~J-8oXFg2Q$=;hR9Kx9*Lj{ueO)e-_fs90c7AkmZgAB@=HW6BQ>V>p0Hd}~_ zDVO-2z|FlgWIgo-K?Vkux~spC9D+iU95D8 zr)2il6`<6$Ni!FY)9msW@xn9BSR9@}r~OL@b)}F>3SX@RIBOS050VLYxvft{XAdMu zW)K|r%HbK;kxf)@IHo4Ii_sI5CcrmvF}8zVsvgmV7@|)FEhlf4iEM)4LzD;71MhA8 z2O6|qNQZN>M<%;dMX8@jF$x0#^iC%ubJKx@kjRSn0}sYjQ0Q-%^!o@@v+sr8YzNhZ zJT|nqv*#jnQ&tb+nHzYytDBLpn9zcOq(c2KjJX^l(nfu6ez~;)6(k2-zIy~l`=GNe zF~fWc5CyER4!(CYU_y03aX$j%HF)Ff)sAe1NB4x9^01Jg3R&D;Vl`wcKJ_YmD$F2N zAmhLo3D;-RE3b>biCN}4oeBO>hD(Fn>zBc&o01)NlA!FQGKYi`ILTw%lieNvFqpMT z`YEe;0W_Pt&dGc(`v8_)QP*fdH~pakZQTCNKAX|89d<_|r#n1CzO|coqW)cXV;a(a z>c~%mMkKQEoq9kV1vHazBdi<1)5XD>Wcr4YEBHrF zKXunta>O=o6(-QOz!}l)kCG0?=ozt)J5$mzsSds0ufRck9{J)JKc13nu10`{2=Xiv zqAxHPggS67bC$3j5g;=!1u^Cbk@F@441zG$cStISo(^nG{H4_3E5#w7odpT6jU%ow zs;5hPY_LU#SiH88-T-{jh%g9*UtS!71oHukCj)MP=u|T!1D2IwVt#ftSzB{cJjLNbEefO0Y8` zZ;Pn=9eqZ^xo^dR#2iP$cf3{Hz$w;K&Zz=TFW5c@SDqTN5T8R; zj?jTxHIsXGl;|u}UsVGQoFN^n*Ii)5_kvUhOa=d>D)HkTEfJgK@S|(xgPz<}G6NPl zRiMien<0)zQLNta8mGoL_)9H=F%1NiR?-UTNbgk}YpR(7zxHS31Kv*489x;(9w!i^ zvh1exM*zA!?34o7iJP0x%4`e|C7~X=OgA_{&cf2}8r8as;3B6p3VXY6Ox!ZoO=Xk) zV*oroDhdxg@D!4;n}{AFrfQs{w@L-~pl2$cbYp!~?0qemeheXJLpV{L!k`{KEiSH% zSzJCmw-WH_IuJlGxrA^B0-tHhJM8yj3n0-BY&fGm*NzxF*qd?I{UP!B1BTu+Bw3j5f@v@oZpT*heuSojckgwkOHmRcLr*#_XHf%oTINAv zo*;z2H^@nSl4qWEWDh*8#!wGJif6((R8?G647huwVH7gD!B!0DOQu}@7u7|j8t4~z ze=x2a{E^KYl%Q>fc9MRC#)I|HdkwC-MsC7mS07Z;9kwVEp70#)27$H_KKU_6G!7gg zXYsBOfskWbB$1B;;C4wDJ6R3r&c_1qLszt~w$zVOjS6UM5e(TkJC1Gll^#V95NJS> z@9&V?I}tLb%#J(s%Z@#>5;48DnfaCPMgU{I`Hox~Fx=ik>$j|$rm0`tbEe@gTSCD3 zKE_%7#+%9CA0Kji8FC2797qwG>fdV=%K>r|0Cx9REdAD-KJy!TV4sMIL`Vk#LjSzQ zf~*28pf@EucFsl=M@Gx=8JD%MgI=vZKo^?8YLCvunwT%(i@?=-mo9@y#-PT}A#$W&;5x9cTJ_ATm;Q-_=d z#SK%>ku*DFtd2O;B9N7ow(^rm@d(az)!qeY*nMa%pdw`tcOb~d+;oXYTk(+wUPn@# z#0+jD^XNxf{92)D3A$U(^%tX2tp~yb(r9R>>SuKPh z8XO#qpKNr!Pu>ob?p$%*14kHwiqIGraqNKOH5r;Q9ZG`|u(#3y7EzuuhitUe3 zf|2TH;0;wFpa;vUN5P1}FZxa(1`u{P^wAB3NIF}NtkH9xY7fEy+JWv;>-#{CmN*}r z2i%|sdzM=^rM_f0)Ek$o8GB{DJZ6XQ`e<7KIMz zqg6bgKYDbJ&UA1K&S^>Xx8+|&wwMPS!_m8y^xIn z2|g|0sW`4~(p_l#;N@!y^!j6zuc_vDKg7@)KiIuXYyZBZ?0y_0$kDTTLNYV#++&Vg zolsRB0lyh;es|@j*fD%dWF!ak<%w#>7HT3g^6uZnBVzf$OFCg$$44_6jn$x}*dOzO zgf!V7{Iahq7P>|x4@HgX48f9G*I$)yX-~2h94Y4f+y&i19PN7Ua5fgZEmMnuqDN5% zer5#2IN5L26z3&b(am4VZ$_v<&lrUJl+ZQ{NfT;cbm$?k|8I zMa5R)M7fw10w1YyyiLmdRTuZ4W~_0!Ursy)FyFKAZ9 zyt#dAVR=bob?ked|G3edbUfPp?!o|}upv4}Rop1G^?nSj{7GZ+BR#9A_~aA!et08iN!|KbKTI&f-gPjq(^W3d^zy1xtC5GDDSx)CDFzWPkq zn=uDwcRLZ#A;1UHagSw!!)%!dlZ-2B58}VC{!?eGLv2HA;bNmF`bJRn#Bd<8>JLKzICPv~k zC;Zmh6g9(-bcwX9?&DZ&OXy8}-Gtn#v20}B%N;T%MAN8+LOzHfz**g&j^uiMtRdxF zfZ=l->S9f1sX;)A5FfX7gypzS)Lby2AL5Qd2#x5d628ezd(>kU3VR=R#DN|kV5U3k zSydo9g2MC~1+(c#?#9#)c@!K8;b-Oqjoq;}KX5jJkKg}YBkRPF(?cGTubG0{h2js< z!6+N;Y65^&GIKVNR*%kdIN_rA2g3Xv3$LvF{IdFwL0yk9!(Za9o`bh-R`Uo@O!CHI zYDOz+bNa)#Ty_ws5>Q*V$kJIwvS7OjEP0(8U;u&K8 z9=iIg&#qo+)Q9gi8Ch=|G|~)Vr5an!sKmU-B2HScRa9#>D_R=bRagPyOv*gXN>%8N zr+90A{2G?EUhf)m1hPhW5~#8?jJh=7wthFNw_vsx8|NfHiup=j50O5(;9A=W;Zv`9nt2FcJ!S(nO)zQ6?R;6 z+jsSUO_2?`LVA&Au!ZHg6}bx#c1d-i3*iQ+_vL3+@?;vwgF}lPyE{^`?>9g`{T3&|K8xI z6)(luV#-KSEdYIOg4L5>LP*C$;hmk}v+$RaS14oUvPL)qJ(1)damS54UM^kl#Tiab zA-C68;%lxlfL-OHOzG&X!A#GrUplucYCvI@3|r0xy}rU0wLGJ23grk6A_uY#+Nl5i zM2IF_L~(~GfFlE@H~iYBcp^!z{R~|l0G;^A)M^V2y=BFf&p4jeINWY=>ZbwdUSCASP<5jh5)t$tea_ico0G3rrC~aQTGFbuD04f zAyy2fzdBWjVqi}lr^fIh2(O4;{yH+~KIR$5d?Ym5Uoe<>OZ|{8e!3fSfL-$0ROU&R z;7QqjchJ16kGsiJc1tA>V>AyNupbVEHh%X(dzX%K1BMe<8MrojM~abDsv+O8C8I=d z57~$+q=0c_t8+6qIM*@D1>DMVu!FwQLC(NF3p4Puae%30xCteiG7@fmJwqEh&EP8; z$H9eG-qLOxy*`VlIEpaa=vjPEcWD%O8Kxb{mi43?=mVX{h80XgFMx!St#D_9yc_(f z#ol$jF77(_zgD5nxpWdrOL?gBZ}8N|1H+rmRow$}0=Mb3c%C-~5>j zyNC36axKLO&LZ=5!~yh$SvI|VC5s-GV5?2lodZEytMq@Vz-X@iR}ZSu>na%I-{Kg# zQuWkHCsl(03m6ATu@VCPOxz{{^u^WU9QUHHhR?#yfy)wMu$%s7p$Z_oUZ`(8w6*qm z49c!}d_sS??etPB!C$ML5v_Z=y(0I&KDlDD5W>9}AAd@JQ4y+-GNqd1o|e>Lp2G|J zFdF-+Py|(=(;`o!5jufSe(vMAWEtVjEa0t)A_p#rsb79~x z0t8L#Ye)NZO{@!pkxf!hLUUrS&1FdzIo{G=K)PP`A7=*3)gPC zD#;>$01v=phiapO$IZ{^-i392NjG(r3vIflML_1Ei7<@98VYzN=BRm2Kt)A7^^A=i9dH&ATweVq&6my*Ye7EY_E7? zGFxz@Bum=p_Mui4FXW}#1MB{RVcx93P`jz{LkUv!{)we7(z7S5vVEWfMVn|}qcmQH zpr&%%{eeAMDz`!=5AO`2v5C!C51gp(==)&o4=0TJT*UE68-3j;r_3j|Mm6j&vGgUK z-m_UcMQc#gRSN?+#YlfxaNi13@cV{mPg7zZDZ>1q=KIW~J7Ct=-yPkK$PTG&3&NsO z1|)3ak0*YYL3d{`w;F%;1y?~q@=>8lA(0L+vZ7H9S4Oesr#9spIo$q=1lXioTDBSE zhoWXvX>4V^PzrH6%cZ|@Yrxle{m8X7?CMTioLu56TMD9SR0iTNoxuN^FE zm#?Ol6ehmdNqhgo=InrVw6Q&~R~GKO=6H4%zM6W9vXgP%EmNqMZ9HSmbO(X)5M&#d z5b&8acpPhanirFWN=6@%7!y0#tCe|Cc}ehXifLpG?N2Kgh7{Ye?I8HVnrLMgC&Xb> zd3M{CfD!mE+t?_`f+VD3tCd%LIrr@Lf=!;4kM+5MGXY~`DJ#J8-*u~slQR@@B6;CF zJJYoCh?vKrA_RmlXzyt1s4|@iiF8EsmOh!8tmt_I<115P4U5==nXrO|I;x=vQxhr< z{n=aTz)e$3v=3>3Xoz%mt1pToCAbdL)H5GdTUw4jkQUj3V2&2uJT2d*9*bL6)C(t# z64D-t)VJSey=EWj;B#&G{_ns8P2XapTvraHS5_klLIx(gz254%M`M zt18QMCf;)mhAVGiMK@XW5E*L-R$0jW$pa+dDVDUzlCeDQz3`o4_tg7yCDe4X@|~WC zgHGa$%mfX;j~sWPcR|78ib;YztewEG35Os6wX~|=DPrKudUh;Jdt`p?=Ge*I51e^a zp6|M1aN-=gMkSz+tcz+?nsm6Z0A^h_Mnj6gu$u@S3c-8OTDqa^4{Mz2dxItS2~iQRjQEFBOn6%V`%x_epbITpv^(x_Iw4iOY&# zCQ%kM7Gk~PWmBnET!)VSS5aKVkHt|B-9m7^VrDE$GN4geT)dgiE*sdQdFWl8+&T|J z;Xzj0Jwir#?(>Q{f2l^svW9%Ej(b-YtopNlBl6n4_vJiZR5@_&7(prL=yHiF?Y zE+pOPnSy8M6&KdH!4pL6gjDtT(GUmD??4!h=Mo^5*vMte)>@pXdM%w2StxkUmrHf- z-%iXmW#3Llgm!p@ zat88_9Ub7$HHxRg-!+9h5p(d3AjgS0Ju#|a?HuQ5qMwLHpD$=qE>vVa7&7Ftp_w^f zO`!86MpyT`tlYDUzf`ZB90MYAJ7xisDMP>e)!ws#eqx%hg?=Dl#b$sent=OhyIJ3U zcH_DbGkg6Tnn5efoFRJ%7L6?Q!}->=P`kMn?}q2VRc{H$R?>dY&j*{jU-T5lpIy4u zE}qa(_#=?v_h0k=c)3opK!&=!H;9=Pq$S|F&K4soma)|~h=cNEd++D)YnY(1bF@KW zCTu?>REvbf9Q<n87rV3XtKSaqLGjYM?2fDUI`1dT7*>bRWqEbSMn}*-O|}2Z zW-N`zr(IsoX3KMql0yDq#L*YlGJ0nmf4+C3zqS8Zw8#Hb_4)W1Lh$p>J_9j!5%Sx| zs1I+K= zR#A`|(hb5GH3lkD(mh%lsS(lxq-zYxA)O;ecaGoQpYQLSowL8TJxR3jI z9=JbhtroNw|J!H;A~sFAX>aC4POKFy5;lXswdtBxxV+L@1hcf*HRdKCY1t(}nVX)V z1*+o)nI5t#Ia7J+hJ{8u_A;dY#}s|*_>}flYUuX>LH=%KteU5A)esIKgu&my%qdM2 z#6(sYt)q?DjY6B79b$8lk&^7$Ix0J4((wM__M^%Tk;BeA#Od;OYJSF}WvTijQ{=&0 zT`Ni?P6)|8Z)`{7ws@eK0%gZ5vnk{2OKfgrq@;Nr{f-Kbk3Ep80Xl$nWI4is*>d7v7QINx0SOoDP(kv|SQ~wq{y^B8YRr5|J&5 z2GF;7@-yiF!uK51$plm{{KWw5y?h!5C8q|W5sYoZsJOg9l~2xV;MYnAY?8^8ciO+W z)2w#RF#+ueW*2w&)@KgZ7;0)aMSer>cW}dljDM1@a%D$`He>fKUIOjUOm)2sn%A>~ z_ZOe*P9_N~lj$kWNedo7?gdQ&EKzrOZ1ef@9=@33NF%MAbp06^EleZ3el)BYEH3Rf z$*m|v^nj8Y|KHtXxW`R%(1aOEf3cvFLH>RKrD0dZ(I`EH>i=6cu)jk(zP4F3E$uW= z=SGt=S8Md==lLFQ?sN-76+8*NQ)G7uy1Ra0S?8_>B*PH=r;HM^DqE%z7^95v? z$GHZUoBkjWxYw0@<^2?G01UkW$4h^E{Pf#8N{1y)63pStx|@-~la#Tno~c+c=Bqu0yR;nnFU#O`E^VEMa*4JTmdo@kN!Ud!9Ds+PAY{d8R>)V}*1E4Jo)y)z0; zUUQljLywr z5|4f9T`m057XGWVULbo5yxo~55o0y=|^7?H?AaWHxC}#e> z#cnHYpt?ZV`tH@UijV5)s{C&as)ghIY$gh#kdxhN{dF15rLOE!><%~MZxQ$ZSTY~9 z5xv){Klp9&UqkChn=CDghn{%9vFkn^a2+!`cnQ+ImmNz|()3R>H`Si55t#Wjcith~ z0QgAY)Oj)q9cL2`jR%*!m)H6UqU%@=%K-RJg>A*PWeaSDJrFR|F?dME)cxXTMyR5 zAO)21{}hNF=1G24BJ>D8L-wn76MNn|c!k7n#Ypl0TOz=K9d}0mB2dWmO>Vch7LC7y zhaR15s^6fCO#$pkDK{vkNiZ;e=+5<5-`P5>XX^}+<@xe@vhI+pO(u36atI^ z(@%!~6IyuKJRtxt^)5c+flxdvbBg#6Ea6cneP6GuIs3Bda)}ehH#6o;jeU>&@qGFu zfe?3me#goqT^lH5%XIk;|INzbPm*M&DSTt{-b#_&);Qz7h{+q#pPNmGiY$oie zfKmeXCHv;o+~e)rpZWD%rvKhMK(!(` z)?g#V<(V~xdLWB9r56e&ENxsL_~8yIJe<8SmqtM=X;Lh>hGWcQW;6JHiFb2qO-w_h zj*AdW<*exCU%aGHl>AoAVk|E*5)C5$G-+sbH-DuJVan-zk?O1tdtW#*bvsOz{McZ_ z(3o9dL1t-O9pU!vyFy4Xcs+w06v0KUk)gK#_x6&6!e2ykgN5)!6POHrb(vgSqd_CN#QdLH@*KQ7)4>oRKt^j7PJwj|5D$ zqZTA4y6Mk4jal9?R}6pbre=N#uQVpUQgEyDLmrYDUq`uyT`tr2x;4DfwB3?!%+Q?t zEFt9(b=3Ikzlx4n<$zVs?_~(^`g?th4DRjEwjnHC^}*aKoDgVdtGrE!!ZNv9jw2|x z6YG`uWUw-H8<-yui*Jj7jBl;d00)RmnT!Mvi|vV7=SwGIwf z+5a+~3Vh>475?EjutK!`KNkIYI{`d+g?)3&2~z;+b!KH3>iVeIW;Jo%H+=g}Qn1ee z51M`m{MZYvg+f`g$)*yeMR-V;+k#8EyH6Fx+-)`(gF z$99XGde4@tE%TxCGhu$QNvF;K)fAf64glJX7q}f5g+{ZU&UIxg zxg6+rq#YmY?%`jQU32JAd5G88{appB!zmil&z_$vfXv2G-Ef&Un986E&A$g zyN_`srQ_>#>UwhB%XW^k8Wb$k0zs8*1X!)NGE;M5YUFZqziyGbZ(AN`lrngo+#aa} zJNq}gc-wHTB*USRFo+}@^=4`)9E%~P=mF{up=t~5SE;o%BM%PdsoYQBYkEB4kmKj% z7h{WsQ4zlmi&2DLuJZ1kxF5U)%s8bCCN%xN3w>|@7kRM@pB)`;_712M^MIYM{#-Fp zQv7{TGof#O0kz~yVH@5(N%a=y!_x+d^=W?vw6orwyAzl_%6h#aYAdj}YU4D2<>T%7 zn-faY+m!s#o8-SgFTi|vCoiP|c-64M+5*lCNI97y)a@Wkr}(6ZyhpS|BXL1@EaFF7^Z*_ozre zeuWE_MWPJaLT)B}R)%VVwydW#be_&yS>=hH?}NaZc32II*G1R5~lsk!O! zuP0a9iiZGwH!pL-zW{`IpxS!c7v+dldu6;sHShK{kQqAS7aoMuN0CVMbAf3vthe?fgmZ;u z+<-10u9fV;wHv99Fb&a_G*e{a93r!M$}) zwzV@8fCO$k(?Z>iLJ@zRwf!2EPQlTEJfYOt{cL`A`nO`@O`}|=^Uf|im!-(22<<;~ zn47rLuV|xVG-HDl7&e|st_;No-BKs9ks}`l+4@Q_ofgK z^~GF=EM@2s(9!v0meNqMmW)VX#PI#|YIL=LhBZU)tS~0quEgo_Iid-(Q2{k_*Kj@; z>Br)u)bGYf&8sQvA_;qQGM>Z>ZehGy7<}Yr9)4LiAnP@A7-N70D^(5#?qv}+pRqicuYn-@@SP!O zJR{^u%*@Li>7|J5*YQfm0-hgk$>&p--fH_M@qQj|l>#=?3w!V499;dM3?4iF<69y; zD;;tTE+3wPx#Sklu>ah@d6oh^u0AMnpbE@f6w*NRWsZlOtCfL(XLB3b3j{qEC8Ac4vx`sZ2A^OaNeQ!<7B5(a; zc2yp<2jZvmcu#)9C20M8Xr=cenz_Z{H`cNKz)68YkhOE1-rY7QWvZw>)Ty$qVt(D? zE8RvUW9mhJID?f;hS?437@dqk{;-W^ZCqi0QwjJXcd$ny;yPdi!dSju?tV)0j&!*O zG~|9K;xFUa=n>63QcJo=(39ht6+o74bVXyeJ?LVf6N$R`H-?knIZ@@qbeTr>$)*TS zbDPKjiOsdkIRgzFc3JEH^cTT&B|6w{`mq}8JGYm2ZuelQ!A0Y-}4K+o;%1 ztv3nMlN6&{0*m$V_HzusmBO^dIZ?qS+#bToonnh9UbDWD;s6t^A4Nn&pfU$Zr!b)k zU@F-_VR(MSgWa%cRz;7eynw^;e$l>)Ax-@i@P@lPFvZ8S_X)glPT+9eAPXd*d0Qx1 z0MW2qU!L-=P`f_UJno(FWy`@qZKE!HhAW0bUkn)mL>k#C;RMpMTKslllW2jBEa*d_L5mqwK3BJRwq`ZB=*vyxKRG{c5 zyC#jW`{ES}kHz)vtskPqROPha3hQUJ(`E|wONn~x!<^JGby)}FITcxy^Z zhV^Ni3P!$8QS{3QXy& zIW3P%TPh`FSG(MYMhLG=12$?u{cv)%r9GVfr5Kkc3wV81^4DrzFKZsRq^|6@e9>cJxJ29U77jy2@wV0wNF=@(&KUHRPIHyrQTW!(9Y3u z5U#UxAguqc@BKWFvzoWbYdGKlp!OBr?)G)t)a$v~cG73`P!ObSv$e&4#ldzjdi2A* z%@H~oWeRaYiSd3GsR8rVNW~t^_4r&#q+c_-DcdHnue1ao1VHAU)Z(fN5BCnawCS86-$M+yTuFejiSPEA8G@sqe^MxD#Xf^XvTU1wmrUIQi2Kn!AUTEv} zVtKg}!)C3&3gJ7S`Gk^ z-aadGWhl0b`-DuFfvZN)Pv&!rymp4py4hHvQ7+!W2ppXn+~U^u-25`HYO!#5q{7kBd09KxSX;Kgd*6B4^I=Me zzj_HfcQT@*dEVE|yJ(H)54I%rH#1U?<_5ThiGv0=`cuN#Ksnz?&|)Gjd-F?kw`Kyr zEL|61lWSm14^iQ_LjWk{5B8O`;SydBSAx|JCIS+BKK&&sz1p$Frlovo0T~XGnxT*g zXsu6iMo0vnWHJg26bd#=Idsn%Y3(6DeufN`#UJRqMKPMMieZ}4*XimV>UsUdoB-M` z3@pw1RmzoP&3+?K0=t#&mu+{Qbi#Euep-C1PcAcsf_6)0Y77@Lo9q0QK25avwxtXK zO{Hxxb5#kukxVArfYY8ncLw$H662;uOEb4ywrs&odecgQwHIY5SdQAxs$1KW&U2GH z2;mW*tDP)1uH>EUC3Yz{$m;P)D8egqvdfX?-DrZR;Z4UNkiFXKxnRwb!V387KcCct z)`4?Vt2$G=Zxy0@jm98Ucrur5IGfg;be>%d(LK8-7 zj#cSM>$hjz#h3iZK{(B~$p-97A$;!UJWDXt>$K!hwc7Z%Pe|6 z&Qf)7nf@&oh(qK)mGBjs)P2%Lfo~n9nDpdIR=?7)ycVG@g)yX!^1ARaJbO_(@#Lb< zfc``sx){s=EY=#qqknM9UHD22UxFD`6bgzbu4AGf&|H(n)8JO3>_VN-=lM5EZ;&NI z-AAp!(_J~<-ac!ce~P<7Hkl#4*V~CxPSa~|=b-ZBbJ85bXJyu32K!Mk(SYNc;pri-HP)zu32`^2DH6$uQ1m5W7QOGX zEZ6H_KC!7WoKHn;qqeI2T8TO(9Yy-~W@>lM;*IOj^1#B+;M}V1^)AX`@Lh@|-@82E+@jv<_p7EkeVWQai zDSn$g-g&l7cdPx%Z|3){&u-z!=vQ3lR{aVB5GO~z0>8r1ZS&q+^Ab&xT0?F1KWPj|Lr zT5{S)pOc;m4~(e;__>kGTRPCe7T%{~ck}q-mxD9#>@C;XHd$p5`aodE5ysf5)^c0l z+vaq1J*)@*ym#o{2Uv(AP0r`#rAwMO*q*0$C0wZvs{B6e$2ZXv#cXD3%E3c1buFde zSjL$=DIrWERHY`1dZ!+k$(meM_=?*=4E`PcuSmgQMl&Sl>IoWK@ z^?a0*_p{E(w+mI8^~9)5h~4Zpga(rwlWnHtikTA|bB#&!vFa+mTg2JJZtBr`#Zx|f zMxxjjaXBE@dOINB=J$#W3%Dqc1*wap;+%H01yOJFgTE~>XBwULc#mamNHO~`^-j{~ z{;^sR_Q_p;@e^bg0Q4|0p=N?pDy3IRC_uVf&%wPl=<2^h3n^7x3b%h!6ZId78JA1z zWeZ7#!O%QBJu6%~cle^&=_beNEMiej_-^Ev@twIE(xWC8v%>kGNod-ac7Gwd87(en zBRp;JthP__SAWi=Z!SAgP{??F_DvyngcVj7H zv16@@rZ6-^frgpkSA%}m)OAHbRr9jbrI*hNwm0kIpa89V-D+XlW?m;~&RQX-|9P|e zDd%%TdclwT8+kEGxbu~OfB=7poMzy0ZXEP*wZGiBcI$7>OKoj3xk<{$qJMgOi7h!6 zcXrBQvH}97CiSjD#=keFs;pkUy4S_c&5gLgqz|RbghJlEi#L9Bh=5i7y!YCKmQB%5 zk~=77wL1rvEM&6$*w-Djj&d0*B#$S#RZ~~*R4+HF&l0!!(FNgs%Vy+(go(X*;?G1! z$J4*Dy82z4+kvQ>lcOqs*Lo~Axblo`i5+2Hoopo52G<7S zuH8xe*+Kz()cQW5{H33sEd?a;vjq06V_C?FQ$ z|43~gH+LIQ`|`+^0xx#iRM}^f*yH8$odbt#Dt!WTb|O!eZU)p>D%{mm-=huQ8yLPf zFfcHjOk8L&G&AY!8OK{?&S%V@=wNzy3a=|{u5N-wOfVLz2-oit^D_9}{@(DOxbz5^ zZ>6Qer~NS3LF)&fpfIC+oAq%SH6;f)!L=#6MQ(OwnhG6(A_N7V8_hHaPRl@P+P3IU zE{6G`7{eidi=Hva$_HQ8#IR<`;g@8L)W8%ErQNBM&fBcxQQ;o%i=osS*Sir%89-^j zo=mYn8-*#p-zc&ei2X9WJ*04w+|AiqYT4QGkdp}Ph`@49_VT45f7XhZt>}JJ3*&P~ zMD+WY9pC;Ma&-D|ipThRe@91`Zs(WmfxW(g$LPEY!7D_zZv~ICpUH$5xbTWgZ#N+#*H$mj3?gEere;mv&ng%|*FMfZA6 z$Q64p{M*rm%Feg5JyjH7#wT-L*0JMymKlkP&0mlqsxYhfz#&J*_{dNiG56ki?@ZUm z$D4TX&I*gz1zMQ3_$hL6l{QsBY)zulH|zA#&G5Z`Z*6Pa1c1*hehNoBSS>627D5*o zfH!N(d!ARl`es=HRUBNQW|2klggwhrPLs2ZpmltpyUf%j`PgzVfw7ZGNlE3vmdhxa zd5&O(Bcuc%lj3k$C4pC`uj@}2zAGnfoH+htYsJ5DkLewC!6%${$BGVlJOc{5@y ztj)LT%kx3y9?4z&Q&e73@(%eV{J8|GxZy*oLC!Mnw7%`@z1Kn9FS#exJFv7#y#;N! zODwar^Owk2R-3M5qehQ4s~E+}0H1YhAlYGHM}t`x#C@X9u>I!ISb&Q+xqXO@-AGf znd#_yU%gIjkipE`+$R9pOWOPdXxM$wG^oAQ@HuApYo_VZeFC^v6B|$5ShWL9OL9Sq zPD8!71=EFQFGY>5uAY`oh7@S46#lzD3*B;dw1qInL|Bw6ZPfoPPWx46Q&RHm6P3l3 zijJ@92Puf9*$3YbjG(j0Z8d+%mY^}23Eaw0Rd&lPr`%Q+tZ5!sz7VS~}3Gha}hBfIb&vEWQ zLiJ+7K?;YNYHK+07iTN6+c-jrD_q8OP2ja5G`Ec<<7n{P=%zVw;IzYhy3@-*$|(7G ztJg^qR5`82hs=qCtoD%!2M83{Wf5!}9+wKY@_s4!cha>1DX47&WTwM=#kiWU2E%^O z(soV=Su_$dupb`-c9xixKiPDEpvh24`wRTVbzb);59MOd?m*LhIs8IB0J;pli!^&&lkbF2^a!+1gh0foZlPU`WI~CRdF(3I4mEy)Ik($ zZfs0ul^ePabMrgh9B(u!LhXGpG)zfZNIC>`>*tYgE0n1My|?xc>SvU$MreiuuRO2X z&6@Z^GOUYSCfepy*i?v-5mYlv!H-xdgTGp-+_`^%S2nHq1hwyv>+3yNfuoggj>n#| z@r2ybB+Kq#g(UoZLra)#`8EDYY#_%v5vg%7O#NwHr zb3A>zadWnCyRLjI=QJspNW}9+-bnc3(Juuf0FHJ!F8s}WtrPkM`<;@>U;0Jr>`>3m z(SrPL?z=e-pCy)FRDGyg(-^WF&N36oQc?erQ;DGC{=j?7v&QxHHNgh=XLU_YM@LB} zcb!dD`2AMoUg*TYMY_~_#-AD)tnmx<=53bM{zo61aqYRV-6KGb?-X_6YFBNZqO|`h zDj9v*eXUg$m0?bzmxzWz9iFiJT7O}hx$bO;|xm+OPF za`$qqTPS}%94NPGqCCH8GuII*vDO@fP2&|UC27q`Qc2r!-P=gP{IX&pJ59JSZkY?y zLs$4M3uL)lA^}fmjd{G2J_TPm8HumRzG`X9^~C)cXdH8G&}-TREM4x48HPqa`+WG6 zMfPy^4qBmzvnl)jW`O6w)|tLq_MSe3yl+=I$LAPS^AXs4dM_Hy-$LHr@f;9_2Ez`Q zdrFc(nuXfW4l+Js#5SYX^JmzsDkxaJ9r_wNa;zTSrfVT` z&=-l`X)SQ7x5<>@u8^Z=&&Z(1clbF^$sNNNG@oR1E`!a~D;_rVBT>&%)4*=;rsq
  • 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 bHh~^*uG<@2sG&LYD(+=cQihGOb!huH@Z&L$ literal 0 HcmV?d00001 diff --git a/tools/test/stress2/doc/stress.pdf b/tools/test/stress2/doc/stress.pdf new file mode 100644 index 0000000000000000000000000000000000000000..8c82924129a7953bd559f1a118b65955843731c4 GIT binary patch literal 39840 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 KPF)@k=YIg=hx1VY literal 0 HcmV?d00001 diff --git a/tools/test/stress2/include/stress.h b/tools/test/stress2/include/stress.h new file mode 100644 index 000000000000..3ffb49410a20 --- /dev/null +++ b/tools/test/stress2/include/stress.h @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2008 Peter Holm + * All rights reserved. + * + * 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. + */ + +#ifndef _STRESS_H_ +#define _STRESS_H_ +extern int setup(int); +extern int test(void); +extern void cleanup(void); +extern void options(int, char **); +extern int random_int(int, int); +/*extern void limits(void);*/ + +typedef struct { + int argc; + char **argv; + int run_time; + int load; + char *wd; + char *cd; + int verbose; + int incarnations; + int hog; + int nodelay; + int kill; + int64_t kblocks; + int64_t inodes; +} opt_t; + +extern opt_t *op; + +extern volatile int done_testing; +extern char *home; +extern void rmval(void); +extern void putval(unsigned long); +extern unsigned long getval(void); +extern void getdf(int64_t *, int64_t *); +extern void reservedf(int64_t, int64_t); +extern void show_status(void); +extern int64_t swap(void); +extern unsigned long usermem(void); +#endif diff --git a/tools/test/stress2/io.cfg b/tools/test/stress2/io.cfg new file mode 100644 index 000000000000..38830d6bbd63 --- /dev/null +++ b/tools/test/stress2/io.cfg @@ -0,0 +1,9 @@ +# Stress Test Suite Configuration + +# Default values +. ./default.cfg + +# Only run these three test programs for VFS tests + +export TESTPROGS="testcases/swap/swap testcases/creat/creat testcases/mkdir/mkdir testcases/rw/rw" +export swapLOAD=10 diff --git a/tools/test/stress2/jeff.cfg b/tools/test/stress2/jeff.cfg new file mode 100644 index 000000000000..66345968d635 --- /dev/null +++ b/tools/test/stress2/jeff.cfg @@ -0,0 +1,8 @@ +# Stress Test Suite Configuration + +# Default values +. ./default.cfg + +# Only run these two test programs for VFS tests + +export TESTPROGS="testcases/creat/creat testcases/mkdir/mkdir" diff --git a/tools/test/stress2/lib/Makefile b/tools/test/stress2/lib/Makefile new file mode 100644 index 000000000000..b2f3cfb0efee --- /dev/null +++ b/tools/test/stress2/lib/Makefile @@ -0,0 +1,9 @@ +LIB= stress +SRCS= main.c options.c random_int.c resources.c +INTERNALLIB= true +MK_AUTO_OBJ= no + +.include "../testcases/Makefile.inc" +CFLAGS+=-fPIE + +.include diff --git a/tools/test/stress2/lib/main.c b/tools/test/stress2/lib/main.c new file mode 100644 index 000000000000..e7267fff2ed9 --- /dev/null +++ b/tools/test/stress2/lib/main.c @@ -0,0 +1,212 @@ +/*- + * Copyright (c) 2008 Peter Holm + * All rights reserved. + * + * 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. + * + */ + +/* Main program for all test programs */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stress.h" + +volatile int done_testing; +static int cleanupcalled = 0; +char *home; + +static pid_t *r; + +static void +handler(int i __unused) +{ + int j; + + done_testing = 1; + for (j = 0; j < op->incarnations; j++) { + if (op->verbose > 2) + printf("handler: kill -HUP %d\n", r[j]); + if (r[j] != 0 && kill(r[j], SIGHUP) == -1) + if (errno != ESRCH) + warn("kill(%d, SIGHUP), %s:%d", r[j], __FILE__, __LINE__); + } + if (op->kill == 1) { + sleep(5); + /* test programs may have blocked for the SIGHUP, so try harder */ + for (j = 0; j < op->incarnations; j++) { + if (op->verbose > 2) + printf("handler: kill -KILL %d\n", r[j]); + if (r[j] != 0) + (void) kill(r[j], SIGKILL); + } + } +} + +static void +run_test_handler(int i __unused) +{ + + done_testing = 1; +} + +static void +exit_handler(int i __unused) +{ + + _exit(1); +} + +static void +callcleanup(void) +{ + if (cleanupcalled == 0) + cleanup(); + cleanupcalled = 1; +} + +static void +run_tests(int i) +{ + time_t start; + int e; + + signal(SIGHUP, run_test_handler); + signal(SIGINT, exit_handler); + atexit(callcleanup); + setup(i); + if ((strcmp(getprogname(), "run") != 0) && (op->nodelay == 0)) + sleep(random_int(1,10)); + e = 0; + start = time(NULL); + while (done_testing == 0 && e == 0 && + (time(NULL) - start) < op->run_time) { + e = test(); + } + callcleanup(); + exit(e); +} + +static void +run_incarnations(void) +{ + int e, i, s; + + e = 0; + signal(SIGHUP, handler); + for (i = 0; i < op->incarnations && done_testing == 0; i++) { + if ((r[i] = fork()) == 0) { + run_tests(i); + } + if (r[i] < 0) { + warn("fork(), %s:%d", __FILE__, __LINE__); + r[i] = 0; + break; + } + } + for (i = 0; i < op->incarnations; i++) { + if (r[i] != 0 && waitpid(r[i], &s, 0) == -1) + warn("waitpid(%d), %s:%d", r[i], __FILE__, __LINE__); + if (s != 0) + e = 1; + } + + exit(e); +} + +static int +run_test(void) +{ + pid_t p; + time_t start; + int status = 0; + + if (random_int(1,100) > op->load) + return (status); + + show_status(); + + start = time(NULL); + done_testing = 0; + fflush(stdout); + rmval(); + p = fork(); + if (p == 0) + run_incarnations(); + if (p < 0) + err(1, "fork() in %s:%d", __FILE__, __LINE__); + while (done_testing != 1 && + (time(NULL) - start) < op->run_time) { + sleep(1); + if (waitpid(p, &status, WNOHANG) == p) + return (status != 0); + } + if (kill(p, SIGHUP) == -1) + warn("kill(%d, SIGHUP), %s:%d", p, __FILE__, __LINE__); + + if (waitpid(p, &status, 0) == -1) + err(1, "waitpid(%d), %s:%d", p, __FILE__, __LINE__); + + return (status != 0); +} + +int +main(int argc, char **argv) +{ + struct stat sb; + int status = 0; + + options(argc, argv); + + umask(0); + if (stat(op->wd, &sb) == -1) { + if (mkdir(op->wd, 0770) == -1) + if (errno != EEXIST) + err(1, "mkdir(%s) %s:%d", op->wd, __FILE__, __LINE__); + } else if ((sb.st_mode & S_IRWXU) == 0) + errx(1, "No RWX access to %s", op->wd); + if (stat(op->cd, &sb) == -1) { + if (mkdir(op->cd, 0770) == -1) + if (errno != EEXIST) + err(1, "mkdir(%s) %s:%d", op->cd, __FILE__, __LINE__); + } + if ((home = getcwd(NULL, 0)) == NULL) + err(1, "getcwd(), %s:%d", __FILE__, __LINE__); + if (chdir(op->wd) == -1) + err(1, "chdir(%s) %s:%d", op->wd, __FILE__, __LINE__); + + r = (pid_t *)calloc(1, op->incarnations * sizeof(pid_t)); + + status = run_test(); + + return (status); +} diff --git a/tools/test/stress2/lib/options.c b/tools/test/stress2/lib/options.c new file mode 100644 index 000000000000..a081ca4c6c84 --- /dev/null +++ b/tools/test/stress2/lib/options.c @@ -0,0 +1,268 @@ +/*- + * Copyright (c) 2008 Peter Holm + * All rights reserved. + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "stress.h" + +static opt_t opt; +opt_t *op; + +static char path[64]; + +static void +usage(const char *where) +{ + const char *help; + + if (where != NULL) + printf("Error in \"%s\"\n", where); + fprintf(stderr, "Usage: %s [-t | -l | -i | -d | -h | -k | -v]\n", getprogname()); + help = " t : time to run test\n" + " l : load factor 0 - 100%\n" + " i : max # of parallel incarnations\n" + " d : working directory\n" + " h : hog resources\n" + " k : terminate with SIGHUP + SIGKILL\n" + " n : no startup delay\n" + " v : verbose\n"; + printf("%s", help); + exit(EX_USAGE); +} + +static int +time2sec(const char *string) +{ + int r, s = 0; + char modifier; + r = sscanf(string, "%d%c", &s, &modifier); + if (r == 2) + switch(modifier) { + case 's': break; + case 'm': s = s * 60; break; + case 'h': s = s * 60 * 60; break; + case 'd': s = s * 60 * 60 * 24; break; + default: + usage("-t"); + } + else + usage("-t"); + return (s); +} + +static char *gete(const char *name) +{ + char *cp; + char help[128]; + + snprintf(help, sizeof(help), "%s%s", getprogname(), name); + cp = getenv(help); + if (cp == NULL) + cp = getenv(name); + return (cp); +} + +static void +environment(void) +{ + char *cp; + + if ((cp = gete("INCARNATIONS")) != NULL) { + if (sscanf(cp, "%d", &op->incarnations) != 1) + usage("INCARNATIONS"); + } + if ((cp = gete("LOAD")) != NULL) { + if (sscanf(cp, "%d", &op->load) != 1) + usage("LOAD"); + } + if ((cp = gete("RUNTIME")) != NULL) { + op->run_time = time2sec(cp); + } + if ((cp = gete("RUNDIR")) != NULL) { + op->wd = cp; + } + if ((cp = gete("CTRLDIR")) != NULL) { + op->cd = cp; + } + if ((cp = gete("HOG")) != NULL) { + op->hog = 1; + } + if ((cp = gete("KILL")) != NULL) { + op->kill = 1; + } + if ((cp = gete("NODELAY")) != NULL) { + op->nodelay = 1; + } + if ((cp = gete("VERBOSE")) != NULL) { + if (sscanf(cp, "%d", &op->verbose) != 1) + usage("VERBOSE"); + } + if ((cp = gete("KBLOCKS")) != NULL) { + if (sscanf(cp, "%jd", &op->kblocks) != 1) + usage("KBLOCKS"); + } + if ((cp = gete("INODES")) != NULL) { + if (sscanf(cp, "%jd", &op->inodes) != 1) + usage("INODES"); + } +} + +void +options(int argc, char **argv) +{ + int ch; + + op = &opt; + + op->run_time = 60; + op->load = 100; + op->wd = strdup("/tmp/stressX"); + op->cd = strdup("/tmp/stressX.control"); + op->incarnations = 1; + op->hog = 0; + op->kill = 0; + op->nodelay = 0; + op->verbose = 0; + op->kblocks = 0; + op->inodes = 0; + + environment(); + + while ((ch = getopt(argc, argv, "t:l:i:d:hknv")) != -1) + switch(ch) { + case 't': /* run time */ + op->run_time = time2sec(optarg); + break; + case 'l': /* load factor in pct */ + if (sscanf(optarg, "%d", &op->load) != 1) + usage("-l"); + break; + case 'i': /* max incarnations */ + if (sscanf(optarg, "%d", &op->incarnations) != 1) + usage("-i"); + break; + case 'd': /* working directory */ + op->wd = strdup(optarg); + break; + case 'h': /* hog flag */ + op->hog += 1; + break; + case 'k': /* kill flag */ + op->kill = 1; + break; + case 'n': /* no delay flag */ + op->nodelay = 1; + break; + case 'v': /* verbose flag */ + op->verbose += 1; + break; + default: + usage(NULL); + } + op->argc = argc -= optind; + op->argv = argv += optind; + + if (op->incarnations < 1) + op->incarnations = 1; + if (op->hog == 0) + op->incarnations = random_int(1, op->incarnations); + if (op->run_time < 15) + op->run_time = 15; + if (op->load < 0 || op->load > 100) + op->load = 100; +} + +void +show_status(void) +{ + char buf[80], pgname[9]; + int days; + time_t t; + + if (op->verbose > 0) { + strncpy(pgname, getprogname(), sizeof(pgname)); + pgname[8] = 0; + t = op->run_time; + days = t / (60 * 60 * 24); + t = t % (60 * 60 * 24); + strftime(buf, sizeof(buf), "%T", gmtime(&t)); + printf("%8s: run time %2d+%s, incarnations %3d, load %3d, " + "verbose %d\n", + pgname, days, buf, op->incarnations, op->load, + op->verbose); + fflush(stdout); + } +} + +void +rmval(void) +{ + if (snprintf(path, sizeof(path), "%s/%s.conf", op->cd, + getprogname()) < 0) + err(1, "snprintf path"); + (void) unlink(path); +} + +void +putval(unsigned long v) +{ + char buf[64]; + + rmval(); + snprintf(buf, sizeof(buf), "%lu", v); + if (symlink(buf, path) < 0) + err(1, "symlink(%s, %s)", path, buf); +} + +unsigned long +getval(void) +{ + int i, n; + unsigned long val; + char buf[64]; + + if ((n = readlink(path, buf, sizeof(buf) -1)) < 0) { + for (i = 0; i < 60; i++) { + sleep(1); + if ((n = readlink(path, buf, sizeof(buf) -1)) > 0) + break; + } + if (n < 0) + err(1, "readlink(%s). %s:%d", path, __FILE__, + __LINE__); + } + buf[n] = '\0'; + if (sscanf(buf, "%ld", &val) != 1) + err(1, "sscanf(%s)", buf); + return val; +} diff --git a/tools/test/stress2/lib/random_int.c b/tools/test/stress2/lib/random_int.c new file mode 100644 index 000000000000..2f74523ba83c --- /dev/null +++ b/tools/test/stress2/lib/random_int.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2008 Peter Holm + * All rights reserved. + * + * 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. + * + */ + +#include +#include +#include "stress.h" + +int +random_int(int mi, int ma) +{ + return (arc4random() % (ma - mi + 1) + mi); +} + +#ifdef TEST +#include +int +main() +{ + int i, j, min, max, r; + min = 100; + max = 1; + for (i = 0; i < 10000; i++) { + j += (r = random_int(1,100)); + if (max < r) + max = r; + if (min > r) + min = r; + } + printf("Average is %d, min = %d, max = %d\n", j / 10000, min, max); + return (0); +} +#endif diff --git a/tools/test/stress2/lib/resources.c b/tools/test/stress2/lib/resources.c new file mode 100644 index 000000000000..935a085a58de --- /dev/null +++ b/tools/test/stress2/lib/resources.c @@ -0,0 +1,248 @@ +/*- + * Copyright (c) 2008 Peter Holm + * All rights reserved. + * + * 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. + * + */ + +/* Get various resource limits for the tests */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stress.h" + +static int lockfd; +static int dffd; +static int flags; +static char lockpath[128]; +static char dfpath[128]; + +static int64_t +inodes(void) +{ + char path[MAXPATHLEN+1]; + struct statfs buf; + + if (op->inodes != 0) + return (op->inodes); + if (getcwd(path, sizeof(path)) == NULL) + err(1, "getcwd()"); + + if (statfs(path, &buf) < 0) + err(1, "statfs(%s)", path); + if (!strcmp(buf.f_fstypename, "msdosfs")) + buf.f_ffree = 9999; + flags = buf.f_flags & MNT_VISFLAGMASK; + if (op->verbose > 2) + printf("Free inodes on %s (%s): %jd\n", path, + buf.f_mntonname, buf.f_ffree); + return (buf.f_ffree); +} + +static int64_t +df(void) +{ + char path[MAXPATHLEN+1]; + struct statfs buf; + + if (op->kblocks != 0) + return (op->kblocks * (uint64_t)1024); + + if (getcwd(path, sizeof(path)) == NULL) + err(1, "getcwd()"); + + if (statfs(path, &buf) < 0) + err(1, "statfs(%s)", path); + if (buf.f_bavail > (int64_t)buf.f_blocks || buf.f_bavail < 0) { + warnx("Corrupt statfs(%s). f_bavail = %jd!", path, + buf.f_bavail); + buf.f_bavail = 100; + } + if (op->verbose > 2) + printf("Free space on %s: %jd Mb\n", path, buf.f_bavail * + buf.f_bsize / 1024 / 1024); + return (buf.f_bavail * buf.f_bsize); +} + +int64_t +swap(void) +{ + struct xswdev xsw; + size_t mibsize, size; + int mib[16], n; + int64_t sz; + + mibsize = sizeof mib / sizeof mib[0]; + sz = 0; + + if (sysctlnametomib("vm.swap_info", mib, &mibsize) == -1) + err(1, "sysctlnametomib()"); + + for (n = 0; ; ++n) { + mib[mibsize] = n; + size = sizeof xsw; + if (sysctl(mib, mibsize + 1, &xsw, &size, NULL, 0) == -1) + break; + if (xsw.xsw_version != XSWDEV_VERSION) + errx(1, "xswdev version mismatch"); + sz = sz + xsw.xsw_nblks - xsw.xsw_used; + } + if (errno != ENOENT) + err(1, "sysctl()"); + + if (op->verbose > 2) + printf("Total free swap space %jd Mb\n", + sz * getpagesize() / 1024 / 1024); + + return (sz * getpagesize()); +} + +unsigned long +usermem(void) +{ + unsigned long mem; + size_t nlen = sizeof(mem); + + if (sysctlbyname("hw.usermem", &mem, &nlen, NULL, 0) == -1) + err(1, "sysctlbyname() %s:%d", __FILE__, __LINE__); + + if (op->verbose > 2) + printf("Total free user memory %lu Mb\n", + mem / 1024 / 1024); + + return (mem); +} + +static void +cleanupdf() +{ + unlink(dfpath); +} + +void +getdf(int64_t *block, int64_t *inode) +{ + int i, j; + char buf[128]; + + snprintf(lockpath, sizeof(lockpath), "%s/lock", op->cd); + for (j = 0; j < 2; j++) { + for (i = 0; i < 10000; i++) { + if ((lockfd = open(lockpath, + O_CREAT | O_TRUNC | O_WRONLY | + O_EXCL, 0644)) != -1) + break; + usleep(10000); /* sleep 1/100 sec */ + if (i > 0 && i % 1000 == 0) + fprintf(stderr, "%s is waiting for lock file" + " %s\n", + getprogname(), lockpath); + } + if (lockfd != -1) + break; + fprintf(stderr, "%s. Removing stale %s\n", getprogname(), + lockpath); + unlink(lockpath); + } + if (lockfd == -1) + errx(1, "%s. Can not create %s\n", getprogname(), lockpath); + snprintf(dfpath, sizeof(dfpath), "%s/df", op->cd); + if ((dffd = open(dfpath, O_RDWR, 0644)) == -1) { + if ((dffd = open(dfpath, + O_CREAT | O_TRUNC | O_WRONLY, 0644)) == -1) { + unlink(lockpath); + err(1, "creat(%s) %s:%d", dfpath, __FILE__, + __LINE__); + } + atexit(cleanupdf); + *block = df(); + *inode = inodes(); + snprintf(buf, sizeof(buf), "%jd %jd", *block, *inode); + + if (write(dffd, buf, strlen(buf) + 1) != + (ssize_t)strlen(buf) +1) + err(1, "write df. %s:%d", __FILE__, __LINE__); + } else { + if (read(dffd, buf, sizeof(buf)) < 1) { + system("ls -l /tmp/stressX.control"); + unlink(lockpath); + err(1, "read df. %s:%d", __FILE__, __LINE__); + } + sscanf(buf, "%jd %jd", block, inode); + } + close(dffd); +} + +void +reservedf(int64_t blks, int64_t inos) +{ + char buf[128]; + int64_t blocks, inodes; + + if ((dffd = open(dfpath, O_RDWR, 0644)) == -1) { + warn("open(%s) %s:%d. %s", dfpath, __FILE__, __LINE__, + getprogname()); + goto err; + } + if (read(dffd, buf, sizeof(buf)) < 1) { + warn("read df. %s:%d", __FILE__, __LINE__); + goto err; + } + sscanf(buf, "%jd %jd", &blocks, &inodes); + + if (op->verbose > 2) + printf("%-8s: reservefd(%9jdK, %6jd) out of (%9jdK, %6jd)\n", + getprogname(), blks/1024, inos, blocks/1024, + inodes); + blocks -= blks; + inodes -= inos; + + snprintf(buf, sizeof(buf), "%jd %jd", blocks, inodes); + if (blocks < 0 || inodes < 0) + printf("******************************** %s: %s\n", + getprogname(), buf); + if (lseek(dffd, 0, 0) == -1) + err(1, "lseek. %s:%d", __FILE__, __LINE__); + if (write(dffd, buf, strlen(buf) + 1) != (ssize_t)strlen(buf) +1) + warn("write df. %s:%d", __FILE__, __LINE__); +err: + close(dffd); + close(lockfd); + if (unlink(lockpath) == -1) + err(1, "unlink(%s)", lockpath); +} diff --git a/tools/test/stress2/link.cfg b/tools/test/stress2/link.cfg new file mode 100644 index 000000000000..e66c5a24031e --- /dev/null +++ b/tools/test/stress2/link.cfg @@ -0,0 +1,9 @@ +# Stress Test Suite Configuration + +# Default values +. ./default.cfg + +export TESTPROGS="testcases/link/link testcases/swap/swap" +export linkHOG=1 +export linkLOAD=100 +export linkINCARNATIONS=100 diff --git a/tools/test/stress2/load.cfg b/tools/test/stress2/load.cfg new file mode 100644 index 000000000000..d4d70161a790 --- /dev/null +++ b/tools/test/stress2/load.cfg @@ -0,0 +1,18 @@ +# Just a test of the EXCLUDETESTS feature + +# Default values +. ./default.cfg + +###export TESTPROGS="" # Remove comments for test +###export HOG=1 # Remove comments for test + +###export LOAD=100 # Remove comments for test +###export swapLOAD=100 # Remove comments for test +###export rwLOAD=100 # Remove comments for test +###export mkdirLOAD=100 # Remove comments for test +###export creatLOAD=100 # Remove comments for test +###export symlinkLOAD=100 # Remove comments for test +###export swapLOAD=100 # Remove comments for test +###export linkLOAD=100 # Remove comments for test + +EXCLUDETESTS="sysctl|swap|tcp|udp|syscall|mmap|socket|thr|thr1|thr2|shm|badcode" diff --git a/tools/test/stress2/lockf.cfg b/tools/test/stress2/lockf.cfg new file mode 100644 index 000000000000..279814a73a65 --- /dev/null +++ b/tools/test/stress2/lockf.cfg @@ -0,0 +1,9 @@ +# Stress Test Suite Configuration + +# Default values +. ./default.cfg + +export TESTPROGS="testcases/lockf2/lockf2 testcases/lockf/lockf testcases/swap/swap" +export lockf2HOG=1 +export lockf2LOAD=100 +export lockf2INCARNATIONS=100 diff --git a/tools/test/stress2/marcus.cfg b/tools/test/stress2/marcus.cfg new file mode 100644 index 000000000000..855f1dd4e80b --- /dev/null +++ b/tools/test/stress2/marcus.cfg @@ -0,0 +1,24 @@ +# Stress Test Suite Configuration + +# Default values +. ./default.cfg + +# Test configuration for the vop_stdvptocnp implementation + +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/swap/swap +testcases/mkfifo/mkfifo +" diff --git a/tools/test/stress2/misc/1st.sh b/tools/test/stress2/misc/1st.sh new file mode 100755 index 000000000000..00602d67e803 --- /dev/null +++ b/tools/test/stress2/misc/1st.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# stress2 config test: +# Check that diskimage and RUNDIR has not been clobbered in `hostname`. +# Variables must be set like this: var=${var:-value} + +export diskimage=dummy +export RUNDIR=dummy +. ../default.cfg + +[ "`sysctl -in debug.vmem_check`" = "1" ] && + echo "debug.vmem_check must be set to 0" +[ "`sysctl -in debug.vmmap_check`" = "0" ] && + echo "debug.vmmap_check must be set to 1" + +if [ "$diskimage" != "dummy" ]; then + echo "FATAL: diskimage was overwritten with \"$diskimage\"" + exit 1 +fi +if [ "$RUNDIR" != "dummy" ]; then + echo "FATAL: RUNDIR was overwritten with \"$RUNDIR\"" + exit 1 +fi +if [ "`dirname $mntpoint`" != "/" ]; then + echo "FATAL: mntpoint \"$mntpoint\" must be a root directory" + exit 1 +fi +[ -z "`which ruby 2>/dev/null`" ] && echo "Consider installing ruby" +[ -z "`type mke2fs 2>/dev/null`" ] && echo "Consider installing e2fsprogs" +[ -z "`type mkisofs 2>/dev/null`" ] && echo "Consider installing cdrtools" +[ -z "`type mDNSNetMonitor 2>/dev/null`" ] && echo "Consider installing mDNSResponder" +[ ! -x /usr/local/lib/libmill.so ] && echo "Consider installing libmill" + +# Random sanity checks + +df -k $(dirname $diskimage) | tail -1 | awk '{print $4}' | + grep -Eq '^[0-9]+$' || { echo FATAL; df -k $(dirname $diskimage); } + +grep -Eq "^discard" /etc/inetd.conf || + echo "Discard is not enabled in /etc/inetd.conf" +pgrep -Sq inetd || echo "inetd is not running" + +[ `sysctl -n kern.maxvnodes` -le 2000 ] && + echo "FATAL kern.maxvnodes is too small" + +exit 0 diff --git a/tools/test/stress2/misc/256m.sh b/tools/test/stress2/misc/256m.sh new file mode 100755 index 000000000000..79b96010af05 --- /dev/null +++ b/tools/test/stress2/misc/256m.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 scenario with 256MB RAM on a single CPU i386. + +# "panic: ffs_checkblk: bad block -1" seen: +# https://people.freebsd.org/~pho/stress/log/256m.txt +# Fixed by r291743. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +[ `uname -m` = "i386" ] || exit 0 +[ `sysctl -n hw.ncpu` -eq 1 ] || { echo "Single CPU test."; exit 0; } +[ `sysctl -n hw.physmem` -gt $((256 * 1024 * 1024)) ] && + { echo "RAM must be clamped to 256MB for this test."; exit 0; } +[ -f /usr/src/sys/i386/conf/GENERIC ] || exit 0 + +cd /usr/src +make -j 2 buildkernel KERNCONF=GENERIC +rm -rf /usr/obj/usr/src/sys/GENERIC diff --git a/tools/test/stress2/misc/README b/tools/test/stress2/misc/README new file mode 100644 index 000000000000..7b19252cf219 --- /dev/null +++ b/tools/test/stress2/misc/README @@ -0,0 +1,4 @@ +This directory contains various test scenarios. Most are regression +tests for problems fixed. + +The script "all.sh" will run all the test scenarios forever. diff --git a/tools/test/stress2/misc/advlock.sh b/tools/test/stress2/misc/advlock.sh new file mode 100755 index 000000000000..16b67c3f3340 --- /dev/null +++ b/tools/test/stress2/misc/advlock.sh @@ -0,0 +1,245 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# From r238952's commit log: +# The first change closes a race where an open() that will block with O_SHLOCK +# or O_EXLOCK can increase the write count while it waits. If the process +# holding the current lock on the file then tries to call exec() on the file +# it has locked, it can fail with ETXTBUSY even though the advisory lock is +# preventing other threads from successfully completing a writable open(). +# +# The second change closes a race where a read-only open() with O_SHLOCK or +# O_EXLOCK may return successfully while the write count is non-zero due to +# another descriptor that had the advisory lock and was blocking the open() +# still being in the process of closing. If the process that completed the +# open() then attempts to call exec() on the file it locked, it can fail with +# ETXTBUSY even though the other process that held a write lock has closed +# the file and released the lock. + +# https://people.freebsd.org/~pho/stress/log/kostik859.txt +# https://people.freebsd.org/~pho/stress/log/kostik860.txt + +# Fixed by r294204. + +. ../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/advlock.c +mycc -o advlock -Wall -Wextra -O0 -g advlock.c || exit 1 +rm -f advlock.c + +mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 512m -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +cp /usr/bin/true $mntpoint +cd $mntpoint +/tmp/advlock +r=$? +cd $odir + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/advlock +exit $r + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +volatile u_int *share; +char *cmdline[] = { "./true", NULL }; +const char *tp; + +#define SYNC 0 +#define PARALLEL 2 + +#define RUNTIME (1 * 60) + +void +handler(int i __unused) { + + fprintf(stderr, "ALARM from %s.\n", tp); + _exit(1); +} + +void +slock(void) +{ + int fd; + + setproctitle("%s", __func__); + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + tp = __func__; + alarm(2); + if ((fd = open(cmdline[0], O_RDONLY | O_SHLOCK)) == -1) + err(1, "open(%s). %d", cmdline[0], __LINE__); + usleep(500); + close(fd); + + _exit(0); +} + +void +elock(void) +{ + int fd; + + setproctitle("%s", __func__); + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + tp = __func__; + alarm(2); + if ((fd = open(cmdline[0], O_WRONLY | O_EXLOCK)) == -1) { + if (errno != ETXTBSY) + err(1, "open(%s). %d", cmdline[0], __LINE__); + } else { + usleep(500); + close(fd); + } + + _exit(0); +} + +void +stest(void) +{ + int fd; + + setproctitle("%s", __func__); + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + tp = __func__; + alarm(2); + if ((fd = open(cmdline[0], O_RDONLY | O_SHLOCK)) == -1) + err(1, "open(%s). %d", cmdline[0], __LINE__); + + if (execve(cmdline[0], cmdline, NULL) == -1) + err(1, "execve(%s) @ %d", cmdline[0], __LINE__); + + _exit(0); +} + +void +etest(void) +{ + int fd; + + setproctitle("%s", __func__); + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + tp = __func__; + alarm(2); + if ((fd = open(cmdline[0], O_RDONLY | O_EXLOCK)) == -1) + err(1, "open(%s). %d", cmdline[0], __LINE__); + + if (execve(cmdline[0], cmdline, NULL) == -1) + err(1, "execve(%s) @ %d", cmdline[0], __LINE__); + + _exit(0); +} + +int +main(void) +{ + size_t len; + time_t start; + int i, n, r, s; + + len = PAGE_SIZE; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, + -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + signal(SIGALRM, handler); + n = r = 0; + start = time(NULL); + while ((time(NULL) - start) < RUNTIME) { + n++; + share[SYNC] = 0; + if (fork() == 0) + slock(); + if (fork() == 0) + stest(); + + for (i = 0; i < PARALLEL; i++) { + wait(&s); + r += s == 0 ? 0 : 1; + } + if (r != 0) + break; + + share[SYNC] = 0; + if (fork() == 0) + elock(); + if (fork() == 0) + etest(); + + for (i = 0; i < PARALLEL; i++) { + wait(&s); + r += s == 0 ? 0 : 1; + } + if (r != 0) + break; + } + if (r != 0) + fprintf(stderr, "FAIL @ %d\n", n); + + return (r); +} diff --git a/tools/test/stress2/misc/aesni.sh b/tools/test/stress2/misc/aesni.sh new file mode 100755 index 000000000000..c25694fa002a --- /dev/null +++ b/tools/test/stress2/misc/aesni.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# Simple AESNI(4) test. + +kldstat -v | grep -qw aesni || { kldload aesni.ko; loaded=1; } + +../misc/geli.sh + +[ $loaded ] && kldunload aesni.ko + +exit 0 diff --git a/tools/test/stress2/misc/all.debug.inc b/tools/test/stress2/misc/all.debug.inc new file mode 100644 index 000000000000..ea0f2d6a5c58 --- /dev/null +++ b/tools/test/stress2/misc/all.debug.inc @@ -0,0 +1,95 @@ +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# +# $FreeBSD$ +# + +# Example debug include file for misc/all.sh + +pre_debug() { + debug_statfs=`vmstat -m | grep -w statfs | awk '{print $2}'` + debug_freework=`vmstat -m | grep -w freework | awk '{print $2}'` + debug_newblk=`vmstat -m | grep -w newblk | awk '{print $2}'` + debug_pts=`vmstat -m | grep -w pts | awk '{print $2}'` + debug_routetbl=`vmstat -m | grep -w routetbl | awk '{print $2}'` + debug_mount=`vmstat -m | awk '/ mount/{print $2}'` + debug_geom=`vmstat -m | grep -w GEOM | awk '{print $2}'` +# debug_indirdep=`vmstat -m | grep -w indirdep | awk '{print $2}'` +} + +post_debug() { + local debug_new + + debug_new=`vmstat -m | grep -w statfs | awk '{print $2}'` + [ $((debug_new - debug_statfs)) -gt 0 ] && + { printf "stress2: statfs leak: %d/%d.\r\n" \ + $((debug_new - debug_statfs)) $debug_new > $console + debug_statfs=$debug_new; } + + debug_new=`vmstat -m | grep -w freework | awk '{print $2}'` + [ $((debug_new - debug_freework)) -gt 0 -a $debug_new -gt 100 ] && + { printf "stress2: freework leak: %d/%d.\r\n" \ + $((debug_new - debug_freework)) $debug_new > $console + debug_freework=$debug_new; } + + debug_new=`vmstat -m | grep -w newblk | awk '{print $2}'` + [ $((debug_new - debug_newblk)) -gt 0 -a $debug_new -gt 100 ] && + { printf "stress2: newblk leak: %d/%d.\r\n" \ + $((debug_new - debug_newblk)) $debug_new > $console + debug_newblk=$debug_new; } + + debug_new=`vmstat -m | grep -w pts | awk '{print $2}'` + [ $((debug_new - debug_pts)) -gt 0 ] && + { printf "stress2: pts leak: %d/%d\r\n" \ + $((debug_new - debug_pts)) $debug_new > $console + debug_pts=$debug_new; } + + debug_new=`vmstat -m | grep -w routetbl | awk '{print $2}'` + [ $((debug_new - debug_routetbl)) -gt 0 ] && + { printf "stress2: routetbl leak: %d/%d\r\n" \ + $((debug_new - debug_routetbl)) $debug_new > $console + debug_routetbl=$debug_new; } + + debug_new=`vmstat -m | awk '/ mount/{print $2}'` + [ $((debug_new - debug_mount)) -gt 0 ] && + { printf "stress2: mount leak: %d/%d\r\n" \ + $((debug_new - debug_mount)) $debug_new > $console + debug_mount=$debug_new; } + + debug_new=`vmstat -m | awk '/GEOM/{print $2}'` + [ $((debug_new - debug_geom)) -gt 0 ] && + { printf "stress2: GEOM leak: %d/%d\r\n" \ + $((debug_new - debug_geom)) $debug_new > $console + debug_geom=$debug_new; } + +# debug_new=`vmstat -m | awk '/indirdep/{print $2}'` +# [ $((debug_new - debug_indirdep)) -gt 100 -a $debug_new -gt 100 ] && +# { printf "stress2: indirdep leak: %d/%d\r\n" \ +# $((debug_new - debug_indirdep)) $debug_new > $console +# debug_indirdep=$debug_new; } +} + +all_debug=1 diff --git a/tools/test/stress2/misc/all.exclude b/tools/test/stress2/misc/all.exclude new file mode 100644 index 000000000000..f04766c3c2ec --- /dev/null +++ b/tools/test/stress2/misc/all.exclude @@ -0,0 +1,111 @@ +# List of tests not to run, unless the '-a' option is used with run.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 +collapse.sh panic: freeing mapped page 0xfffffe0028ed1d50 20200106 +dd.sh CAM stuck in vmwait 20200116 +devfs4.sh Hang seen 20210210 +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 +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 +gnop7.sh Waiting for patch commit 20190820 +gnop8.sh Waiting for patch commit 20201214 +gnop9.sh Waiting for patch commit 20201214 +gnop10.sh Waiting for patch commit 20210105 +graid1_8.sh Known issue 20170909 +graid1_9.sh panic: Bad effnlink 20180212 +lockf5.sh Spinning threads seen 20160718 +ifconfig2.sh https://people.freebsd.org/~pho/stress/log/log0051.txt 20210210 +maxvnodes.sh Only supposed to work in single user mode 20190412 +maxvnodes2.sh Only supposed to work in single user mode 20190412 +memguard.sh Waiting for fix commit +memguard2.sh Waiting for fix commit +memguard3.sh Waiting for fix commit +memsetdomain.sh May change policy for random threads to to domainset_fixed 20210104 +mlockall2.sh Unrecoverable OOM killing seen 20190203 +mlockall7.sh Needs further investigation 20210123 +nfs15lockd.sh panic: Assertion td->td_realucred == td->td_ucred failed ... 20210211 +Xnfs15lockd2.sh WiP 20200805 +Xnfs15lockd3.sh WiP 20200805 +newfs4.sh watchdog fired. newbuf 20190225 +nfs10.sh Double fault 20151013 +nfs13.sh mount_nfs hangs in mntref 20191007 +nfs16.sh panic: Failed to register NFS lock locally - error=11 20160608 +oom2.sh Hang in pfault 20180324 +overcommit2.sh CAM stuck in vmwait seen 20200112 +pageout.sh panic: handle_written_filepage: not started 20190218 +pmc4.sh ld: error: /usr/lib/libpmc.so: undefined reference 20210124 +pmc5.sh ld: error: /usr/lib/libpmc.so: undefined reference 20210124 +pmc6.sh ld: error: /usr/lib/libpmc.so: undefined reference 20210124 +quota10.sh people.freebsd.org/~pho/stress/log/quota10-2.txt 20200525 +quota2.sh panic: dqflush: stray dquot 20120221 +quota3.sh panic: softdep_deallocate_dependencies: unrecovered ... 20111222 +quota7.sh panic: dqflush: stray dquot 20120221 +Xrename14.sh mark136.txt 20200525 +sctp.sh panic: Queues are not empty when handling ... i386 20201104 +sctp2.sh panic: soclose: SS_NOFDREF on enter 20200307 +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/log0049.txt 20210216 +snap9.sh panic: handle_written_filepage: not started 20170722 +snap11.sh panic: handle_written_filepage: not started 20200928 +suj13.sh Stuck with suspfs 20210105 +suj31.sh Stuck with suspfs 20210105 +suj34.sh Various hangs and panics (SUJ + NULLFS issue) 20131210 +Xswap4.sh WiP 20171208 +swapoff2.sh swap_pager_force_pagein: read from swap failed 20171223 +swapoff5.sh log0005.txt, known issue 20210111 +systrace.sh WiP 20200227 +systrace2.sh WiP 20200227 +syzkaller11.sh WiP 20200721 +syzkaller15.sh WiP 20200712 +syzkaller16.sh WiP 20200620 +syzkaller17.sh WiP 20200630 +syzkaller19.sh WiP 20200712 +syzkaller25.sh WiP 20201116 +syzkaller28.sh WiP 20201120 +syzkaller29.sh May change policy for random threads to to domainset_fixed 20210104 +syzkaller30.sh May change policy for random threads to to domainset_fixed 20210104 +truss3.sh WiP 20200915 +unionfs.sh insmntque: non-locked vp: xx is not exclusive locked... 20130909 +unionfs2.sh insmntque: mp-safe fs and non-locked vp is not ... 20111219 +unionfs3.sh insmntque: mp-safe fs and non-locked vp is not ... 20111216 + +# 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 +nfs6.sh +nfs11.sh vmwait deadlock 20151004 +nullfs8.sh +tmpfs18.sh mntref hang seen 20191019 diff --git a/tools/test/stress2/misc/all.exclude.pae b/tools/test/stress2/misc/all.exclude.pae new file mode 100644 index 000000000000..281eff644e77 --- /dev/null +++ b/tools/test/stress2/misc/all.exclude.pae @@ -0,0 +1,11 @@ +PAE tests + +# crossmp7.sh +# zfs.sh +# zfs2.sh +# zfs3.sh +# zfs4.sh +# zfs5.sh +# zfs6.sh +# zfs7.sh +# zfs8.sh diff --git a/tools/test/stress2/misc/all.sh b/tools/test/stress2/misc/all.sh new file mode 100755 index 000000000000..58bf3a630294 --- /dev/null +++ b/tools/test/stress2/misc/all.sh @@ -0,0 +1,255 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2009, 2012-13 Peter Holm +# All rights reserved. +# +# 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. +# + +# Run all the scripts in stress2/misc. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +# Log and config files: +sdir=/tmp/stress2.d +mkdir -p $sdir +allconfig=$sdir/`hostname` # config file +allfaillog=$sdir/fail # Tests that failed +alllast=$sdir/last # Last test run +alllist=$sdir/list # -o list +alllog=$sdir/log # Tests run +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 +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 "$@"` +[ $? -ne 0 ] && + echo "Usage $0 [-a] [-c] [-l ] [-m ] [-n] [-o] []" && + exit 1 +set -- $args +for i; do + case "$i" in + -a) all=1 # Run all tests + echo "Note: including known problem tests." + shift + ;; + -c) rm -f $alllast # Clear last know test + rm -f $alllist + shift + ;; + -l) loops=$2 # Number of time to run + shift; shift + ;; + -m) minutes=$(($2 * 60)) # Run for minutes + shift; shift + ;; + -n) noshuffle=1 # Do not shuffle the list of tests + shift # Resume test after last test + ;; + -o) loops=1 # Only run once + shift + ;; + --) + shift + break + ;; + esac +done + +export allconfig +if [ ! -f $allconfig ]; then + echo "Creating local configuration file: $allconfig." + ../tools/setup.sh || exit 1 +fi + +. ../default.cfg + +# Sanity checks +minspace=$((1024 * 1024)) # in k +[ -d `dirname "$diskimage"` ] || + { echo "diskimage dir: $diskimage not found"; exit 1; } +[ `df -k $(dirname $diskimage) | tail -1 | awk '{print $4}'` -lt \ + $minspace ] && + echo "Warn: Not enough disk space on `dirname $diskimage` " \ + "for \$diskimage" +[ ! -d $(dirname $RUNDIR) ] && + echo "No such \$RUNDIR \"`dirname $RUNDIR`\"" && + exit 1 +[ `sysctl -n hw.physmem` -le $((3 * 1024 * 1024 * 1024)) ] && + echo "Warn: Small RAM size for stress tests `sysctl -n hw.physmem`" +[ `df -k $(dirname $RUNDIR) | tail -1 | awk '{print $4}'` -lt \ + $minspace ] && + echo "Warn: Not enough disk space on `dirname $RUNDIR` for \$RUNDIR" +id $testuser > /dev/null 2>&1 || + { echo "\$testuser \"$testuser\" not found."; exit 1; } +probe=`dirname $RUNDIR`/probe +su $testuser -c "touch $probe" > /dev/null 2>&1 +[ -f $probe ] && rm $probe || + { echo "No write access to `dirname $RUNDIR`."; exit 1; } +[ `swapinfo | wc -l` -eq 1 ] && + echo "Consider adding a swap disk. Many tests rely on this." +mount | grep -wq $mntpoint && + echo "\$mntpoint ($mntpoint) is already in use" && exit 1 +[ -x ../testcases/run/run ] || + (cd ..; make) +ping -c 2 -t 2 $BLASTHOST > /dev/null 2>&1 || + { echo "Note: Can not ping \$BLASTHOST: $BLASTHOST"; } +echo "$loops" | grep -Eq "^[0-9]+$" || + { echo "The -l argument must be a positive number"; exit 1; } +[ `grep "^[a-zA-Z].*\.sh" $alllocal 2>/dev/null | wc -l` -ne 0 ] && + echo "Using $alllocal" + +find `dirname $alllast` -maxdepth 1 -name $alllast -mtime +12h -delete +touch $alllast $alllog +chmod 640 $alllast $alllog +find ../testcases -perm -1 \( -name "*.debug" -o -name "*.full" \) -delete +tail -2000 $alllog > ${alllog}.new; mv ${alllog}.new $alllog +touch $allelapsed +tail -20000 $allelapsed > ${allelapsed}.new; mv ${allelapsed}.new $allelapsed + +console=/dev/console +printf "\r\n" > $console & +pid=$! +sleep 1 +kill -0 $pid > /dev/null 2>&1 && +{ console=/dev/null; kill -9 $pid; } +while pgrep -q fsck; do sleep 10; done + +status() { + local s2 r + + s2=`date +%s` + r=$(echo "elapsed $(((s2 - s1) / 86400)) day(s)," \ + "`date -u -j -f '%s' '+%H:%M.%S' $((s2 - s1))`") + printf "`date '+%Y%m%d %T'` all.sh done, $r\n" + printf "`date '+%Y%m%d %T'` all.sh done, $r\r\n" > $console +} + +intr() { + printf "\nExit all.sh\n" + ./cleanup.sh + exit 1 +} +trap status EXIT +trap intr INT + +[ -f all.debug.inc ] && . all.debug.inc +s1=`date +%s` +while true; do + exclude=`cat all.exclude $alllocal 2>/dev/null | sed '/^#/d' | + grep "^[a-zA-Z].*\.sh" | awk '{print $1}'` + list=`echo *.sh` + [ $# -ne 0 ] && list=$* + list=`echo $list | + sed "s/[[:<:]]all\.sh[[:>:]]//g;\ + s/[[:<:]]cleanup\.sh[[:>:]]//g"` + + if [ -n "$noshuffle" -a $# -eq 0 ]; then + last=`cat $alllast` + if [ -n "$last" ]; then + last=`basename $last` + l=`cat "$alllist" | sed "s/.*$last//"` + [ -z "$l" ] && l=$list # start over + list=$l + echo "Last test was $last,"\ + "resuming test at" \ + "`echo "$list" | awk '{print $1}'`" + fi + fi + [ -n "$noshuffle" ] || + list=`echo $list | tr ' ' '\n' | sort -R | + tr '\n' ' '` + + lst="" + for i in $list; do + [ -z "$all" ] && echo $exclude | grep -qw `basename $i` && + continue + lst="$lst $i" + done + [ -z "$lst" ] && exit + echo "$lst" > $alllist + + pgrep -fq vmstat.sh || + daemon ../tools/vmstat.sh > /tmp/stress2.d/vmstat 2>&1 + + n1=0 + n2=`echo $lst | wc -w | sed 's/ //g'` + for i in $lst; do + i=`basename $i` + [ ! -f ./$i ] && { echo "No such file ./$i"; continue; } + n1=$((n1 + 1)) + echo $i > $alllast + ./cleanup.sh || exit 1 + ts=`date '+%Y%m%d %T'` + echo "$ts all: $i" + printf "$ts all ($n1/$n2): $i\n" >> $alllog + printf "$ts all ($n1/$n2): $i\r\n" > $console + logger "Starting stress2 test all.sh: $i" + [ $all_debug ] && pre_debug + [ -f $i ] || loops=1 # break + sync; sleep .5; sync; sleep .5 + grep -E "^USE_TIMEOUT=1" $i && TIMEOUT_ONE=1 || + unset TIMEOUT_ONE + start=`date '+%s'` + ( + if [ $USE_TIMEOUT ] || [ $TIMEOUT_ONE ]; then + timeout -k 1m 1h ./$i + else + ./$i + fi + e=$? + [ $e -ne 0 ] && + echo "FAIL $i exit code $e" + ) 2>&1 | tee $alloutput + ts=`date '+%Y%m%d %T'` + grep -qw FAIL $alloutput && + echo "$ts $rev $i" >> $allfaillog && + logger "stress2 test $i failed" + grep -qw FATAL $alloutput && exit $e + rm -f $alloutput + printf "$ts $rev $i $((`date '+%s'` - start))\n" >> \ + $allelapsed + [ -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 + while pgrep -q "^swap$"; do + echo "swap still running" + sleep 2 + done + [ $USE_SWAPOFF ] && { swapoff -a; swapon -a; } + [ $all_debug ] && post_debug + [ $minutes ] && [ $((`date +%s` - s1)) -ge $minutes ] && + break 2 + done + [ $((loops -= 1)) -eq 0 ] && break +done +[ -x ../tools/fail.sh ] && ../tools/fail.sh +find /tmp . -name "*.core" -mtime -2 -maxdepth 2 -ls 2>/dev/null diff --git a/tools/test/stress2/misc/altbufferflushes.sh b/tools/test/stress2/misc/altbufferflushes.sh new file mode 100755 index 000000000000..20b1928d5236 --- /dev/null +++ b/tools/test/stress2/misc/altbufferflushes.sh @@ -0,0 +1,98 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. This script caused this panic: + +# panic: lockmgr: locking against myself +# cpuid = 2 +# KDB: enter: panic +# [thread pid 2526 tid 100070 ] +# Stopped at kdb_enter+0x2b: nop +# db> bt +# Tracing pid 2526 tid 100070 td 0xc46f8360 +# kdb_enter(c094247f) at kdb_enter+0x2b +# panic(c09402b6,c46f8360,0,12,c06af5d9,...) at panic+0x14b +# _lockmgr(d864a748,202122,c479f788,c46f8360,c094b01c,12d) at _lockmgr+0x41a +# getblk(c479f6b8,5d51940,0,4000,0,...) at getblk+0x13c +# breadn(c479f6b8,5d51940,0,4000,0,...) at breadn+0x2f +# bread(c479f6b8,5d51940,0,4000,0,e6d13544,c4743eac,0,c095a185,56d) at bread+0x20 +# ffs_alloccg(c47408c4,104,1754628,0,4000,c4743eac,1,c095a185,4d8) at ffs_alloccg+0x11d +# ffs_hashalloc(c47408c4,104,1754628,0,4000,...) at ffs_hashalloc+0x45 +# ffs_alloc(c47408c4,3f2cd,0,1754628,0,4000,c42fd400,e6d13674) at ffs_alloc+0x1a5 +# ffs_balloc_ufs2(c4735d70,fcb34000,0,4000,c42fd400,...) at ffs_balloc_ufs2+0x1619 +# ffs_copyonwrite(c479f6b8,d84e3d08) at ffs_copyonwrite+0x3d3 +# ffs_geom_strategy(c479f7c0,d84e3d08) at ffs_geom_strategy+0xbd +# bufwrite(d84e3d08,4000,d84e3d08,e6d137e4,c070b7a9,...) at bufwrite+0x17a +# ffs_bufwrite(d84e3d08) at ffs_bufwrite+0x282 +# vfs_bio_awrite(d84e3d08) at vfs_bio_awrite+0x235 +# bdwrite(d864a6e8,c4743eac,0,c095a185,57c,...) at bdwrite+0x237 +# ffs_alloccg(c4b54a50,104,1754628,0,4000,c4743eac,1,c095a185,4d8) at ffs_alloccg+0x1f6 +# ffs_hashalloc(c4b54a50,104,1754628,0,4000,...) at ffs_hashalloc+0x45 +# ffs_alloc(c4b54a50,1b00c,0,1754628,0,4000,c4b22a80,e6d139ac) at ffs_alloc+0x1a5 +# ffs_balloc_ufs2(c4e72158,6c030000,0,4000,c4b22a80,...) at ffs_balloc_ufs2+0x1619 +# ffs_write(e6d13b98) at ffs_write+0x2ac +# VOP_WRITE_APV(c0a00e80,e6d13b98) at VOP_WRITE_APV+0x132 +# vn_write(c46c65a0,e6d13c60,c4b22a80,0,c46f8360) at vn_write+0x1f6 +# dofilewrite(c46f8360,4,c46c65a0,e6d13c60,ffffffff,...) at dofilewrite+0x77 +# kern_writev(c46f8360,4,e6d13c60,8430000,d0000,...) at kern_writev+0x36 +# write(c46f8360,e6d13d00) at write+0x45 +# syscall(e6d13d38) at syscall+0x256 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +persist () { + false + while [ $? -ne 0 ]; do + $1 > /dev/null 2>&1 + sleep 1 + done +} + +diskfree=`df -k /var/tmp | tail -1 | awk '{print $4}'` +[ $((diskfree / 1024 / 1024)) -lt 5 ] && echo "Not enough disk space" && exit 1 + +rm -f /var/.snap/stress2 /var/tmp/big.? +trap "rm -f /var/.snap/stress2 /var/tmp/big.?" EXIT INT +persist 'mksnap_ffs /var /var/.snap/stress2' +tresh=`sysctl vfs.dirtybufthresh | awk '{print $NF}'` +sysctl vfs.dirtybufthresh=10 + +cd /var/tmp +for j in `jot 5`; do + old=`sysctl vfs.altbufferflushes | awk '{print $NF}'` + for i in `jot 4`; do + echo "`date '+%T'` Create big.$i" + dd if=/dev/zero of=big.$i bs=1m count=4k status=none + done + sleep 1 + rm -rf /var/tmp/big.? + new=`sysctl vfs.altbufferflushes | awk '{print $NF}'` + [ $new -ne $old ] && echo "vfs.altbufferflushes changed from $old to $new." +done +sysctl vfs.dirtybufthresh=$tresh +rm -f /var/.snap/stress2 diff --git a/tools/test/stress2/misc/alternativeFlushPath.sh b/tools/test/stress2/misc/alternativeFlushPath.sh new file mode 100755 index 000000000000..d122b095902a --- /dev/null +++ b/tools/test/stress2/misc/alternativeFlushPath.sh @@ -0,0 +1,131 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Alternate buffer flush path test (Not verified). +# Regression test for r169006. +# Apply this patch to amplify the problem: +# +# diff -r1.520 vfs_bio.c +# 894c894 +# < if (bo->bo_dirty.bv_cnt > dirtybufthresh + 10) { +# --- +# > if (bo->bo_dirty.bv_cnt > dirtybufthresh /*+ 10*/) { + +. ../default.cfg + +odir=`pwd` +dir=$RUNDIR/alternativeFlushPath + +[ -d $dir ] && find $dir -type f | xargs rm +rm -rf $dir +mkdir -p $dir +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/alternativeFlushPath.c +mycc -o /tmp/alternativeFlushPath -Wall -Wextra alternativeFlushPath.c || + exit 1 +rm -f alternativeFlushPath.c + +for j in `jot 10`; do + /tmp/alternativeFlushPath & +done +wait +sysctl vfs.altbufferflushes + +cd $odir +rm -rf /tmp/alternativeFlushPath $dir + +exit + +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXNOFILE 500000 /* To limit runtime */ + +static volatile sig_atomic_t more; + +static void +handler(int i __unused) { + more = 0; +} + +void +test(void) +{ + int i, j; + char name[80]; + pid_t mypid; + int *fd; + struct rlimit rlp; + + if (getrlimit(RLIMIT_NOFILE, &rlp) == -1) + err(1, "getrlimit(RLIMIT_NOFILE)"); + if (rlp.rlim_cur > MAXNOFILE) + rlp.rlim_cur = MAXNOFILE; + rlp.rlim_cur /= 10; + mypid = getpid(); + fd = malloc(rlp.rlim_cur * sizeof(int)); + + for (i = 0, j = 0; i < rlp.rlim_cur && more == 1; i++, j++) { + sprintf(name, "f%05d.%05d", mypid, i); + if ((fd[i] = open(name, O_CREAT|O_WRONLY, 0666)) == -1) { + warn("open(%s)", name); + more = 0; + break; + } + } + for (i = 0; i < j; i++) { + sprintf(name, "f%05d.%05d", mypid, i); + if (unlink(name) == -1) + warn("unlink(%s)", name); + } + for (i = 0; i < j; i++) { + if (close(fd[i]) == -1) + warn("close(%d)", i); + } + free(fd); +} + +int +main() +{ + more = 1; + signal(SIGALRM, handler); + alarm(20 * 60); + while (more == 1) + test(); + + return(0); +} diff --git a/tools/test/stress2/misc/arp.sh b/tools/test/stress2/misc/arp.sh new file mode 100755 index 000000000000..ef66ce351e24 --- /dev/null +++ b/tools/test/stress2/misc/arp.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# arp(8) seen waiting in "sbwait" (on non HEAD): +# UID PID PPID CPU PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND +# 0 70090 68079 0 20 0 9872 2384 sbwait S+ u0 0:00.32 arp -da + +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 + +start=`date +%s` +for i in `jot 3`; do + while [ $((`date +%s` - start)) -lt 120 ]; do arp -da > /dev/null 2>&1; done & + pids="$pids $!" +done +(cd ../testcases/swap; ./swap -t 2m -i 20 -h -l 100) > /dev/null +while [ $((`date +%s` - start)) -lt 120 ]; do sleep 1; done + +for i in `jot 10`; do + n=`pgrep -f arp.sh | wc -l` + [ $n -eq 0 ] && break + sleep 10 +done +s=0 +if [ $n -ne 0 ]; then + ps -l | grep -v grep | grep arp + pgrep arp | xargs procstat -k + while pkill arp; do :; done + s=1 +fi +wait +exit $s diff --git a/tools/test/stress2/misc/aslr.sh b/tools/test/stress2/misc/aslr.sh new file mode 100755 index 000000000000..6261fae4546b --- /dev/null +++ b/tools/test/stress2/misc/aslr.sh @@ -0,0 +1,46 @@ +#/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# ELF32/64 address map randomization test. + +# "panic: page 0xfffff8103971b840 has queue state" seen in WiP kernel code. +# https://people.freebsd.org/~pho/stress/log/mark087.txt + +old32=`sysctl -ni kern.elf32.aslr.enable` +old64=`sysctl -ni kern.elf64.aslr.enable` + +if [ -n "$old32" ]; then + sysctl kern.elf32.aslr.enable=$((1 - old32)) + ./su.sh + sysctl kern.elf32.aslr.enable=$old32 +elif [ -n "$old64" ]; then + sysctl kern.elf64.aslr.enable=$((1 - old64)) + ./su.sh + sysctl kern.elf64.aslr.enable=$old64 +fi diff --git a/tools/test/stress2/misc/audit.sh b/tools/test/stress2/misc/audit.sh new file mode 100755 index 000000000000..70e1ef8b6977 --- /dev/null +++ b/tools/test/stress2/misc/audit.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 12: page fault while in kernel mode" seen. +# https://people.freebsd.org/~pho/stress/log/audit.txt +# Fixed by: r294137 + +# Test scenario by: kib + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -z "$footshoot" ] && exit 0 + +[ -f /usr/sbin/auditd -a -f /etc/rc.d/auditd ] || exit 0 +pgrep -q auditd && exit 0 +mount | grep -q /var || exit 0 + +service auditd onestart + +sleep 1 +su $testuser -c date > /dev/null + +sleep 1 +umount -f /var +sleep 1 +mount /var + +service auditd onestop + +# Some services react badly to /var being unmounted. +service -R +exit 0 diff --git a/tools/test/stress2/misc/audit2.sh b/tools/test/stress2/misc/audit2.sh new file mode 100755 index 000000000000..1435b13d9768 --- /dev/null +++ b/tools/test/stress2/misc/audit2.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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. +# +# No problems seen. + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +[ -f /usr/sbin/auditd -a -f /etc/rc.d/auditd ] || exit 0 +pgrep -q auditd && exit 0 || service auditd onestart + +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=5m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' + +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}$part; s=$? +mdconfig -d -u $mdstart +service auditd onestop + +exit 0 diff --git a/tools/test/stress2/misc/backingstore.sh b/tools/test/stress2/misc/backingstore.sh new file mode 100755 index 000000000000..b16ff852acd9 --- /dev/null +++ b/tools/test/stress2/misc/backingstore.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 sparse backing store + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +D=$diskimage +export here=`pwd` + +m=$mdstart + +mount | grep "$mntpoint" | grep -q md$m && umount ${mntpoint}$m +mdconfig -l | grep -q md$m && mdconfig -d -u $m + +dd if=/dev/zero of=$D$m bs=100m count=1 status=none || exit 1 + +mdconfig -a -t vnode -f $D$m -u $m + +bsdlabel -w md$m auto +newfs md${m}$part > /dev/null 2>&1 +[ -d ${mntpoint}$m ] || mkdir -p ${mntpoint}$m +mount $opt /dev/md${m}$part ${mntpoint}$m + +n=$m +m=$((m + 1)) + +mount | grep "$mntpoint" | grep -q md$m && umount ${mntpoint}$m +mdconfig -l | grep -q md$m && mdconfig -d -u $m + +truncate -s 500M ${mntpoint}$n/diskimage +mdconfig -a -t vnode -f ${mntpoint}$n/diskimage -u $m + +bsdlabel -w md$m auto +newfs md${m}$part > /dev/null 2>&1 +[ -d ${mntpoint}$m ] || mkdir -p ${mntpoint}$m +mount $opt /dev/md${m}$part ${mntpoint}$m + +export RUNDIR=${mntpoint}$m/stressX +../testcases/rw/rw -t 5m -i 200 -h -n + +while mount | grep -q ${mntpoint}$m; do + flag=$([ $((`date '+%s'` % 2)) -eq 0 ] && echo "-f" || echo "") + umount $flag ${mntpoint}$m > /dev/null 2>&1 +done +mdconfig -l | grep -q md$m && mdconfig -d -u $m + +m=$((m - 1)) +while mount | grep -q ${mntpoint}$m; do + umount $([ $((`date '+%s'` % 2)) -eq 0 ] && \ + echo "-f" || echo "") ${mntpoint}$m > /dev/null 2>&1 +done +mdconfig -l | grep -q md$m && mdconfig -d -u $m +rm -f $D diff --git a/tools/test/stress2/misc/backingstore2.sh b/tools/test/stress2/misc/backingstore2.sh new file mode 100755 index 000000000000..48dc6109f719 --- /dev/null +++ b/tools/test/stress2/misc/backingstore2.sh @@ -0,0 +1,72 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 unmount of a device that is already gone + +# Leaves /mnt6 unmountable and leads to a "panic: 1 vncache entries remaining" +# during shut down. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +D=$diskimage +export here=`pwd` + +m1=$mdstart +m2=$((m1 + 1)) +mount | grep "$mntpoint" | grep -q md$m2 && umount ${mntpoint}$m2 +mdconfig -l | grep -q md$m2 && mdconfig -d -u $m2 +mount | grep "$mntpoint" | grep -q md$m1 && umount ${mntpoint}$m1 +mdconfig -l | grep -q md$m1 && mdconfig -d -u $m1 +[ -d ${mntpoint}$m1 ] || mkdir -p ${mntpoint}$m1 +[ -d ${mntpoint}$m2 ] || mkdir -p ${mntpoint}$m2 + +dd if=/dev/zero of=$D$m bs=100m count=1 status=none || exit 1 + +mdconfig -a -t vnode -f $D$m1 -u $m1 + +bsdlabel -w md$m1 auto +newfs md${m1}$part > /dev/null 2>&1 +mount /dev/md${m1}$part ${mntpoint}$m1 + +truncate -s 500M ${mntpoint}$m1/diskimage +mdconfig -a -t vnode -f ${mntpoint}$m1/diskimage -u $m2 + +bsdlabel -w md$m2 auto +newfs md${m2}$part > /dev/null 2>&1 +mount /dev/md${m2}$part ${mntpoint}$m2 + +# Reversed umount sequence: +umount -f /dev/md${m1}$part +umount -f /dev/md${m2}$part + +mount | grep "$mntpoint" | grep -q md$m2 && umount ${mntpoint}$m2 +mdconfig -l | grep -q md$m2 && mdconfig -d -u $m2 +mount | grep "$mntpoint" | grep -q md$m1 && umount ${mntpoint}$m1 +mdconfig -l | grep -q md$m1 && mdconfig -d -u $m1 diff --git a/tools/test/stress2/misc/backingstore3.sh b/tools/test/stress2/misc/backingstore3.sh new file mode 100755 index 000000000000..2610983da92e --- /dev/null +++ b/tools/test/stress2/misc/backingstore3.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 unmount of a device that is already gone + +# Caused "panic: bundirty: buffer 0xdafaf2c4 still on queue 1" + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +D=$diskimage +export here=`pwd` + +m1=$mdstart +m2=$((m1 + 1)) +mount | grep "$mntpoint" | grep -q md$m2 && umount ${mntpoint}$m2 +mdconfig -l | grep -q md$m2 && mdconfig -d -u $m2 +mount | grep "$mntpoint" | grep -q md$m1 && umount ${mntpoint}$m1 +mdconfig -l | grep -q md$m1 && mdconfig -d -u $m1 +[ -d ${mntpoint}$m1 ] || mkdir -p ${mntpoint}$m1 +[ -d ${mntpoint}$m2 ] || mkdir -p ${mntpoint}$m2 + +dd if=/dev=zero of=$D$m bs=25m count=1 status=none || exit 1 + +mdconfig -a -t vnode -f $D$m1 -u $m1 + +bsdlabel -w md$m1 auto +newfs md${m1}$part > /dev/null 2>&1 +mount /dev/md${m1}$part ${mntpoint}$m1 + +truncate -s 500M ${mntpoint}$m1/diskimage +mdconfig -a -t vnode -f ${mntpoint}$m1/diskimage -u $m2 + +bsdlabel -w md$m2 auto +newfs md${m2}$part > /dev/null 2>&1 +mount /dev/md${m2}$part ${mntpoint}$m2 + +dd if=/dev/zero of=${mntpoint}$m2/file bs=1m > /dev/null 2>&1 + +# Reversed umount sequence: +umount -f /dev/md${m1}$part +umount -f /dev/md${m2}$part + +mount | grep "$mntpoint" | grep -q md$m2 && umount ${mntpoint}$m2 +mdconfig -l | grep -q md$m2 && mdconfig -d -u $m2 +mount | grep "$mntpoint" | grep -q md$m1 && umount ${mntpoint}$m1 +mdconfig -l | grep -q md$m1 && mdconfig -d -u $m1 diff --git a/tools/test/stress2/misc/badcode.sh b/tools/test/stress2/misc/badcode.sh new file mode 100755 index 000000000000..c869c3a8c13e --- /dev/null +++ b/tools/test/stress2/misc/badcode.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC +# All rights reserved. +# +# 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 + +# Run tests on a 2g swap backed MD with UFS SU fs. + +# "panic: SACK scoreboard must not be empty" seen: +# https://people.freebsd.org/~pho/stress/log/full.txt +# Fixed by r310547. + +. ../default.cfg +kldstat -v | grep -q pty || kldload pty # ignore any load failure + +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export LOAD=80 +export rwLOAD=80 +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX + +export TESTPROGS=" +testcases/badcode/badcode +testcases/swap/swap +testcases/sysctl/sysctl +" +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' + +../tools/killall.sh +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +checkfs /dev/md${mdstart}$part +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/badcode2.sh b/tools/test/stress2/misc/badcode2.sh new file mode 100755 index 000000000000..8e47a74a87d1 --- /dev/null +++ b/tools/test/stress2/misc/badcode2.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 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. +# + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +# Freeze seen: https://people.freebsd.org/~pho/stress/log/kostik1241.txt +# Fixed by: r355474 + +. ../default.cfg + +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 +chmod 777 $mntpoint + +export badcodeLOAD=100 +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX + +export TESTPROGS="testcases/badcode/badcode testcases/swap/swap" +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' + +../tools/killall.sh +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +exit + diff --git a/tools/test/stress2/misc/badcode3.sh b/tools/test/stress2/misc/badcode3.sh new file mode 100755 index 000000000000..e0a10d0074a4 --- /dev/null +++ b/tools/test/stress2/misc/badcode3.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 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. +# + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +# No problems seen. + +. ../default.cfg + +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 $newfs_flags md$mdstart > /dev/null +mount /dev/md$mdstart $mntpoint +chmod 777 $mntpoint + +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 +done +wait +cd $here +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +exit + diff --git a/tools/test/stress2/misc/bench.sh b/tools/test/stress2/misc/bench.sh new file mode 100755 index 000000000000..965c9a3d9b99 --- /dev/null +++ b/tools/test/stress2/misc/bench.sh @@ -0,0 +1,300 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# "benchmark" for file system use, using no physical disk. + +. ../default.cfg +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +export LANG=C +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/bench.c +mycc -o bench -Wall -Wextra -O0 -g bench.c || exit 1 +rm -f bench.c +cd $odir + +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 || exit 1 +bsdlabel -w md$mdstart auto + +log=/tmp/stress2.d/bench.sh.log +[ -f $log ] && old=`tail -1 $log | awk '{print $2}'` +tmp=/tmp/bench.sh.tmp +s=0 +for j in `jot 5`; do + newfs -n -b 4096 -f 512 -i 1024 md${mdstart}$part > \ + /dev/null + mount -o async /dev/md${mdstart}$part $mntpoint + /usr/bin/time sh -c "(cd $mntpoint; /tmp/bench)" 2>&1 | \ + awk '{print $1}' + [ $? -ne 0 ] && s=1 + umount $mntpoint +done | ministat -n | tail -1 | awk '{printf "%.3f %.3f\n",$6,$7}' > $tmp +r=`cat $tmp` +echo "`date +%Y%m%d%H%M` $r `uname -a`" >> $log +tail -5 $log | cut -c 1-92 +rm $tmp + +if [ $old ]; then + awk -v old=$old -v new=$(echo $r | awk '{print $1}') \ + 'BEGIN {if ((new - old) * 100 / old > 5) exit 1; else exit 0}' + s=$? +fi + +for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && exit 1 +mdconfig -d -u $mdstart +rm -rf /tmp/bench +exit 0 + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 50000 +#define TESTS 6 +#define TIMEOUT 600 + +static void (*functions[TESTS])(); + +static void +t1(void) +{ + int fd, i; + char file[128]; + + alarm(TIMEOUT); + for (i = 0; i < LOOPS; i++) { + if (i % 1000 == 0) + setproctitle("%s @ %d", __func__, i); + snprintf(file, sizeof(file), "t1.%06d.%03d", getpid(), i); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, + DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + close(fd); + if (unlink(file) == -1) + err(1, "unlink(%s)", file); + usleep(100); + } + _exit(0); +} + +static void +t2(void) +{ + int fd, i; + char file[128]; + + alarm(TIMEOUT); + for (i = 0; i < LOOPS; i++) { + if (i % 1000 == 0) + setproctitle("%s @ %d", __func__, i); + snprintf(file, sizeof(file), "t2.%06d.%03d", getpid(), i); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, + DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + close(fd); + usleep(100); + } + for (i = 0; i < LOOPS; i++) { + snprintf(file, sizeof(file), "t2.%06d.%03d", getpid(), i); + if (unlink(file) == -1) + err(1, "unlink(%s)", file); + } + _exit(0); +} + +static void +t3(void) +{ + int fd, i; + char dir[128], file[128]; + + alarm(TIMEOUT); + snprintf(dir, sizeof(dir), "t3.%06d.dir", getpid()); + if (mkdir(dir, 700) == -1) + err(1, "mkdir(%s)", dir); + for (i = 0; i < LOOPS; i++) { + if (i % 1000 == 0) + setproctitle("%s @ %d", __func__, i); + snprintf(file, sizeof(file), "%s/t3.%06d.%03d", dir, + getpid(), i); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, + DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + close(fd); + if (unlink(file) == -1) + err(1, "unlink(%s)", file); + usleep(100); + } + if (rmdir(dir) == -1) + err(1, "rmdir(%s)", dir); + + _exit(0); +} + +static void +t4(void) +{ + int fd, i; + char file[128], new[128]; + + alarm(TIMEOUT); + for (i = 0; i < LOOPS / 2; i++) { + if (i % 1000 == 0) + setproctitle("%s @ %d", __func__, i); + snprintf(file, sizeof(file), "t4.%06d.%03d", getpid(), i); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, + DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + close(fd); + snprintf(new, sizeof(new), "t4.%06d.%03d.new", getpid(), i); + if (rename(file, new) == -1) + err(1, "rename(%s, %s)", file, new); + if (unlink(new) == -1) + err(1, "unlink(%s)", new); + usleep(100); + } + _exit(0); +} + +static void +t5(void) +{ + int fd, i; + char buf[512], file[128]; + + alarm(TIMEOUT); + memset(buf, 0, sizeof(buf)); + for (i = 0; i < LOOPS; i++) { + if (i % 1000 == 0) + setproctitle("%s @ %d", __func__, i); + snprintf(file, sizeof(file), "t5.%06d.%03d", getpid(), i); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, + DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + if (write(fd, buf, sizeof(buf)) != sizeof(buf)) + err(1, "write(%s)", file); + close(fd); + if (unlink(file) == -1) + err(1, "unlink(%s)", file); + usleep(100); + } + _exit(0); +} + +static void +t6(void) +{ + int fd, i; + char buf[512], file[128]; + + alarm(TIMEOUT); + memset(buf, 0, sizeof(buf)); + for (i = 0; i < LOOPS / 2; i++) { + if (i % 1000 == 0) + setproctitle("%s/write @ %d", __func__, i); + snprintf(file, sizeof(file), "t6.%06d.%03d", getpid(), i); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, + DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + if (write(fd, buf, sizeof(buf)) != sizeof(buf)) + err(1, "write(%s)", file); + close(fd); + } + for (i = 0; i < LOOPS / 2; i++) { + if (i % 1000 == 0) + setproctitle("%s/read @ %d", __func__, i); + snprintf(file, sizeof(file), "t6.%06d.%03d", getpid(), i); + if ((fd = open(file, O_RDONLY)) == -1) + err(1, "open(%s)", file); + if (read(fd, buf, sizeof(buf)) != sizeof(buf)) + err(1, "write(%s)", file); + close(fd); + usleep(100); + } + for (i = 0; i < LOOPS / 2; i++) { + snprintf(file, sizeof(file), "t6.%06d.%03d", getpid(), i); + if (unlink(file) == -1) + err(1, "unlink(%s)", file); + } + _exit(0); +} + +static int +test(void) +{ + pid_t pids[TESTS]; + int e, i, status; + + e = 0; + for (i = 0; i < TESTS; i++) + if ((pids[i] = fork()) == 0) + functions[i](); + for (i = 0; i < TESTS; i++) { + if (waitpid(pids[i], &status, 0) != pids[i]) + err(1, "waitpid(%d)", pids[i]); + e += status != 0; + } + + return (e); +} + +int +main(void) +{ + int e; + + functions[0] = &t1; + functions[1] = &t2; + functions[2] = &t3; + functions[3] = &t4; + functions[4] = &t5; + functions[5] = &t6; + + e = test(); + + return (e); +} diff --git a/tools/test/stress2/misc/beneath.sh b/tools/test/stress2/misc/beneath.sh new file mode 100755 index 000000000000..6c2f71a7e992 --- /dev/null +++ b/tools/test/stress2/misc/beneath.sh @@ -0,0 +1,110 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 Konstantin Belousov +# +# 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 of open(2) with the O_BENEATH flag. + +# userret: returning with the following locks held: +# shared lockmgr ufs (ufs) r = 0 (0xfffff804ec0d2a48) locked @ +# kern/vfs_subr.c:2590 seen in WiP code: +# https://people.freebsd.org/~pho/stress/log/kostik1126.txt + +top=/tmp/beneath.d +mkdir -p $top +cat > $top/beneath.c < +#include +#include +#include +#include +#include + +#ifndef O_BENEATH +#define O_BENEATH 0x00400000 /* Fail if not under cwd */ +#define AT_BENEATH 0x1000 /* Fail if not under dirfd */ +#endif + +int +main(int argc, char *argv[]) +{ + struct stat st; + char *name; + int error, fd, i; + + for (i = 1; i < argc; i++) { + name = argv[i]; + alarm(120); + fd = open(name, O_RDONLY | O_BENEATH); + if (fd == -1) { + fprintf(stderr, "open(\"%s\") failed, error %d %s\n", + name, errno, strerror(errno)); + } else { + fprintf(stderr, "open(\"%s\") succeeded\n", name); + close(fd); + } + error = fstatat(AT_FDCWD, name, &st, AT_BENEATH); + if (error == -1){ + fprintf(stderr, "stat(\"%s\") failed, error %d %s\n", + name, errno, strerror(errno)); + } else { + fprintf(stderr, "stat(\"%s\") succeeded\n", name); + } + } +} +EOF +cc -o $top/beneath -Wall -Wextra $top/beneath.c || exit 1 +rm $top/beneath.c + +# Test with two directories as arguments: +cd $top +mkdir -p a/b +./beneath a/b +./beneath $top/a/b +touch $top/a/c +./beneath a/c +./beneath $top/a/c +./beneath a/d +./beneath $top/a/d + +# CWD is still $top for this test +top2=/var/tmp/beneath.d +mkdir -p $top2 +mkdir -p $top2/a/b +./beneath $top2/a/b > /dev/null 2>&1 + +touch $top2/a/c +./beneath $top2/a/c > /dev/null 2>&1 + +# Other CWDs +(cd /etc; find . | head -1000 | xargs $top/beneath) > /dev/null 2>&1 +(cd /var; find . | head -1000 | xargs $top/beneath) > /dev/null 2>&1 + +rm -rf $top $top2 +exit 0 diff --git a/tools/test/stress2/misc/beneath2.sh b/tools/test/stress2/misc/beneath2.sh new file mode 100755 index 000000000000..93a937c054ff --- /dev/null +++ b/tools/test/stress2/misc/beneath2.sh @@ -0,0 +1,101 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# O_BENEATH test with a relative path, which is a symbolic link pointing +# to an absolute path. + +# "panic: Assertion (ndp->ni_lcf & NI_LCF_LATCH) != 0 failed at +# ../../../kern/vfs_lookup.c:182" seen. Fixed by r340343. + +# Based on scenario by Vladimir Kondratyev + +. ../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/beneath2.c +mycc -o beneath2 -Wall -Wextra -O0 -g beneath2.c || exit 1 +rm -f beneath2.c +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 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +set +e + +cd $mntpoint +ln -s /tmp/justalongname symlink +$dir/beneath2 symlink +s=$? +[ -f beneath2.core -a $s -eq 0 ] && + { ls -l beneath2.core; mv beneath2.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 +rm -rf $dir/beneath2 +exit $s + +EOF +#include + +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int fd; + char *file; + + if (argc != 2) { + fprintf(stderr, "Usage: %s ", argv[0]); + exit(1); + } + file = argv[1]; + if ((fd = open(file, O_RDONLY | O_BENEATH)) != 0 && + errno != ENOTCAPABLE) + err(1, "open(%s)", file); + + return (0); +} diff --git a/tools/test/stress2/misc/beneath3.sh b/tools/test/stress2/misc/beneath3.sh new file mode 100755 index 000000000000..52dc37a7f873 --- /dev/null +++ b/tools/test/stress2/misc/beneath3.sh @@ -0,0 +1,92 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# vput: 0xfffff808d79c0278 is not locked but should be +# KDB: enter: lock violation +# Test scenario suggestions by kib@ and markj@ + +# Fixed by r348052. + +. ../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/beneath3.c +mycc -o beneath3 -Wall -Wextra -O0 -g beneath3.c || exit 1 +rm -f beneath3.c +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 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +set +e + +cd $mntpoint +(cd /usr; $dir/beneath3) +s=$? +[ -f beneath3.core -a $s -eq 0 ] && + { ls -l beneath3.core; mv beneath3.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 +rm -rf $dir/beneath3 +exit $s + +EOF +#include + +#include +#include +#include + +int +main(void) +{ + int fd; + char file[] = "/.."; + + errno = 0; + fd = open(file, O_CREAT | O_RDONLY | O_BENEATH); + if (fd != -1 || errno != ENOTCAPABLE) + err(1, "open(%s) returns %d", file, fd); + + return (0); +} diff --git a/tools/test/stress2/misc/beneath4.sh b/tools/test/stress2/misc/beneath4.sh new file mode 100755 index 000000000000..d9ee71a8f222 --- /dev/null +++ b/tools/test/stress2/misc/beneath4.sh @@ -0,0 +1,133 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# Test of: +# AT_BENEATH 0x1000 /* Fail if not under dirfd */ +# AT_RESOLVE_BENEATH 0x2000 /* As AT_BENEATH, but do not allow +# resolve to walk out of dirfd even + +dir=/tmp/beneath4.dir +rm -rf $dir +mkdir -p $dir +here=`pwd` +cd $dir + +cat > beneath4.c < + +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + struct stat st; + int exp, fd, flag, r; + char *cwd, *dir, *obj, *s; + + if (argc != 5) { + fprintf(stderr, + "Usage: %s

    \n", + argv[0]); + return (1); + } + + cwd = getwd(NULL); + dir = argv[1]; + obj = argv[2]; + sscanf(argv[3], "%x", &flag); + exp = atoi(argv[4]); +#if 0 + if ((flag & (AT_BENEATH | AT_RESOLVE_BENEATH)) == 0) { + fprintf(stderr, "Flag must be %#x or %#x\n", + AT_BENEATH, AT_RESOLVE_BENEATH); + return (1); + } +#endif + if ((fd = open(dir, O_DIRECTORY | O_RDONLY)) == -1) + err(1, "open(%s)", dir); + + if (fstatat(fd, obj, &st, flag) == -1) + r = errno; + else + r = 0; + s = "FAIL"; + if (r == exp) + s = "OK"; + warn("cwd=%s, top=%s. flag=%0.6x. fstatf(%s) = %2d (expect %2d). %4s", + cwd, dir, flag, obj, r, exp, s); + + return (r == exp ? 0 : errno); +} +EOF +cc -o beneath4 -Wall -Wextra -O2 -g beneath4.c || exit 1 +rm beneath4.c + +mkdir -p /tmp/beneath4.dir/a/a +touch /tmp/beneath4.dir/a/f +ln /tmp/beneath4.dir/a/f /tmp/beneath4.dir/a/c +ln -s /tmp/beneath4.dir/a/a /tmp/beneath4.dir/a/d +ln -s /tmp/beneath4.dir/a/b /tmp/beneath4.dir/a/e +mkfifo /tmp/beneath4.dir/a/fifo + +top=$dir/a + +cd $here +s=0 +ls -lR $dir +echo AT_BENEATH +$dir/beneath4 $top a 0x1000 0 || s=1 +$dir/beneath4 $top b 0x1000 2 || s=1 +$dir/beneath4 $top c 0x1000 0 || s=1 +$dir/beneath4 $top d 0x1000 0 || s=1 +$dir/beneath4 $top e 0x1000 2 || s=1 +$dir/beneath4 $top fifo 0x1000 0 || s=1 +$dir/beneath4 $top $top/../../beneath4.d/a/a 0x1000 93 || s=1 +$dir/beneath4 $top $top/.. 0x1000 93 || s=1 +$dir/beneath4 $top ../a 0x1000 0 || s=1 + +printf "\nAT_RESOLVE_BENEATH\n" +$dir/beneath4 $top a 0x2000 0 || s=1 +$dir/beneath4 $top b 0x2000 2 || s=1 +$dir/beneath4 $top c 0x2000 0 || s=1 +$dir/beneath4 $top d 0x2000 93 || s=1 +$dir/beneath4 $top e 0x2000 93 || s=1 +$dir/beneath4 $top fifo 0x2000 0 || s=1 +$dir/beneath4 $top $top/../../beneath4.d/a/a 0x2000 22 || s=1 +$dir/beneath4 $top $top/.. 0x2000 22 || s=1 +$dir/beneath4 $top ../a 0x2000 93 || s=1 +printf "\nNo flag\n" +$dir/beneath4 $top ../a 0x0000 0 || s=1 +rm -rf $top +exit $s diff --git a/tools/test/stress2/misc/bio.sh b/tools/test/stress2/misc/bio.sh new file mode 100755 index 000000000000..d344fdb281c3 --- /dev/null +++ b/tools/test/stress2/misc/bio.sh @@ -0,0 +1,225 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# mmap() & read()/write() on same file. +# Test scenario suggestion by: jeff@ + +# Out of VM deadlock seen: +# https://people.freebsd.org/~pho/stress/log/jeff114.txt + +# panic: deadlkres: possible deadlock detected: +# https://people.freebsd.org/~pho/stress/log/jeff115.txt + +. ../default.cfg +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +dir=/tmp +odir=`pwd` +cd $dir +ps=`sysctl -n hw.pagesize` +sed "1,/^EOF/d;s/\$ps/$ps/" < $odir/$0 > $dir/bio.c +mycc -o bio -Wall -Wextra -O0 -g bio.c || exit 1 +rm -f bio.c +cd $odir + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs -n md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +(cd $mntpoint; /tmp/bio) & +pid1=$! +sleep 5 +(cd ../testcases/swap; ./swap -t 5m -i 20 -k -l 100 -h) & +pid2=$! + +while pgrep -q bio; do + sleep 2 +done + +while pgrep -q swap; do + pkill -9 swap +done +wait $pid2 +wait $pid1 +s=$? + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -rf /tmp/bio +exit $s + +EOF +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PS $ps /* From hw.pagesize */ +#define SYN1 0 +#define SYN2 1 +#define INDX 2 + +#define PAGES (512 * 1024 * 1024 / PS) /* 512MB file size */ +#define PARALLEL 3 +#define RUNTIME (5 * 60) +#define TIMEOUT (30 * 60) + +char buf[PS]; + +void +test(int inx) +{ + pid_t pid; + size_t i, len, slen; + time_t start; + volatile u_int *share; + int fd, r; + u_int *ip, val; + char file[80]; + + slen = PS; + if ((share = mmap(NULL, slen, PROT_READ | PROT_WRITE, MAP_ANON | + MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + snprintf(file, sizeof(file), "file.%06d", inx); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0640)) < 0) + err(1, "%s", file); + + for (i = 0; i < PAGES; i++) { + if (write(fd, buf, sizeof(buf)) != sizeof(buf)) + err(1, "write error"); + } + + len = PS * PAGES * sizeof(u_int); + if ((ip = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, 0)) == MAP_FAILED) + err(1, "mmap"); + + start = time(NULL); + if ((pid = fork()) == 0) { + alarm(2 * RUNTIME); + /* mmap read / write access */ + for (i = 0; i < (size_t)(PAGES * PS); i += PS) { + while (share[SYN1] == 0) + sched_yield(); + atomic_add_int(&share[SYN1], -1); + if (ip[share[INDX] / sizeof(u_int)] != share[INDX]) + warn("child expected %d, but got %d\n", + ip[share[INDX] / sizeof(u_int)], + share[INDX]); + share[INDX] += PS; + ip[share[INDX] / sizeof(u_int)] = share[INDX]; + atomic_add_int(&share[SYN2], 1); /* signal parent */ + if (i % 1000 == 0 && time(NULL) - start > TIMEOUT) + errx(1, "Timed out");; + } + _exit(0); + } + if (pid == -1) + err(1, "fork()"); + share[INDX] = 0; + atomic_add_int(&share[SYN2], 1); + alarm(2 * RUNTIME); + for (i = 0; i < (size_t)(PAGES * PS); i += PS) { + while (share[SYN2] == 0) + sched_yield(); + atomic_add_int(&share[SYN2], -1); + if (lseek(fd, share[INDX], SEEK_SET) == -1) + err(1, "lseek error"); + if ((r = read(fd, &val, sizeof(val))) != sizeof(val)) + err(1, "parent read read %d bytes", r); + if (val != share[INDX]) + warn("parent expected %d, but got %d\n", + share[INDX], val); + val += PS; + if (lseek(fd, val, SEEK_SET) == -1) + err(1, "lseek error"); + if (write(fd, &val, sizeof(val)) != sizeof(val)) + err(1, "write"); + + atomic_add_int(&share[SYN1], 1); /* signal child */ + if (i % 1000 == 0 && time(NULL) - start > TIMEOUT) + errx(1, "Timed out");; + } + atomic_add_int(&share[SYN2], -1); + if (waitpid(pid, NULL, 0) != pid) + err(1, "wait"); + + if (munmap(ip, len) == -1) + err(1, "unmap()"); + if (munmap((void *)share, slen) == -1) + err(1, "unmap()"); + close(fd); + if (unlink(file) == -1) + err(1, "unlink(%s)", file); + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + time_t start; + int i, s, status; + + start = time(NULL); + s = 0; + while ((time(NULL) - start) < RUNTIME && s == 0) { + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(i); + } + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], &status, 0) == -1) + err(1, "waitpid(%d)", pids[i]); + if (status != 0) + fprintf(stderr, "Child exit status = %d\n", + status); + s += status == 0 ? 0 : 1; + } + } + + return (s); +} diff --git a/tools/test/stress2/misc/buildkernel.sh b/tools/test/stress2/misc/buildkernel.sh new file mode 100755 index 000000000000..fe8d530dfab7 --- /dev/null +++ b/tools/test/stress2/misc/buildkernel.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# Buildkernel test with SU + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +[ -d /usr/src/sys ] || exit 0 +set -e +mount | grep -q "on $mntpoint " && umount $mntpoint +mdconfig -a -t swap -s 5g -u $mdstart +newfs $newfs_flags md$mdstart > /dev/null +mount /dev/md$mdstart $mntpoint +set +e + +cd /usr/src +export MAKEOBJDIRPREFIX=$mntpoint/obj +export TMPDIR=$mntpoint/tmp +mkdir $TMPDIR +chmod 0777 $TMPDIR +log=$mntpoint/log + +p=$((`sysctl -n hw.ncpu`+ 1)) +p=`jot -r 1 1 $p` +echo "make -j $p buildkernel KERNCONF=GENERIC DESTDIR=$mntpoint" \ + "TARGET=amd64 TARGET_ARCH=amd64" +make -j $p buildkernel KERNCONF=GENERIC DESTDIR=$mntpoint TARGET=amd64 \ + TARGET_ARCH=amd64 > $log 2>&1; s=$? +[ $s -ne 0 ] && tail -50 $log + +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/buildworld.sh b/tools/test/stress2/misc/buildworld.sh new file mode 100755 index 000000000000..ef4927d8dd1b --- /dev/null +++ b/tools/test/stress2/misc/buildworld.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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: Invalid page 0xfffff8007f227cf0 on inact queue" seen. +# https://people.freebsd.org/~pho/stress/log/buildworld.txt +# Fixed by r289377 + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +[ -d /usr/src/sys ] || exit 0 +[ `sysctl -n hw.physmem` -gt $(( 2 * 1024 * 1024 * 1024)) ] && + { echo "RAM must be clamped to 2GB or less for this test."; exit 0; } +rm -f $diskimage +[ `df -k $(dirname $diskimage) | tail -1 | awk '{print $4}'` -lt \ + $((3 * 1024 * 1024)) ] && { echo "Need 3GB on `dirname $diskimage`"; \ + exit 0; } +mount | grep -q "on $mntpoint " && umount $mntpoint +dd if=/dev/zero of=$diskimage bs=1m count=3k status=none +trap "rm -f $diskimage" EXIT INT +mdconfig -a -t vnode -f $diskimage -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount -o async /dev/md${mdstart}$part $mntpoint + +cd /usr/src +export MAKEOBJDIRPREFIX=$mntpoint/obj +export TMPDIR=$mntpoint/tmp +mkdir $TMPDIR +chmod 0777 $TMPDIR + +p=$((`sysctl -n hw.ncpu`+ 1)) +timeout 20m make -i -j $p buildworld DESTDIR=$mntpoint TARGET=amd64 \ + TARGET_ARCH=amd64 > /dev/null + +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +checkfs /dev/md$mdstart || s=$? +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/buildworld2.sh b/tools/test/stress2/misc/buildworld2.sh new file mode 100755 index 000000000000..9c1eed97b7ea --- /dev/null +++ b/tools/test/stress2/misc/buildworld2.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# tmpfs version of buildworld.sh + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +[ -d /usr/src/sys ] || exit 0 +[ `swapinfo | wc -l` -eq 1 ] && exit 0 +[ `sysctl -n hw.physmem` -gt $(( 2 * 1024 * 1024 * 1024)) ] && + { echo "RAM must be clamped to 2GB or less."; exit 0; } +mount | grep -q "on $mntpoint " && umount $mntpoint +mount -t tmpfs tmpfs $mntpoint || exit 1 + +cd /usr/src +export MAKEOBJDIRPREFIX=$mntpoint/obj +export TMPDIR=$mntpoint/tmp +mkdir $TMPDIR +chmod 0777 $TMPDIR + +p=$((`sysctl -n hw.ncpu`+ 1)) +make -j $p buildworld DESTDIR=$mntpoint TARGET=amd64 TARGET_ARCH=amd64 \ + > /dev/null & +sleep $((20 * 60)) +kill $! +wait + +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done diff --git a/tools/test/stress2/misc/buildworld3.sh b/tools/test/stress2/misc/buildworld3.sh new file mode 100755 index 000000000000..518c16151bcd --- /dev/null +++ b/tools/test/stress2/misc/buildworld3.sh @@ -0,0 +1,95 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# Buildworld / quota test scenario. + +# "panic: chkdquot: missing dquot" seen +# https://people.freebsd.org/~pho/stress/log/kostik1113.txt +# Fixed in r338798 + r338799 + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 +[ -d /usr/src/sys ] || exit 0 +mount | grep -q "on $mntpoint " && umount $mntpoint +mdconfig -a -t swap -s 2g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null + +export PATH_FSTAB=/tmp/fstab +trap "rm -f $PATH_FSTAB" EXIT INT +echo "/dev/md${mdstart}$part $mntpoint ufs rw,userquota 2 2" > $PATH_FSTAB +mount $mntpoint +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export QK=$(($1 / 2)) +export QI=$(($2 / 2)) +edquota -u -f $mntpoint -e \ + ${mntpoint}:$((QK - 50)):$QK:$((QI - 50 )):$QI $testuser +quotaon $mntpoint +mount | grep $mntpoint + +cd /usr/src +export MAKEOBJDIRPREFIX=$mntpoint/obj +export TMPDIR=$mntpoint/tmp +mkdir $TMPDIR $MAKEOBJDIRPREFIX +chmod 0777 $TMPDIR $MAKEOBJDIRPREFIX + +p=$((`sysctl -n hw.ncpu`+ 1)) +su $testuser -c \ + "make -i -j $p buildworld DESTDIR=$mntpoint TARGET=amd64 \ + TARGET_ARCH=amd64 > /dev/null" & +sleep 2 +start=`date +%s` +while [ $((`date +%s` - start)) -lt 1200 ]; do + kill -0 $! > /dev/null 2>&1 || break + sleep 2 +done +kill $! > /dev/null 2>&1 +# Let make run 50% of the time so quotaoff runs on an active FS +[ `jot -r 1 0 1` -eq 1 ] && + pkill -U$testuser make +wait + +while ! quotaoff $mntpoint; do + sync + sleep 5 +done +pgrep -q -U$testuser make && pkill -U$testuser make +export tmp=/tmp/$(basename $0).$$ +quotacheck -v $mntpoint > $tmp 2>&1 +grep -q failed $tmp && { cat $tmp; s=1; } +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +checkfs /dev/md$mdstart || s=$? +mdconfig -d -u $mdstart +rm -f $PATH_FSTAB +exit $s diff --git a/tools/test/stress2/misc/buildworld4.sh b/tools/test/stress2/misc/buildworld4.sh new file mode 100755 index 000000000000..fae22b9a17b9 --- /dev/null +++ b/tools/test/stress2/misc/buildworld4.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# Buildworld test with SUJ +# "fsync: giving up on dirty (error = 35): tag devfs, type VCHR" seen. + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +[ -d /usr/src/sys ] || exit 0 +rm -f $diskimage +mount | grep -q "on $mntpoint " && umount $mntpoint +mdconfig -a -t swap -s 5g -u $mdstart +bsdlabel -w md$mdstart auto +[ "$newfs_flags" = "-U" ] && newfs_flags="-j" +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +mount | grep $mntpoint + +cd /usr/src +export MAKEOBJDIRPREFIX=$mntpoint/obj +export TMPDIR=$mntpoint/tmp +mkdir $TMPDIR +chmod 0777 $TMPDIR + +p=$((`sysctl -n hw.ncpu`+ 1)) +[ `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 "\ + "TARGET_ARCH=amd64" +make -i -j $p buildworld DESTDIR=$mntpoint TARGET=amd64 TARGET_ARCH=amd64 \ + > /dev/null & +sleep 1 +start=`date +%s` +while [ $((`date +%s` - start)) -lt 600 ]; do + kill -0 $! > /dev/null 2>&1 || break + sleep 30 +done +kill $! > /dev/null 2>&1 +wait + +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +checkfs /dev/md$mdstart; s=$? +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/burnin.sh b/tools/test/stress2/misc/burnin.sh new file mode 100755 index 000000000000..0b6c206cd69b --- /dev/null +++ b/tools/test/stress2/misc/burnin.sh @@ -0,0 +1,210 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Time creating and deleting a number of files once a minute. + +. ../default.cfg +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +export LANG=C +dir=/tmp +runtime=1200 # default +[ $# -eq 1 ] && runtime=$1 +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/burnin.c +mycc -o burnin -Wall -Wextra -O0 -g burnin.c || exit 1 +rm -f burnin.c +cd $odir + +mount | grep "on $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 || exit 1 +bsdlabel -w md$mdstart auto +newfs -n md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +d=`date '+%Y%m%dT%H%M%S'` +log=/tmp/burnin.$d.log +mode=`pgrep -q cron && echo "Multi-user" || echo "Single-user"` +echo "# `uname -a` $mode mode `hostname`" > $log + +/tmp/burnin -r 10 -d $mntpoint > /dev/null 2>&1 +/tmp/burnin -r $runtime -d $mntpoint >> $log + +ministat -A -C 2 -w 72 $log | tail -1 | awk '{if ($NF > .1) exit(1)}' +s=$? +[ $s -ne 0 ] && ministat -C 2 -w 72 $log + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -rf /tmp/burnin $log +exit 0 +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define DELAY 60 +#define SYNC 0 + +volatile u_int *share; +int bufsize, files, parallel, runtime; +char *buf, *dir; + +void +usage(void) +{ + fprintf(stderr, "Usage: %s [-b buf size] [-d directory] [-p parallel] " + "[-r runtime]\n", + getprogname()); + _exit(1); +} + +void +test(void) +{ + pid_t pid; + int fd, i; + char path[MAXPATHLEN + 1]; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != (volatile u_int)parallel) + ; + + pid =getpid(); + for (i = 0; i < files; i++) { + snprintf(path, sizeof(path), "%s/f%06d.%06d", dir, pid, i); + if ((fd = open(path, O_RDWR | O_CREAT | O_TRUNC, DEFFILEMODE)) == + -1) + err(1, "open(%s)", path); + if (write(fd, buf, bufsize) != bufsize) + err(1, "write()"); + if (close(fd) == -1) + err(1, "close(%d)", fd); + if (unlink(path) == -1) + err(1, "unlink(%s)", path); + } + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + struct timeval t1, t2, diff; + struct tm *tp; + size_t len; + time_t start, now; + int ch, e, i, *pids, status; + char help[80]; + + bufsize = 8 * 1024; + dir = "/tmp"; + files = 5000; + parallel = 4; + runtime = 1 * 60 * 60 * 24; + + while ((ch = getopt(argc, argv, "b:d:f:r:")) != -1) + switch(ch) { + case 'b': /* bufsize */ + if (sscanf(optarg, "%d", &bufsize) != 1) + usage(); + break; + case 'd': /* dir */ + dir = optarg; + break; + case 'f': /* files */ + if (sscanf(optarg, "%d", &files) != 1) + usage(); + break; + case 'p': /* parallel */ + if (sscanf(optarg, "%d", ¶llel) != 1) + usage(); + break; + case 'r': /* runtime */ + if (sscanf(optarg, "%d", &runtime) != 1) + usage(); + break; + default: + usage(); + } + argc -= optind; + argv += optind; + + printf("# Options used: dir=%s, bufsize=%d, files=%d, parallel=%d, " + "runtime=%d\n", + dir, bufsize, files, parallel, runtime); + if ((buf = malloc(bufsize)) == NULL) + err(1, "malloc(%d)", bufsize); + if ((pids = malloc(sizeof(pid_t) * parallel)) == NULL) + err(1, "malloc(%d)", (int)(sizeof(pid_t) * parallel)); + 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; + gettimeofday(&t1, NULL); + for (i = 0; i < parallel; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + for (i = 0; i < parallel; i++) { + waitpid(pids[i], &status, 0); + e += status == 0 ? 0 : 1; + } + gettimeofday(&t2, NULL); + timersub(&t2, &t1, &diff); + now = time(NULL); + tp = localtime(&now); + strftime(help, sizeof(help), "%Y%m%d%H%M%S", tp); + printf("%s %ld.%06ld\n", help, (long)diff.tv_sec, + diff.tv_usec); + fflush(stdout); + if (runtime > DELAY) + sleep(DELAY); + } + + return (e); +} diff --git a/tools/test/stress2/misc/callout_reset_on.sh b/tools/test/stress2/misc/callout_reset_on.sh new file mode 100755 index 000000000000..cdffc0dd67f7 --- /dev/null +++ b/tools/test/stress2/misc/callout_reset_on.sh @@ -0,0 +1,331 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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. +# + +# Scenario based on pr. kern/166340 +# Process under FreeBSD 9.0 hangs in uninterruptable sleep with apparently +# no syscall (empty wchan). + +# http://people.freebsd.org/~pho/stress/log/callout_reset_on.txt +# Fixed in r243901. + +# panic: Bad link elm 0xfffff80012ba8ec8 prev->next != elm +# https://people.freebsd.org/~pho/stress/log/rrs005.txt +# Fixed in r278623. + +# "ritwait DE 0- 0:00.01 crlogger: writer" seen. +# https://people.freebsd.org/~pho/stress/log/kostik917.txt +# Fixed in r302981 + +. ../default.cfg + +rm -f /tmp/crwriter /tmp/crlogger || exit 1 + +cat > /tmp/crwriter.c < +#include +#include +#include + +char *txt[] = { + "0 This is a line of text: abcdefghijklmnopqrstuvwxyz", + "1 Another line of text: ABCDEFGHIJKLMNOPQRSTUVWXYZ", + "2 A different line of text", + "3 A very, very different text", + "4 A much longer line with a lot of characters in the line", + "5 Now this is a quite long line of text, with both upper and lower case letters, and one digit!" +}; + +int +main(void) +{ + int i, j, n; + char help[256]; + + for (i = 0; i < 100000; i++) { + j = arc4random() % 6; + n = arc4random() % strlen(txt[j]); + strncpy(help, txt[j], n); + help[n] = 0; + printf("%s\n", txt[j]); + if ((arc4random() % 1000) == 1) + usleep(100000); + } + + return (0); +} +EOF +mycc -o /tmp/crwriter -Wall -Wextra -O2 -g /tmp/crwriter.c +rm -f /tmp/crwriter.c + +cat > /tmp/crlogger.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BARRIER_CREATE 1 +#define BARRIER_WAIT 2 +#define BARRIER_DELETE 3 + +void +barrier(int mode) +{ + int fd; + char path[128]; + + if (mode == BARRIER_CREATE) { + snprintf(path, sizeof(path), "barrier.%d", getpid()); + if ((fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) + err(1, "%s", path); + } else if (mode == BARRIER_WAIT) { + snprintf(path, sizeof(path), "barrier.%d", getppid()); + for(;;) { + if (access(path, R_OK) == -1) + break; + usleep(10000); + } + } else if (mode == BARRIER_DELETE) { + snprintf(path, sizeof(path), "barrier.%d", getpid()); + if (unlink(path) == -1) + err(1, "unlink(%s)", path); + } else + errx(1, "Bad barrier mode: %d", mode); +} + +pid_t pid; +int bufsize; +int port; +int alarm_exit; + +void +killer(void) +{ + setproctitle("killer"); + alarm(120); + barrier(BARRIER_WAIT); + for (;;) { + if (pid == 0) + break; + if (kill(pid, SIGUSR1) == -1) + break; + usleep(1000); + } + _exit(0); +} + +void +handler(int s __unused) +{ +} + +void +ahandler(int s __unused) +{ + if (alarm_exit) + _exit(0); +} + +/* Read form socket, discard */ +static void +reader(void) { + int tcpsock, msgsock; + int on; + socklen_t len; + struct sockaddr_in inetaddr, inetpeer; + int n, *buf; + + setproctitle("reader - init"); + 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); + + signal(SIGUSR1, handler); + alarm(60); + 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 ((buf = malloc(bufsize)) == NULL) + err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__); + setproctitle("reader"); + alarm(0); + signal(SIGALRM, ahandler); + for (;;) { + ualarm(5000, 0); + if ((n = recvfrom(msgsock, buf, 4, 0, NULL, NULL)) < 0) { + if (errno == EAGAIN) + continue; + err(1, "read(), %s:%d", __FILE__, __LINE__); + } + if (n == 0) + break; + if (write(msgsock, "OK", 3) != 3) + err(1, "write ack. %s:%d", __FILE__, __LINE__); + + } + close(msgsock); + _exit(0); +} + +/* read from stdin, write to socket */ +static void +writer(void) { + int tcpsock, on; + struct sockaddr_in inetaddr; + struct hostent *hostent; + int i, r; + char line[1024], ack[80];; + pid_t ppid; + + setproctitle("writer - init"); + ppid = getppid(); + signal(SIGUSR1, handler); + alarm(60); + 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__); + + hostent = gethostbyname ("localhost"); + bzero(&inetaddr, sizeof(inetaddr)); + 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__); + + setproctitle("writer"); + barrier(BARRIER_DELETE); + alarm(0); + while (fgets(line, sizeof(line), stdin) != NULL) { + alarm(10); + alarm_exit = 1; + if (write(tcpsock, line, strlen(line)) < 0) + err(1, "socket write(). %s:%d", __FILE__, __LINE__); + alarm_exit = 0; + ualarm(5000, 0); + if (recvfrom(tcpsock, ack, 4, 0, NULL, NULL) < 0) { + if (errno == EAGAIN) + continue; + err(1, "read(), %s:%d", __FILE__, __LINE__); + } + } + sleep(30); + return; +} + +int +main(int argc, char **argv) +{ + + pid_t kpid; + + if (argc != 2) + errx(1, "Usage: %s \n", argv[0]); + port = atoi(argv[1]); + bufsize = 128; + + barrier(BARRIER_CREATE); + signal(SIGCHLD, SIG_IGN); + if ((pid = fork()) == 0) + reader(); + + if ((kpid = fork()) == 0) + killer(); + + writer(); + sleep(1); + kill(pid, SIGINT); + kill(kpid, SIGINT); + + return (0); +} +EOF +mycc -o /tmp/crlogger -Wall -Wextra -O2 -g /tmp/crlogger.c +rm -f /tmp/crlogger.c + +N=200 +cd /tmp +start=`date '+%s'` +for i in `jot 40`; do + for j in `jot $N`; do + /tmp/crwriter | /tmp/crlogger 1236$j 2>/dev/null & + done + + for j in `jot $N`; do + wait + done + [ $((`date '+%s'` - start)) -gt 1200 ] && break +done +rm -f /tmp/crwriter /tmp/crlogger ./barrier.* +exit 0 diff --git a/tools/test/stress2/misc/callout_reset_on2.sh b/tools/test/stress2/misc/callout_reset_on2.sh new file mode 100755 index 000000000000..270aeb95aa97 --- /dev/null +++ b/tools/test/stress2/misc/callout_reset_on2.sh @@ -0,0 +1,303 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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. +# + +# Copy of callout_reset_on.sh. Waiting to see if this catches anything. + +. ../default.cfg + +rm -f /tmp/crwriter2 /tmp/crlogger2 || exit 1 + +cat > /tmp/crwriter2.c < +#include +#include +#include +#include + +char *txt[] = { + "0 This is a line of text: abcdefghijklmnopqrstuvwxyz", + "1 Another line of text: ABCDEFGHIJKLMNOPQRSTUVWXYZ", + "2 A different line of text", + "3 A very, very different text", + "4 A much longer line with a lot of characters in the line", + "5 Now this is a quite long line of text, with both upper and lower case letters, and one digit!" +}; + +#define RUNTIME (10 * 60) + +int +main(void) +{ + time_t start; + int j, n; + char help[256]; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + j = arc4random() % 6; + n = arc4random() % strlen(txt[j]); + strncpy(help, txt[j], n); + help[n] = 0; + printf("%s\n", txt[j]); + if ((arc4random() % 1000) == 1) + usleep(100000); + } + + return (0); +} +EOF +mycc -o /tmp/crwriter2 -Wall -Wextra -O2 -g /tmp/crwriter2.c +rm -f /tmp/crwriter2.c + +cat > /tmp/crlogger2.c < +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +volatile u_int *share; + +#define SYNC 0 + +pid_t pid; +int bufsize; +int port; +int alarm_exit; + +void +killer(void) +{ + setproctitle("killer"); + while (share[SYNC] == 0) + ; + alarm(120); + for (;;) { + if (pid == 0) + break; + if (kill(pid, SIGUSR1) == -1) + break; + usleep(arc4random() % 2000 + 10); + } + _exit(0); +} + +void +handler(int s __unused) +{ +} + +void +ahandler(int s __unused) +{ + if (alarm_exit) + _exit(0); +} + +/* Read form socket, discard */ +static void +reader(void) { + int tcpsock, msgsock; + int on; + socklen_t len; + struct sockaddr_in inetaddr, inetpeer; + int n, *buf; + + setproctitle("reader - init"); + 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); + + signal(SIGUSR1, handler); + alarm(60); + 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 ((buf = malloc(bufsize)) == NULL) + err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__); + setproctitle("reader"); + alarm(0); + signal(SIGALRM, ahandler); + for (;;) { + ualarm(arc4random() % 5000 + 100, 0); + if ((n = recvfrom(msgsock, buf, bufsize, 0, NULL, NULL)) < 0) { + if (errno == EAGAIN) + continue; + err(1, "read(), %s:%d", __FILE__, __LINE__); + } + if (n == 0) + break; + if (write(msgsock, "OK", 3) != 3) + err(1, "write ack. %s:%d", __FILE__, __LINE__); + + } + close(msgsock); + _exit(0); +} + +/* read from stdin, write to socket */ +static void +writer(void) { + int tcpsock, on; + struct sockaddr_in inetaddr; + struct hostent *hostent; + int i, r; + char line[1024], ack[80];; + pid_t ppid; + + setproctitle("writer - init"); + share[SYNC] = 1; + ppid = getppid(); + signal(SIGUSR1, handler); + signal(SIGALRM, ahandler); + alarm(60); + 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__); + + hostent = gethostbyname ("localhost"); + bzero(&inetaddr, sizeof(inetaddr)); + 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__); + + setproctitle("writer"); + alarm(0); + while (fgets(line, sizeof(line), stdin) != NULL) { + alarm(10); + alarm_exit = 1; + if (write(tcpsock, line, strlen(line)) < 0) + err(1, "socket write(). %s:%d", __FILE__, __LINE__); + alarm_exit = 0; + ualarm(arc4random() % 5000 + 1000, 0); + if (recvfrom(tcpsock, ack, 4, 0, NULL, NULL) < 0) { + if (errno == EAGAIN) + continue; + err(1, "read(), %s:%d", __FILE__, __LINE__); + } + } + sleep(30); + return; +} + +int +main(int argc, char **argv) +{ + + pid_t kpid; + size_t len; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + _exit(1); + } + port = atoi(argv[1]); + bufsize = 128; + + len = PAGE_SIZE; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + signal(SIGCHLD, SIG_IGN); + if ((pid = fork()) == 0) + reader(); + + if ((kpid = fork()) == 0) + killer(); + + writer(); + sleep(1); + kill(pid, SIGINT); + kill(kpid, SIGINT); + + return (0); +} +EOF +mycc -o /tmp/crlogger2 -Wall -Wextra -O2 -g /tmp/crlogger2.c +rm -f /tmp/crlogger2.c + +N=50 +cd /tmp +for j in `jot $N`; do + /tmp/crwriter2 | /tmp/crlogger2 1236$j & +done +wait +rm -f /tmp/crwriter2 /tmp/crlogger2 +exit 0 diff --git a/tools/test/stress2/misc/chain.sh b/tools/test/stress2/misc/chain.sh new file mode 100755 index 000000000000..46d2f32cd7c4 --- /dev/null +++ b/tools/test/stress2/misc/chain.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 Peter Jeremy +# +# 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. +# +# Unkillable process in "vm map (user)" seen. +# https://people.freebsd.org/~pho/stress/log/kostik1070.txt +# Fixed by: r327468 + +# OOM killing: https://people.freebsd.org/~pho/stress/log/chain.txt + +if [ ! -f /usr/local/include/libmill.h -o \ + ! -x /usr/local/lib/libmill.so ]; then + echo "ports/devel/libmill needed." + exit 0 +fi + +. ../default.cfg + +cat > /tmp/chain.c < +#include +#include + +coroutine void f(chan left, chan right) { + chs(left, int, 1 + chr(right, int)); +} + +int +main(int argc __unused, char **argv) +{ + int i, n = argv[1] ? atoi(argv[1]) : 10000; + chan leftmost = chmake(int, 0); + chan left = NULL; + chan right = leftmost; + + alarm(600); + for (i = 0; i < n; i++) { + left = right; + right = chmake(int, 0); + go(f(left, right)); + } + chs(right, int, 0); + i = chr(leftmost, int); + printf("result = %d\n", i); + return(0); +} +EOF + +mycc -o /tmp/chain -I /usr/local/include -L /usr/local/lib -Wall -Wextra \ + -O2 -g /tmp/chain.c -lmill || exit 1 +limits -c 0 /tmp/chain 1000000 +rm -f /tmp/chain /tmp/chain.c +exit 0 diff --git a/tools/test/stress2/misc/churn.sh b/tools/test/stress2/misc/churn.sh new file mode 100755 index 000000000000..6d40381e32bd --- /dev/null +++ b/tools/test/stress2/misc/churn.sh @@ -0,0 +1,211 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# VM test. No problems seen. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/churn.c +mycc -o churn -Wall -Wextra -O0 -g churn.c -lpthread || exit 1 +rm -f churn.c + +/tmp/churn `sysctl -n hw.ncpu` `sysctl -n hw.usermem` +s=$? + +rm -rf /tmp/churn +exit $? + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#define __NP__ +#endif +#include +#include +#include +#include + +#define ARRAYSIZE (4 * 1024) +#define RUNTIME (10 * 60) +#define SYNC 0 + +volatile u_int *share; +long mem, parallel; +int done; + +struct { + void *addr; + long pages; + volatile u_int busy; +} v[ARRAYSIZE]; + +void * +test2(void *arg __unused) +{ + long i, j, n; + volatile char *cp; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + while (done == 0) { + n = 0; + for (i = 0; i < ARRAYSIZE; i++) { + if (v[i].pages == 0) + continue; + atomic_add_int(&v[i].busy, 1); + if (v[i].busy != 1) { + atomic_add_int(&v[i].busy, -1); + continue; + } + cp = v[i].addr; + for (j = 0; j < v[i].pages; j++) + cp[j * PAGE_SIZE] = 1; + atomic_add_int(&v[i].busy, -1); + n++; + } + if (n == 0) { + usleep(10000); + } + } + + return (0); +} + +void +test(void) +{ + pthread_t tp[2]; + size_t len; + time_t start; + long i, j, k, size; + int r; + volatile char *cp; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != (volatile u_int)parallel) + ; + + if ((r = pthread_create(&tp[0], NULL, test2, NULL)) != 0) + errc(1, r, "pthread_create"); + if ((r = pthread_create(&tp[1], NULL, test2, NULL)) != 0) + errc(1, r, "pthread_create"); + size = 0; + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + for (k = 0; k < ARRAYSIZE; k++) { + i = arc4random() % ARRAYSIZE; + if (v[i].pages != 0) + break; + } + if (v[i].addr != NULL) { + atomic_add_int(&v[i].busy, 1); + if (v[i].busy != 1) { + atomic_add_int(&v[i].busy, -1); + continue; + } + if (munmap(v[i].addr, v[i].pages * PAGE_SIZE) == -1) + err(1, "munmap(%p, %ld)", v[i].addr, v[i].pages); + v[i].addr = NULL; + size -= v[i].pages; + v[i].pages = 0; + atomic_add_int(&v[i].busy, -1); + } + if (size < mem) { + j = round_page((arc4random() % (mem / 10)) + 1); + len = j * PAGE_SIZE; + if ((v[i].addr = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) { + v[i].addr = NULL; + continue; + } + atomic_add_int(&v[i].busy, 1); + v[i].pages = j; + size += j; + assert(size > 0); + cp = v[i].addr; + for (k = 0; k < j * PAGE_SIZE; k += PAGE_SIZE) + cp[k] = 1; + atomic_add_int(&v[i].busy, -1); + } + } + done = 1; + pthread_join(tp[0], NULL); + pthread_join(tp[1], NULL); + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + size_t len; + int e, i, *pids, status; + + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + _exit(1); + } + + parallel = atol(argv[1]); + mem = atol(argv[2]) / PAGE_SIZE; + mem = mem / parallel; + + 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"); + + pids = malloc(sizeof(void *) * parallel); + for (i = 0; i < parallel; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + for (i = 0; i < parallel; i++) { + waitpid(pids[i], &status, 0); + e += status == 0 ? 0 : 1; + } + + return (e); +} diff --git a/tools/test/stress2/misc/cleanup.sh b/tools/test/stress2/misc/cleanup.sh new file mode 100755 index 000000000000..ac8762d225b5 --- /dev/null +++ b/tools/test/stress2/misc/cleanup.sh @@ -0,0 +1,105 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2013 Peter Holm +# All rights reserved. +# +# 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 + +bname=`basename $mntpoint` +mounts=`mount | awk "/$bname/{print \\$3}"` +nmounts=`sysctl -n hw.ncpu` # Max number of mounts in use +[ $nmounts -lt 31 ] && nmounts=31 # Arbitrary value +s=0 +# Unmount the test mount points: /mnt, /mnt10 .. mnt31 +for i in $mounts; do + u=`echo $i | sed "s/\/$bname//"` + [ -z "$u" ] && u=$mdstart + echo "$u" | grep -Eq '^[0-9]+$' || continue +# [ $u -lt $mdstart -o $u -gt $((mdstart + nmounts)) ] && continue + while mount | grep -q "on $i "; do + r=`fstat -mf $i 2>/dev/null | awk '$3 ~ /^[0-9]+$/ {print $3}'` + if [ -n "$r" ]; then + echo "cleanup.sh: kill $r" + echo $r | xargs kill; sleep 1 + fi + echo "cleanup.sh: umount -f $i" + umount -f $i > /dev/null 2>&1 || s=1 + [ -z "$r" ] && break + done +done + +# Delete the test mount points /mnt10 .. /mnt31 +for i in `ls -d $mntpoint* 2>/dev/null | grep -Ev '^$mntpoint$'`; do + u=`echo $i | sed "s/\/$bname//"` + echo "$u" | grep -Eq '^[0-9]+$' || continue +# [ $u -lt $mdstart -o $u -gt $((mdstart + nmounts)) ] && continue + if ! mount | grep -q "on $i "; then + [ -d $i ] && find $i -delete \ + 2>/dev/null + rm -rf $i > /dev/null 2>&1 + fi +done + +# Delete the memory disks +units=`mdconfig -l | sed 's/md//g'` +for u in $units; do + if [ $u -ge $mdstart -a $u -lt $((mdstart + nmounts)) ]; then + echo "cleanup.sh: mdconfig -d -u $u" + mdconfig -d -u $u || s=1 + [ -c /dev/md$u ] && sleep .1 + fi +done + +[ -d "$mntpoint" ] && (cd $mntpoint && find . -delete) +rm -f /tmp/.snap/stress2* /var/.snap/stress2* +rm -rf /tmp/stressX.control $RUNDIR +[ -d `dirname "$diskimage"` ] || mkdir -p `dirname "$diskimage"` +mkdir -p $RUNDIR +chmod 0777 $RUNDIR + +# Delete $testuser's ipcs +ipcs | awk "\$5 ~/$testuser/ && \$6 ~/$testuser/ {print \"-\" \$1,\$2}" | \ + xargs -t ipcrm + +# Modules +#mlist=/tmp/stress2.d/mlist +#find $mlist -mtime +1 -delete 2>/dev/null +#[ -f $mlist ] && touch $mlist || +# { kldstat | kldstat | awk '/\.ko$/ {print $NF}' > $mlist; \ +# echo "Updating $mlist"; } +#for m in `kldstat | awk '/\.ko$/ {print $NF}'`; do +# grep -q $m $mlist && continue +# echo "pty.ko mqueuefs.ko ioat.ko ums.ko" | grep -q $m && continue +# echo "cleanup.sh: kldunload $m" +# kldunload $m +#done +# unloading an active dtrace causes a panic +#kldstat | grep -q dtraceall.ko && kldunload dtraceall.ko +kldstat | grep -q ext2fs.ko && kldunload ext2fs.ko +[ $s -ne 0 ] && echo "cleanup.sh: FAIL $s" +exit $s diff --git a/tools/test/stress2/misc/cluster.sh b/tools/test/stress2/misc/cluster.sh new file mode 100755 index 000000000000..bcda95da4755 --- /dev/null +++ b/tools/test/stress2/misc/cluster.sh @@ -0,0 +1,269 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Open four (sparse) files for random read and write. + +# "panic: softdep_deallocate_dependencies: dangling deps" seen: +# https://people.freebsd.org/~pho/stress/log/kirk075.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +dir=`dirname $diskimage` +free=`df -k $dir | tail -1 | awk '{print $4}'` +[ $((free / 1024 / 1024)) -lt 9 ] && echo "Not enough disk space." && exit + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > cluster.c +rm -f /tmp/cluster +mycc -o cluster -Wall -Wextra -g -O2 cluster.c || exit 1 +rm -f cluster.c +cd $odir + +su $testuser -c "/tmp/cluster $dir abc" + +rm -f /tmp/cluster +exit 0 +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define BSIZE (8 * 1024 * 1024) +#define MX (8LL * 1024 * 1024 * 1024) +#define PARALLEL 4 +#define RUNTIME 600 +#define WRLOOPS 1024 + +int rfd; +char *buf; +char *path; +char *uid; +char file[MAXPATHLEN + 1]; + +unsigned long long +rnd(void) { + unsigned long long v; + + read(rfd, &v, sizeof(v)); + v = v % MX; + return (v); +} + +void +wr(int idx) +{ + off_t offset; + size_t ln; + int fd, i, n; + + snprintf(file, sizeof(file), "%s/f.%s.%06d", path, uid, idx); + setproctitle(__func__); + if ((fd = open(file, O_RDWR | O_CREAT, 0644)) == -1) + err(1, "open(%s)", file); + n = arc4random() % WRLOOPS + 1; + for (i = 0; i < n; i++) { + ln = rnd() % BSIZE + 1; + offset = rnd() % (MX - ln); + if (lseek(fd, offset, SEEK_SET) == -1) + err(1, "lseek in rw 1"); + while (lockf(fd, F_LOCK, ln) == -1) { + if (errno != EDEADLK) + err(1, "lockf(%s, F_LOCK)", file); + } + if (write(fd, buf, ln) < 0) + err(1, "write"); + if (lseek(fd, offset, SEEK_SET) == -1) + err(1, "lseek in rw 2"); + if (lockf(fd, F_ULOCK, ln) == -1) + err(1, "lockf(%s, F_ULOCK)", file); + } + close(fd); + _exit(0); +} + +void +rd(int idx) +{ + off_t offset; + size_t ln; + int fd, i, n; + + snprintf(file, sizeof(file), "%s/f.%s.%06d", path, uid, idx); + setproctitle(__func__); + for (i = 0; i < 100; i++) { + if (access(file, R_OK) == 0) + break; + usleep(1000); + } + if ((fd = open(file, O_RDONLY)) == -1) + if (errno != ENOENT) + err(1, "open(%s)for read", file); + n = arc4random() % WRLOOPS + 1; + for (i = 0; i < n; i++) { + ln = rnd() % BSIZE + 1; + offset = rnd() % (MX - ln); + if (lseek(fd, offset, SEEK_SET) == -1) { + if (errno == EBADF) + continue; + err(1, "lseek in rd"); + } + if (read(fd, buf, ln) < 0) + err(1, "write"); + } + close(fd); + _exit(0); +} + +void +mv(int idx) +{ + int i; + char file2[MAXPATHLEN + 1]; + + snprintf(file, sizeof(file), "%s/f.%s.%06d", path, uid, idx); + snprintf(file2, sizeof(file2), "%s/f.%s.%06d.old", path, uid, idx); + for (i = 0; i < 100; i++) { + if (access(file, R_OK) == 0) + break; + usleep(1000); + } + if (rename(file, file2) == -1) + if (errno != ENOENT) + warn("rename(%s, %s)", file, file2); + _exit(0); +} + +void +tr(int idx) +{ + off_t offset; + int fd; + + if (arc4random() % 100 < 10) { + snprintf(file, sizeof(file), "%s/f.%s.%06d", path, uid, idx); + setproctitle(__func__); + if ((fd = open(file, O_RDWR | O_CREAT, 0644)) == -1) + err(1, "open(%s)for read", file); + offset = rnd() % MX; + offset = rnd(); + if (ftruncate(fd, offset) == -1) + err(1, "truncate"); + close(fd); + } + _exit(0); +} + +void +rm(int idx) +{ + int i; + char file2[MAXPATHLEN + 1]; + + snprintf(file2, sizeof(file2), "%s/f.%s.%06d.old", path, uid, idx); + for (i = 0; i < 100; i++) { + if (access(file2, R_OK) == 0) + break; + usleep(1000); + } + if (unlink(file2) == -1) + if (errno != ENOENT) + warn("unlink(%s)", file2); + _exit(0); +} + +void +test2(void (*func)(int nr)) +{ + time_t start; + int i; + + setproctitle(__func__); + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + func(i); + } + for (i = 0; i < PARALLEL; i++) + wait(NULL); + } + _exit(0); + +} + +void +test(void (*func)(int nr)) +{ + + if (fork() == 0) + test2(func); +} + +int +main(int argc, char *argv[]) +{ + int i; + + if (argc != 3) + errx(1, "Usage: %s ", argv[0]); + + path = argv[1]; + uid = argv[2]; + + if ((rfd = open("/dev/random", O_RDONLY)) == -1) + err(1, "open(/dev/random)"); + setproctitle(__func__); + buf = malloc(BSIZE); + test(wr); + test(rd); + test(tr); + test(mv); + for (i = 0; i < 4; i++) + if (wait(NULL) == -1) + err(1, "wait"); + + for (i = 0; i < PARALLEL; i++) { + snprintf(file, sizeof(file), "%s/f.%s.%06d", path, uid, i); + unlink(file); + snprintf(file, sizeof(file), "%s/f.%s.%06d.old", path, uid, i); + unlink(file); + } + + return (0); +} diff --git a/tools/test/stress2/misc/cmp.sh b/tools/test/stress2/misc/cmp.sh new file mode 100755 index 000000000000..bd492c8493ca --- /dev/null +++ b/tools/test/stress2/misc/cmp.sh @@ -0,0 +1,187 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Cross mount test of mkdir(2). +# Page fault seen: +# http://people.freebsd.org/~pho/stress/log/cmp.txt +# Fixed by r275347 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > cmp.c +mycc -o cmp -Wall -Wextra -O2 -g cmp.c || exit 1 +rm -f cmp.c + +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 2g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +# Don't use SU due to bogus "out of inodes" messages. +newfs md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +daemon sh -c "(cd $here/../testcases/swap; ./swap -t 5m -i 20 -h -l 100)" \ + > /dev/null 2>&1 +sleep 1 +su $testuser -c "/tmp/cmp $mntpoint" & + +while kill -0 $! 2>/dev/null; do + umount -f $mntpoint && + mount /dev/md${mdstart}$part $mntpoint + chmod 777 $mntpoint + sleep .1 +done +wait + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +[ -d "$mntpoint" ] && (cd $mntpoint && find . -delete) + +# tmpfs +mount -t tmpfs tmpfs $mntpoint +chmod 777 $mntpoint + +su $testuser -c "/tmp/cmp $mntpoint" & + +while kill -0 $! 2>/dev/null; do + umount -f $mntpoint && + mount -t tmpfs tmpfs $mntpoint + chmod 777 $mntpoint + sleep .1 +done +pkill -9 swap +wait + +while pkill -9 swap; do + : +done > /dev/null 2>&1 +while mount | grep $mntpoint | grep -q tmpfs; do + umount $mntpoint || sleep 1 +done +[ -d "$mntpoint" ] && (cd $mntpoint && find . -delete) +rm -f /tmp/cmp +exit 0 +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 160 +#define PARALLEL 16 + +int nbc, nbd; +char *dir; + +void +tmkdir(void) +{ + int i, j; + char d[MAXPATHLEN + 1], name[MAXPATHLEN + 1]; + + setproctitle(__func__); + + i = 0; + snprintf(name, sizeof(name), "%s/d1.%05d", dir, getpid()); + if (mkdir(name, 0755) == -1) { + if (errno != ENAMETOOLONG && errno != ENOENT && + errno != EBUSY && errno != EACCES && errno != EPERM) + warn("mkdir(%s)", name); + _exit(0); + } + for (;;) { + snprintf(d, sizeof(d), "/%d", i++); + strncat(name, d, sizeof(name) - 1); + if (mkdir(name, 0755) == -1) { + if (errno != ENAMETOOLONG && errno != ENOENT && + errno != EBUSY && errno != EACCES && errno != EPERM) + warn("mkdir(%s)", name); + i--; + break; + } + nbc++; + } + + while (i >= 0) { + snprintf(name, sizeof(name), "%s/d1.%05d", dir, getpid()); + for (j = 0; j < i; j++) { + snprintf(d, sizeof(d), "/%d", j); + strncat(name, d, sizeof(name) - 1); + } + if (rmdir(name) == -1) { + if (errno != ENOTEMPTY && errno != ENOENT && errno != + EBUSY) + warn("rmdir(%s)", name); + } else + nbd++; + i--; + } +#if defined(TEST) + if (nbc == 0) + fprintf(stderr, "FAIL nbc = %d, nbd = %d\n", nbc, nbd); +#endif + _exit(0); +} + +int +main(int argc, char **argv) +{ + int i, j; + + if (argc != 2) { + fprintf(stderr, "Usage: %s ", argv[0]); + exit(1); + } + dir = argv[1]; + + for (j = 0; j < LOOPS; j++) { + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + tmkdir(); + } + for (i = 0; i < PARALLEL; i++) + wait(NULL); + } + + return(0); +} diff --git a/tools/test/stress2/misc/collapse.sh b/tools/test/stress2/misc/collapse.sh new file mode 100755 index 000000000000..fc903d49c6a2 --- /dev/null +++ b/tools/test/stress2/misc/collapse.sh @@ -0,0 +1,153 @@ +#!/bin/sh + +# +# Copyright (c) 2020 Jeffrey Roberson +# All rights reserved. +# +# 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. +# + +. ../default.cfg + +# "panic: freeing mapped page 0xfffffe000aa73910" seen: +# https://people.freebsd.org/~pho/stress/log/collapse.txt + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > collapse.c +mycc -o collapse -Wall -Wextra -g -O0 collapse.c || exit 1 +rm -f collapse.c +cd $odir + +daemon sh -c '(cd ../testcases/swap; ./swap -t 20m -i 16 -l 85)' > \ + /dev/null 2>&1 +sleep 2 +/tmp/collapse +while pgrep -q swap; do + pkill -9 swap +done +rm -f /tmp/collapse +exit 0 + +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADRSPACE (256 * 1024) +#define DEPTH 6 +#define WIDTH 3 +#define PARALLEL 4 +#define RUNTIME 1200 +#define CHILDTIME 5 +#define STARTTIME 5 +#define TOUCH 16 + +char *p; + +static void +child(int depth, time_t start) +{ + time_t run, delay; + int i, shared, off; + int len; + + /* Pick a random bit of address space to change inherit on. */ + for (i = 0; i < ADRSPACE; i += len) { + shared = arc4random() & 0x1; + len = roundup2(arc4random() % ((ADRSPACE - i) / 4), + PAGE_SIZE); + if (minherit(p + i, len, shared ? INHERIT_SHARE : + INHERIT_COPY) != 0) + err(1, "minherit"); + } + + for (i = 0; depth != 0 && i < WIDTH; i++) + if (fork() == 0) + child(depth - 1, start); + + /* + * Touch all of the memory and exit at a random time to collapse + * some portion of the chain. + */ + delay = arc4random() % (CHILDTIME - 1); + run = arc4random() % (CHILDTIME - delay); + for (;;) { + if (time(NULL) >= start + delay) + break; + usleep(100); + } + while (time(NULL) - start < run) { + off = rounddown2(arc4random() % ADRSPACE, PAGE_SIZE); + bzero(p + off, PAGE_SIZE); + usleep((run * 1000) / TOUCH); + } + + _exit(0); +} + +static void +work(int depth) +{ + + if ((p = mmap(NULL, ADRSPACE, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANON, -1, 0)) == MAP_FAILED) { + if (errno == ENOMEM) + return; + err(1, "mmap()"); + } + child(depth, time(NULL) + STARTTIME); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + time_t start; + int i, n; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + n = arc4random() % PARALLEL + 1; + for (i = 0; i < n; i++) { + if ((pids[i] = fork()) == 0) + work(DEPTH); + } + + sleep(CHILDTIME + STARTTIME + 1); + + for (i = 0; i < n; i++) + if (waitpid(pids[i], NULL, 0) != pids[i]) + err(1, "waitpid(%d)", pids[i]); + } + + return (0); +} diff --git a/tools/test/stress2/misc/compare.sh b/tools/test/stress2/misc/compare.sh new file mode 100755 index 000000000000..c983046384b5 --- /dev/null +++ b/tools/test/stress2/misc/compare.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# Compare two disk files. + +diskimage=/var/tmp/diskimage + +d1=$diskimage +d2=${diskimage}2 +have=`df -k $(dirname $d1) | tail -1 | awk '{print int($4 / 1024)}'` +[ $have -lt 1024 ] && + { echo "Not enough disk space on `dirname $d1`"; exit 1; } + +dd if=/dev/random of=$d1 bs=1m count=512 status=none || exit 1 +cp $d1 $d2 +cmp $d1 $d2 && s=0 || { echo FAIL; s=1; } +rm -f $d1 $d2 +exit $s diff --git a/tools/test/stress2/misc/context.sh b/tools/test/stress2/misc/context.sh new file mode 100755 index 000000000000..02fc9b8df4c1 --- /dev/null +++ b/tools/test/stress2/misc/context.sh @@ -0,0 +1,130 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > context.c +mycc -o context -Wall -Wextra -O2 -g context.c || exit 1 +rm -f context.c +[ -d $RUNDIR ] || mkdir -p $RUNDIR +cd $RUNDIR + +daemon sh -c "(cd $here/../testcases/swap; ./swap -t 10m -i 20)" > \ + /dev/null 2>&1 +for i in `jot 4`; do + /tmp/context & + pids="$pids $!" +done +s=0 +for i in $pids; do + wait $i + [ $? -ne 0 ] && s=$((s + 1)) +done +while pgrep -q swap; do + pkill -9 swap +done +rm -f /tmp/context +exit $s +EOF +/* + * Inspired by lmbench-3.0-a9/src/lat_ctx.c + * Pass a token thru pipes to CHILDREN+1 processes in a circular list + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define CHILDREN 64 +#define RUNTIME 300 + +int fds[CHILDREN +1 ][2]; +pid_t pid[CHILDREN]; + +void +handler(int s __unused) +{ + _exit(0); +} + +int +main(void) +{ + time_t start; + int i, j; + int token; + + for (i = 0; i < CHILDREN + 1; i++) { + if (pipe(fds[i]) == -1) + err(1, "pipe"); + } + + signal(SIGHUP, handler); + start = time(NULL); + for (i = 0; i < CHILDREN; i++) { + pid[i] = fork(); + if (pid[i] == -1) { + perror("fork"); + exit(2); + } + + if (pid[i] == 0) { /* child */ + for (;;) { + if (read(fds[i][0], &token, sizeof(token)) + != sizeof(token)) + err(1, "read pipe 2"); + if (write(fds[i+1][1], &token, sizeof(token)) + != sizeof(token)) + err(1, "write pipe 1"); + } + } + + } /* parent */ + + for (j = 0; time(NULL) - start < RUNTIME; j++) { + token = j; + if (write(fds[0][1], &token, sizeof(token)) != sizeof(token)) + err(1, "write pipe 2"); + if (read(fds[CHILDREN][0], &token, sizeof(token)) + != sizeof(token)) + err(1, "read pipe 1"); + } + + for (i = 0; i < CHILDREN; i++) + kill(pid[i], SIGHUP); + + return (0); +} diff --git a/tools/test/stress2/misc/context2.sh b/tools/test/stress2/misc/context2.sh new file mode 100755 index 000000000000..093e72e9084d --- /dev/null +++ b/tools/test/stress2/misc/context2.sh @@ -0,0 +1,131 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# This problem was seen with WiP kernel code: +# https://people.freebsd.org/~pho/stress/log/kostik1210.txt + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > context2.c +mycc -o context2 -Wall -Wextra -O2 context2.c -lpthread || exit 1 +rm -f context2.c +[ -d $RUNDIR ] || mkdir -p $RUNDIR +cd $RUNDIR + +daemon sh -c "(cd $here/../testcases/swap; ./swap -t 10m -i 20)" > \ + /dev/null 2>&1 +for i in `jot 4`; do + /tmp/context2 & +done +wait +while pgrep -q swap; do + pkill -9 swap +done +rm -f /tmp/context2 +exit 0 +EOF +/* + * Inspired by lmbench-3.0-a9/src/lat_ctx.c + * Pass a token thru pipes to NTHREADS+1 threads in a circular list. + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define NTHREADS 64 +#define RUNTIME 300 + +pid_t pid[NTHREADS]; +int fds[NTHREADS+1][2]; + +void * +thr_routine(void *arg) +{ + int i; + int token; + + i = (long)arg; + for (;;) { + if (read(fds[i][0], &token, sizeof(token)) != sizeof(token)) + err(1, "read pipe 2"); + token++; + if (write(fds[i+1][1], &token, sizeof(token)) != sizeof(token)) + err(1, "write pipe 1"); + } + return (0); +} + +int +main(void) +{ + pthread_t threads[NTHREADS]; + time_t start; + long arg; + int i, r, token; + + for (i = 0; i < NTHREADS + 1; i++) { + if (pipe(fds[i]) == -1) + err(1, "pipe"); + } + + for (i = 0; i < NTHREADS; i++) { + arg = i; + if ((r = pthread_create(&threads[i], NULL, thr_routine, + (void *)arg)) != 0) + errc(1, r, "pthread_create(): %s\n", strerror(r)); + } + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + token = 0; + if (write(fds[0][1], &token, sizeof(token)) != sizeof(token)) + err(1, "write pipe 2"); + if (read(fds[NTHREADS][0], &token, sizeof(token)) != + sizeof(token)) + err(1, "read pipe 1"); + } + + for (i = 0; i < NTHREADS; i++) + if ((r = pthread_cancel(threads[i])) != 0) + errc(1, r, "pthread_cancel(%d)", i); + for (i = 0; i < NTHREADS; i++) + if ((r = pthread_join(threads[i], NULL)) != 0) + errc(1, r, "pthread_join(%d)", i); + + return (0); +} diff --git a/tools/test/stress2/misc/contigmalloc.sh b/tools/test/stress2/misc/contigmalloc.sh new file mode 100755 index 000000000000..92bf6ff40905 --- /dev/null +++ b/tools/test/stress2/misc/contigmalloc.sh @@ -0,0 +1,255 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# contigmalloc(9) / contigfree(9) test scenario. +# malloc() a random number of buffers with random size and then free them. + +# A malloc pattern might look like this: +# contigmalloc(186 pages) +# contigmalloc(56 pages) +# contigmalloc(9 pages) +# contigmalloc(202 pages) +# contigmalloc(49 pages) +# contigmalloc(5 pages) + +# "panic: vm_reserv_alloc_contig: reserv 0xff... isn't free" seen. +# http://people.freebsd.org/~pho/stress/log/contigmalloc.txt +# Fixed by r271351. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -d /usr/src/sys ] || exit 0 +builddir=`sysctl kern.version | grep @ | sed 's/.*://'` +[ -d "$builddir" ] && export KERNBUILDDIR=$builddir || exit 0 +export SYSDIR=`echo $builddir | sed 's#/sys.*#/sys#'` + +. ../default.cfg + +odir=`pwd` +dir=/tmp/contigmalloc +rm -rf $dir; mkdir -p $dir +cat > $dir/ctest.c < +#include + +#include +#include +#include +#include +#include + +#define min(a,b) (((a)<(b))?(a):(b)) +#define CAP (64 * 1024 * 1024) /* Total allocation */ +#define MAXBUF (32 * 1024 * 1024) /* Max buffer size */ +#define N 512 /* Max allocations */ +#define RUNTIME 120 +#define TALLOC 1 +#define TFREE 2 + +void *p[N]; +long size[N]; +int n; + +void +test(int argc, char *argv[]) +{ + long mw, s; + int i, no, ps, res; + + if (argc == 3) { + no = atoi(argv[1]); + mw = atol(argv[2]); + } + if (argc != 3 || no == 0 || mw == 0) + errx(1, "Usage: %s ", argv[0]); + + ps = getpagesize(); + s = 0; + n = arc4random() % N + 1; + mw = mw / 100 * 10 * ps; /* Use 10% of vm.max_user_wired */ + mw = min(mw, CAP); + for (i = 0; i < n; i++) { + size[i] = round_page((arc4random() % MAXBUF) + 1); + if (s + size[i] > mw) + continue; + res = syscall(no, TALLOC, &p[i], &size[i]); + if (res == -1) { + warn("contigmalloc(%lu pages) failed at loop %d", + size[i] / ps, i); + usleep(200000); + } else { +#if defined(TEST) + fprintf(stderr, "contigmalloc(%lu pages)\n", + size[i] / ps); +#endif + s += size[i]; + } + } + + setproctitle("%ld Mb", s / 1024 / 1024); + + for (i = 0; i < n; i++) { + if (p[i] != NULL) { + res = syscall(no, TFREE, &p[i], &size[i]); +#if defined(TEST) + fprintf(stderr, "contigfree(%lu pages)\n", + size[i] / ps); +#endif + p[i] = NULL; + } + } +} + +int +main(int argc, char *argv[]) +{ + time_t start; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) + test(argc, argv); + + return (0); +} + +EOF +mycc -o /tmp/ctest -Wall -Wextra -O0 -g $dir/ctest.c || exit 1 +rm $dir/ctest.c + +cd $dir +cat > Makefile < +EOF + +sed '1,/^EOF2/d' < $odir/$0 > cmalloc.c +make || exit 1 +kldload $dir/cmalloc.ko || exit 1 + +cd $odir +mw=`sysctl -n vm.max_user_wired` || exit 1 +/tmp/ctest `sysctl -n debug.cmalloc_offset` $mw 2>&1 | tail -5 +kldunload $dir/cmalloc.ko +rm -rf $dir /tmp/ctest +exit 0 + +EOF2 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TALLOC 1 +#define TFREE 2 + +/* + * Hook up a syscall for contigmalloc testing. + */ + +struct cmalloc_args { + int a_op; + void *a_ptr; + void *a_size; +}; + +static int +cmalloc(struct thread *td, struct cmalloc_args *uap) +{ + void *p; + unsigned long size; + int error; + + error = copyin(uap->a_size, &size, sizeof(size)); + if (error != 0) { + return (error); + } + 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); + } + return (error); + + case TALLOC: + p = contigmalloc(size, M_TEMP, M_NOWAIT, 0ul, ~0ul, 4096, 0); + if (p != NULL) { + error = copyout(&p, uap->a_ptr, sizeof(p)); + return (error); + } + return (ENOMEM); + } + return (EINVAL); +} + +/* + * The sysent for the new syscall + */ +static struct sysent cmalloc_sysent = { + .sy_narg = 3, /* sy_narg */ + .sy_call = (sy_call_t *) cmalloc /* sy_call */ +}; + +/* + * The offset in sysent where the syscall is allocated. + */ +static int cmalloc_offset = NO_SYSCALL; + +SYSCTL_INT(_debug, OID_AUTO, cmalloc_offset, CTLFLAG_RD, &cmalloc_offset, 0, + "cmalloc syscall number"); + +/* + * The function called at load/unload. + */ + +static int +cmalloc_load(struct module *module, int cmd, void *arg) +{ + int error = 0; + + switch (cmd) { + case MOD_LOAD : + break; + case MOD_UNLOAD : + break; + default : + error = EOPNOTSUPP; + break; + } + return (error); +} + +SYSCALL_MODULE(cmalloc_syscall, &cmalloc_offset, &cmalloc_sysent, + cmalloc_load, NULL); diff --git a/tools/test/stress2/misc/contigmalloc2.sh b/tools/test/stress2/misc/contigmalloc2.sh new file mode 100755 index 000000000000..e3ec5bf3a358 --- /dev/null +++ b/tools/test/stress2/misc/contigmalloc2.sh @@ -0,0 +1,223 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# contigmalloc(9) / contigfree(9) test scenario. +# Regression test for allocations >= 2 GiB. +# "panic: vm_page_insert_after: mpred doesn't precede pindex" seen. +# Fixed by r284207. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -d /usr/src/sys ] || exit 0 +builddir=`sysctl kern.version | grep @ | sed 's/.*://'` +[ -d "$builddir" ] && export KERNBUILDDIR=$builddir || exit 0 +export SYSDIR=`echo $builddir | sed 's#/sys.*#/sys#'` + +. ../default.cfg + +odir=`pwd` +dir=/tmp/contigmalloc +rm -rf $dir; mkdir -p $dir +cat > $dir/ctest2.c < +#include + +#include +#include +#include +#include +#include + +#define TALLOC 1 +#define TFREE 2 + +void *p; +long size; +int n; + +void +test(int argc, char *argv[]) +{ + long mw; + int no, ps, res; + + if (argc == 3) { + no = atoi(argv[1]); + mw = atol(argv[2]); + } + if (argc != 3 || no == 0 || mw == 0) + errx(1, "Usage: %s ", argv[0]); + + ps = getpagesize(); + size = mw / 100 * 80 * ps; /* Use 80% of vm.max_user_wired */ + while (size > 0) { + res = syscall(no, TALLOC, &p, &size); + if (res == -1) { + if (errno != ENOMEM) + warn("contigmalloc(%lu pages) failed", + size); + } else { +#if defined(TEST) + fprintf(stderr, "pre contigmalloc(%lu pages): %lu MiB\n", + size, size * ps / 1024 / 1024); +#endif + res = syscall(no, TFREE, &p, &size); +#if defined(TEST) + fprintf(stderr, "contigfree(%lu pages)\n", + size); +#endif + } + size /= 2; + } +} + +int +main(int argc, char *argv[]) +{ + test(argc, argv); + + return (0); +} + +EOF +mycc -o /tmp/ctest2 -Wall -Wextra -O0 -g $dir/ctest2.c || exit 1 +rm $dir/ctest2.c + +cd $dir +cat > Makefile < +EOF + +sed '1,/^EOF2/d' < $odir/$0 > cmalloc2.c +make depend all || exit 1 +kldload $dir/cmalloc2.ko || exit 1 + +cd $odir +mw=$((`sysctl -n vm.max_user_wired` - \ + `sysctl -n vm.stats.vm.v_user_wire_count`)) || exit 1 +/tmp/ctest2 `sysctl -n debug.cmalloc_offset` $mw #2>&1 | tail -5 +kldunload $dir/cmalloc2.ko +rm -rf $dir /tmp/ctest2 +exit 0 + +EOF2 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TALLOC 1 +#define TFREE 2 + +/* + * Hook up a syscall for contigmalloc testing. + */ + +struct cmalloc_args { + int a_op; + void *a_ptr; + void *a_size; +}; + +static int +cmalloc(struct thread *td, struct cmalloc_args *uap) +{ + void *p; + unsigned long size; + int error; + + error = copyin(uap->a_size, &size, sizeof(size)); + if (error != 0) { + return (error); + } + 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); + } + return (error); + + case TALLOC: + p = contigmalloc(size, M_TEMP, M_NOWAIT, 0ul, ~0ul, 4096, 0); + if (p != NULL) { + error = copyout(&p, uap->a_ptr, sizeof(p)); + return (error); + } + return (ENOMEM); + } + return (EINVAL); +} + +/* + * The sysent for the new syscall + */ +static struct sysent cmalloc_sysent = { + .sy_narg = 3, /* sy_narg */ + .sy_call = (sy_call_t *) cmalloc /* sy_call */ +}; + +/* + * The offset in sysent where the syscall is allocated. + */ +static int cmalloc_offset = NO_SYSCALL; + +SYSCTL_INT(_debug, OID_AUTO, cmalloc_offset, CTLFLAG_RD, &cmalloc_offset, 0, + "cmalloc syscall number"); + +/* + * The function called at load/unload. + */ + +static int +cmalloc_load(struct module *module, int cmd, void *arg) +{ + int error = 0; + + switch (cmd) { + case MOD_LOAD : + break; + case MOD_UNLOAD : + break; + default : + error = EOPNOTSUPP; + break; + } + return (error); +} + +SYSCALL_MODULE(cmalloc_syscall, &cmalloc_offset, &cmalloc_sysent, + cmalloc_load, NULL); diff --git a/tools/test/stress2/misc/contigmalloc3.sh b/tools/test/stress2/misc/contigmalloc3.sh new file mode 100755 index 000000000000..9497a67f21cf --- /dev/null +++ b/tools/test/stress2/misc/contigmalloc3.sh @@ -0,0 +1,225 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# contigmalloc(9) / contigfree(9) test scenario. +# Test allocation with 1GB + +# "panic: Bad link elm 0x6766fbc next->prev != elm" seen: +# https://people.freebsd.org/~pho/stress/log/kostik1094.txt +# Fixed by r331247 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -d /usr/src/sys ] || exit 0 +builddir=`sysctl kern.version | grep @ | sed 's/.*://'` +[ -d "$builddir" ] && export KERNBUILDDIR=$builddir || exit 0 +export SYSDIR=`echo $builddir | sed 's#/sys.*#/sys#'` + +. ../default.cfg + +odir=`pwd` +dir=/tmp/contigmalloc +rm -rf $dir; mkdir -p $dir +cat > $dir/ctest.c < +#include + +#include +#include +#include +#include +#include + +#define MAXBUF (1LL * 1024 * 1024 * 1024) /* Max buffer size */ +#define TALLOC 1 +#define TFREE 2 + +void +test(int argc, char *argv[]) +{ + long mw, size; + int i, no, ps, res; + char *cp; + + if (argc == 3) { + no = atoi(argv[1]); + mw = atol(argv[2]); + } + if (argc != 3 || no == 0 || mw == 0) + errx(1, "Usage: %s ", argv[0]); + + ps = getpagesize(); + if (mw < MAXBUF / ps) { + fprintf(stderr, "max_user_wired too small for this test\n"); + exit (0); + } + i = 0; + size = round_page(MAXBUF); + res = syscall(no, TALLOC, &cp, &size); + if (res == -1) { + err(1, "contigmalloc(%lu MB) failed", + size / 1024 / 1024); + } else { +#if defined(TEST) + fprintf(stderr, "contigmalloc(%lu pages) %luMB\n", + size / ps, size / 1024 / 1024); +#endif + } + + res = syscall(no, TFREE, &cp, &size); +#if defined(TEST) + fprintf(stderr, "contigfree(%lu pages) %luMB\n", + size / ps, size / 1024 / 1024); +#endif +} + +int +main(int argc, char *argv[]) +{ + + test(argc, argv); + + return (0); +} + +EOF +mycc -o /tmp/ctest -Wall -Wextra -O0 -g $dir/ctest.c || exit 1 +rm $dir/ctest.c + +cd $dir +cat > Makefile < +EOF + +sed '1,/^EOF2/d' < $odir/$0 > cmalloc.c +make || exit 1 +kldload $dir/cmalloc.ko || exit 1 + +cd $odir +mw=`sysctl -n vm.max_user_wired` || exit 1 +/tmp/ctest `sysctl -n debug.cmalloc_offset` $mw 2>&1 | tail -5 +kldunload $dir/cmalloc.ko +rm -rf $dir /tmp/ctest +exit 0 + +EOF2 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TALLOC 1 +#define TFREE 2 + +/* + * Hook up a syscall for contigmalloc testing. + */ + +struct cmalloc_args { + int a_op; + void *a_ptr; + void *a_size; +}; + +static int +cmalloc(struct thread *td, struct cmalloc_args *uap) +{ + void *p; + unsigned long size; + int error; + + error = copyin(uap->a_size, &size, sizeof(size)); + if (error != 0) { + return (error); + } + 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); + } + return (error); + + case TALLOC: + p = contigmalloc(size, M_TEMP, M_NOWAIT, 0ul, ~0ul, 4096, 0); + if (p != NULL) { + error = copyout(&p, uap->a_ptr, sizeof(p)); + return (error); + } + return (ENOMEM); + } + return (EINVAL); +} + +/* + * The sysent for the new syscall + */ +static struct sysent cmalloc_sysent = { + .sy_narg = 3, /* sy_narg */ + .sy_call = (sy_call_t *) cmalloc /* sy_call */ +}; + +/* + * The offset in sysent where the syscall is allocated. + */ +static int cmalloc_offset = NO_SYSCALL; + +SYSCTL_INT(_debug, OID_AUTO, cmalloc_offset, CTLFLAG_RD, &cmalloc_offset, 0, + "cmalloc syscall number"); + +/* + * The function called at load/unload. + */ + +static int +cmalloc_load(struct module *module, int cmd, void *arg) +{ + int error = 0; + + switch (cmd) { + case MOD_LOAD : + break; + case MOD_UNLOAD : + break; + default : + error = EOPNOTSUPP; + break; + } + return (error); +} + +SYSCALL_MODULE(cmalloc_syscall, &cmalloc_offset, &cmalloc_sysent, + cmalloc_load, NULL); diff --git a/tools/test/stress2/misc/core.sh b/tools/test/stress2/misc/core.sh new file mode 100755 index 000000000000..10d957f1f888 --- /dev/null +++ b/tools/test/stress2/misc/core.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 multiple (parallel) core dumps + +. ../default.cfg + +odir=`pwd` + +cd /tmp +rm -f core +sed '1,/^EOF/d' < $odir/$0 > core.c +mycc -o core -Wall core.c +rm -f core.c +cd $RUNDIR + +for i in `jot 2`; do + for j in `jot 4`; do + /tmp/core & + done + for j in `jot 4`; do + wait + done +done +rm -f /tmp/core +exit +EOF +#include +#include +#include +#include +#include +#include +#include + +#define SIZ 10*1024*1024 + +int +main(int argc, char **argv) +{ + char *cp; + + if ((cp = malloc(SIZ)) == NULL) + err(1, "Could not malloc 10Mb!"); + + memset(cp, 1, SIZ); + + sleep(120 - (time(NULL) % 120)); + raise(SIGSEGV); + + return (0); +} diff --git a/tools/test/stress2/misc/core2.sh b/tools/test/stress2/misc/core2.sh new file mode 100755 index 000000000000..4f0e0472af95 --- /dev/null +++ b/tools/test/stress2/misc/core2.sh @@ -0,0 +1,95 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 multiple (parallel) core dumps and umount + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > core2.c +mycc -o core2 -Wall -Wextra -O0 core2.c || exit 1 +rm -f core2.c +cd $RUNDIR + +mount | grep "on $mntpoint " | grep -q md$mdstart && umount $mntpoint +[ -c /dev/mn$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +touch /tmp/continue +for i in `jot 64`; do + mkdir -p $mntpoint/d$i + (cd $mntpoint; /tmp/core2) & +done +rm -f /tmp/continue + +for i in `jot 60`; do + umount $mntpoint 2>/dev/null || sleep 1 + mount | grep -q "on $mntpoint " || break +done +wait +mount | grep -q "on $mntpoint " && + umount -f $mntpoint +mdconfig -d -u $mdstart +rm -f /tmp/core2 +exit +EOF +#include + +#include +#include +#include +#include +#include +#include +#include + +#define SIZ 1L * 128 * 1024 * 1024 + +void *p; + +int +main(void) +{ + size_t len; + + len = SIZ; + p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + + while (access("/tmp/continue", R_OK) == 0) + usleep(1); + + raise(SIGSEGV); + + return (0); +} diff --git a/tools/test/stress2/misc/core3.sh b/tools/test/stress2/misc/core3.sh new file mode 100755 index 000000000000..68d55468c087 --- /dev/null +++ b/tools/test/stress2/misc/core3.sh @@ -0,0 +1,171 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 multiple (parallel) core dumps and mount / umount. +# mount(8) stuck in "ufs" or "tmpfs". +# http://people.freebsd.org/~pho/stress/log/kostik724.txt +# Fixed by r272535. +# On i386 pgrep(1) loops. Fixed by r272566. + +# "Sleeping on "pmapdi" with the following non-sleepable locks held:" +# https://people.freebsd.org/~pho/stress/log/kostik883.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > core3.c +mycc -o core3 -Wall -Wextra -O2 core3.c || exit 1 +rm -f core3.c +cd $odir + +mount | grep -q "on $mntpoint " && umount $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +mkdir $mntpoint/d +chmod 777 $mntpoint/d + +su $testuser -c "/tmp/core3 $mntpoint/d" & +pid=$! +sleep 1 + +while pgrep -q core3; do + [ -d $mntpoint/d ] && + umount -f $mntpoint +done > /dev/null 2>&1 & +while pgrep -q core3; do + [ -d $mntpoint/d ] || + mount /dev/md${mdstart}$part $mntpoint +done > /dev/null 2>&1 +wait $pid +status=$? +mount | grep -q "on $mntpoint " && + umount -f $mntpoint +mdconfig -d -u $mdstart +[ $status -ne 0 ] && exit $status + +# tmpfs +mount -o size=1g -t tmpfs tmpfs $mntpoint +su $testuser -c "/tmp/core3 $mntpoint/d" & +pid=$! +sleep 1 + +while pgrep -q core3; do + [ -d $mntpoint/d ] && + umount -f $mntpoint +done > /dev/null & +while pgrep -q core3; do + if [ ! -d $mntpoint/d ]; then + mount -t tmpfs tmpfs $mntpoint + mkdir $mntpoint/d + fi +done +wait $pid +status=$? +for i in `jot 5` ; do + mount | grep -q "on $mntpoint " || break + umount -f $mntpoint + sleep 1 +done +rm -f /tmp/core3 +exit $status +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 64 +#define SIZ (4 * 1024 * 1024) +#define TIMEDOUT 22 + +void *p; + +static void +hand(int i __unused) { /* handler */ + _exit(TIMEDOUT); +} + +void +test(char *argv[]) +{ + size_t len; + + len = SIZ; + p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + + /* + * This loop caused mount to wait in "ufs". + * Adding a usleep(200) would remove the hang. + */ + signal(SIGALRM, hand); + alarm(600); + while (chdir(argv[1]) == -1) + ; + + raise(SIGSEGV); + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + time_t start; + int i, s, status; + + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + + status = 0; + start = time(NULL); + while (time(NULL) - start < 600 && status == 0) { + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + test(argv); + } + for (i = 0; i < PARALLEL; i++) { + wait(&s); + if (WEXITSTATUS(s) == TIMEDOUT) + status = 1; + } + } + + return (status); +} diff --git a/tools/test/stress2/misc/core4.sh b/tools/test/stress2/misc/core4.sh new file mode 100755 index 000000000000..562160a1a314 --- /dev/null +++ b/tools/test/stress2/misc/core4.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 multiple (parallel) core dumps and umount -f + +# "panic: vn_finished_write: neg cnt" seen. +# http://people.freebsd.org/~pho/core4.sh +# Fixed in r274501 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > core4.c +mycc -o core4 -Wall -Wextra -O0 -g core4.c || exit 1 +rm -f core4.c + +mount | grep -q "$mntpoint" && umount $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 2g -u $mdstart +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null +for i in `jot 20`; do + mount /dev/md${mdstart}$part $mntpoint + chmod 777 $mntpoint + su $testuser -c "(cd $mntpoint; /tmp/core4)" & + su $testuser -c "(cd $mntpoint; /tmp/core4)" & + su $testuser -c "(cd $mntpoint; /tmp/core4)" & + sleep .5 + sleep .`jot -r 1 1 9` + umount -f $mntpoint + wait +done 2>/dev/null + +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/core4 +exit 0 +EOF +#include +#include + +#include +#include +#include + +#define SIZ (1024L * 1024 * 1024) + +int +main(void) +{ + void *p; + + p = mmap(NULL, SIZ, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + usleep(1000); + raise(SIGSEGV); + + return (0); +} diff --git a/tools/test/stress2/misc/core5.sh b/tools/test/stress2/misc/core5.sh new file mode 100755 index 000000000000..6dc6ba96b742 --- /dev/null +++ b/tools/test/stress2/misc/core5.sh @@ -0,0 +1,199 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# The core file vnode is unreferenced before notification is sent. + +# Problem reported by sbruno@ +# http://people.freebsd.org/~pho/stress/log/core5.txt +# Fixed by r279237. + +# 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. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > core5.c +mycc -o core5 -Wall -Wextra -O0 -g core5.c || exit 1 +rm -f core5.c + +cat > core5-dumper.c << EOT +#include + +#include +#include +#include +#include +#include +#include + +int +main(int argc __unused, char *argv[]) +{ + time_t start; + char core[80]; + + snprintf(core, sizeof(core), "%s.core", argv[0]); + + if (unlink(core) == -1) + if (errno != ENOENT) + warn("unlink(%s)", core); + + start = time(NULL); + while (time(NULL) - start < 600) { + if (fork() == 0) + raise(SIGSEGV); + wait(NULL); + } + if (unlink(core) == -1) + if (errno != ENOENT) + warn("unlink(%s)", core); + + return (0); +} +EOT +mycc -o core5-dumper -Wall -Wextra -O0 -g core5-dumper.c || exit 1 +rm -f core5-dumper.c +for i in `jot 10`; do + cp core5-dumper core5-dumper$i +done +rm -f core5-dumper + +mount | grep -q "on $mntpoint " && umount $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t malloc -s 1g -u $mdstart +bsdlabel -w md$mdstart auto + +newfs -b 4096 -f 512 -i 2048 md${mdstart}$part > /dev/null +mount -o async /dev/md${mdstart}$part $mntpoint || exit 1 + +cp /tmp/core5 $mntpoint +mkdir $mntpoint/dir +cd $mntpoint + +mp2=${mntpoint}2 +[ -d $mp2 ] || mkdir $mp2 +mount | grep -q "on $mp2 " && umount $mp2 +mount -o size=2g -t tmpfs tmpfs $mp2 || exit 1 +for i in `jot 10`; do + (cd $mp2; /tmp/core5-dumper$i ) & +done +maxvnodes=`sysctl -n kern.maxvnodes` +trap "sysctl kern.maxvnodes=$maxvnodes > /dev/null" EXIT INT +$mntpoint/core5 $mntpoint/dir +wait +umount $mp2 + +cd $here +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/core5 /tmp/core5-dumper* /tmp/core5-dumper*.core +exit 0 +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define MAXVNODES 4000 +#define NBFILES 10000 +#define PARALLEL 4 +#define RTIME (10 * 60) + +char *path; + +void +test(int n) +{ + int fd, i; + char file[80]; + + usleep(arc4random() % 1000); + for (i = 0; i < NBFILES; i++) { + snprintf(file, sizeof(file), "%s/f%d.%06d", path, n, i); + if ((fd = open(file, O_CREAT, 0644)) == -1) { + warn("open(%s)", file); + break; + } + close(fd); + } + for (i = 0; i < NBFILES; i++) { + snprintf(file, sizeof(file), "%s/f%d.%06d", path, n, i); + if (unlink(file) == -1) + err(1, "unlink(%s)", file); + } + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + size_t len; + time_t start; + unsigned long nv, maxvnodes; + int j; + + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + path = argv[1]; + + nv = MAXVNODES; + len = sizeof(maxvnodes); + if (sysctlbyname("kern.maxvnodes", &maxvnodes, &len, &nv, + sizeof(nv)) != 0) + err(1, "sysctl kern.maxvnodes 1"); + + start = time(NULL); + while (time(NULL) - start < RTIME) { + for (j = 0; j < PARALLEL; j++) + if (fork() == 0) + test(j); + + for (j = 0; j < PARALLEL; j++) + wait(NULL); + } + + if (sysctlbyname("kern.maxvnodes", NULL, NULL, &maxvnodes, + sizeof(maxvnodes)) != 0) + err(1, "sysctl kern.maxvnodes 2"); + + return (0); +} diff --git a/tools/test/stress2/misc/cpuset.sh b/tools/test/stress2/misc/cpuset.sh new file mode 100755 index 000000000000..ad9f8569f386 --- /dev/null +++ b/tools/test/stress2/misc/cpuset.sh @@ -0,0 +1,49 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# Deadlock with one really small domain: +# https://people.freebsd.org/~pho/stress/log/mark074.txt + +[ `sysctl -n vm.ndomains` -eq 1 ] && exit 0 + +#set -e +# * round-robin:0-4 explicit +# * round-robin:all explicit root domains +# * 0-4 implicit root policy +# * round-robin implicit root domains +# * all explicit root domains and implicit policy + +for p in "round-robin:0" "round-robin:1" "round-robin:0-1" \ + "round-robin:all" "0-1" round-robin all first-touch prefer:1 \ + interleave; do + echo "`date +%T` cpuset -n $p" + cpuset -n $p ../misc/ufsbench.sh +done + +exit 0 diff --git a/tools/test/stress2/misc/credleak.sh b/tools/test/stress2/misc/credleak.sh new file mode 100755 index 000000000000..da6c0b73f460 --- /dev/null +++ b/tools/test/stress2/misc/credleak.sh @@ -0,0 +1,162 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC +# All rights reserved. +# +# 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 vfs_export() leaks M_CRED when mountd(8) is started: +# "M_CRED leaked 160". + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +pgrep -q mountd || echo "Note: mountd(8) must run for this test to fail" +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > credleak.c +mycc -o credleak -Wall -Wextra -O2 -g credleak.c || exit 1 +rm -f credleak.c + +mount | grep -q "on $mntpoint " && umount -f $mntpoint +mount -t tmpfs tmpfs $mntpoint +chmod 777 $mntpoint + +old=`vmstat -m | grep -w cred | awk '{print $2}'` +su $testuser -c "/tmp/credleak $mntpoint" & + +while kill -0 $! 2>/dev/null; do + umount -f $mntpoint && + mount -t tmpfs tmpfs $mntpoint + chmod 777 $mntpoint + sleep .1 +done +pkill -9 swap +wait + +while pkill -9 swap; do + : +done > /dev/null 2>&1 +while mount | grep $mntpoint | grep -q tmpfs; do + umount $mntpoint || sleep 1 +done +[ -d "$mntpoint" ] && (cd $mntpoint && find . -delete) +rm -f /tmp/credleak + +s=0 +leak=$((`vmstat -m | grep -w cred | awk '{print $2}'` - old)) +[ $leak -gt 10 ] && { echo "M_CRED leaked $leak"; s=1; } +exit $s +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 160 +#define PARALLEL 16 + +int nbc, nbd; +char *dir; + +void +tmkdir(void) +{ + int i, j; + char d[MAXPATHLEN + 1], name[MAXPATHLEN + 1]; + + setproctitle(__func__); + + i = 0; + snprintf(name, sizeof(name), "%s/d1.%05d", dir, getpid()); + if (mkdir(name, 0755) == -1) { + if (errno != ENAMETOOLONG && errno != ENOENT && + errno != EBUSY && errno != EACCES && errno != EPERM) + warn("mkdir(%s)", name); + _exit(0); + } + for (;;) { + snprintf(d, sizeof(d), "/%d", i++); + strncat(name, d, sizeof(name) - 1); + if (mkdir(name, 0755) == -1) { + if (errno != ENAMETOOLONG && errno != ENOENT && + errno != EBUSY && errno != EACCES && errno != EPERM) + warn("mkdir(%s)", name); + i--; + break; + } + nbc++; + } + + while (i >= 0) { + snprintf(name, sizeof(name), "%s/d1.%05d", dir, getpid()); + for (j = 0; j < i; j++) { + snprintf(d, sizeof(d), "/%d", j); + strncat(name, d, sizeof(name) - 1); + } + if (rmdir(name) == -1) { + if (errno != ENOTEMPTY && errno != ENOENT && errno != + EBUSY) + warn("rmdir(%s)", name); + } else + nbd++; + i--; + } +#if defined(TEST) + if (nbc == 0) + fprintf(stderr, "FAIL nbc = %d, nbd = %d\n", nbc, nbd); +#endif + _exit(0); +} + +int +main(int argc, char **argv) +{ + int i, j; + + if (argc != 2) { + fprintf(stderr, "Usage: %s ", argv[0]); + exit(1); + } + dir = argv[1]; + + for (j = 0; j < LOOPS; j++) { + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + tmkdir(); + } + for (i = 0; i < PARALLEL; i++) + wait(NULL); + } + + return(0); +} diff --git a/tools/test/stress2/misc/crossmp.sh b/tools/test/stress2/misc/crossmp.sh new file mode 100755 index 000000000000..7d1ccbe3a469 --- /dev/null +++ b/tools/test/stress2/misc/crossmp.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 of file systems + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mounts=15 # Number of parallel scripts +cont=/tmp/crossmp.continue +mdstart=$mdstart # Use md unit numbers from this point +D=$diskimage + +if [ $# -eq 0 ]; then + touch $cont + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + [ ! -d ${mntpoint}$m ] && mkdir ${mntpoint}$m + mount | grep "on ${mntpoint}$m " | grep -q md$m && + umount ${mntpoint}$m + mdconfig -l | grep -q md$m && mdconfig -d -u $m + + dd if=/dev/zero of=$D$m bs=1m count=1 status=none + mdconfig -a -t vnode -f $D$m -u $m + bsdlabel -w md$m auto + newfs $newfs_flags md${m}$part > /dev/null 2>&1 + done + + # start the parallel tests + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + ./$0 $m & + ./$0 find & + done + + wait + + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + mdconfig -d -u $m + rm -f $D$m + done + exit 0 +else + if [ $1 = find ]; then + while [ -r $cont ]; do + find ${mntpoint}* -type f > /dev/null 2>&1 + done + else + + # The test: Parallel mount and unmounts + for i in `jot 1024`; do + m=$1 + mount /dev/md${m}$part ${mntpoint}$m + while mount | grep -q "on ${mntpoint}$m "; do + opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && + echo "-f") + umount $opt ${mntpoint}$m > /dev/null 2>&1 + done + done + rm -f $cont + fi +fi diff --git a/tools/test/stress2/misc/crossmp10.sh b/tools/test/stress2/misc/crossmp10.sh new file mode 100755 index 000000000000..30e64a064dac --- /dev/null +++ b/tools/test/stress2/misc/crossmp10.sh @@ -0,0 +1,104 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# ext2fs parallel mount & umount test scenario +# "panic: vm_fault_hold: fault on nofault entry" seen. +# https://people.freebsd.org/~pho/stress/log/crossmp10.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -z "`which mke2fs`" ] && echo "mke2fs not found" && exit 0 + +. ../default.cfg + +CONT=/tmp/crossmp10.continue +mounts=4 # Number of parallel scripts +size=512 # Disk size in MB + +if [ $# -eq 0 ]; then + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + [ ! -d ${mntpoint}$m ] && + { mkdir ${mntpoint}$m; chmod 755 ${mntpoint}$m; } + mount | grep "${mntpoint}$m " | grep -q md$m && umount ${mntpoint}$m + mdconfig -l | grep -q md$m && mdconfig -d -u $m + + mdconfig -a -t swap -s ${size}m -u $m + bsdlabel -w md$m auto + mke2fs -m 0 /dev/md${m}$part > /dev/null 2>&1 + done + + # start the parallel tests + touch $CONT + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + ./$0 $m & + ./$0 find & + done + + wait + + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + while mount | grep -q "on ${mntpoint}$m "; do + umount ${mntpoint}$m && break + sleep 1 + done + mdconfig -d -u $m + done + exit 0 +else + if [ $1 = find ]; then + while [ -f $CONT ]; do + find ${mntpoint}* -ls > /dev/null 2>&1 + sleep .1 + done + else + export runRUNTIME=30s + # The test: Parallel mount and unmounts + start=`date '+%s'` + while [ $((`date '+%s'` - start)) -lt 300 ]; do + m=$1 + mount -t ext2fs /dev/md${m}$part ${mntpoint}$m && + chmod 777 ${mntpoint}$m + export RUNDIR=${mntpoint}$m/stressX + export CTRLDIR=${mntpoint}$m/stressX.control + (cd ${mntpoint}$m && find . -delete) + su $testuser -c 'cd ..; ./run.sh disk.cfg' > /dev/null 2>&1 & + + sleep 2 + while mount | grep -q "on ${mntpoint}$m "; do + opt=$([ `jot -r 1 0 1` -eq 0 ] && echo "-f") + umount $opt ${mntpoint}$m > /dev/null 2>&1 + [ -f $CONT ] || break 2 + done + wait $! + done + rm -f $CONT + ../tools/killall.sh + fi +fi diff --git a/tools/test/stress2/misc/crossmp11.sh b/tools/test/stress2/misc/crossmp11.sh new file mode 100755 index 000000000000..8bc008f6f504 --- /dev/null +++ b/tools/test/stress2/misc/crossmp11.sh @@ -0,0 +1,121 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Copy of crossmp3.sh + elements from dfull.sh + +# Live lock seen: +# https://people.freebsd.org/~pho/stress/log/crossmp11.txt + +# umount stuck in mnt_ref seen: +# https://people.freebsd.org/~pho/stress/log/kostik1002.txt + +# Fixed by r319518, r319519 and r319539. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +g3=$((3 * 1024 * 1024 * 1024)) +CONT=/tmp/crossmp11.continue +N=`sysctl -n hw.ncpu` +[ $N -gt 4 ] && N=4 +usermem=`sysctl -n hw.usermem` +[ $usermem -gt $g3 ] && usermem=$g3 +[ `sysctl -n vm.swap_total` -eq 0 ] && usermem=$((usermem/100*80)) +size=$((usermem / 1024 / 1024 / N)) + +mounts=$N # Number of parallel scripts + +if [ $# -eq 0 ]; then + echo "Expect: + /mnt6: write failed, filesystem is full + /mnt6: create/symlink failed, no inodes free" + + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + [ ! -d ${mntpoint}$m ] && + { mkdir ${mntpoint}$m; chmod 755 ${mntpoint}$m; } + mount | grep "${mntpoint}$m " | grep -q md$m && umount ${mntpoint}$m + mdconfig -l | grep -q md$m && mdconfig -d -u $m + + mdconfig -a -t swap -s ${size}m -u $m + bsdlabel -w md$m auto + newfs $newfs_flags md${m}$part > /dev/null 2>&1 + done + + # start the parallel tests + touch $CONT + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + ./$0 $m & + ./$0 find & + done + + wait + + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + while mount | grep -q "on ${mntpoint}$m "; do + umount ${mntpoint}$m && break + sleep 1 + done + mdconfig -d -u $m + done + exit 0 +else + if [ $1 = find ]; then + while [ -f $CONT ]; do + find ${mntpoint}* -type f > /dev/null 2>&1 + done + else + m=$1 + export runRUNTIME=20s + # The test: Parallel mount and unmounts + for i in `jot 3`; do + mount /dev/md${m}$part ${mntpoint}$m && + chmod 777 ${mntpoint}$m + export RUNDIR=${mntpoint}$m/stressX + export CTRLDIR=${mntpoint}$m/stressX.control + (cd ${mntpoint}$m && find . -delete) + if [ -z "$KBLOCKS" ]; then + r=`df -ik ${mntpoint}$m | tail -1 | awk '{print $4,$7}'` + export KBLOCKS=`echo $r | awk '{print $1 * 10}'` + export INODES=`echo $r | awk '{print $2 * 10}'` + fi + su $testuser -c 'cd ..; ./run.sh disk.cfg' > \ + /dev/null 2>&1 + + while mount | grep -q "on ${mntpoint}$m "; do + opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && echo "-f") + umount $opt ${mntpoint}$m > /dev/null 2>&1 + [ -f $CONT ] || break 2 + done + done + rm -f $CONT + fi +fi diff --git a/tools/test/stress2/misc/crossmp2.sh b/tools/test/stress2/misc/crossmp2.sh new file mode 100755 index 000000000000..03cd04e077c1 --- /dev/null +++ b/tools/test/stress2/misc/crossmp2.sh @@ -0,0 +1,86 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# NFS test + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +cont=/tmp/crossmp2.continue +mounts=10 # Number of parallel scripts + +if [ $# -eq 0 ]; then + [ -z "$nfs_export" ] && exit 0 + ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + touch $cont + mount -t nfs -o tcp -o nfsv3 -o retrycnt=1 -o intr,soft,timeout=1 \ + -o rw $nfs_export $mntpoint || exit 0 + sleep .2 + umount $mntpoint + + for i in `jot $mounts`; do + mp=${mntpoint}$i + [ ! -d $mp ] && mkdir $mp + mount | grep -q "$mp " && umount $mp + done + + # start the parallel tests + for i in `jot $mounts`; do + ./$0 $i & + ./$0 find & + done + wait + exit 0 +else + if [ $1 = find ]; then + while [ -r $cont ]; do + find ${mntpoint}* -maxdepth 1 -type f > \ + /dev/null 2>&1 + done + else + + # The test: Parallel mount and unmounts + for i in `jot 128`; do + m=$1 + mount -t nfs -o tcp -o nfsv3 -o retrycnt=3 \ + -o intr,soft -o rw $nfs_export ${mntpoint}$m + sleep .5 + opt=`[ $(( m % 2 )) -eq 0 ] && echo -f` + n=0 + while mount | grep -q "${mntpoint}$m "; do + umount $opt ${mntpoint}$m > /dev/null 2>&1 + [ $((n += 1)) -gt 99 ] && umount -f \ + ${mntpoint}$m > /dev/null 2>&1 + [ $n -gt 100 ] && exit + done + done + rm -f $cont + fi +fi diff --git a/tools/test/stress2/misc/crossmp3.sh b/tools/test/stress2/misc/crossmp3.sh new file mode 100755 index 000000000000..30c9f86840f1 --- /dev/null +++ b/tools/test/stress2/misc/crossmp3.sh @@ -0,0 +1,108 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 of file systems +# "panic: Bad link elm 0xfffff8052a20cc00 prev->next != elm" seen: +# http://people.freebsd.org/~pho/stress/log/crossmp3.txt +# Fixed in r269853 + +# panic: softdep_waitidle: work added after flush: +# http://people.freebsd.org/~pho/stress/log/crossmp3-2.txt, fixed by r273967. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +CONT=/tmp/crossmp3.continue +if [ $# -eq 0 ]; then + N=`sysctl -n hw.ncpu` + usermem=`sysctl -n hw.usermem` + [ `sysctl -n vm.swap_total` -eq 0 ] && usermem=$((usermem / 2)) + size=$((usermem / 1024 / 1024 / N)) + echo "Using $N memory disks of size $size MB." + + mounts=$N # Number of parallel scripts + + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + [ ! -d ${mntpoint}$m ] && + { mkdir ${mntpoint}$m; chmod 755 ${mntpoint}$m; } + mount | grep "${mntpoint}$m " | grep -q md$m && + umount ${mntpoint}$m + mdconfig -l | grep -q md$m && mdconfig -d -u $m + + mdconfig -a -t swap -s ${size}m -u $m + bsdlabel -w md$m auto + newfs $newfs_flags md${m}$part > /dev/null 2>&1 + done + + # start the parallel tests + touch $CONT + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + ./$0 $m & + ./$0 find & + done + wait + + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + while mount | grep -q "on ${mntpoint}$m "; do + umount ${mntpoint}$m && break + sleep 1 + done + mdconfig -d -u $m + done + exit 0 +else + if [ $1 = find ]; then + while [ -f $CONT ]; do + find ${mntpoint}* -type f > /dev/null 2>&1 + done + else + export runRUNTIME=20s + # The test: Parallel mount and unmounts + for i in `jot 3`; do + m=$1 + mount /dev/md${m}$part ${mntpoint}$m && + chmod 777 ${mntpoint}$m + export RUNDIR=${mntpoint}$m/stressX + export CTRLDIR=${mntpoint}$m/stressX.control + (cd ${mntpoint}$m && find . -delete) + su $testuser -c 'cd ..; ./run.sh disk.cfg' > \ + /dev/null 2>&1 + + while mount | grep -q "on ${mntpoint}$m "; do + opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && echo "-f") + umount $opt ${mntpoint}$m > /dev/null 2>&1 + [ -f $CONT ] || break 2 + done + done + rm -f $CONT + fi +fi diff --git a/tools/test/stress2/misc/crossmp4.sh b/tools/test/stress2/misc/crossmp4.sh new file mode 100755 index 000000000000..7f24097475f3 --- /dev/null +++ b/tools/test/stress2/misc/crossmp4.sh @@ -0,0 +1,107 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 of file systems. Nullfs version. + +# "panic: Lock (lockmgr) null not locked @ kern/vfs_default.c:523." seen. +# http://people.freebsd.org/~pho/stress/log/kostik698.txt +# Fixed by r269708. + +# Not fixed: https://people.freebsd.org/~pho/stress/log/kostik798.txt +# https://people.freebsd.org/~pho/stress/log/kostik856.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +N=`sysctl -n hw.ncpu` +usermem=`sysctl -n hw.usermem` +[ `swapinfo | wc -l` -eq 1 ] && usermem=$((usermem/100*80)) +size=$((usermem / 1024 / 1024 - 2)) + +CONT=/tmp/crossmp4.continue +mounts=$N # Number of parallel scripts + +if [ $# -eq 0 ]; then + mount | grep "$mntpoint" | grep -q md && umount $mntpoint + mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + + mdconfig -a -t swap -s ${size}m -u $mdstart + bsdlabel -w md$mdstart auto + newfs $newfs_flags md${mdstart}$part > /dev/null 2>&1 + mount /dev/md${mdstart}$part $mntpoint + + # start the parallel tests + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + ./$0 $m & + ./$0 find & + done + + wait + + while mount | grep -q "on $mntpoint "; do + umount $mntpoint > /dev/null 2>&1 || sleep 1 + done + mdconfig -d -u $mdstart + exit 0 +else + touch $CONT + if [ $1 = find ]; then + while [ -f $CONT ]; do + find ${mntpoint}* -type f > /dev/null 2>&1 + done + else + m=$1 + set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` + export KBLOCKS=$(($1 / N)) + export INODES=$(($2 / N)) + export runRUNTIME=1m + export INCARNATIONS=4 + # The test: Parallel mount and unmounts + for i in `jot 4`; do + [ ! -d ${mntpoint}$m ] && mkdir ${mntpoint}$m + mount -t nullfs $mntpoint ${mntpoint}$m + mkdir -p ${mntpoint}$m/$m + chmod 777 ${mntpoint}$m/$m + export RUNDIR=${mntpoint}$m/$m/stressX + export CTRLDIR=${mntpoint}$m/$m/stressX.control + (cd ${mntpoint}$m/$m && find . -delete) + su $testuser -c 'cd ..; ./run.sh disk.cfg' > \ + /dev/null 2>&1 & + sleep 30 + + while mount | grep -q "on ${mntpoint}$m "; do + opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && echo "-f") + umount $opt ${mntpoint}$m > /dev/null 2>&1 + done + wait + done + rm -f $CONT + fi +fi diff --git a/tools/test/stress2/misc/crossmp5.sh b/tools/test/stress2/misc/crossmp5.sh new file mode 100755 index 000000000000..9a636c9aae45 --- /dev/null +++ b/tools/test/stress2/misc/crossmp5.sh @@ -0,0 +1,95 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 crossmp3.sh + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +N=`sysctl -n hw.ncpu` +usermem=`sysctl -n hw.usermem` +[ `swapinfo | wc -l` -eq 1 ] && usermem=$((usermem/100*80)) +size=$((usermem / 1024 / 1024 / N)) + +mounts=$N # Number of parallel scripts + +if [ $# -eq 0 ]; then + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + [ ! -d ${mntpoint}$m ] && mkdir ${mntpoint}$m + mount | grep "${mntpoint}$m " | grep -q md$m && + umount ${mntpoint}$m + mdconfig -l | grep -q md$m && mdconfig -d -u $m + + mdconfig -a -t swap -s ${size}m -u $m + bsdlabel -w md$m auto + newfs $newfs_flags md${m}$part > /dev/null 2>&1 + done + + # start the parallel tests + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + ./$0 $m & + ./$0 find & + done + + wait + + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + mdconfig -d -u $m + rm -f $D$m + done + exit 0 +else + touch /tmp/crossmp.continue + if [ $1 = find ]; then + while [ -f /tmp/crossmp.continue ]; do + find ${mntpoint}* -type f > /dev/null 2>&1 + done + else + # The test: Parallel mount and unmount + m=$1 + for i in `jot 200`; do + mount /dev/md${m}$part ${mntpoint}$m + chmod 777 ${mntpoint}$m + l=`jot -r 1 65535` + dd if=/dev/zero of=$mntpoint/$i bs=$l count=100 \ + status=none + rm -f $mntpoint/$i + + while mount | grep -q "on ${mntpoint}$m "; do + opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && + echo "-f") + umount $opt ${mntpoint}$m > /dev/null 2>&1 + done + done + rm -f /tmp/crossmp.continue + fi +fi diff --git a/tools/test/stress2/misc/crossmp6.sh b/tools/test/stress2/misc/crossmp6.sh new file mode 100755 index 000000000000..92ca0abcba27 --- /dev/null +++ b/tools/test/stress2/misc/crossmp6.sh @@ -0,0 +1,103 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Copy of crossmp2.sh: NFS test, with lockf(1) added. +# "panic: vinvalbuf: dirty bufs" seen. +# https://people.freebsd.org/~pho/stress/log/crossmp6.txt +# Fixed by r283968. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 +pgrep -q lockd || { echo "lockd not running."; exit 0; } + +CONT=/tmp/crossmp6.continue +mounts=10 # Number of parallel scripts + +if [ $# -eq 0 ]; then + [ -z "$nfs_export" ] && exit 0 + ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + mount -t nfs -o tcp -o nfsv3 -o retrycnt=1 -o soft,timeout=1 \ + -o rw $nfs_export $mntpoint || exit 0 + umount $mntpoint + + for i in `jot $mounts`; do + mp=${mntpoint}$i + [ ! -d $mp ] && mkdir $mp + mount | grep -qw "$mp" && umount $mp + done + + # start the parallel tests + for i in `jot $mounts`; do + ./$0 $i & + ./$0 find $i & + done + wait + mount -t nfs -o tcp -o nfsv3 -o retrycnt=1 -o soft,timeout=1 \ + -o rw $nfs_export $mntpoint || exit 0 + sleep .5 + rm -f $mntpoint/$0.* + umount $mntpoint + rm -f $mntpoint*/$0.* + exit 0 +else + if [ $1 = find ]; then + for i in `jot 128`; do + find ${mntpoint}* -maxdepth 1 -type f > \ + /dev/null 2>&1 + (lockf -t 10 ${mntpoint}$2/$0.$$.$i sleep 1 &) > \ + /dev/null 2>&1 + [ -f $CONT ] || break + done + wait + else + # The test: Parallel mount and unmounts + start=`date '+%s'` + while [ $((`date '+%s'` - start)) -lt 300 ]; do + m=$1 + mount -t nfs -o tcp -o nfsv3 -o retrycnt=3 \ + -o soft -o rw $nfs_export ${mntpoint}$m + sleep .5 + opt=`[ $(( m % 2 )) -eq 0 ] && echo -f` + n=0 + while mount | grep -qw ${mntpoint}$m; do + umount $opt ${mntpoint}$m > /dev/null 2>&1 + n=$((n + 1)) + [ $n -gt 99 ] && umount -f ${mntpoint}$m > \ + /dev/null 2>&1 + [ $n -gt 100 ] && exit + done + done + rm -f $CONT + fi +fi diff --git a/tools/test/stress2/misc/crossmp7.sh b/tools/test/stress2/misc/crossmp7.sh new file mode 100755 index 000000000000..c2c2752f38e7 --- /dev/null +++ b/tools/test/stress2/misc/crossmp7.sh @@ -0,0 +1,100 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 of zfs file systems. + +# Page fault seen: +# https://people.freebsd.org/~pho/stress/log/avg002.txt +# Fixed by r309090. + +# Page fault seen: +# https://people.freebsd.org/~pho/stress/log/crossmp7.txt +# Fixed by r352437. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `uname -m` = "i386" ] && exit 0 +[ `sysctl -n kern.kstack_pages` -lt 4 ] && exit 0 + +. ../default.cfg + +mounts=15 # Number of parallel scripts + +if [ $# -eq 0 ]; then + kldstat -v | grep -q zfs.ko || { kldload zfs.ko || + exit 0; loaded=1; } + zpool list | egrep -q "^stress2_tank" && zpool destroy stress2_tank + + u1=$mdstart + u2=$((u1 + 1)) + u3=$((u2 + 1)) + + [ -c /dev/md$u1 ] && mdconfig -d -u $u1 + [ -c /dev/md$u2 ] && mdconfig -d -u $u2 + [ -c /dev/md$u3 ] && mdconfig -d -u $u3 + + mdconfig -s 512m -u $u1 + mdconfig -s 512m -u $u2 + mdconfig -s 512m -u $u3 + + zpool create stress2_tank raidz md$u1 md$u2 md$u3 + + for i in `jot $mounts`; do + zfs create stress2_tank/test$i + zfs umount stress2_tank/test$i + done + + # start the parallel tests + touch /tmp/crossmp7.continue + for i in `jot $mounts`; do + ./$0 $i & + ./$0 find & + done + + wait + + zpool destroy stress2_tank + [ -n "$loaded" ] && kldunload zfs.ko + mdconfig -d -u $u1 + mdconfig -d -u $u2 + mdconfig -d -u $u3 + exit 0 +else + if [ $1 = find ]; then + while [ -f /tmp/crossmp7.continue ]; do + find /stress2_tank -type f > /dev/null 2>&1 + done + else + # The test: Parallel mount and unmounts + m=$1 + for i in `jot 1024`; do + zfs mount stress2_tank/test$m + zfs umount -f stress2_tank/test$m + done 2>/dev/null + rm -f /tmp/crossmp7.continue + fi +fi diff --git a/tools/test/stress2/misc/crossmp8.sh b/tools/test/stress2/misc/crossmp8.sh new file mode 100755 index 000000000000..f8d06d6a4a30 --- /dev/null +++ b/tools/test/stress2/misc/crossmp8.sh @@ -0,0 +1,125 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 crossmp3.sh. fifos and sockets added to load. +# Not really a cross mount point test, but a test of the old +# non-directory use of the vnode v_un union. +# mckusick@ suggested using fifos for this test. + +# "panic: mtx_lock() of spin mutex @ ../kern/vfs_subr.c:512" seen. +# https://people.freebsd.org/~pho/stress/log/crossmp8.txt +# Fixed by r291671. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +CONT=/tmp/crossmp8.continue +N=`sysctl -n hw.ncpu` +usermem=`sysctl -n hw.usermem` +[ `swapinfo | wc -l` -eq 1 ] && usermem=$((usermem/100*80)) +size=$((usermem / 1024 / 1024 / N)) + +mounts=$N # Number of parallel scripts + +if [ $# -eq 0 ]; then + oldmx=`sysctl -n kern.maxvnodes` + trap "sysctl kern.maxvnodes=$oldmx > /dev/null" EXIT SIGINT + sysctl kern.maxvnodes=3072 > /dev/null + + for i in `jot $mounts`; do + m=$((i + mdstart - 1)) + [ ! -d ${mntpoint}$m ] && + { mkdir ${mntpoint}$m; chmod 755 ${mntpoint}$m; } + mount | grep "${mntpoint}$m " | grep -q md$m && + umount ${mntpoint}$m + mdconfig -l | grep -q md$m && mdconfig -d -u $m + + mdconfig -a -t swap -s ${size}m -u $m + bsdlabel -w md$m auto + newfs md${m}$part > /dev/null 2>&1 + done + + # start the parallel tests + touch $CONT + for i in `jot $mounts`; do + m=$((i + mdstart - 1)) + ./$0 $m & + ./$0 find & + done + sleep 60 + rm -f $CONT + ../tools/killall.sh + wait + + for i in `jot $mounts`; do + m=$((i + mdstart - 1)) + while mount | grep -q "on ${mntpoint}$m "; do + umount ${mntpoint}$m && break + sleep 1 + done + mdconfig -d -u $m + done + ./cleanup.sh + exit 0 +else + if [ $1 = find ]; then + while [ -f $CONT ]; do + find ${mntpoint}* -maxdepth 1 -ls > /dev/null 2>&1 + sleep .1 + done + else + export RUNTIME=15s + export runRUNTIME=15s + # The test: Parallel mount and unmounts + start=`date '+%s'` + while [ $((`date '+%s'` - start)) -lt 300 ]; do + m=$1 + mount /dev/md${m}$part ${mntpoint}$m && + chmod 777 ${mntpoint}$m + export RUNDIR=${mntpoint}$m/stressX + export CTRLDIR=${mntpoint}$m/stressX.control + export mkfifoLOAD=80 + export socketLOAD=80 + export TP=" + testcases/mkfifo/mkfifo + testcases/mkdir/mkdir + " + (cd ${mntpoint}$m && find . -delete) + su $testuser -c 'cd ..; ./testcases/run/run $TP' > \ + /dev/null 2>&1 + + while mount | grep -q "on ${mntpoint}$m "; do + opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && echo "-f") + umount $opt ${mntpoint}$m > /dev/null 2>&1 + [ -f $CONT ] || break 2 + done + done + rm -f $CONT + fi +fi diff --git a/tools/test/stress2/misc/crossmp9.sh b/tools/test/stress2/misc/crossmp9.sh new file mode 100755 index 000000000000..e55f16b5ede4 --- /dev/null +++ b/tools/test/stress2/misc/crossmp9.sh @@ -0,0 +1,90 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC Isilon +# All rights reserved. +# +# 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 of file systems, while using getfsstat(2) via +# mount(8). + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mounts=15 # Number of parallel scripts +cont=/tmp/crossmp.continue +mdstart=$mdstart # Use md unit numbers from this point + +if [ $# -eq 0 ]; then + touch $cont + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + [ ! -d ${mntpoint}$m ] && mkdir ${mntpoint}$m + mount | grep "${mntpoint}$m " | grep -q md$m && + umount ${mntpoint}$m + mdconfig -l | grep -q md$m && mdconfig -d -u $m + + mdconfig -a -t swap -s 512m -u $m + bsdlabel -w md$m auto + newfs $newfs_flags md${m}$part > /dev/null 2>&1 + done + + # start the parallel tests + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + ./$0 $m & + ./$0 find $m & + done + wait + + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + mdconfig -d -u $m + rm -f $D$m + done + exit 0 +else + if [ $1 = find ]; then + m=$2 + while [ -r $cont ]; do + df ${mntpoint}$m + mount + done > /dev/null 2>&1 + else + + # The test: Parallel mount and unmounts + start=`date '+%s'` + while [ $((`date '+%s'` - start)) -lt 300 ] ; do + m=$1 + mount /dev/md${m}$part ${mntpoint}$m + while mount | grep -qw ${mntpoint}$m; do + opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && + echo "-f") + umount $opt ${mntpoint}$m > /dev/null 2>&1 + done + done + rm -f $cont + fi +fi diff --git a/tools/test/stress2/misc/dangling.sh b/tools/test/stress2/misc/dangling.sh new file mode 100755 index 000000000000..5f3db6db00ec --- /dev/null +++ b/tools/test/stress2/misc/dangling.sh @@ -0,0 +1,87 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 + +# "panic: softdep_deallocate_dependencies: dangling deps" seen. +# "panic: softdep_write_inodeblock: indirect pointer #0 mismatch" seen. +# http://people.freebsd.org/~pho/stress/log/dangling.txt +# http://people.freebsd.org/~pho/stress/log/dangling2.txt +# https://people.freebsd.org/~pho/stress/log/kostik1101.txt + +# Test scenario seems optimized for 4 CPUs. + +. ../default.cfg + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint || exit 1 +chmod 777 $mntpoint + +export runRUNTIME=4m +export RUNDIR=$mntpoint/stressX +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$(($1 / 4)) +export INODES=$(($2 / 4)) + +export symlinkHOG=1 +export rwHOG=1 +export mkdirHOG=1 + +export LOAD=100 +export symlinkLOAD=100 +export rwLOAD=100 +export mkdirLOAD=100 +export TESTPROGS=" +testcases/symlink/symlink +testcases/fts/fts +testcases/mkdir/mkdir +testcases/rw/rw +" + +for i in `jot 10`; do + su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > \ + /dev/null 2>&1 & + sleep 60 + kill $! + ../tools/killall.sh > /dev/null 2>&1 + ../tools/killall.sh > /dev/null 2>&1 + wait +done + +s=0 +for i in `jot 6`; do + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && s=1 +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/datagram.sh b/tools/test/stress2/misc/datagram.sh new file mode 100755 index 000000000000..895145a22c84 --- /dev/null +++ b/tools/test/stress2/misc/datagram.sh @@ -0,0 +1,96 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# UNIX datagram socket test. + +# "panic: mutex unp not owned at ../../../kern/uipc_usrreq.c:879" seen: +# https://people.freebsd.org/~pho/stress/log/datagram.txt +# Fixed by r334756. + +. ../default.cfg + +cd /tmp +cat > datagram.c < +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +char *filename = "/tmp/datagram.socket"; + +int +main(void) { + + struct sockaddr_un addr; + int bytes, sockfd; + char buf[1024]; + + unlink(filename); + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, filename, 104); + + if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) + err(1, "socket"); + + if (bind(sockfd, (struct sockaddr *) &addr, + sizeof(addr)) == -1) + err(1, "bind"); + + if (connect(sockfd, (struct sockaddr *) &addr, + sizeof(addr)) == -1) + err(1, "connect"); + + bytes = read(sockfd, buf, sizeof(buf)); + + return (0); +} +EOF + +mycc -o datagram -Wall -Wextra -O2 -g datagram.c || exit 1 +rm datagram.c + +./datagram & +sleep 1 +kill $! +wait + +rm -f datagram /tmp/datagram.socket +exit 0 diff --git a/tools/test/stress2/misc/datagram2.sh b/tools/test/stress2/misc/datagram2.sh new file mode 100755 index 000000000000..66cfd44711c2 --- /dev/null +++ b/tools/test/stress2/misc/datagram2.sh @@ -0,0 +1,104 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# UNIX datagram socket test. + +# "panic: mutex unp not owned at ../../../kern/uipc_usrreq.c:879" seen. +# Fixed by r334756. + +. ../default.cfg + +cd /tmp +cat > datagram2.c < +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +char *filename = "/tmp/datagram2.socket"; + +int +main(void) { + + struct message { struct cmsghdr msg_hdr; int fd; } m; + struct msghdr mh; + struct sockaddr_un addr; + ssize_t len; + int sockfd; + + unlink(filename); + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, filename, 104); + + if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) + err(1, "socket"); + + if (bind(sockfd, (struct sockaddr *) &addr, + sizeof(addr)) == -1) + err(1, "bind"); + + if (connect(sockfd, (struct sockaddr *) &addr, + sizeof(addr)) == -1) + err(1, "connect"); + + bzero(&mh, sizeof(mh)); + bzero(&m, sizeof(m)); + mh.msg_control = &m; + mh.msg_controllen = sizeof(m); + m.msg_hdr.cmsg_len = sizeof(m); + m.msg_hdr.cmsg_level = SOL_SOCKET; + m.msg_hdr.cmsg_type = SCM_RIGHTS; + m.fd = sockfd; + len = sendmsg(sockfd, &mh, 0); + if (len < 0) + err(1, "sendmsg"); + + return (0); +} +EOF + +cc -o datagram2 -Wall -Wextra -O2 -g datagram2.c || exit 1 +rm -f datagram2.c datagram2.socket + +./datagram2 + +rm datagram2 datagram2.socket +exit 0 diff --git a/tools/test/stress2/misc/datagram3.sh b/tools/test/stress2/misc/datagram3.sh new file mode 100755 index 000000000000..ca54377befcc --- /dev/null +++ b/tools/test/stress2/misc/datagram3.sh @@ -0,0 +1,106 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# UNIX datagram socket test. + +# "panic: mutex unp not owned at ../../../kern/uipc_usrreq.c:879" seen. +# Fixed by r334756. + +. ../default.cfg + +cd /tmp +cat > datagram3.c < +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +char *filename = "/tmp/datagram3.socket"; + +int +main(void) { + + struct message { struct cmsghdr msg_hdr; int fd; } m; + struct msghdr mh; + struct sockaddr_un addr; + ssize_t len; + int i, sockfd; + + unlink(filename); + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, filename, 104); + + if ((sockfd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) + err(1, "socket"); + + if (bind(sockfd, (struct sockaddr *) &addr, + sizeof(addr)) == -1) + err(1, "bind"); + + if (connect(sockfd, (struct sockaddr *) &addr, + sizeof(addr)) == -1) + err(1, "connect"); + + for (i = 0; i < 32; i++) { + bzero(&mh, sizeof(mh)); + bzero(&m, sizeof(m)); + mh.msg_control = &m; + mh.msg_controllen = sizeof(m); + m.msg_hdr.cmsg_len = sizeof(m); + m.msg_hdr.cmsg_level = SOL_SOCKET; + m.msg_hdr.cmsg_type = SCM_RIGHTS; + m.fd = sockfd; + len = sendmsg(sockfd, &mh, 0); + if (len < 0) + err(1, "sendmsg"); + } + + return (0); +} +EOF + +mycc -o datagram3 -Wall -Wextra -O2 -g datagram3.c || exit 1 +rm -f datagram3.c datagram3.socket + +./datagram3 + +rm datagram3 datagram3.socket +exit 0 diff --git a/tools/test/stress2/misc/datamove.sh b/tools/test/stress2/misc/datamove.sh new file mode 100755 index 000000000000..a27a53e5e31b --- /dev/null +++ b/tools/test/stress2/misc/datamove.sh @@ -0,0 +1,230 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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. +# + +# There is a well-known problem in FreeBSD, caused by allowing page faults +# while doing filesystem data move to or from userspace during read(2) and +# write(2). The issue is that if the userspace address being read or write +# from/to is backed by the mapping of the same file we are doing i/o to, +# we deadlock. + +# Test scenario by ups + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > datamove.c +mycc -o datamove -Wall datamove.c +rm -f datamove.c + +n=5 +old=`sysctl vm.old_msync | awk '{print $NF}'` +sysctl vm.old_msync=1 +for i in `jot $n`; do + mkdir -p /tmp/datamove.dir.$i + cd /tmp/datamove.dir.$i + /tmp/datamove & +done +cd /tmp +for i in `jot $n`; do + wait +done +for i in `jot $n`; do + rm -rf /tmp/datamove.dir.$i +done +sysctl vm.old_msync=$old + +rm -rf /tmp/datamove +exit 0 +EOF +/*- + * Copyright (c) 2006, Stephan Uphoff + * All rights reserved. + * + * 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 unmodified, 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 ``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 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. + */ + +#include +#include +#include +#include +#include +#include +#include + +int prepareFile(char* filename,int* fdp); +int mapBuffer(char** bufferp,int fd1,int fd2); +int startIO(int fd,char *buffer); + +int pagesize; + +#define FILESIZE (32*1024) +char wbuffer[FILESIZE]; + +/* Create a FILESIZE sized file - then remove file data from the cache*/ +int prepareFile(char* filename,int* fdp) +{ + int fd; + int len; + int status; + void *addr; + + fd = open(filename,O_CREAT | O_TRUNC | O_RDWR,S_IRWXU); + if (fd == -1) + { + perror("Creating file"); + return fd; + } + + len = write(fd,wbuffer,FILESIZE); + if (len < 0) + { + perror("Write failed"); + return 1; + } + + status = fsync(fd); + if (status != 0) + { + perror("fsync failed"); + return 1; + } + + addr = mmap(NULL,FILESIZE, PROT_READ | PROT_WRITE , MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) + { + perror("Mmap failed"); + return 1; + } + + status = msync(addr,FILESIZE,MS_INVALIDATE | MS_SYNC); + if (status != 0) + { + perror("Msync failed"); + return 1; + } + + munmap(addr,FILESIZE); + + *fdp = fd; + return 0; +} + +/* mmap a 2 page buffer - first page is from fd1, second page from fd2 */ +int mapBuffer(char** bufferp,int fd1,int fd2) +{ + void* addr; + char *buffer; + + addr = mmap(NULL,pagesize*2, PROT_READ | PROT_WRITE , MAP_SHARED, fd1, 0); + if (addr == MAP_FAILED) + { + perror("Mmap failed"); + return 1; + } + + buffer = addr; + addr = mmap(buffer + pagesize,pagesize, PROT_READ | PROT_WRITE , MAP_FIXED | + MAP_SHARED, fd2, 0); + + if (addr == MAP_FAILED) + { + perror("Mmap2 failed"); + return 1; + } + *bufferp = buffer; + return 0; +} + +int startIO(int fd,char *buffer) +{ + ssize_t len; + len = write(fd,buffer,2*pagesize); + if (len == -1) + { + perror("write failed"); + return 1; + } + return 0; +} + +int main(int argc,char *argv[],char *envp[]) +{ + + int fdA,fdB,fdDelayA,fdDelayB; + int status; + char *bufferA,*bufferB; + pid_t pid; + + pagesize = getpagesize(); + + if ((prepareFile("A",&fdA)) + || (prepareFile("B",&fdB)) + || (prepareFile("DelayA",&fdDelayA)) + || (prepareFile("DelayB",&fdDelayB)) + || (mapBuffer(&bufferA,fdDelayA,fdB)) + || (mapBuffer(&bufferB,fdDelayB,fdA))) + exit(1); + + pid = fork(); + + if (pid == 0) + { + status = startIO(fdA,bufferA); + exit(status); + } + + if (pid == -1) + { + exit(1); + } + status = startIO(fdB,bufferB); + exit(status); + +} diff --git a/tools/test/stress2/misc/datamove2.sh b/tools/test/stress2/misc/datamove2.sh new file mode 100755 index 000000000000..1b4c964a1f12 --- /dev/null +++ b/tools/test/stress2/misc/datamove2.sh @@ -0,0 +1,244 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 the datamove.sh scenario by not using "sysctl vm.old_msync=1" + +# Deadlock seen: +# https://people.freebsd.org/~pho/stress/log/numa042.txt + +# Test scenario by ups + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > datamove2.c +mycc -o datamove2 -Wall datamove2.c +rm -f datamove2.c + +for i in `jot 2`; do + $here/../testcases/swap/swap -t 5m -i 100 -h & + sleep 1 + /tmp/datamove2 || { echo FAIL; r=1; } + while pkill -9 swap; do :; done + [ -n "$r" ] && break +done +rm -rf /tmp/datamove2 +exit $r +EOF +/*- + * Copyright (c) 2006, Stephan Uphoff + * All rights reserved. + * + * 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 unmodified, 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 ``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 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int prepareFile(char *filename, int *fdp); +int mapBuffer (char **bufferp, int fd1, int fd2); +int startIO (int fd, char *buffer); + +int pagesize; + +#define FILESIZE (32*1024) +char wbuffer [FILESIZE]; + +/* Create a FILESIZE sized file - then remove file data from the cache */ +int +prepareFile(char *filename, int *fdp) +{ + int fd; + int len; + int status; + void *addr; + + fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU); + if (fd == -1) { + perror("Creating file"); + return fd; + } + len = write(fd, wbuffer, FILESIZE); + if (len < 0) { + perror("Write failed"); + return 1; + } + status = fsync(fd); + if (status != 0) { + perror("fsync failed"); + return 1; + } + addr = mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) { + perror("Mmap failed"); + return 1; + } + status = msync(addr, FILESIZE, MS_INVALIDATE | MS_SYNC); + if (status != 0) { + perror("Msync failed"); + return 1; + } + if (munmap(addr, FILESIZE) == -1) { + perror("munmap failed"); + return 1; + } + + *fdp = fd; + return 0; +} + +/* mmap a 2 page buffer - first page is from fd1, second page from fd2 */ +int +mapBuffer(char **bufferp, int fd1, int fd2) +{ + void *addr; + char *buffer; + + addr = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd1, 0); + if (addr == MAP_FAILED) { + perror("Mmap failed"); + return 1; + } + buffer = addr; + addr = mmap(buffer + pagesize, pagesize, PROT_READ | PROT_WRITE, MAP_FIXED | + MAP_SHARED, fd2, 0); + + if (addr == MAP_FAILED) { + perror("Mmap2 failed"); + return 1; + } + *bufferp = buffer; + return 0; +} + +void +unmapBuffer(char *bufferp) +{ + if (munmap(bufferp, pagesize * 2) == -1) + err(1, "unmap 1. buffer"); + /* + The following unmaps something random, which could trigger: + Program received signal SIGSEGV, Segmentation fault. + free (cp=0x28070000) at /usr/src/libexec/rtld-elf/malloc.c:311 + */ + +#if 0 + if (munmap(bufferp + pagesize * 2, pagesize * 2) == -1) + err(1, "unmap 2. buffer"); +#endif +} + +int +startIO(int fd, char *buffer) +{ + ssize_t len; + + len = write(fd, buffer, 2 * pagesize); + if (len == -1) { + perror("write failed"); + return 1; + } + return 0; +} + +int +main(int argc, char *argv[], char *envp[]) +{ + + int fdA, fdB, fdDelayA, fdDelayB; + int status; + int i; + char *bufferA, *bufferB; + pid_t pid; + + pagesize = getpagesize(); + + for (i = 0; i < 1000; i++) { + if ((prepareFile("A", &fdA)) + || (prepareFile("B", &fdB)) + || (prepareFile("DelayA", &fdDelayA)) + || (prepareFile("DelayB", &fdDelayB)) + || (mapBuffer(&bufferA, fdDelayA, fdB)) + || (mapBuffer(&bufferB, fdDelayB, fdA))) + exit(1); + + pid = fork(); + + if (pid == 0) { + status = startIO(fdA, bufferA); + exit(status); + } + if (pid == -1) { + perror("fork"); + exit(1); + } + status = startIO(fdB, bufferB); + if (wait(&status) == -1) + err(1, "wait"); + + close(fdA); + close(fdB); + close(fdDelayA); + close(fdDelayB); + unmapBuffer(bufferA); + unmapBuffer(bufferB); + unlink("A"); + unlink("B"); + unlink("DelayA"); + unlink("DelayB"); + } + exit(status); + +} diff --git a/tools/test/stress2/misc/datamove3.sh b/tools/test/stress2/misc/datamove3.sh new file mode 100755 index 000000000000..47a1cbce4c95 --- /dev/null +++ b/tools/test/stress2/misc/datamove3.sh @@ -0,0 +1,241 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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. +# + +# Threaded variation of datamove.sh + +# Based on a test scenario by ups and suggestions by kib + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > datamove3.c +mycc -o datamove3 -Wall datamove3.c -lpthread +rm -f datamove3.c + +n=5 +old=`sysctl vm.old_msync | awk '{print $NF}'` +sysctl vm.old_msync=1 +for i in `jot $n`; do + mkdir -p /tmp/datamove3.dir.$i + cd /tmp/datamove3.dir.$i + /tmp/datamove3 & +done +cd /tmp +for i in `jot $n`; do + wait +done +for i in `jot $n`; do + rm -rf /tmp/datamove3.dir.$i +done +sysctl vm.old_msync=$old + +rm -rf /tmp/datamove3 +exit 0 +EOF +/*- + * Copyright (c) 2006, Stephan Uphoff + * All rights reserved. + * + * 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 unmodified, 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 ``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 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct args { + char *bp; + int fd1; + int fd2; +} a[2]; + +int prepareFile(char *, int *); +void * mapBuffer(void *); +int startIO(int, char *); + +int pagesize; + +#define FILESIZE (32*1024) +char wbuffer [FILESIZE]; + +/* Create a FILESIZE sized file - then remove file data from the cache */ +int +prepareFile(char *filename, int *fdp) +{ + int fd; + int len; + int status; + void *addr; + + fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU); + if (fd == -1) { + perror("Creating file"); + return fd; + } + len = write(fd, wbuffer, FILESIZE); + if (len < 0) { + perror("Write failed"); + return 1; + } + status = fsync(fd); + if (status != 0) { + perror("fsync failed"); + return 1; + } + addr = mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) { + perror("Mmap failed"); + return 1; + } + status = msync(addr, FILESIZE, MS_INVALIDATE | MS_SYNC); + if (status != 0) { + perror("Msync failed"); + return 1; + } + munmap(addr, FILESIZE); + + *fdp = fd; + return 0; +} + +/* mmap a 2 page buffer - first page is from fd1, second page from fd2 */ +void * +mapBuffer(void *ar) +{ + void *addr; + char *buffer; + int i; + + i = (int )ar; + addr = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, a[i].fd1, 0); + if (addr == MAP_FAILED) { + err(1, "Mmap failed"); + } + buffer = addr; + addr = mmap(buffer + pagesize, pagesize, PROT_READ | PROT_WRITE, MAP_FIXED | + MAP_SHARED, a[i].fd2, 0); + + if (addr == MAP_FAILED) { + err(1, "Mmap2 failed"); + } + a[i].bp = buffer; + sleep(1); + return (NULL); +} + +int +startIO(int fd, char *buffer) +{ + ssize_t len; + + len = write(fd, buffer, 2 * pagesize); + if (len == -1) { + warn("startIO(%d, %p): write failed", fd, buffer); + return 1; + } + return 0; +} + +int +main(int argc, char *argv[], char *envp[]) +{ + + int fdA, fdB, fdDelayA, fdDelayB; + int r, status; + char *bufferA, *bufferB; + pid_t pid; + pthread_t threads[2]; + + pagesize = getpagesize(); + + if ((prepareFile("A", &fdA)) + || (prepareFile("B", &fdB)) + || (prepareFile("DelayA", &fdDelayA)) + || (prepareFile("DelayB", &fdDelayB))) + exit(1); + + a[0].fd1 = fdDelayA; + a[0].fd2 = fdB; + + a[1].fd1 = fdDelayB; + a[1].fd2 = fdA; + + if ((r = pthread_create(&threads[0], NULL, mapBuffer, (void *)0)) != 0) + errc(1, r, "pthread_create()"); + if ((r = pthread_create(&threads[1], NULL, mapBuffer, (void *)1)) != 0) + errc(1, r, "pthread_create()"); + + while (a[0].bp == NULL || a[1].bp == NULL) + pthread_yield(); + + bufferA = a[0].bp; + bufferB = a[1].bp; + + pid = fork(); + + if (pid == 0) { + status = startIO(fdA, bufferA); + exit(status); + } + if (pid == -1) { + exit(1); + } + status = startIO(fdB, bufferB); + exit(status); + +} diff --git a/tools/test/stress2/misc/datamove4.sh b/tools/test/stress2/misc/datamove4.sh new file mode 100755 index 000000000000..4b4726b8dace --- /dev/null +++ b/tools/test/stress2/misc/datamove4.sh @@ -0,0 +1,251 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 the datamove2.sh, using TMPFS +# Deadlock seen +# https://people.freebsd.org/~pho/stress/log/datamove4.txt + +# panic: elf32_putnote: Note type 10 changed as we read it (2236 > 2220)... +# https://people.freebsd.org/~pho/stress/log/datamove4-2.txt +# Fixed by r288944. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > datamove4.c +mycc -o datamove4 -Wall -Wextra -O2 -g datamove4.c +rm -f datamove4.c + +mount | grep -q "$mntpoint " && umount $mntpoint +mount -t tmpfs tmpfs $mntpoint +chmod 777 $mntpoint + +for i in `jot 5`; do + su $testuser -c "cd $mntpoint; /tmp/datamove4" +done +while mount | grep -q $mntpoint; do + umount -f $mntpoint > /dev/null 2>&1 +done + +rm -rf /tmp/datamove4 +exit 0 +EOF +/*- + * Copyright (c) 2006, Stephan Uphoff + * All rights reserved. + * + * 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 unmodified, 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 ``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 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int prepareFile(char *filename, int *fdp); +int mapBuffer (char **bufferp, int fd1, int fd2); +int startIO (int fd, char *buffer); + +int pagesize; + +#define FILESIZE (32*1024) +char wbuffer [FILESIZE]; + +/* Create a FILESIZE sized file - then remove file data from the cache */ +int +prepareFile(char *filename, int *fdp) +{ + int fd; + int len; + int status; + void *addr; + + fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU); + if (fd == -1) { + perror(filename); + return fd; + } + len = write(fd, wbuffer, FILESIZE); + if (len < 0) { + perror("Write failed"); + return 1; + } + status = fsync(fd); + if (status != 0) { + perror("fsync failed"); + return 1; + } + addr = mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) { + perror("Mmap failed"); + return 1; + } + status = msync(addr, FILESIZE, MS_INVALIDATE | MS_SYNC); + if (status != 0) { + perror("Msync failed"); + return 1; + } + if (munmap(addr, FILESIZE) == -1) { + perror("munmap failed"); + return 1; + } + + *fdp = fd; + return 0; +} + +/* mmap a 2 page buffer - first page is from fd1, second page from fd2 */ +int +mapBuffer(char **bufferp, int fd1, int fd2) +{ + void *addr; + char *buffer; + + addr = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd1, 0); + if (addr == MAP_FAILED) { + perror("Mmap failed"); + return 1; + } + buffer = addr; + addr = mmap(buffer + pagesize, pagesize, PROT_READ | PROT_WRITE, MAP_FIXED | + MAP_SHARED, fd2, 0); + + if (addr == MAP_FAILED) { + perror("Mmap2 failed"); + return 1; + } + *bufferp = buffer; + return 0; +} + +void +unmapBuffer(char *bufferp) +{ + if (munmap(bufferp, pagesize * 2) == -1) + err(1, "unmap 1. buffer"); + /* + The following unmaps something random, which could trigger: + Program received signal SIGSEGV, Segmentation fault. + free (cp=0x28070000) at /usr/src/libexec/rtld-elf/malloc.c:311 + */ + +#if 0 + if (munmap(bufferp + pagesize * 2, pagesize * 2) == -1) + err(1, "unmap 2. buffer"); +#endif +} + +int +startIO(int fd, char *buffer) +{ + ssize_t len; + + len = write(fd, buffer, 2 * pagesize); + if (len == -1) { + perror("write failed"); + return 1; + } + return 0; +} + +int +main() +{ + + int fdA, fdB, fdDelayA, fdDelayB; + int status; + int i; + char *bufferA, *bufferB; + pid_t pid; + + pagesize = getpagesize(); + + for (i = 0; i < 1000; i++) { + if ((prepareFile("A", &fdA)) + || (prepareFile("B", &fdB)) + || (prepareFile("DelayA", &fdDelayA)) + || (prepareFile("DelayB", &fdDelayB)) + || (mapBuffer(&bufferA, fdDelayA, fdB)) + || (mapBuffer(&bufferB, fdDelayB, fdA))) + exit(1); + + pid = fork(); + + if (pid == 0) { + status = startIO(fdA, bufferA); + exit(status); + } + if (pid == -1) { + perror("fork"); + exit(1); + } + status = startIO(fdB, bufferB); + if (wait(&status) == -1) + err(1, "wait"); + + close(fdA); + close(fdB); + close(fdDelayA); + close(fdDelayB); + unmapBuffer(bufferA); + unmapBuffer(bufferB); + unlink("A"); + unlink("B"); + unlink("DelayA"); + unlink("DelayB"); + } + exit(status); + +} diff --git a/tools/test/stress2/misc/datamove5.sh b/tools/test/stress2/misc/datamove5.sh new file mode 100755 index 000000000000..5f4a868f03b1 --- /dev/null +++ b/tools/test/stress2/misc/datamove5.sh @@ -0,0 +1,262 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 the datamove2.sh, using NULLFS +# No problems seen. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > datamove5.c +mycc -o datamove5 -Wall -Wextra -O2 -g datamove5.c +rm -f datamove5.c + +mp1=$mntpoint +mp2=${mntpoint}2 +[ -d $mp2 ] || mkdir $mp2 + +mount | grep -wq $mp2 && umount $mp2 +mount | grep -wq $mp1 && umount $mp1 +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 2g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mp1 + +mount -t nullfs $opt $mp1 $mp2 +chmod 777 $mp2 + +for i in `jot 5`; do + su $testuser -c "cd $mp2; /tmp/datamove5" +done + +while mount | grep -wq $mp2; do + umount $mp2 || sleep 1 +done +while mount | grep $mp1 | grep -q /dev/md; do + umount $mp1 || sleep 1 +done +mdconfig -d -u $mdstart + +rm -rf /tmp/datamove5 +exit 0 +EOF +/*- + * Copyright (c) 2006, Stephan Uphoff + * All rights reserved. + * + * 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 unmodified, 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 ``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 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int prepareFile(char *filename, int *fdp); +int mapBuffer (char **bufferp, int fd1, int fd2); +int startIO (int fd, char *buffer); + +int pagesize; + +#define FILESIZE (32*1024) +char wbuffer [FILESIZE]; + +/* Create a FILESIZE sized file - then remove file data from the cache */ +int +prepareFile(char *filename, int *fdp) +{ + int fd; + int len; + int status; + void *addr; + + fd = open(filename, O_CREAT | O_TRUNC | O_RDWR, S_IRWXU); + if (fd == -1) { + perror(filename); + return fd; + } + len = write(fd, wbuffer, FILESIZE); + if (len < 0) { + perror("Write failed"); + return 1; + } + status = fsync(fd); + if (status != 0) { + perror("fsync failed"); + return 1; + } + addr = mmap(NULL, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (addr == MAP_FAILED) { + perror("Mmap failed"); + return 1; + } + status = msync(addr, FILESIZE, MS_INVALIDATE | MS_SYNC); + if (status != 0) { + perror("Msync failed"); + return 1; + } + if (munmap(addr, FILESIZE) == -1) { + perror("munmap failed"); + return 1; + } + + *fdp = fd; + return 0; +} + +/* mmap a 2 page buffer - first page is from fd1, second page from fd2 */ +int +mapBuffer(char **bufferp, int fd1, int fd2) +{ + void *addr; + char *buffer; + + addr = mmap(NULL, pagesize * 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd1, 0); + if (addr == MAP_FAILED) { + perror("Mmap failed"); + return 1; + } + buffer = addr; + addr = mmap(buffer + pagesize, pagesize, PROT_READ | PROT_WRITE, MAP_FIXED | + MAP_SHARED, fd2, 0); + + if (addr == MAP_FAILED) { + perror("Mmap2 failed"); + return 1; + } + *bufferp = buffer; + return 0; +} + +void +unmapBuffer(char *bufferp) +{ + if (munmap(bufferp, pagesize * 2) == -1) + err(1, "unmap 1. buffer"); + /* + The following unmaps something random, which could trigger: + Program received signal SIGSEGV, Segmentation fault. + free (cp=0x28070000) at /usr/src/libexec/rtld-elf/malloc.c:311 + */ + +#if 0 + if (munmap(bufferp + pagesize * 2, pagesize * 2) == -1) + err(1, "unmap 2. buffer"); +#endif +} + +int +startIO(int fd, char *buffer) +{ + ssize_t len; + + len = write(fd, buffer, 2 * pagesize); + if (len == -1) { + perror("write failed"); + return 1; + } + return 0; +} + +int +main() +{ + + int fdA, fdB, fdDelayA, fdDelayB; + int status; + int i; + char *bufferA, *bufferB; + pid_t pid; + + pagesize = getpagesize(); + + for (i = 0; i < 1000; i++) { + if ((prepareFile("A", &fdA)) + || (prepareFile("B", &fdB)) + || (prepareFile("DelayA", &fdDelayA)) + || (prepareFile("DelayB", &fdDelayB)) + || (mapBuffer(&bufferA, fdDelayA, fdB)) + || (mapBuffer(&bufferB, fdDelayB, fdA))) + exit(1); + + pid = fork(); + + if (pid == 0) { + status = startIO(fdA, bufferA); + exit(status); + } + if (pid == -1) { + perror("fork"); + exit(1); + } + status = startIO(fdB, bufferB); + if (wait(&status) == -1) + err(1, "wait"); + + close(fdA); + close(fdB); + close(fdDelayA); + close(fdDelayB); + unmapBuffer(bufferA); + unmapBuffer(bufferB); + unlink("A"); + unlink("B"); + unlink("DelayA"); + unlink("DelayB"); + } + exit(status); + +} diff --git a/tools/test/stress2/misc/db.sh b/tools/test/stress2/misc/db.sh new file mode 100755 index 000000000000..580ee71c4c94 --- /dev/null +++ b/tools/test/stress2/misc/db.sh @@ -0,0 +1,178 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 resource starvation using msync(2). + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/db.c +mycc -o db -Wall -Wextra -O0 -g db.c -lpthread || exit 1 +rm -f db.c +cd $odir + +dd if=/dev/zero of=$diskimage bs=1m count=10 status=none + +/tmp/db $diskimage & + +start=`date '+%s'` +ls -l $diskimage > /dev/null # Will wait for more than 90 seconds +[ `date '+%s'` -gt $((start + 90)) ] && fail="yes" +wait +e=$((`date +%s` - start)) +[ $fail ] && + echo "Time for a ls is $((e / 60)) minutes $((e % 60)) seconds" +rm -f /tmp/db $diskimage +#[ $fail ] && exit 1 || exit 0 # Known issue +exit 0 + +EOF +#include +#include +#include +#include +#include + +#include +#include +#include +#ifdef __FreeBSD__ +#include +#define __NP__ +#endif +#include +#include +#include +#include +#include + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +size_t len; +void *p; +int wthreads; + +#define BZ 128 /* buffer size */ +#define RUNTIME 180 /* runtime for test */ +#define RTHREADS 64 /* reader threads */ +#define WTHREADS 64 /* writer threads */ + +void * +wt(void *arg __unused) +{ + time_t start; + int64_t pos; + void *c; + int r; + char buf[BZ]; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + if ((r = pthread_mutex_lock(&mutex)) != 0) + errc(1, r, "pthread_mutex_lock"); + wthreads++; + if ((r = pthread_mutex_unlock(&mutex)) != 0) + errc(1, r, "pthread_mutex_unlock"); + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + pos = arc4random() % (len / BZ); + pos = pos * BZ; + c = p + pos; + bcopy(buf, c, BZ); + c = (void *)trunc_page((unsigned long)c); + if (msync((void *)c, round_page(BZ), MS_SYNC) == -1) + err(1, "msync(%p)", c); + usleep(10000 + arc4random() % 1000); + } + + if ((r = pthread_mutex_lock(&mutex)) != 0) + errc(1, r, "pthread_mutex_lock"); + wthreads--; + if ((r = pthread_mutex_unlock(&mutex)) != 0) + errc(1, r, "pthread_mutex_unlock"); + + return (NULL); +} + +void * +rt(void *arg __unused) +{ + int64_t pos; + char buf[BZ], *c; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + c = p; + do { + pos = arc4random() % (len / BZ); + pos = pos * BZ; + bcopy(&c[pos], buf, BZ); + usleep(10000 + arc4random() % 1000); + } while (wthreads != 0); + + return (NULL); +} + +int +main(int argc, char *argv[]) +{ + pthread_t cp[RTHREADS + WTHREADS]; + struct stat st; + int fd, i, j, rc; + + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + if ((fd = open(argv[1], O_RDWR)) == -1) + err(1, "open %s", argv[1]); + if (fstat(fd, &st) == -1) + err(1, "stat"); + len = round_page(st.st_size); + p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if ((void *)p == MAP_FAILED) + err(1, "mmap"); + + i = 0; + for (j = 0; j < WTHREADS; j++) { + if ((rc = pthread_create(&cp[i++], NULL, wt, NULL)) != 0) + errc(1, rc, "pthread_create()"); + } + usleep(100); + for (j = 0; j < RTHREADS; j++) { + if ((rc = pthread_create(&cp[i++], NULL, rt, NULL)) != 0) + errc(1, rc, "pthread_create()"); + } + + for (j = 0; j < RTHREADS + WTHREADS; j++) + pthread_join(cp[--i], NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/dd.sh b/tools/test/stress2/misc/dd.sh new file mode 100755 index 000000000000..ba57e7f1d0a2 --- /dev/null +++ b/tools/test/stress2/misc/dd.sh @@ -0,0 +1,64 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Watchdog fired: +# https://people.freebsd.org/~pho/stress/log/mark013.txt +# Fixed by: r327213 + +# watchdogd: https://people.freebsd.org/~pho/stress/log/kostik1245.txt + +. ../default.cfg + +outputfile=$RUNDIR/dd.outputfile +(cd ../testcases/swap; ./swap -t 30m -i 20) > /dev/null 2>&1 & +trap "rm -f ${outputfile}*" EXIT INT +N=2 +NCPU=`sysctl -n hw.ncpu` +s=0 +size=512 +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 720 ]; do + pids="" + for i in `jot $N`; do + dd if=/dev/zero of=${outputfile}$i bs=1m count=$size & + pids="$pids $!" + done > /dev/null 2>&1 + for pid in $pids; do + wait $pid + s=$? + [ $s -ne 0 ] && break 2 + done + N=$((N * 2)) + rm -f ${outputfile}* + [ $N -gt $((NCPU * 2)) ] && break +done + +while pgrep -q swap; do + pkill -9 swap +done +exit $s diff --git a/tools/test/stress2/misc/dev.sh b/tools/test/stress2/misc/dev.sh new file mode 100755 index 000000000000..1dc094a09e5b --- /dev/null +++ b/tools/test/stress2/misc/dev.sh @@ -0,0 +1,137 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 parallel read access to /dev. + +# "panic: Most recently used by DEVFS1" seen. +# https://people.freebsd.org/~pho/stress/log/dev.txt +# Fixed by r293826. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > dev.c +mycc -o dev -Wall -Wextra -O2 dev.c || exit 1 +rm -f dev.c + +echo "Expect: g_access(958): provider ufsid/5c581221fcac7d80 has error 6 set" +daemon sh -c \ + "(cd $here/../testcases/swap; ./swap -t 6m -i 20 -k -l 100)" > \ + /dev/null + +/tmp/dev # Note: this runs as root. +s=$? + +while pkill -9 swap; do + : +done + +rm -f /tmp/dev +exit $s +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 4 +#define RUNTIME 300 + +char path[80]; + +void +churn(char *path) +{ + FTS *fts; + FTSENT *p; + time_t start; + int fd, ftsoptions; + char *args[2]; + + ftsoptions = FTS_PHYSICAL; + args[0] = path; + args[1] = 0; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) { + if (p->fts_info == FTS_D || + p->fts_info == FTS_DP) + continue; + if (strstr(p->fts_path, "ttyu") != NULL) + continue; + if (strstr(p->fts_path, "fcdm") != NULL) + continue; + if ((fd = open(p->fts_path, O_RDONLY|O_NONBLOCK)) == -1) + continue; + usleep(arc4random() % 1000); + close(fd); + + } + + if (errno != 0 && errno != ENOENT) + warn("fts_read"); + if (fts_close(fts) == -1) + err(1, "fts_close()"); + } + + _exit(0); +} + +int +main(void) +{ + int e, i, status;; + + e = 0; + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + churn("/dev"); + + for (i = 0; i < PARALLEL; i++) { + wait(&status); + if (status != 0) + e++; + } + + return (e); +} diff --git a/tools/test/stress2/misc/dev2.sh b/tools/test/stress2/misc/dev2.sh new file mode 100755 index 000000000000..5a194974e135 --- /dev/null +++ b/tools/test/stress2/misc/dev2.sh @@ -0,0 +1,144 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 parallel access to /dev. A non-root version. + +# "panic: Bad link elm 0xfffff8000b07ed00 prev->next != elm" seen. +# https://people.freebsd.org/~pho/stress/log/dev2.txt + +# Fixed by r294204. + +# "panic: Assertion !tty_gone(tp) failed at ../sys/ttydevsw.h:165" seen: +# https://people.freebsd.org/~pho/stress/log/dev2-2.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +kldstat -v | grep -q pty || { kldload pty || exit 0; } +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > dev2.c +mycc -o dev2 -Wall -Wextra -O2 dev2.c || exit 1 +rm -f dev2.c + +daemon sh -c \ + "(cd $here/../testcases/swap; ./swap -t 6m -i 20 -k -l 100)" > \ + /dev/null + +su $testuser -c /tmp/dev2 + +while pkill -9 swap; do + : +done + +rm -f /tmp/dev2 +exit +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 4 +#define RUNTIME 300 + +jmp_buf jbuf; +char path[80]; + +void +handler(int i __unused) { + longjmp(jbuf, 1); +} + +void +churn(char *path) +{ + FTS *fts; + FTSENT *p; + time_t start; + int fd, ftsoptions; + char *args[2]; + + ftsoptions = FTS_PHYSICAL; + args[0] = path; + args[1] = 0; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + (void)setjmp(jbuf); + ualarm(0, 0); + while ((p = fts_read(fts)) != NULL) { + if (p->fts_info == FTS_D || + p->fts_info == FTS_DP) + continue; + ualarm(500000, 0); + if ((fd = open(p->fts_path, arc4random() % (O_CLOEXEC << 2))) == -1) + continue; + ualarm(0, 0); + usleep(arc4random() % 1000); + close(fd); + + } + + if (errno != 0 && errno != ENOENT) + warn("fts_read"); + if (fts_close(fts) == -1) + err(1, "fts_close()"); + } + + _exit(0); +} + +int +main(void) +{ + int i; + + signal(SIGALRM, handler); + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + churn("/dev"); + + for (i = 0; i < PARALLEL; i++) + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/dev3.sh b/tools/test/stress2/misc/dev3.sh new file mode 100755 index 000000000000..b120266faf83 --- /dev/null +++ b/tools/test/stress2/misc/dev3.sh @@ -0,0 +1,160 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# pts memory leak regression test. + +# Leaks seen when flags is either O_SHLOCK or O_EXLOCK and /dev/ptmx and +# /dev/pts/ is being opened. +# Fixed in r313496. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +kldstat -v | grep -q pty || { kldload pty || exit 0; } +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > dev3.c +mycc -o dev3 -Wall -Wextra -O2 dev3.c || exit 1 +rm -f dev3.c + +#(cd $here/../testcases/swap; ./swap -t 10h -i 20 -l 100) > \ +# /dev/null & + +pts=`vmstat -m | grep pts | awk '{print $2}'` +[ -z "$pts" ] && pts=0 + +e=0 +n=0 +while true; do + su $testuser -c "/tmp/dev3 $n" + new=`vmstat -m | grep pts | awk '{print $2}'` + if [ $new -gt $pts ]; then + leak=$((new - pts)) + printf "flag %d (0x%x) leaks %d pts, %d allocated.\n" $n $n \ + $leak $new + pts=$new + e=1 + fi + [ $n -eq 0 ] && n=1 || n=$((n * 2)) + [ $n -gt $((0x00200000)) ] && break # O_VERIFY +done +while pkill -9 swap; do + sleep 1 +done +wait +rm -f /tmp/dev3 +exit $e +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 4 +#define RUNTIME 60 + +jmp_buf jbuf; +char path[80]; + +void +handler(int i __unused) { + longjmp(jbuf, 1); +} + +void +churn(int flag, char *path) +{ + FTS *fts; + FTSENT *p; + time_t start; + int fd, ftsoptions; + char *args[2]; + + ftsoptions = FTS_PHYSICAL; + args[0] = path; + args[1] = 0; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + (void)setjmp(jbuf); + ualarm(0, 0); + while ((p = fts_read(fts)) != NULL) { + if (p->fts_info == FTS_D || + p->fts_info == FTS_DP) + continue; + ualarm(500000, 0); + if ((fd = open(p->fts_path, flag)) == -1) + continue; + ualarm(0, 0); + usleep(arc4random() % 1000); + close(fd); + + } + + if (errno != 0 && errno != ENOENT) + warn("fts_read"); + if (fts_close(fts) == -1) + err(1, "fts_close()"); + } + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + int flag, i; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + flag = atoi(argv[1]); + signal(SIGALRM, handler); + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + churn(flag, "/dev"); + + for (i = 0; i < PARALLEL; i++) + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/devfd.sh b/tools/test/stress2/misc/devfd.sh new file mode 100755 index 000000000000..1f5eecece0ca --- /dev/null +++ b/tools/test/stress2/misc/devfd.sh @@ -0,0 +1,130 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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: vn_lock 0xc65b5828: zero hold count" seen. + +# Originally found by the iknowthis test suite +# by Tavis Ormandy +# Fixed by r227952 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > devfd.c +rm -f /tmp/devfd +mycc -o devfd -Wall -Wextra -O2 -g devfd.c -lpthread || exit 1 +rm -f devfd.c + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +su $testuser -c "(cd $mntpoint; /tmp/devfd)" + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/devfd +exit +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int fd[3], fd2[3]; + +void * +thr1(void *arg __unused) +{ + int i, j; + char path[80]; + + for (i = 0; i < 100000; i++) { + for (j = 0; j < 3; j++) { + if (fd[j] != -1) + close(fd[j]); + sprintf(path, "fx%d", j); + fd[j] = open(path, O_RDWR | O_CREAT, 0640); + } + } + return (0); +} + +void * +thr2(void *arg __unused) +{ + int i, j; + char path[80]; + + for (i = 0; i < 100000; i++) { + for (j = 0; j < 3; j++) { + if (fd2[j] != -1) + close(fd2[j]); + sprintf(path, "/dev/fd/%d", j); + if ((fd2[j] = open(path, O_RDONLY)) != -1) + fchflags(fd2[j], UF_NODUMP); + } + + } + return (0); +} + +int +main(void) +{ + pthread_t p1, p2; + int r; + + close(0); + close(1); + close(2); + if ((r = pthread_create(&p1, NULL, thr1, NULL)) != 0) + errc(1, r, "pthread_create"); + if ((r = pthread_create(&p2, NULL, thr2, NULL)) != 0) + errc(1, r, "pthread_create"); + pthread_join(p1, NULL); + pthread_join(p2, NULL); + + return (0); +} + diff --git a/tools/test/stress2/misc/devfs.sh b/tools/test/stress2/misc/devfs.sh new file mode 100755 index 000000000000..acb351f26e56 --- /dev/null +++ b/tools/test/stress2/misc/devfs.sh @@ -0,0 +1,72 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Page fault seen: +# https://people.freebsd.org/~pho/stress/log/devfs.txt +# Fixed by r326851. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mounts=15 # Number of parallel scripts +cont=/tmp/devfs.continue + +if [ $# -eq 0 ]; then + touch $cont + for i in `jot $mounts`; do + [ ! -d ${mntpoint}$i ] && mkdir ${mntpoint}$i + mount | grep -q "on ${mntpoint}$i " && umount ${mntpoint}$i + done + + # start the parallel tests + for i in `jot $mounts`; do + ./$0 $i & + ./$0 find & + done + wait +else + if [ $1 = find ]; then + while [ -r $cont ]; do + find ${mntpoint}* > /dev/null 2>&1 + done + else + + # The test: Parallel mount and unmounts + start=`date '+%s'` + while [ `date '+%s'` -lt $((start + 300)) ]; do + m=$1 + mount -t devfs none ${mntpoint}$m + opt=`[ $(( m % 2 )) -eq 0 ] && echo -f` + while mount | grep -q " ${mntpoint}$m "; do + umount $opt ${mntpoint}$m > /dev/null 2>&1 + done + done + rm -f $cont + fi +fi diff --git a/tools/test/stress2/misc/devfs2.sh b/tools/test/stress2/misc/devfs2.sh new file mode 100755 index 000000000000..47f80a09f7f8 --- /dev/null +++ b/tools/test/stress2/misc/devfs2.sh @@ -0,0 +1,107 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Stopped at devfs_open+0x23f: pushl 0x14(%ebx) +# db> where +# Tracing pid 46017 tid 100350 td 0xc4c08510 +# devfs_open(e6d06a10) at devfs_open+0x23f +# VOP_OPEN_APV(c09edda0,e6d06a10) at VOP_OPEN_APV+0x9b +# vn_open_cred(e6d06b78,e6d06c78,0,c4883900,3,...) at vn_open_cred+0x41e +# vn_open(e6d06b78,e6d06c78,0,3) at vn_open+0x1e +# kern_open(c4c08510,8048887,0,1,0,...) at kern_open+0xb7 +# open(c4c08510,e6d06d00) at open+0x18 +# syscall(e6d06d38) at syscall+0x252 + +# Test scenario by kib@freebsd.org + +. ../default.cfg + +odir=`pwd` +dir=/tmp + +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/devfs2.c +mycc -o devfs2 -Wall devfs2.c -lthr || exit 1 +rm -f devfs2.c + +./devfs2 + +rm devfs2 +exit 0 + +EOF +#include +#include +#include +#include +#include +#include +#include +#include + +void * +thr1(void *arg) +{ + int fd; + int i; + + for (i = 0; i < 1024; i++) { + if ((fd = open("/dev/zero", O_RDONLY)) == -1) + perror("open /dev/zero"); + close(fd); + } + return (0); +} + +void * +thr2(void *arg) +{ + int i; + for (i = 0; i < 1024; i++) + close(3); + return (0); +} + +int +main() +{ + pthread_t threads[2]; + int i; + int r; + + if ((r = pthread_create(&threads[0], NULL, thr1, 0)) != 0) + err(1, "pthread_create(): %s\n", strerror(r)); + if ((r = pthread_create(&threads[1], NULL, thr2, 0)) != 0) + err(1, "pthread_create(): %s\n", strerror(r)); + + for (i = 0; i < 2; i++) + if ((r = pthread_join(threads[i], NULL)) != 0) + errc(1, r, "pthread_join(%d)", i); + + return (0); +} diff --git a/tools/test/stress2/misc/devfs3.sh b/tools/test/stress2/misc/devfs3.sh new file mode 100755 index 000000000000..4bfce110eade --- /dev/null +++ b/tools/test/stress2/misc/devfs3.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 seen with two instances of devfs.sh running simultaneously. + +# "panic: dev_rel() gave negative count" seen: +# https://people.freebsd.org/~pho/stress/log/devfs3.txt + +# "panic: No vop_unlock(0xfffff80089eb0750, 0xfffffe104944f4c8)" seen: +# https://people.freebsd.org/~pho/stress/log/kostik898.txt + +# Fixed by r301928 + r301929. + +./devfs.sh > /dev/null 2>&1 & +p1=$! +./devfs.sh > /dev/null 2>&1 & +p2=$! + +wait $p1 +wait $p2 diff --git a/tools/test/stress2/misc/devfs4.sh b/tools/test/stress2/misc/devfs4.sh new file mode 100755 index 000000000000..eac87374db11 --- /dev/null +++ b/tools/test/stress2/misc/devfs4.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# Bug 235513 - panic: dead bo 0xfffff8000a838b48 +# https://people.freebsd.org/~pho/stress/log/devfs4.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +umount -f /dev && mount /dev diff --git a/tools/test/stress2/misc/devfs5.sh b/tools/test/stress2/misc/devfs5.sh new file mode 100755 index 000000000000..b0b1d98fc83e --- /dev/null +++ b/tools/test/stress2/misc/devfs5.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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 scenario for https://reviews.freebsd.org/D20411 +# Add devfs(5) support for VOP_MKDIR(9) and VOP_RMDIR(9) + +. ../default.cfg + +mkdir /dev/devfs5 2>/dev/null || exit 0 +rmdir /dev/devfs5 +mount | grep -q "on $mntpoint " && umount -f $mntpoint +mount -t devfs null $mntpoint || exit 1 + +(cd ../testcases/swap; ./swap -t 30m -i 20 -h -l 100) & +spid=$! +cd $mntpoint +N=3000 +for i in `jot 25`; do + ( + mkdir s$i; cd s$i + for k in `jot 5`; do + for j in `jot $N`; do mkdir d$i.$j; done + for j in `jot $N`; do rmdir d$i.$j; done + done + cd ..; rmdir s$i + ) & + pids="$pids $!" +done +for i in $pids; do + wait $i +done +while pkill swap; do :; done +wait spid + +cd / +while mount | grep -q "on $mntpoint "; do + umount $mntpoint && break + sleep 1 +done +exit 0 diff --git a/tools/test/stress2/misc/dfull.sh b/tools/test/stress2/misc/dfull.sh new file mode 100755 index 000000000000..100784047dbc --- /dev/null +++ b/tools/test/stress2/misc/dfull.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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. +# + +# Processes stuck in "ufs" seen. +# Looping softdep_request_cleanup() seen + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep "$mntpoint" | grep md${mdstart}$part > /dev/null && umount $mntpoint +mdconfig -l | grep md$mdstart > /dev/null && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 512m -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +export RUNDIR=$mntpoint/stressX +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$(($1 * 10)) +export INODES=$(($2 * 10)) +export runRUNTIME=20m +export RUNTIME=1m + +(cd ..; ./run.sh disk.cfg > /dev/null 2>&1) + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/dtrace.sh b/tools/test/stress2/misc/dtrace.sh new file mode 100755 index 000000000000..3521ef3099e5 --- /dev/null +++ b/tools/test/stress2/misc/dtrace.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Simple dtrace(1) test scenario. +# https://people.freebsd.org/~pho/stress/log/dtrace.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg +dtrace -n 'dtrace:::BEGIN { exit(0); }' > /dev/null 2>&1 || exit 0 + +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 +bsdlabel -w md$mdstart auto +newfs md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=5m +export RUNDIR=$mntpoint/stressX + +log=/tmp/dtrace.$$ +trap "rm -f $log" EXIT INT +dtrace -w -n 'syscall::*read:entry,syscall::*write:entry {\ + @rw[execname,probefunc] = count(); }' > $log 2>&1 & +pid=$! +sleep 1 +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1 +kill -INT $pid > /dev/null 2>&1 +while pgrep -q dtrace; do + pkill dtrace + sleep 2 +done +wait +tail -5 $log + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +kldstat | grep -q dtraceall && + kldunload dtraceall.ko +exit 0 diff --git a/tools/test/stress2/misc/dtrace_fault.sh b/tools/test/stress2/misc/dtrace_fault.sh new file mode 100755 index 000000000000..508cfc48cd59 --- /dev/null +++ b/tools/test/stress2/misc/dtrace_fault.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 Konstantin Belousov +# +# 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: + +# panic: invalid signal +# KDB: stack backtrace: +# db_trace_self_wrapper(c161045c,c18b9e7c,0,c15df420,f3de7ad8,...) at db_trace_self_wrapper+0x2a/frame 0xf3de7aa8 +# kdb_backtrace(c160aaf6,5984403e,0,f3de7b74,d,...) at kdb_backtrace+0x2d/frame 0xf3de7b10 +# vpanic(c160b255,f3de7b74,c160b255,f3de7b74,f3de7b74,...) at vpanic+0x133/frame 0xf3de7b44 +# kassert_panic(c160b255,c1612dc1,7d,cc97240c,0,...) at kassert_panic+0xd9/frame 0xf3de7b68 +# trapsignal(cc29ea80,f3de7c30,c0cb259e,2,0,...) at trapsignal+0x246/frame 0xf3de7ba0 +# trap(f3de7ce8) at trap+0x7fe/frame 0xf3de7cdc +# calltrap() at calltrap+0x6/frame 0xf3de7cdc +# --- trap 0x20, eip = 0x8048565, esp = 0xbfbfe7d4, ebp = 0xbfbfe7d4 --- + +# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=221151 +# Fixed by r321919 + +. ../default.cfg + +uname -a | egrep -q "i386|amd64" || exit 0 + +cat > /tmp/dtrace_fault.c < /dev/null || exit 1 + +mount /dev/md$mdstart $mntpoint || exit 1 + +here=`pwd` +cd $mntpoint +for i in `jot 10`; do + echo $i +done > file1 +cp file1 file2 +cp file2 file3 +mv file1 filea +rm file2 + +cd $here +umount $mntpoint +dumpfs /dev/md$mdstart | expand > $dump +r=`sed 's/time *[A-Z].*//;s/id .*//' < $dump | md5` +if [ $md != $r ]; then + echo "$r != $md" + s=1 + [ -f $good ] && diff $good $dump +else + [ ! -f $good ] && mv $dump $good # save good dump +fi +mdconfig -d -u $mdstart +[ $s -eq 0 ] && rm -f $disk $dump +rm -f $disk $dump # for now +exit $s diff --git a/tools/test/stress2/misc/dup.sh b/tools/test/stress2/misc/dup.sh new file mode 100755 index 000000000000..7223709d09c4 --- /dev/null +++ b/tools/test/stress2/misc/dup.sh @@ -0,0 +1,122 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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 scenario for "D20947: Check and avoid overflow when incrementing +# fp->f_count in fget_unlocked() and fhold()". + +# OOM killing seen. Cap files and procs for now. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +rm -f /tmp/dup /tmp/dup.c || exit 1 +sed '1,/^EOF/d' < $odir/$0 > $dir/dup.c +mycc -o dup -Wall -Wextra dup.c || exit 1 +rm -f dup.c +cd $odir + +/tmp/dup; s=$? + +rm -f /tmp/dup +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; +#define N 10240 +#define CAP_FILES 50000 +#define CAP_PROCS 1000 +#define SYNC 0 + +int +main(void) +{ + struct stat st; + pid_t pid[N]; + size_t len; + int fd, fd2, i, j, last; + + len = PAGE_SIZE; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + if ((fd = open("/dev/zero", O_RDONLY)) == -1) + err(1, "open(/dev/zero)"); + i = 0; + for (;;) { + if ((fd2 = dup(fd)) == -1) { + if (errno == EMFILE) + break; + err(1, "dup()"); + } + last = fd2; + if (++i == CAP_FILES) + break; + } +#if defined(DEBUG) + fprintf(stderr, "i = %d\n", i); +#endif + + for (i = 0; i < N; i++) { + if ((pid[i] = fork()) == 0) { + if (fstat(last, &st) == -1) + err(1, "stat(%s)", "/dev/zero"); + while(share[SYNC] == 0) + usleep(100000); + _exit(0); + } + if (pid[i] == -1) { + warn("fork()"); + i--; + break; + } + if (i + 1 == CAP_PROCS) + break; + } + share[SYNC] = 1; + for (j = 0; j < i; j++) { + if (waitpid(pid[j], NULL, 0) != pid[j]) + err(1, "waitpid(%d), index %d", pid[j], j); + } + + return (0); +} diff --git a/tools/test/stress2/misc/dup2.sh b/tools/test/stress2/misc/dup2.sh new file mode 100755 index 000000000000..2e575d6625f9 --- /dev/null +++ b/tools/test/stress2/misc/dup2.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 r234131. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/dup2.c +mycc -o dup2 -Wall -Wextra dup2.c || exit 1 +rm -f dup2.c +cd $odir + +/tmp/dup2 || { echo FAIL; exit 1; } + +rm -f /tmp/dup2 +exit 0 + +EOF +#include +#include +#include +#include + +int +main(void) +{ + int error, fd2, i; + + error = 0; + for (i = 0; i < 10000; i++) { + fd2 = arc4random() % 1000000; + if (dup2(1, fd2) == -1) { + if (errno != EBADF) { + warn("dup2(1, %d)", fd2); + error = 1; + break; + } + } else + close(fd2); + } + + return (error); +} diff --git a/tools/test/stress2/misc/execi386.sh b/tools/test/stress2/misc/execi386.sh new file mode 100755 index 000000000000..c59a96765746 --- /dev/null +++ b/tools/test/stress2/misc/execi386.sh @@ -0,0 +1,86 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Calling exec*(2) in a thread of a i386 binary on amd64 caused a reboot. +# Test scenario by: Steven Chamberlain +# Fixed by r266464 + +[ `uname -p` = "amd64" ] || exit 0 + +. ../default.cfg + +wd=/tmp/execi386.dir +mkdir -p $wd +here=`pwd` +cd $wd + +cat > execi386.c < +#include + +void * +thread_main() { + char *cmdline[] = { "./i386", NULL }; + + execve(cmdline[0], cmdline, NULL); + + return (NULL); +} + +int +main() { + pthread_t thread; + + pthread_create(&thread, NULL, thread_main, NULL); + pthread_join(thread, NULL); + + return (0); +} +EOF + +mycc -o execi386 -Wall -Wextra -O2 -g execi386.c -lpthread || exit 1 + +cat > i386.c < + +int +main(void) +{ + fprintf(stdout, "Hello, world\n"); + return (0); +} +EOF + +mycc -m32 -o i386 -Wall -Wextra -O2 -g i386.c || exit 1 + +./execi386 > /dev/null || echo FAIL + +cd $here +rm -rf $wd +exit 0 diff --git a/tools/test/stress2/misc/execve.sh b/tools/test/stress2/misc/execve.sh new file mode 100755 index 000000000000..7a36ec4ca3e7 --- /dev/null +++ b/tools/test/stress2/misc/execve.sh @@ -0,0 +1,130 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 of execve(2) from a threaded program. +# "load: 5.40 cmd: bash 24517 [vmmaps] 2.45r 0.00u 0.00s 0% 3448k" seen. +# Fixed by r282708. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > execve.c +mycc -o execve -Wall -Wextra -O2 execve.c -lpthread || exit 1 +rm -f execve.c + +daemon sh -c "(cd $here/../testcases/swap; ./swap -t 20m -i 20 -l 100)" > \ + /dev/null 2>&1 +sleep `jot -r 1 1 9` +for i in `jot 2`; do + /tmp/execve +done +while pgrep -q swap; do + pkill -9 swap +done + +rm -f /tmp/execve /tmp/execve.core +exit 0 +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 50 +#define PARALLEL 50 + +volatile int go; + +void * +texecve(void *arg __unused) +{ + char *cmdline[] = { "/usr/bin/true", NULL }; + + while (go == 0) + usleep(100); + if (execve(cmdline[0], cmdline, NULL) == -1) + err(1, "execve"); + + return (NULL); +} + +void +test(void) +{ + pthread_t tid[5]; + int i, rc; + + go = 0; + + for (i = 0; i < 5; i++) { + if ((rc = pthread_create(&tid[i], NULL, texecve, NULL)) != 0) + errc(1, rc, "texecve()"); + } + + usleep(arc4random() % 2000); + go = 1; + + for (i = 0; i < 5; i++) + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + _exit(0); +} + +int +main(void) +{ + struct rlimit rl; + int i, j; + + rl.rlim_max = rl.rlim_cur = 0; + if (setrlimit(RLIMIT_CORE, &rl) == -1) + warn("setrlimit"); + + for (i = 0; i < LOOPS; i++) { + for (j = 0; j < PARALLEL; j++) { + if (fork() == 0) + test(); + } + + for (j = 0; j < PARALLEL; j++) + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/exlock.sh b/tools/test/stress2/misc/exlock.sh new file mode 100755 index 000000000000..6e88f9437177 --- /dev/null +++ b/tools/test/stress2/misc/exlock.sh @@ -0,0 +1,122 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 + +# Simple O_EXLOCK test scenario. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > exlock.c +mycc -o exlock -Wall -Wextra exlock.c || exit 1 +rm -f exlock.c +cd $here + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +su $testuser -c "cd $mntpoint; /tmp/exlock" + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/exlock +exit +EOF +#include +#include + +#include +#include +#include +#include + +char buf[128]; + +#define PARALLEL 3 + +static void +tst(char *file, int n) +{ + int fd, i; + + for (i = 0; i < (int)sizeof(buf); i++) + buf[i] = '0' + n; + + for (i = 0; i < 1024 * 1024; i++) { + if ((fd = open(file, O_RDWR | O_CREAT | O_APPEND | O_EXLOCK, + 0644)) == -1) + err(1, "open(%s)", file); + if (write(fd, buf, sizeof(buf)) != sizeof(buf)) + err(1, "write"); + close(fd); + } + + _exit(0); +} +static void +test(void) +{ + int i; + char file[80]; + + snprintf(file, sizeof(file), "f06%d", getpid()); + + for (i = 0; i < 3; i++) + if (fork() == 0) + tst(file, i); + for (i = 0; i < 3; i++) + wait(NULL); + + unlink(file); + + _exit(0); +} + +int +main(void) +{ + int i; + + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + test(); + for (i = 0; i < PARALLEL; i++) + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/exlock2.sh b/tools/test/stress2/misc/exlock2.sh new file mode 100755 index 000000000000..94e3f88f48e3 --- /dev/null +++ b/tools/test/stress2/misc/exlock2.sh @@ -0,0 +1,210 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# O_CREAT|O_EXCL|O_EXLOCK atomic implementation test. +# Lots of input from kib@ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/exlock2.c +mycc -o exlock2 -Wall -Wextra -O0 -g exlock2.c || exit 1 +rm -f exlock2.c +cd $odir + +$dir/exlock2 +s=$? +[ -f exlock2.core -a $s -eq 0 ] && + { ls -l exlock2.core; mv exlock2.core $dir; s=1; } +cd $odir + +rm -f $dir/exlock2 /tmp/exlock2.*.file +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static _Atomic(int) *share; +static int quit; +static char file[80]; + +#define RUNTIME (2 * 60) +#define SYNC 0 + +static void +handler(int s __unused) +{ + quit = 1; +} + +static void +test1(void) +{ + time_t start; + int fd, n; + + signal(SIGHUP, handler); + n = 0; + start = time(NULL); + while (time(NULL) - start < RUNTIME && quit == 0) { + n++; + if ((fd = open(file, O_RDWR|O_CREAT|O_EXCL|O_EXLOCK, + DEFFILEMODE)) == -1) + err(1, "open(%s) creat", file); + unlink(file); + if (write(fd, "test", 5) != 5) + err(1, "write()"); + while (share[SYNC] == 1) + ; /* wait for test2 to signal "done" */ + close(fd); + } +#if defined(DEBUG) + fprintf(stderr, "%s: n = %d\n", __func__, n); +#endif + + _exit(0); +} + +static void +test2(void) +{ + struct flock fl; + struct stat st; + time_t start; + int e, fd, n; + + 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; + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + if (fcntl(fd, F_SETLK, &fl) < 0) { + if (errno != EAGAIN) + err(1, "fcntl(F_SETFL)"); + goto out; + } + /* test1 must have dropped the lock */ + fprintf(stderr, "%s got the lock.\n", __func__); + if (fstat(fd, &st) == -1) + err(1, "stat(%s)", file); + /* As test1 has opened the file exclusivly, this + should not happen */ + if (st.st_size == 0) + fprintf(stderr, "%s has size 0\n", file); + e = 1; + break; +out: + if (fd != -1) + close(fd); + share[SYNC] = 0; + usleep(100); + } +#if defined(DEBUG) + if (e != 0) { + system("ps -Uroot | grep -v grep | grep /tmp/exlock2 | "\ + "awk '{print $1}' | xargs procstat -f"); + } +#endif + share[SYNC] = 0; + + _exit(e); +} + +int +main(void) +{ + pid_t pid1, pid2; + size_t len; + int e, 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"); + + snprintf(file, sizeof(file), "/tmp/exlock2.%d.file", getpid()); + if ((pid1 = fork()) == 0) + test1(); + if (pid1 == -1) + err(1, "fork()"); + + if ((pid2 = fork()) == 0) + test2(); + if (pid2 == -1) + err(1, "fork()"); + + if (waitpid(pid2, &status, 0) != pid2) + err(1, "waitpid(%d)", pid2); + if (status != 0) { + if (WIFSIGNALED(status)) + fprintf(stderr, + "pid %d exit signal %d\n", + pid2, WTERMSIG(status)); + } + e += status == 0 ? 0 : 1; + kill(pid1, SIGHUP); + if (waitpid(pid1, &status, 0) != pid1) + err(1, "waitpid(%d)", pid1); + if (status != 0) { + if (WIFSIGNALED(status)) + fprintf(stderr, + "pid %d exit signal %d\n", + pid1, WTERMSIG(status)); + } + e += status == 0 ? 0 : 1; + + return (e); +} diff --git a/tools/test/stress2/misc/ext2fs.sh b/tools/test/stress2/misc/ext2fs.sh new file mode 100755 index 000000000000..f4d33116faed --- /dev/null +++ b/tools/test/stress2/misc/ext2fs.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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. +# + +# Deadlock seen: http://people.freebsd.org/~pho/stress/log/ext2fs.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +# Uses mke2fs from sysutils/e2fsprogs +[ -z "`type mke2fs 2>/dev/null`" ] && + echo "Skipping test as mke2fs not installed" && exit 0 + +mount | grep "$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 +mke2fs -m 0 /dev/md$mdstart > /dev/null + +mount -t ext2fs /dev/md$mdstart $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done + +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/ext2fs2.sh b/tools/test/stress2/misc/ext2fs2.sh new file mode 100755 index 000000000000..a576c582cc7e --- /dev/null +++ b/tools/test/stress2/misc/ext2fs2.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 + +# "panic: ext2_dirbad: /mnt: bad dir ino ...: mangled entry" seen. +# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=191895 + +. ../default.cfg + +# Uses mke2fs from sysutils/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 + +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +mke2fs /dev/md${mdstart}a +# No panic seen when disabling hashed b-tree lookup for large directories +# tune2fs -O ^dir_index /dev/md${mdstart}$part +mount -t ext2fs /dev/md${mdstart}$part $mntpoint + +export RUNDIR=$mntpoint/stressX +export runRUNTIME=10m # Run tests for 10 minutes +(cd ..; ./run.sh disk.cfg) + +while mount | grep "$mntpoint " | grep -q md$mdstart; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/ext2fs3.sh b/tools/test/stress2/misc/ext2fs3.sh new file mode 100755 index 000000000000..f33b4cc73547 --- /dev/null +++ b/tools/test/stress2/misc/ext2fs3.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# ext2fs(5) test scenario with a 1k block size +# "panic: ext2_reallocblks: alloc mismatch" seen. +# "Fatal trap 12: page fault while in kernel mode" seen. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -r /usr/src/tools/regression/fsx/fsx.c ] || exit 0 + +. ../default.cfg + +# Uses mke2fs from sysutils/e2fsprogs +[ -z "`type mke2fs 2>/dev/null`" ] && + echo "Skipping test as mke2fs not installed" && exit 0 + +dir=/tmp +odir=`pwd` +cd $dir +cc -o fsx -Wall -Wextra -O2 -g /usr/src/tools/regression/fsx/fsx.c || exit 1 +rm -f fsx.c +cd $odir + +mount | grep "$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 +mke2fs -m 0 -b 1024 /dev/md$mdstart > /dev/null + +mount -t ext2fs /dev/md$mdstart $mntpoint +chmod 777 $mntpoint + +cp /tmp/fsx $mntpoint +cd $mntpoint +./fsx -S 2016 -N 2000 ./TEST_FILE +cd $here + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done + +mdconfig -d -u $mdstart +exit 0 diff --git a/tools/test/stress2/misc/ext3fs.sh b/tools/test/stress2/misc/ext3fs.sh new file mode 100755 index 000000000000..826317857f85 --- /dev/null +++ b/tools/test/stress2/misc/ext3fs.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# Simple ext3 test. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +# Uses mke2fs from sysutils/e2fsprogs +[ -z "`type mke2fs 2>/dev/null`" ] && + echo "Skipping test as mke2fs not installed" && exit 0 + +mount | grep "$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 +mke2fs -t ext3 -m 0 -b 2048 /dev/md$mdstart > /dev/null + +mount -t ext2fs /dev/md$mdstart $mntpoint || exit 1 +chmod 777 $mntpoint + +export runRUNTIME=5m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' & +sleep 300 +../tools/killall.sh +wait + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done + +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/ext4fs.sh b/tools/test/stress2/misc/ext4fs.sh new file mode 100755 index 000000000000..610351352501 --- /dev/null +++ b/tools/test/stress2/misc/ext4fs.sh @@ -0,0 +1,64 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# Simple ext4 test. + +# "panic: buf_vlist_add: Preallocated nodes insufficient" seen: +# https://people.freebsd.org/~pho/stress/log/mjguzik036.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +# Uses mke2fs from sysutils/e2fsprogs +[ -z "`type mke2fs 2>/dev/null`" ] && + echo "Skipping test as mke2fs not installed" && exit 0 + +mount | grep "$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 +mke2fs -t ext4 -m 0 -b 2048 /dev/md$mdstart > /dev/null + +mount -t ext2fs /dev/md$mdstart $mntpoint || exit 1 +chmod 777 $mntpoint + +export runRUNTIME=5m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' & +sleep 300 +../tools/killall.sh +wait + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done + +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/extattr.sh b/tools/test/stress2/misc/extattr.sh new file mode 100755 index 000000000000..31027eec696b --- /dev/null +++ b/tools/test/stress2/misc/extattr.sh @@ -0,0 +1,95 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 of extattr on a UFS2 FS using ACLs +# Caused a "Duplicate free" panic. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg +[ -z "`which setfacl`" ] && exit 0 + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > extattr.c +mycc -o extattr -Wall extattr.c +rm -f extattr.c +cd $odir + +mount | grep "$mntpoint" | grep -q md${mdstart}$part && umount $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 20m -u $mdstart +bsdlabel -w md$mdstart auto + +newfs -O 2 md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +mkdir -p $mntpoint/.attribute/system +cd $mntpoint/.attribute/system + +extattrctl initattr -p . 388 posix1e.acl_access +extattrctl initattr -p . 388 posix1e.acl_default +cd / +umount $mntpoint +tunefs -a enable /dev/md${mdstart}$part +mount /dev/md${mdstart}$part $mntpoint +mount | grep md${mdstart}$part + +touch $mntpoint/acl-test +setfacl -b $mntpoint/acl-test +setfacl -m user:nobody:rw-,group:wheel:rw- $mntpoint/acl-test + +for i in `jot 5`; do + /tmp/extattr $mntpoint/acl-test & +done +for i in `jot 5`; do + wait +done + +umount $mntpoint +mdconfig -d -u $mdstart +rm -f /tmp/extattr +exit +EOF +#include +#include +#include + +int +main(int argc, char **argv) +{ + int i; + struct stat sb; + + for (i = 0; i < 100000; i++) + if (lstat(argv[1], &sb) == -1) + err(1, "lstat(%s)", argv[1]); + return (0); +} diff --git a/tools/test/stress2/misc/extattr2.sh b/tools/test/stress2/misc/extattr2.sh new file mode 100755 index 000000000000..313d4ea26447 --- /dev/null +++ b/tools/test/stress2/misc/extattr2.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# [Bug 230962] Kernel panic when writing extended attributes with soft updates +# enabled. +# "panic: softdep_deallocate_dependencies: dangling deps" seen: +# https://people.freebsd.org/~pho/stress/log/kostik1121.txt +# Fixed in r343536. +# "panic: ffs_truncate3" seen: +# https://people.freebsd.org/~pho/stress/log/extattr2.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg +[ -z "`which setfacl`" ] && exit 0 + +here=`pwd` +mount | grep "$mntpoint" | grep -q md${mdstart}$part && umount $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 2g -u $mdstart +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +mkdir -p $mntpoint/.attribute/system +cd $mntpoint/.attribute/system + +extattrctl initattr -p . 388 posix1e.acl_access +extattrctl initattr -p . 388 posix1e.acl_default +cd / +umount $mntpoint +tunefs -a enable /dev/md${mdstart}$part +mount /dev/md${mdstart}$part $mntpoint +mount | grep md${mdstart}$part + +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX +if [ `jot -r 1 0 1` -eq 1 ]; then + set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` + export KBLOCKS=$(($1 / 2)) + export INODES=$(($2 / 2)) +fi + +mkdir -p $RUNDIR +chmod 0777 $RUNDIR +setfacl -b $RUNDIR +setfacl -m user:$testuser:rwx,group:$testuser:rwx $RUNDIR +su $testuser -c "cd $here/..; ./run.sh marcus.cfg" & + +sleep 5 +while pgrep -U$testuser -q -f run.sh; do + find $RUNDIR | \ + xargs -P0 -J% setfacl -m user:$testuser:rwx,group:$testuser:rwx % +done > /dev/null 2>&1 +wait + +s=0 +for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 + [ $i -eq 6 ] && + { echo FAIL; fstat -mf $mntpoint; exit 1; } +done +checkfs /dev/md${mdstart}$part || s=1 +mdconfig -d -u $mdstart || s=2 +exit $s diff --git a/tools/test/stress2/misc/extattr3.sh b/tools/test/stress2/misc/extattr3.sh new file mode 100755 index 000000000000..84b5e1821473 --- /dev/null +++ b/tools/test/stress2/misc/extattr3.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# Bug 230962 Kernel panic when writing extended attributes with soft updates +# "panic: softdep_disk_write_complete: softdep_bp_to_mp returned NULL with +# outstanding dependencies" seen. + +# Original test scenario by Koro + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg +[ -z "`which setfacl`" ] && exit 0 + +here=`pwd` +mount | grep "$mntpoint" | grep -q md$mdstart && umount $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 512m -u $mdstart +newfs $newfs_flags md$mdstart > /dev/null +tunefs -a enable /dev/md$mdstart +mount /dev/md$mdstart $mntpoint +setfacl -d -m u::rwx,g::rx,o::,u:nobody:r $mntpoint + +timeout 2s nc -lU $mntpoint/socket + +s=0 +for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 + [ $i -eq 6 ] && + { echo FAIL; fstat -mf $mntpoint; exit 1; } +done +checkfs /dev/md$mdstart || s=1 +mdconfig -d -u $mdstart || s=2 +exit $s diff --git a/tools/test/stress2/misc/extattr_set_fd.sh b/tools/test/stress2/misc/extattr_set_fd.sh new file mode 100755 index 000000000000..22bfa52f4813 --- /dev/null +++ b/tools/test/stress2/misc/extattr_set_fd.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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: kmem_malloc(2069012480): kmem_map too small" seen. +# Fixed in r237366. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg +[ -z "`which setfacl`" ] && exit 0 + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > extattr_set_fd.c +mycc -o extattr_set_fd -Wall -Wextra -O2 extattr_set_fd.c +rm -f extattr_set_fd.c + +mount | grep -q "$mntpoint" && umount $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +(cd $mntpoint; /tmp/extattr_set_fd) + +while mount | grep -q $mntpoint; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/extattr_set_fd +exit 0 +EOF +#include +#include +#include +#include +#include + +char buf[4096]; + +int +main(void) +{ + int fd; + + if ((fd = open("theFile", O_RDWR | O_CREAT, 0622)) == -1) + err(1, "open(%s)", "theFile"); + + (void) extattr_set_fd(fd, 1, "test", buf, 0x7b5294a6); + + return (0); +} diff --git a/tools/test/stress2/misc/extattrctl.sh b/tools/test/stress2/misc/extattrctl.sh new file mode 100755 index 000000000000..dad79023a2fc --- /dev/null +++ b/tools/test/stress2/misc/extattrctl.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 of extattrctl and ACLs on UFS1 FS +# Kernel must be compiled with options UFS_EXTATTR and UFS_EXTATTR_AUTOSTART + +# Scenario by rwatson@ from: +# +# Newsgroups: lucky.freebsd.current +# Subject: Re: setfacl requirements? +# Date: Thu, 5 Dec 2002 15:50:02 +0000 (UTC) + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ "`sysctl -in kern.features.ufs_extattr`" != "1" ] && + { echo "Kernel not build with UFS_EXTATTR"; exit 0; } +[ -z "`which setfacl`" ] && exit 0 + +mount | grep "$mntpoint" | grep -q md${mdstart}$part && umount $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 20m -u $mdstart +bsdlabel -w md$mdstart auto + +newfs -O 1 md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +mkdir -p $mntpoint/.attribute/system +cd $mntpoint/.attribute/system + +extattrctl initattr -p . 388 posix1e.acl_access +extattrctl initattr -p . 388 posix1e.acl_default +cd / +umount $mntpoint +tunefs -a enable /dev/md${mdstart}$part +mount /dev/md${mdstart}$part $mntpoint +mount | grep md${mdstart}$part + +touch $mntpoint/acl-test +setfacl -b $mntpoint/acl-test +setfacl -m user:nobody:rw-,group:wheel:rw- $mntpoint/acl-test +getfacl $mntpoint/acl-test +ls -l $mntpoint/acl-test + +umount $mntpoint +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/f_offset.sh b/tools/test/stress2/misc/f_offset.sh new file mode 100755 index 000000000000..746f14bea265 --- /dev/null +++ b/tools/test/stress2/misc/f_offset.sh @@ -0,0 +1,160 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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. +# + +# Problem seen with atomic assignment of f_offset. Fixed in r238029. + +# Test scenario by kib@ + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > f_offset.c +mycc -o f_offset -Wall -Wextra -O2 f_offset.c -lpthread +rm -f f_offset.c + +/tmp/f_offset + +rm -f /tmp/f_offset +exit 0 +EOF +/* + Description by kib: +To really exercise the race conditions, all the following items must +be fulfilled simultaneously: +1. you use 32bit host, i.e. i386 +2. you operate on the file offsets larger than 4GB (but see below) +3. there are several threads or processes that operate on the same + file descriptor simultaneously. + +Please note that the normal fork(2) causes file descriptor table +copy, so only rfork(2) call with RFFDG flag unset causes sharing. Or, +multi-threading can be used. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int errors, fd; +char file[128]; + +#define START 0x100000000ULL +#define N 1000000 + +void * +t1(void *arg __unused) +{ + int i; + off_t offset; + + offset = START + 2; + + for (i = 0; i < N; i++) { + if (lseek(fd, offset, SEEK_SET) == -1) + err(1, "lseek error"); + } + + return (0); +} + +void * +t2(void *arg __unused) +{ + int i; + off_t offset; + + offset = 1; + + for (i = 0; i < N; i++) { + if (lseek(fd, offset, SEEK_SET) == -1) + err(1, "lseek error"); + } + return (0); +} +void * +t3(void *arg __unused) +{ + int i; + off_t offset; + + offset = 1; + + for (i = 0; i < N; i++) { + if ((offset = lseek(fd, 0, SEEK_CUR)) == -1) + err(1, "lseek error"); + if (offset != 1 && offset != START + 2) + fprintf(stderr, "FAIL #%d offset = %10jd (0x%09jx)\n", + errors++, offset, offset); + } + + return (0); +} + +int +main(void) +{ + pthread_t threads[3]; + int r; + int i; + off_t offset; + + snprintf(file, sizeof(file), "file.%06d", getpid()); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) + err(1, "%s", file); + + offset = 1; + if (lseek(fd, offset, SEEK_SET) == -1) + err(1, "lseek error"); + + for (i = 0; i < 20 && errors < 10; i++) { + if ((r = pthread_create(&threads[0], NULL, t1, 0)) != 0) + errc(1, r, "pthread_create()"); + if ((r = pthread_create(&threads[1], NULL, t2, 0)) != 0) + errc(1, r, "pthread_create()"); + if ((r = pthread_create(&threads[2], NULL, t3, 0)) != 0) + errc(1, r, "pthread_create()"); + + if ((r = pthread_join(threads[0], NULL)) != 0) + errc(1, r, "pthread_join(%d)", 0); + if ((r = pthread_join(threads[1], NULL)) != 0) + errc(1, r, "pthread_join(%d)", 1); + if ((r = pthread_join(threads[2], NULL)) != 0) + errc(1, r, "pthread_join(%d)", 2); + } + close(fd); + if (unlink(file) == -1) + err(3, "unlink(%s)", file); + + return (0); +} diff --git a/tools/test/stress2/misc/fcntl.sh b/tools/test/stress2/misc/fcntl.sh new file mode 100755 index 000000000000..ccbcc45a325f --- /dev/null +++ b/tools/test/stress2/misc/fcntl.sh @@ -0,0 +1,234 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# fcntl(2) locking scenario. No problems seen. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > fcntl.c +mycc -o fcntl -Wall -Wextra -O0 -g fcntl.c || exit 1 +rm -f fcntl.c + +mkdir -p $RUNDIR +cd $RUNDIR +/tmp/fcntl +status=$? + +rm -f /tmp/fcntl +exit $status +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 16 +#define N 4096 + +static volatile sig_atomic_t completed; +const char name[] = "work"; +int fd; + +static void +ahandler(int s __unused) +{ + unlink(name); + _exit(1); +} + +static void +handler(int s __unused) +{ + completed++; +} + +void +add(int n, int increment) +{ + struct flock fl; + off_t pos; + long val, oval; + int r; + + pos = n * sizeof(val); + memset(&fl, 0, sizeof(fl)); + fl.l_start = pos; + fl.l_len = sizeof(val); + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + + while (fcntl(fd, F_SETLK, &fl) < 0) { + if (errno != EAGAIN) + err(1, "F_SETLK (child)"); + usleep(100); + } + + if (lseek(fd, pos, SEEK_SET) == -1) + err(1, "lseek"); + oval = 999999; + while ((r = read(fd, &val, sizeof(val)) != sizeof(val))) { + if (r == -1 && errno != EAGAIN) + err(1, "read"); + if (lseek(fd, pos, SEEK_SET) == -1) + err(1, "lseek"); + } + 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 (lseek(fd, pos, SEEK_SET) == -1) + err(1, "lseek"); + while ((r = write(fd, &val, sizeof(val)) != sizeof(val))) { + if (r == -1 && errno != EAGAIN) + err(1, "write"); + if (lseek(fd, pos, SEEK_SET) == -1) + err(1, "lseek"); + } + + fl.l_type = F_UNLCK; + if (fcntl(fd, F_SETLK, &fl) < 0) + err(1, "F_UNLCK"); + +} + +void +up(void) +{ + int flags, i; + + /* Need to re-open after a fork() */ + close(fd); + if ((fd = open(name, O_RDWR)) == -1) + err(1, "open(%s)", name); + if ((flags = fcntl(fd, F_GETFL)) == -1) + err(1, "fcntl(%d, T_GETFL)", fd); + flags |= O_NONBLOCK; + if ((flags = fcntl(fd, F_SETFL, flags)) == -1) + err(1, "fcntl(%d, T_SETFL, %d)", fd, flags); + + for (i = 0; i < N; i++) + add(i, 1); + + kill(getppid(), SIGHUP); + while (access("work", R_OK) == 0) + usleep(100); + + _exit(0); +} + +void +down(void) +{ + int flags, i; + + close(fd); + if ((fd = open(name, O_RDWR)) == -1) + err(1, "open(%s)", name); + if ((flags = fcntl(fd, F_GETFL)) == -1) + err(1, "fcntl(%d, T_GETFL)", fd); + flags |= O_NONBLOCK; + if ((flags = fcntl(fd, F_SETFL, flags)) == -1) + err(1, "fcntl(%d, T_SETFL, %d)", fd, flags); + + for (i = 0; i < N; i++) + add(i, -1); + + kill(getppid(), SIGHUP); + while (access("work", R_OK) == 0) + usleep(100); + + _exit(0); +} + +int +main(void) +{ + int flags, i; + long val, sum; + off_t len; + + signal(SIGHUP, handler); + signal(SIGALRM, ahandler); + alarm(300); + if ((fd = open(name, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) + err(1, "open(%s)", name); + len = N * sizeof(val); + if (ftruncate(fd, len) == -1) + err(1, "ftruncate"); + + if ((flags = fcntl(fd, F_GETFL)) == -1) + err(1, "fcntl(%d, T_GETFL)", fd); + flags |= O_NONBLOCK; + if ((flags = fcntl(fd, F_SETFL, flags)) == -1) + err(1, "fcntl(%d, T_SETFL, %d)", fd, flags); + + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + up(); + } + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + down(); + } + + while (completed != PARALLEL * 2) + usleep(200); + + if (lseek(fd, 0, SEEK_SET) == -1) + err(1, "lseek"); + sum = 0; + for (i = 0; i < N; i++) { + if (read(fd, &val, sizeof(val)) != sizeof(val)) + err(1, "Final read"); + if (val != 0) + fprintf(stderr, "index %d: %ld\n", i, val); + sum += val; + } + if (sum != 0) + fprintf(stderr, "FAIL\n"); + unlink(name); + + for (i = 0; i < PARALLEL; i++) { + wait(NULL); + wait(NULL); + } + + close(fd); + + return (sum != 0); +} diff --git a/tools/test/stress2/misc/fcntl2.sh b/tools/test/stress2/misc/fcntl2.sh new file mode 100755 index 000000000000..5f276ae81ccc --- /dev/null +++ b/tools/test/stress2/misc/fcntl2.sh @@ -0,0 +1,188 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# fcntl(2) fuzz +# "umount: unmount of /mnt failed: Device busy" seen: +# https://people.freebsd.org/~pho/stress/log/fcntl2.txt + +. ../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/fcntl2.c +mycc -o fcntl2 -Wall -Wextra -O0 -g fcntl2.c || exit 1 +rm -f fcntl2.c +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 $odir/../testcases/swap; ./swap -t 3m -i 20) & +cd $mntpoint +limits -n 10000 $dir/fcntl2 +s=$? +[ -f fcntl2.core -a $s -eq 0 ] && + { ls -l fcntl2.core; mv fcntl2.core $dir; s=1; } +cd $odir +while pkill swap; do :; 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/fcntl2 +exit $s + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; + +#define PARALLEL 64 +#define RUNTIME (3 * 60) +#define SYNC 0 + +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +static u_int32_t r[N]; + +static unsigned long +makearg(void) +{ + unsigned long val; + unsigned int i; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return (val); +} +static void +test(void) +{ + time_t start; + unsigned long arg3; + int cmd, fd, i, n, success; + char file[80]; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + success = 0; + snprintf(file, sizeof(file), "file.%d", getpid()); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, DEFFILEMODE)) + == -1) + err(1, "open(%s)", file); + n = arc4random() % 100 + 1; + for (i = 0; i < n; i++) + if (write(fd, file, sizeof(file)) != sizeof(file)) + err(1, "write()"); + start = time(NULL); + while (time(NULL) - start < 60) { + cmd = arc4random() % 20; + arg3 = makearg(); + alarm(20); + if (fcntl(fd, cmd, arg3) != -1) + success++; + alarm(0); + } + close(fd); + unlink(file); + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + size_t len; + time_t start; + int i, status; + + 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) { + for (i = 0; i < N; i++) + r[i] = arc4random(); + 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]); + } + } + + return (0); +} diff --git a/tools/test/stress2/misc/fcntl3.sh b/tools/test/stress2/misc/fcntl3.sh new file mode 100755 index 000000000000..8892a9d5670b --- /dev/null +++ b/tools/test/stress2/misc/fcntl3.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 Mark Johnston +# +# 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 scenario submitted by Mark Johnston + +# "Fatal trap 18: integer divide fault while in kernel mode" seen. +# Reported by syzkaller +# Fixed by r353010 + +cat > /tmp/fcntl3.c < +#include +#include + +int +main(void) +{ + + if (fcntl(STDIN_FILENO, F_RDAHEAD) != 0) + err(1, "fcntl"); + return (0); +} +EOF +cc -o /tmp/fcntl3 -Wall -Wextra -O2 /tmp/fcntl3.c || exit 1 + +echo "Expect: fcntl3: fcntl: Inappropriate ioctl for device" +/tmp/fcntl3 + +rm -f /tmp/fcntl3 /tmp/fcntl3.c +exit 0 diff --git a/tools/test/stress2/misc/fdatasync.sh b/tools/test/stress2/misc/fdatasync.sh new file mode 100755 index 000000000000..f17e2826ad94 --- /dev/null +++ b/tools/test/stress2/misc/fdatasync.sh @@ -0,0 +1,197 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# fdatasync(2) fuzz. + +# Deadlock seen: +# https://people.freebsd.org/~pho/stress/log/fdatasync.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +dir=$RUNDIR +nfiles=500 +[ `df -i $dir | tail -1 | awk '{print $7}'` -lt $nfiles ] && exit 0 + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > fdatasync.c +rm -f /tmp/fdatasync +mycc -o fdatasync -Wall -Wextra -O2 -g fdatasync.c -lpthread || exit 1 +rm -f fdatasync.c + +mkdir -p $dir && chmod 777 $dir + +cd $dir +jot $nfiles | xargs touch +jot $nfiles | xargs chmod 666 +cd $odir + +(cd /tmp; /tmp/fdatasync $dir) +e=$? + +rm -rf $dir/* /tmp/fdatasync +exit $e +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +#define RUNTIME 180 +#define THREADS 2 + +static int fd[900]; +static u_int32_t r[N]; +static char *args[2]; + +static unsigned long +makearg(void) +{ + unsigned long val; + + val = arc4random(); +#if defined(__LP64__) + val = (val << 32) | arc4random(); + val = val & 0x00007fffffffffffUL; +#endif + + return(val); +} + +static void * +test(void *arg __unused) +{ + FTS *fts; + FTSENT *p; + int ftsoptions, i, n; + + ftsoptions = FTS_PHYSICAL; + + for (;;) { + for (i = 0; i < N; i++) + r[i] = arc4random(); + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + i = n = 0; + while ((p = fts_read(fts)) != NULL) { + if (fd[i] > 0) + close(fd[i]); + if ((fd[i] = open(p->fts_path, O_RDWR)) == -1) + if ((fd[i] = open(p->fts_path, O_WRONLY)) == + -1) + continue; + if (ftruncate(fd[i], 0) != 0) + err(1, "ftruncate"); + i++; + i = i % nitems(fd); + } + + if (fts_close(fts) == -1) + err(1, "fts_close()"); + sleep(1); + } + return(0); +} + +static void * +calls(void *arg __unused) +{ + off_t offset; + time_t start; + int fd2; + + start = time(NULL); + while ((time(NULL) - start) < RUNTIME) { + fd2 = makearg() % nitems(fd) + 3; + offset = makearg(); + if (lseek(fd2, offset - 1, SEEK_SET) != -1) { + if (write(fd2, "x", 1) != 1) + if (errno != EBADF && errno != ENOSPC && + errno != E2BIG && errno != ESTALE && + errno != EFBIG) + warn("write"); + } else + if (errno != EBADF) + warn("lseek"); + if (fdatasync(fd2) == -1) + if (errno != EBADF) + warn("x"); + + } + + return (0); +} + +int +main(int argc, char **argv) +{ + struct passwd *pw; + pthread_t rp, cp[THREADS]; + int e, i; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + args[0] = argv[1]; + args[1] = 0; + + if ((pw = getpwnam("nobody")) == NULL) + err(1, "failed to resolve nobody"); + 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(); + + if ((e = pthread_create(&rp, NULL, test, NULL)) != 0) + errc(1, e, "pthread_create"); + usleep(1000); + for (i = 0; i < THREADS; i++) + if ((e = pthread_create(&cp[i], NULL, calls, NULL)) != 0) + errc(1, e, "pthread_create"); + for (i = 0; i < THREADS; i++) + pthread_join(cp[i], NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/fdatasync2.sh b/tools/test/stress2/misc/fdatasync2.sh new file mode 100755 index 000000000000..6011eba53698 --- /dev/null +++ b/tools/test/stress2/misc/fdatasync2.sh @@ -0,0 +1,196 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# fdatasync(2) fuzz. Variation of fdatasync.sh. +# https://people.freebsd.org/~pho/stress/log/fdatasync2.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +dir=$RUNDIR +nfiles=10000 +[ `df -i $dir | tail -1 | awk '{print $7}'` -lt $nfiles ] && exit 0 + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > fdatasync2.c +rm -f /tmp/fdatasync2 +mycc -o fdatasync2 -Wall -Wextra -O2 -g fdatasync2.c -lpthread || exit 1 +rm -f fdatasync2.c + +mkdir -p $dir && chmod 777 $dir + +cd $dir +jot $nfiles | xargs touch +jot $nfiles | xargs chmod 666 +cd $odir + +(cd /tmp; /tmp/fdatasync2 $dir) +e=$? + +rm -rf $dir/* /tmp/fdatasync2 +exit $e +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +#define RUNTIME 180 +#define THREADS 6 + +static int fd[900]; +static u_int32_t r[N]; +static char *args[2]; + +static unsigned long +makearg(void) +{ + unsigned long val; + + val = arc4random(); +#if defined(__LP64__) + val = (val << 32) | arc4random(); + val = val & 0x00007fffffffffffUL; +#endif + + return(val); +} + +static void * +test(void *arg __unused) +{ + FTS *fts; + FTSENT *p; + int ftsoptions, i, n; + + ftsoptions = FTS_PHYSICAL; + + for (;;) { + for (i = 0; i < N; i++) + r[i] = arc4random(); + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + i = n = 0; + while ((p = fts_read(fts)) != NULL) { + if (fd[i] > 0) + close(fd[i]); + if ((fd[i] = open(p->fts_path, O_RDWR)) == -1) + if ((fd[i] = open(p->fts_path, O_WRONLY)) == + -1) + continue; + if (ftruncate(fd[i], 0) != 0) + err(1, "ftruncate"); + i++; + i = i % nitems(fd); + } + + if (fts_close(fts) == -1) + err(1, "fts_close()"); + sleep(1); + } + return(0); +} + +static void * +calls(void *arg __unused) +{ + off_t offset; + time_t start; + int fd2; + + start = time(NULL); + while ((time(NULL) - start) < RUNTIME) { + fd2 = makearg() % nitems(fd) + 3; + offset = makearg(); + if (lseek(fd2, offset - 1, SEEK_SET) != -1) { + if (write(fd2, "x", 1) != 1) + if (errno != EBADF && errno != ENOSPC && + errno != E2BIG && errno != ESTALE && + errno != EFBIG) + warn("write"); + } else + if (errno != EBADF) + warn("lseek"); + if (fdatasync(fd2) == -1) + if (errno != EBADF) + warn("x"); + + } + + return (0); +} + +int +main(int argc, char **argv) +{ + struct passwd *pw; + pthread_t rp, cp[THREADS]; + int e, i, threads; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + args[0] = argv[1]; + args[1] = 0; + threads = arc4random() % (THREADS -1 ) + 2; /* 2 - THREADS */ + + if ((pw = getpwnam("nobody")) == NULL) + err(1, "failed to resolve nobody"); + 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(); + + if ((e = pthread_create(&rp, NULL, test, NULL)) != 0) + errc(1, e, "pthread_create"); + usleep(1000); + for (i = 0; i < threads; i++) + if ((e = pthread_create(&cp[i], NULL, calls, NULL)) != 0) + errc(1, e, "pthread_create"); + for (i = 0; i < threads; i++) + pthread_join(cp[i], NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/fdescfs.sh b/tools/test/stress2/misc/fdescfs.sh new file mode 100755 index 000000000000..b0f07e34b285 --- /dev/null +++ b/tools/test/stress2/misc/fdescfs.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Page fault seen in fdesc_allocvp+0x8f: +# http://people.freebsd.org/~pho/stress/log/fdescfs-2.txt +# Fixed by r279401 +# https://people.freebsd.org/~pho/stress/log/fdescfs-3.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mounts=15 # Number of parallel scripts +cont=/tmp/fdescfs.continue + +if [ $# -eq 0 ]; then + kldstat -v | grep -q fdescfs || { kldload fdescfs.ko; unload=1; } + touch $cont + # start the parallel tests + for i in `jot $mounts`; do + [ -d ${mntpoint}$i ] || mkdir -p ${mntpoint}$i + ./$0 $i & + ./$0 find & + done + wait + [ $unload ] && kldunload fdescfs.ko + exit 0 +else + if [ $1 = find ]; then + exec 6< /dev/zero + exec 7< /dev/zero + exec 8< /dev/zero + exec 9< /dev/zero + while [ -r $cont ]; do + ls -l ${mntpoint}* > /dev/null 2>&1 + done + else + + # The test: Parallel mount and unmounts + start=`date '+%s'` + while [ `date '+%s'` -lt $((start + 300)) ]; do + mount -t fdescfs null ${mntpoint}$1 + while mount | grep -wq ${mntpoint}$1; do + umount -f ${mntpoint}$1 > /dev/null 2>&1 + done + done + rm -f $cont + fi +fi diff --git a/tools/test/stress2/misc/fdgrowtable.sh b/tools/test/stress2/misc/fdgrowtable.sh new file mode 100755 index 000000000000..b75094489412 --- /dev/null +++ b/tools/test/stress2/misc/fdgrowtable.sh @@ -0,0 +1,105 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 r236822. +# http://people.freebsd.org/~pho/stress/log/fdgrowtable.txt +# Fixed in r256210. + +. ../default.cfg + +max=`ulimit -n` + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > fdgrowtable.c +mycc -o fdgrowtable -Wall -Wextra -O2 fdgrowtable.c || exit 1 +rm -f fdgrowtable.c +cd $here + +su $testuser -c "/tmp/fdgrowtable $max" & +while kill -0 $! 2>/dev/null; do + ../testcases/swap/swap -t 2m -i 40 -h +done +wait +rm -f /tmp/fdgrowtable +exit + +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 3 + +int max; + +void test(void) +{ + int i; + + for (i = 0; i < max; i++) { + if (dup2(1, i + 3) == -1) + err(1, "dup2(%d)", i + 3); + } + _exit(0); +} + +int +main(int argc, char **argv) +{ + time_t start; + int i; + + if (argc == 2) + max = atoi(argv[1]); + else + err(1, "Usage: %s ", argv[0]); + + max = (max - 3) / PARALLEL; + + start = time(NULL); + while (time(NULL) - start < 600) { + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + test(); + } + + for (i = 0; i < PARALLEL; i++) + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/fexecve.sh b/tools/test/stress2/misc/fexecve.sh new file mode 100755 index 000000000000..01ff0b723134 --- /dev/null +++ b/tools/test/stress2/misc/fexecve.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# Reported by syzkaller. +# "panic: vm_page_free_prep: page 0x61e5968 has unexpected ref_count ." seen +# Fixed by r352748 + +# Test scenario by: Mark Johnston + +cat > /tmp/fexecve.c < +#include +#include + +#include +#include +#include +#include +#include + +int +main(int argc __unused, char **argv) +{ + char template[PATH_MAX]; + void *addr; + size_t sz; + int fd; + + sz = 16 * 4096; + + (void)snprintf(template, sizeof(template), "fexecve.XXXXXX"); + fd = mkstemp(template); + if (fd < 0) + err(1, "mkstemp"); + if (fchmod(fd, 0700) < 0) + err(1, "fchmod"); + if (ftruncate(fd, sz) < 0) + err(1, "ftruncate"); + + addr = mmap(NULL, sz, PROT_MAX(PROT_READ) | PROT_READ, MAP_SHARED, + fd, 0); + if (addr == MAP_FAILED) + err(1, "mmap"); + + if (mlock(addr, sz) != 0) + err(1, "mlock"); + + if (ftruncate(fd, 0) != 0) + err(1, "ftruncate"); + if (ftruncate(fd, sz) != 0) + err(1, "ftruncate"); + + (void)close(fd); + + fd = open(template, O_EXEC); + if (fd < 0) + err(1, "open"); + fexecve(fd, argv, NULL); + err(1, "fexecve"); + + return (0); +} +EOF +cc -o /tmp/fexecve -Wall -Wextra -O2 /tmp/fexecve.c || exit 1 +echo "Expect: fexecve: fexecve: Input/output error" +(cd /tmp; /tmp/fexecve) + +rm -f /tmp/fexecve /tmp/fexecve.c /tmp/fexecve.?????? diff --git a/tools/test/stress2/misc/ffs_blkfree.sh b/tools/test/stress2/misc/ffs_blkfree.sh new file mode 100755 index 000000000000..5ea4828429c3 --- /dev/null +++ b/tools/test/stress2/misc/ffs_blkfree.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 + +D=$diskimage +DUMP=$RUNDIR/dump +trap "rm -f $D" EXIT INT +dd if=/dev/zero of=$D bs=1m count=1024 status=none || exit 1 + +mount | grep "$mntpoint" | grep md${mdstart}$part > /dev/null && + umount $mntpoint +mdconfig -l | grep md$mdstart > /dev/null && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +mount + +for i in `jot 10`; do + mkdir $mntpoint/d$i + for j in `jot 100`; do + touch $mntpoint/d$i/f$j + done +done + +dump -L0a -f $DUMP /dev/md${mdstart}$part + +ls -lf $DUMP + +while mount | grep -q $mntpoint; do + umount $([ $((`date '+%s'` % 2)) -eq 0 ] && + echo "-f" || echo "") $mntpoint > /dev/null 2>&1 +done + +for i in `jot 10`; do + newfs $newfs_flags -n md${mdstart}$part > /dev/null + mount /dev/md${mdstart}$part $mntpoint + (cd $mntpoint; restore -rf $DUMP) + rm -rf $mntpoint/* + while mount | grep -q $mntpoint; do + umount $([ $((`date '+%s'` % 2)) -eq 0 ] && + echo "-f" || echo "") $mntpoint > /dev/null 2>&1 + done +done + +mdconfig -d -u $mdstart +rm -f $D $DUMP diff --git a/tools/test/stress2/misc/ffs_sync.sh b/tools/test/stress2/misc/ffs_sync.sh new file mode 100755 index 000000000000..aa970839c7b3 --- /dev/null +++ b/tools/test/stress2/misc/ffs_sync.sh @@ -0,0 +1,254 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 + +# "ffs_fsync: dirty" seen: +# http://people.freebsd.org/~pho/stress/log/ffs_sync.txt + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > ffs_sync.c +mycc -o ffs_sync -Wall -Wextra ffs_sync.c || exit 1 +rm -f ffs_sync.c +cd $here + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +for i in `jot 3`; do + su $testuser -c "cd $mntpoint; /tmp/ffs_sync" & + sleep 60 + killall -q ffs_sync + killall -q ffs_sync +done + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +rm -f /tmp/ffs_sync +mdconfig -d -u $mdstart +exit +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 12 +#define NRW 1000 +#define NFTS 10000 +#define NMKDIR 6000 +#define NSYMLINK 20000 + +void +slinktest(void) +{ + int i, j; + pid_t pid; + char file[128]; + + setproctitle("slink"); + pid = getpid(); + for (j = 0; j < NSYMLINK; j++) { + sprintf(file,"p%05d.%05d", pid, j); + if (symlink("/tmp/not/there", file) == -1) { + if (errno != EINTR) + warn("symlink(%s). %s.%d", file, __FILE__, __LINE__); + } + } + + for (i = --j; i >= 0; i--) { + sprintf(file,"p%05d.%05d", pid, i); + if (unlink(file) == -1) + err(3, "unlink(%s)", file); + } + + _exit(0); +} + +void +mktest(void) +{ + int i; + char path[80]; + + setproctitle("mkdir"); + sprintf(path, "d%06d", getpid()); + if (mkdir(path, 0770) == -1) + err(1, "mkdir(%s)", path); + chdir(path); + + sprintf(path, "d"); + for (i = 0; i < NMKDIR; i++) { + if (mkdir(path, 0770) == -1) { + warn("mkdir(%s), %s:%d", path, __FILE__, __LINE__); + } else + chdir(path); + + } + for (i = 0; i < NMKDIR; i++) { + chdir(".."); + rmdir(path); + } + chdir(".."); + + _exit(0); +} + +void +rwtest(void) +{ + int fd, i, j; + char buf[80], file[80]; + + setproctitle("rw"); + for (i = 0; i < NRW; i++) { + sprintf(file, "f%06d.%06d", getpid(), i); + if ((fd = open(file, O_CREAT | O_EXCL, 0644)) == -1) + err(1, "open(%s)", file); + for (j = 0; j < 1024; j++) + write(fd, buf, sizeof(buf)); + lseek(fd, 0, SEEK_SET); + for (j = 0; j < 1024; j++) + read(fd, buf, sizeof(buf)); + close(fd); + } + for (i = 0; i < NRW; i++) { + sprintf(file, "f%06d.%06d", getpid(), i); + if (unlink(file) == -1) + warn("unlink(%s)", file); + } + _exit(0); +} + +void +slink(void) +{ + int i; + + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + slinktest(); +} + +void +mk(void) +{ + int i; + + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + mktest(); +} + +void +rw(void) +{ + int i; + + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + rwtest(); +} + +void +ftstest(void) +{ + FTS *fts; + FTSENT *p; + int ftsoptions, i; + char *args[2]; + + setproctitle("fts"); + ftsoptions = FTS_PHYSICAL; + args[0] = "."; + args[1] = 0; + + for (i = 0; i < NFTS; i++) { + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) + ; + + if (errno != 0 && errno != ENOENT) + err(1, "fts_read"); + if (fts_close(fts) == -1) + err(1, "fts_close()"); + } + + _exit(0); +} + +void +fts(void) +{ + int i; + + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + ftstest(); +} + +int +main(void) +{ + int i; + + slink(); + mk(); + rw(); + fts(); + + for (i = 0; i < PARALLEL; i++) { + wait(NULL); + wait(NULL); + wait(NULL); + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/ffs_syncvnode.sh b/tools/test/stress2/misc/ffs_syncvnode.sh new file mode 100755 index 000000000000..faa9856a8bca --- /dev/null +++ b/tools/test/stress2/misc/ffs_syncvnode.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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: flush_newblk_deps: Bad newblk 0xc8d2ac00" seen. + +# "panic: softdep_deallocate_dependencies: dangling deps" seen with +# /mnt: out of inodes. 20130627. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=20m +export RUNDIR=$mntpoint/stressX + +find -x / -type f > /dev/null 2>&1 & +su $testuser -c 'cd ..; ./run.sh disk.cfg' +wait + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/ffs_syncvnode2.sh b/tools/test/stress2/misc/ffs_syncvnode2.sh new file mode 100755 index 000000000000..5fd9e4cfe843 --- /dev/null +++ b/tools/test/stress2/misc/ffs_syncvnode2.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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. +# + +# Lock seen with: +# 1001 61985 61981 0 52 0 9624 1028 ufs D+ 0 0:22,89 mkdir +# 1001 61986 61981 0 52 0 9624 1028 ufs D+ 0 0:21,63 mkdir +# 1001 61987 61981 0 52 0 9624 1028 ufs D+ 0 0:23,39 mkdir + +# Fixed in rxxxxxx. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=20m +export RUNDIR=$mntpoint/stressX + +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$(($1 * 4)) +export INODES=$(($2 * 4)) + +su $testuser -c 'cd ..; ./run.sh disk.cfg' 2>/dev/null + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/fifo.sh b/tools/test/stress2/misc/fifo.sh new file mode 100755 index 000000000000..17881bd9eb00 --- /dev/null +++ b/tools/test/stress2/misc/fifo.sh @@ -0,0 +1,87 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Page fault seen. +# http://people.freebsd.org/~pho/stress/log/kostik652.txt +# Fixed by r259522. + +# https://people.freebsd.org/~pho/stress/log/kostik863.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > fifo.c +rm -f /tmp/fifo +mycc -o fifo -Wall -Wextra -O2 -g fifo.c || exit 1 +rm -f fifo.c + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +(cd $mntpoint; /tmp/fifo) + +for i in `jot 10`; do + mount | grep -q md${mdstart}$part && \ + umount $mntpoint && mdconfig -d -u $mdstart && break + sleep 10 +done +rm -f /tmp/fifo +exit +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(void) +{ + int fd; + + if (mkfifo("fifo", 0644) == -1) + err(1, "mkfifo"); + + fd = open("fifo", O_RDWR | O_SHLOCK | O_EXLOCK); + fd = open("fifo", 0x60e9f2, 0xc74c65b1db4be370, 0xb64a34df72368759); + + return (0); +} diff --git a/tools/test/stress2/misc/fifo2.sh b/tools/test/stress2/misc/fifo2.sh new file mode 100755 index 000000000000..7f269f2368d4 --- /dev/null +++ b/tools/test/stress2/misc/fifo2.sh @@ -0,0 +1,206 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Page fault seen +# http://people.freebsd.org/~pho/stress/log/kostik654.txt +# Fixed by r259521. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > fifo2.c +rm -f /tmp/fifo2 +mycc -o fifo2 -Wall -Wextra -O2 -g fifo2.c -lpthread || exit 1 +rm -f fifo2.c + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint +mkfifo $mntpoint/f +chmod 777 $mntpoint/f + +sleeptime=12 +st=`date '+%s'` +while [ $((`date '+%s'` - st)) -lt $((10 * sleeptime)) ]; do + (cd $mntpoint; /tmp/fifo2) & + start=`date '+%s'` + while [ $((`date '+%s'` - start)) -lt $sleeptime ]; do + pgrep -q fifo2 || break + sleep .5 + done + while pkill -9 fifo2; do :; done + wait +done + +for i in `jot 10`; do + mount | grep -q md${mdstart}$part && \ + umount $mntpoint > /dev/null 2>&1 && + mdconfig -d -u $mdstart && break + sleep 10 +done +s=0 +mount | grep -q md${mdstart}$part && + { echo "umount $mntpoint failed"; s=1; } +rm -f /tmp/fifo2 +exit $s +EOF +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +u_int32_t r[N]; + +static void +hand(int i __unused) { /* handler */ + _exit(1); +} + +static unsigned long +makearg(void) +{ + unsigned int i; + unsigned long val; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return(val); +} + +static void * +calls(void *arg __unused) +{ + unsigned long arg1, arg2, arg3, arg4, arg5, arg6, arg7; + int i, num; + + for (i = 0;; i++) { + arg1 = (unsigned long)(void *)"f"; + arg2 = makearg(); + arg3 = makearg(); + arg4 = makearg(); + arg5 = makearg(); + 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); + usleep(100000); +#endif + alarm(1); + syscall(SYS_open, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + num = 0; + } + + return (0); +} + +int +main(void) +{ + struct passwd *pw; + struct rlimit limit; + pthread_t cp[50]; + time_t start; + int e, j; + + if ((pw = getpwnam("nobody")) == NULL) + err(1, "no such user: nobody"); + + 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 (setrlimit(RLIMIT_NPTS, &limit) < 0) + err(1, "setrlimit"); + + signal(SIGALRM, hand); + signal(SIGILL, hand); + signal(SIGFPE, hand); + signal(SIGSEGV, hand); + signal(SIGBUS, hand); + signal(SIGURG, hand); + signal(SIGSYS, hand); + signal(SIGTRAP, hand); + + start = time(NULL); + while ((time(NULL) - start) < 120) { + if (fork() == 0) { + for (j = 0; j < 1; j++) + if ((e = pthread_create(&cp[j], NULL, calls, NULL)) != 0) + errc(1, e,"pthread_create"); + + for (j = 0; j < 1; j++) + pthread_join(cp[j], NULL); + _exit(0); + } + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/fifo3.sh b/tools/test/stress2/misc/fifo3.sh new file mode 100755 index 000000000000..04fca483eabf --- /dev/null +++ b/tools/test/stress2/misc/fifo3.sh @@ -0,0 +1,209 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 fts_read(3) will open a fifo for read. +# Not seen on a pristine FreeBSD. + +# $ while ./fifo.sh; do date; done +# Wed Oct 1 14:07:41 CEST 2014 +# Wed Oct 1 14:09:58 CEST 2014 +# FAIL +# $ ps -l19547 +# UID PID PPID CPU PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND +# 0 19547 19544 0 25 0 12176 3996 fifoor I 0 0:08.19 /tmp/fifo +# $ gdb /tmp/fifo 19547 +# GNU gdb 6.1.1 [FreeBSD] +# Copyright 2004 Free Software Foundation, Inc. +# GDB is free software, covered by the GNU General Public License, and you are +# welcome to change it and/or distribute copies of it under certain conditions. +# Type "show copying" to see the conditions. +# There is absolutely no warranty for GDB. Type "show warranty" for details. +# This GDB was configured as "amd64-marcel-freebsd"... +# Attaching to program: /tmp/fifo, process 19547 +# Reading symbols from /lib/libc.so.7...done. +# Loaded symbols for /lib/libc.so.7 +# Reading symbols from /libexec/ld-elf.so.1...done. +# Loaded symbols for /libexec/ld-elf.so.1 +# 0x00000008008a9ab8 in enc_openat () from /lib/libc.so.7 +# (gdb) bt +# #0 0x00000008008a9ab8 in enc_openat () from /lib/libc.so.7 +# #1 0x00000008008a581b in fts_read () from /lib/libc.so.7 +# #2 0x00000008008a4f24 in fts_read () from /lib/libc.so.7 +# #3 0x0000000000400ee9 in test () at /tmp/fifo.c:86 +# #4 0x0000000000400fd8 in main () at /tmp/fifo.c:108 +# (gdb) f 3 +# #3 0x0000000000400ee9 in test () at /tmp/fifo.c:86 +# 86 while ((p = fts_read(fts)) != NULL) { +# Current language: auto; currently minimal +# (gdb) +# + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +cat > /tmp/fifo3.c < +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 50 +#define PARALLEL 4 + +void +tmkfifo(void) +{ + pid_t pid; + int i, j; + char name[80]; + + setproctitle(__func__); + pid = getpid(); + for (j = 0; j < LOOPS; j++) { + for (i = 0; i < 1000; i++) { + snprintf(name, sizeof(name), "fifo.%d.%06d", pid, i); + if (mkfifo(name, 0644) == -1) + err(1, "mkfifo(%s)", name); + } + for (i = 0; i < 1000; i++) { + snprintf(name, sizeof(name), "fifo.%d.%06d", pid, i); + if (unlink(name) == -1) + err(1, "unlink(%s)", name); + } + } + _exit(0); +} + +void +tmkdir(void) +{ + pid_t pid; + int i, j; + char name[80]; + + setproctitle(__func__); + pid = getpid(); + for (j = 0; j < LOOPS; j++) { + for (i = 0; i < 1000; i++) { + snprintf(name, sizeof(name), "dir.%d.%06d", pid, i); + if (mkdir(name, 0644) == -1) + err(1, "mkdir(%s)", name); + } + for (i = 0; i < 1000; i++) { + snprintf(name, sizeof(name), "dir.%d.%06d", pid, i); + if (rmdir(name) == -1) + err(1, "unlink(%s)", name); + } + } + _exit(0); +} + +void +test(void) +{ + FTS *fts; + FTSENT *p; + int ftsoptions, i; + char *args[2]; + + if (fork() == 0) + tmkfifo(); + if (fork() == 0) + tmkdir(); + + ftsoptions = FTS_PHYSICAL; + args[0] = "."; + args[1] = 0; + + for (i = 0; i < LOOPS; i++) { + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) { +#if defined(TEST) + fprintf(stdout, "%s\n", p->fts_path); +#endif + } + + if (errno != 0 && errno != ENOENT) + err(1, "fts_read"); + if (fts_close(fts) == -1) + err(1, "fts_close()"); + } + wait(NULL); + wait(NULL); + + _exit(0); +} + +int +main(void) +{ + int i; + + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + test(); + for (i = 0; i < PARALLEL; i++) + wait(NULL); + + return (0); +} +EOF +mycc -o /tmp/fifo3 -Wall -Wextra -O0 -g /tmp/fifo3.c || exit 1 + +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +(cd $mntpoint; /tmp/fifo3 ) & + +while pgrep -q fifo3; do + ps -lx | grep -v grep | grep -q fifoor && + { echo FAIL; exit 1; } + sleep 2 +done + +wait + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm /tmp/fifo3 /tmp/fifo3.c diff --git a/tools/test/stress2/misc/fifo4.sh b/tools/test/stress2/misc/fifo4.sh new file mode 100755 index 000000000000..7f46f8537dc6 --- /dev/null +++ b/tools/test/stress2/misc/fifo4.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# tmpfs(5) version of fifo2.sh +# No problems seen on HEAD. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/fifo2.sh > fifo2.c +rm -f /tmp/fifo2 +mycc -o fifo2 -Wall -Wextra -O2 -g fifo2.c -lpthread || exit 1 +rm -f fifo2.c + +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint + +mount -o size=1g -t tmpfs tmpfs $mntpoint +chmod 777 $mntpoint +for i in `jot 5`; do + mkfifo $mntpoint/f$i + chmod 777 $mntpoint/f$i +done + +daemon sh -c "(cd $odir/../testcases/swap; ./swap -t 10m -i 20 -l 100)" > \ + /dev/null +sleeptime=12 +st=`date '+%s'` +while [ $((`date '+%s'` - st)) -lt $((10 * sleeptime)) ]; do + (cd $mntpoint; /tmp/fifo2) & + while ! pgrep -q fifo2; do :; done + start=`date '+%s'` + while [ $((`date '+%s'` - start)) -lt $sleeptime ]; do + pgrep -q fifo2 || break + sleep .5 + done + while pgrep -q fifo2; do pkill -9 fifo2; done + wait +done +pkill -9 swap fifo2 +while pgrep -q "swap|fifo2"; do pkill -9 swap fifo2; done + +for i in `jot 10`; do + mount | grep -q "on $mntpoint " && \ + umount $mntpoint > /dev/null 2>&1 && break + sleep 10 +done +s=0 +mount | grep -q "on $mntpoint " && + { echo "umount $mntpoint failed"; s=1; } +rm -f /tmp/fifo2 +exit $s diff --git a/tools/test/stress2/misc/flock.sh b/tools/test/stress2/misc/flock.sh new file mode 100755 index 000000000000..451fec4b518a --- /dev/null +++ b/tools/test/stress2/misc/flock.sh @@ -0,0 +1,191 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# flock(2) read (shared) lock test. + +# FAIL: Unfair scheduling? +# share[1] = 359171 +# share[2] = 394437 +# share[3] = 359488 +# share[4] = 394429 +# share[5] = 359441 +# share[6] = 394281 +# share[7] = 359314 +# share[8] = 394615 + +. ../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/flock.c +mycc -o flock -Wall -Wextra -O0 -g flock.c || exit 1 +rm -f flock.c +cd $odir + +mount | grep "on $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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +(cd $mntpoint; /tmp/flock) +e=$? + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -rf /tmp/flock +exit $e + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +volatile u_int *share; +int fd; + +#define RENDEZVOUS 0 + +#define CHILDREN 8 +#define LOOPS 8000 +#define PARALLEL 1 +#define RUNTIME (1 * 60) + +void +chld(int id) +{ + while (share[RENDEZVOUS] == 0) + ; + + while (share[RENDEZVOUS] == 1) { + if (flock(fd, LOCK_SH) == -1) + err(1, "fcntl @ %d", __LINE__); + atomic_add_int(&share[id + 1], 1); + if (flock(fd, LOCK_UN) == -1) + err(1, "fcntl @ %d", __LINE__); + usleep(100); + } + + _exit(0); +} + +void +test(void) +{ + int i; + char file[80]; + + snprintf(file, sizeof(file), "file.%05d", getpid()); + if ((fd = open(file, O_RDWR | O_CREAT, 0640)) == -1) + err(1, "open(%s)", file); + if (flock(fd, LOCK_EX) == -1) + err(1, "fcntl @ %d", __LINE__); + + for (i = 0; i < CHILDREN; i++) { + if (fork() == 0) + chld(i); + } + + usleep(200); + atomic_add_int(&share[RENDEZVOUS], 1); /* start chld */ + for (i = 0; i < LOOPS; i++) { + if (flock(fd, LOCK_UN) == -1) + err(1, "fcntl @ %d", __LINE__); + if (flock(fd, LOCK_EX) == -1) + err(1, "fcntl @ %d", __LINE__); + } + atomic_add_int(&share[RENDEZVOUS], 1); /* stop chld */ + + for (i = 0; i < CHILDREN; i++) + wait(NULL); + + close(fd); + unlink(file); + + _exit(0); +} + +int +main(void) +{ + size_t len; + time_t start; + int i, n, pct; + + len = getpagesize(); + 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) { + share[RENDEZVOUS] = 0; + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + test(); + } + for (i = 0; i < PARALLEL; i++) + wait(NULL); + } + n = 0; + for (i = 0; i < CHILDREN; i++) + n += share[i + 1]; + n /= CHILDREN; + for (i = 0; i < CHILDREN; i++) { + pct = abs((int)share[i + 1] - n) * 100 / n; + if (pct > 1) { + fprintf(stderr, "Unfair scheduling?\n"); + for (i = 0; i < CHILDREN; i++) { + pct = abs((int)share[i + 1] - n) * 100 / n; + fprintf(stderr, "share[%d] = %d\n", + i+1, share[i+1]); + } + break; + } + } + + return (0); +} diff --git a/tools/test/stress2/misc/flock_open_close.sh b/tools/test/stress2/misc/flock_open_close.sh new file mode 100755 index 000000000000..173cdcbf2e75 --- /dev/null +++ b/tools/test/stress2/misc/flock_open_close.sh @@ -0,0 +1,174 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 close() of an flock'd file is not atomic. +# Fails with "flock_open_close: execv(/mnt/test): Text file busy" + +# Test scenario by: jhb + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > flock_open_close.c +rm -f /tmp/flock_open_close +mycc -o flock_open_close -Wall -Wextra -O2 -g flock_open_close.c -lpthread || exit 1 +rm -f flock_open_close.c + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +cp /bin/test $mntpoint +chown $testuser $mntpoint/test +chmod +w $mntpoint/test + +su $testuser -c "/tmp/flock_open_close $mntpoint/test" & +pid=$! +while kill -0 $! 2>/dev/null; do + mksnap_ffs $mntpoint $mntpoint/.snap/snap + sleep 2 + rm -f $mntpoint/.snap/snap + sleep 1 +done +wait $pid +s=$? + +for i in `jot 10`; do + mount | grep -q md${mdstart}$part && \ + umount $mntpoint && mdconfig -d -u $mdstart && break + sleep 2 +done +if mount | grep -q md${mdstart}$part; then + fstat $mntpoint + echo "umount $mntpoint failed" + exit 1 +fi +rm -f /tmp/flock_open_close +exit $s +EOF + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void +usage(void) +{ + fprintf(stderr, "Usage: flock_close_race [args]\n"); + exit(1); +} + +static void +child(const char *binary) +{ + int fd; + + /* Exit as soon as our parent exits. */ + while (getppid() != 1) { + fd = open(binary, O_RDWR | O_EXLOCK); + if (fd < 0) { + /* + * This may get ETXTBSY since exit() will + * close its open fd's (thus releasing the + * lock), before it releases the vmspace (and + * mapping of the binary). + */ + if (errno == ETXTBSY) + continue; + err(2, "can't open %s", binary); + } + close(fd); + } + exit(0); +} + +static void +exec_child(char **av) +{ + int fd; + + fd = open(av[0], O_RDONLY | O_SHLOCK); + execv(av[0], av); + /* "flock_open_close: execv(/mnt/test): Text file busy" seen */ + err(127, "execv(%s)", av[0]); +} + +int +main(int ac, char **av) +{ + struct stat sb; + pid_t pid; + int e, i, status; + + if (ac < 2) + usage(); + if (stat(av[1], &sb) != 0) + err(1, "stat(%s)", av[1]); + if (!S_ISREG(sb.st_mode)) + errx(1, "%s not an executable", av[1]); + + pid = fork(); + if (pid < 0) + err(1, "fork"); + if (pid == 0) + child(av[1]); + e = 0; + for (i = 0; i < 200000; i++) { + pid = fork(); + if (pid < 0) + err(1, "vfork"); + if (pid == 0) + exec_child(av + 1); + wait(&status); + if (WIFEXITED(status) && WEXITSTATUS(status) == 127) { + fprintf(stderr, "FAIL\n"); + e = 1; + break; + } + if (WIFEXITED(status) && WEXITSTATUS(status) != 1) { + /* /bin/test returns 1 */ + e = 1; + break; + } + } + return (e); +} diff --git a/tools/test/stress2/misc/force.sh b/tools/test/stress2/misc/force.sh new file mode 100755 index 000000000000..4c5cd6c255f6 --- /dev/null +++ b/tools/test/stress2/misc/force.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# Run with marcus.cfg on a 1g swap backed MD with UFS SU fs. + +# Page fault seen in WiP kernel code: +# https://people.freebsd.org/~pho/stress/log/kirk113.txt + +# Deadlock seen: +# https://people.freebsd.org/~pho/stress/log/chs002.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +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 +flags=$newfs_flags +# Disable SUJ tests for now. Known deadlock issue. +#[ `jot -r 1 0 1` -eq 1 ] && flags="-j" +echo "newfs $flags md$mdstart" +newfs $flags md$mdstart > /dev/null 2>&1 +mount /dev/md$mdstart $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=3m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1 & + +sleep `jot -r 1 10 40` +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 +exit 0 diff --git a/tools/test/stress2/misc/force2.sh b/tools/test/stress2/misc/force2.sh new file mode 100755 index 000000000000..35e448afbbba --- /dev/null +++ b/tools/test/stress2/misc/force2.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# Run with marcus.cfg on a 1g swap backed MD with UFS SU fs. + +# "panic: softdep_load_inodeblock: nlink we read isn't what we wrote" seen in +# WiP kernel code: https://people.freebsd.org/~pho/stress/log/kirk130.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +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 || exit 1 +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 +mount /dev/md$mdstart $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=3m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1 & + +sleep `jot -r 1 10 40` +while mdconfig -l | grep 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 -u $mdstart +fsck_ffs -Rfy /dev/md$mdstart > /dev/null; s=$? +if [ $s -eq 0 ]; then + mount /dev/md$mdstart $mntpoint + ls -lR $mntpoint > /dev/null + umount $mntpoint +fi +mdconfig -d -u $mdstart + +rm -f $diskimage +exit $s diff --git a/tools/test/stress2/misc/force3.sh b/tools/test/stress2/misc/force3.sh new file mode 100755 index 000000000000..4bfb0011cbef --- /dev/null +++ b/tools/test/stress2/misc/force3.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +# "mdconfig -o force" test scenario. +# Copy of force.sh with an added "umount -f" +# Spin seen in umount() with WiP kernel code. + +. ../default.cfg + +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 +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 +mount /dev/md$mdstart $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=3m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1 & + +sleep `jot -r 1 10 40` +while mdconfig -l | grep -q md$mdstart; do + mdconfig -d -u $mdstart -o force || sleep 1 +done +sleep .`jot -r 1 1 9` +../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 +exit 0 diff --git a/tools/test/stress2/misc/force4.sh b/tools/test/stress2/misc/force4.sh new file mode 100755 index 000000000000..b1b05dc54efa --- /dev/null +++ b/tools/test/stress2/misc/force4.sh @@ -0,0 +1,91 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +# "mdconfig -o force" test scenario with nullfs. +# Looping in kernel with WiP kernel code seen: +# https://people.freebsd.org/~pho/stress/log/kirk125.txt + +. ../default.cfg + +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 +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 +mount /dev/md$mdstart $mntpoint +chmod 777 $mntpoint + +mp2=${mntpoint}2 +mkdir -p $mp2 +mount -t nullfs $mntpoint $mp2 || exit 1 + +export LOAD=80 +export MAXSWAPPCT=80 +export RUNDIR=$mp2/stressX +export runRUNTIME=3m +export rwLOAD=80 +export TESTPROGS=' +testcases/lockf2/lockf2 +testcases/symlink/symlink +testcases/openat/openat +testcases/socket/socket +testcases/rw/rw +testcases/mmap/mmap +testcases/fts/fts +testcases/link/link +testcases/lockf/lockf +testcases/creat/creat +testcases/mkdir/mkdir +testcases/rename/rename +testcases/swap/swap +testcases/mkfifo/mkfifo +testcases/dirnprename/dirnprename +testcases/dirrename/dirrename +' + +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > /dev/null 2>&1 & + +sleep `jot -r 1 20 60` +while mdconfig -l | grep -q md$mdstart; do + mdconfig -d -u $mdstart -o force || sleep 1 +done +sleep 1 +../tools/killall.sh +wait +umount $mp2 +n=0 +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 + [ $((n += 1)) -gt 300 ] && { echo FAIL; exit 1; } +done +exit 0 diff --git a/tools/test/stress2/misc/force5.sh b/tools/test/stress2/misc/force5.sh new file mode 100755 index 000000000000..c0aa6436fc1f --- /dev/null +++ b/tools/test/stress2/misc/force5.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# Rename focus + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +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 +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 +mount /dev/md$mdstart $mntpoint +chmod 777 $mntpoint + +export LOAD=80 +export MAXSWAPPCT=80 +export RUNDIR=$mntpoint/stressX +export runRUNTIME=3m +export rwLOAD=80 +export TESTPROGS=' +testcases/fts/fts +testcases/rename/rename +testcases/swap/swap +testcases/dirnprename/dirnprename +testcases/dirrename/dirrename +' + +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > /dev/null 2>&1 & + +sleep `jot -r 1 20 60` +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 +exit 0 diff --git a/tools/test/stress2/misc/force6.sh b/tools/test/stress2/misc/force6.sh new file mode 100755 index 000000000000..5c7d508241ec --- /dev/null +++ b/tools/test/stress2/misc/force6.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# Verify file integrity after a fsync(1) followed by a forced umount +# No problems seen. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +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 || exit 1 +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 +mount /dev/md$mdstart $mntpoint + +file=$mntpoint/file +dd if=/dev/random of=$file bs=1k count=`jot -r 1 1 1024` status=none +s1=`cat $mntpoint/file | md5` +fsync $file + +while mdconfig -l | grep -q md$mdstart; do + mdconfig -d -u $mdstart -o force || sleep 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 -a -t vnode -f $diskimage -u $mdstart +fsck_ffs -Rfy /dev/md$mdstart > /dev/null; s=$? +if [ $s -eq 0 ]; then + mount /dev/md$mdstart $mntpoint + [ ! -f $file ] && + { echo "Lost $file"; s=111; } + if [ $s -eq 0 ]; then + s2=`cat $mntpoint/file | md5` + [ "$s1" != "$s2" ] && + { echo "Checksum error"; s=222; ls -l $file; } + fi + umount $mntpoint +fi +mdconfig -d -u $mdstart + +rm -f $diskimage +exit $s diff --git a/tools/test/stress2/misc/fork.sh b/tools/test/stress2/misc/fork.sh new file mode 100755 index 000000000000..628ffbd4ce93 --- /dev/null +++ b/tools/test/stress2/misc/fork.sh @@ -0,0 +1,129 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# The test program calls fork(2) from a multi-threaded process. +# Test program stuck in uwrlck seen. +# Fixed in r266609. + +# Note that program erroneously calls exit(3) and not _exit(2). + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > fork.c +mycc -o fork -Wall -Wextra -O2 -g fork.c -lpthread || exit 1 + +for i in `jot 100`; do + /tmp/fork & +done +while ! pgrep -q fork; do + sleep .2 +done +for i in `jot 30`; do + pgrep -q fork || break + sleep 1 +done +if pgrep -q fork; then + echo FAIL + exit 1 +fi +wait + +rm -f /tmp/fork /tmp/fork.c +exit 0 +EOF + +/* + * Written by Love Hörnquist Åstrand , March 2003. + * Public domain. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static pid_t parent; +static int thread_survived = 0; + +static void * +print_pid(void *arg __unused) +{ + sleep(3); + + thread_survived = 1; + if (parent != getpid()) { + exit(1); + } + return NULL; +} + +int +main(void) +{ + int r; + pthread_t p; + pid_t fork_pid; + + parent = getpid(); + + r = pthread_create(&p, NULL, print_pid, NULL); + if (r != 0) + errx(1, "r = %d", r); + + fork_pid = fork(); + if (fork_pid == -1) + err(1, "fork"); + + if (fork_pid) { + int status; + + r = pthread_join(p, NULL); + if (r != 0) + errx(1, "r = %d", r); + if (thread_survived == 0) + errx(1, "thread did not survive in parent"); + + waitpid(fork_pid, &status, 0); + if (WIFEXITED(status) != 1) + printf("WIFEXITED(status) = %d\n", WIFEXITED(status)); + if (WEXITSTATUS(status) != 0) + printf("WEXITSTATUS(status) = %d\n", WEXITSTATUS(status)); + } else { + sleep(5); + exit(thread_survived ? 1 : 0); + } +} diff --git a/tools/test/stress2/misc/forkbomb.sh b/tools/test/stress2/misc/forkbomb.sh new file mode 100755 index 000000000000..9638fe796fee --- /dev/null +++ b/tools/test/stress2/misc/forkbomb.sh @@ -0,0 +1,148 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Fork bomb memory leak test scenario. +# https://en.wikipedia.org/wiki/Fork_bomb + +# OO memory seen: +# https://people.freebsd.org/~pho/stress/log/forkbomb.txt +# Fixed by r289026. + +. ../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/forkbomb.c +mycc -o forkbomb -Wall -Wextra -O0 -g forkbomb.c || exit 1 +rm -f forkbomb.c +cd $odir + +mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 512m -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +su $testuser -c /tmp/forkbomb + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -rf /tmp/forkbomb +exit 0 + +EOF +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +volatile u_int *share; + +#define R1 1 /* sync start */ +#define R2 2 /* forks */ +#define R3 3 /* exits */ +#define R4 4 /* fork failed */ + +//#define DEBUG +#define MXFAIL 100 +#define MAXPROC 40000 /* Arbitrary cap */ +#define PARALLEL 200 + +void +test(void) +{ + int r; + + alarm(1200); + atomic_add_int(&share[R1], 1); + while (share[R1] != PARALLEL) + ; + atomic_add_int(&share[R2], 1); + + for (;;) { + if (share[R2] >= MAXPROC || share[R4] > MXFAIL) + break; + atomic_add_int(&share[R2], 1); + if ((r = fork()) == -1) { + atomic_add_int(&share[R4], 1); + atomic_add_int(&share[R2], -1); + break; + } + } + + atomic_add_int(&share[R3], 1); + _exit(0); +} + +int +main(void) +{ + struct sigaction sa; + size_t len; + int i; + + alarm(1200); + len = PAGE_SIZE; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + sa.sa_handler = SIG_IGN; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGCHLD, &sa, 0) == -1) + err(1, "sigaction"); + + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + test(); + } + + while (share[R2] == 0 || share[R3] < share[R2]) + sleep(1); + +#if defined(DEBUG) + fprintf(stderr, "MAXPROC: %d. forks: %u / exits: %u / fails: %u\n", + MAXPROC, share[R2], share[R3], share[R4]); +#endif + + return (0); +} diff --git a/tools/test/stress2/misc/fpclone.sh b/tools/test/stress2/misc/fpclone.sh new file mode 100755 index 000000000000..3b75c5ec8d36 --- /dev/null +++ b/tools/test/stress2/misc/fpclone.sh @@ -0,0 +1,192 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 scenario by kib@freebsd.org + +# Test of patch for Giant trick in cdevsw + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -d /usr/src/sys ] || exit 0 +builddir=`sysctl kern.version | grep @ | sed 's/.*://'` +[ -d "$builddir" ] && export KERNBUILDDIR=$builddir || exit 0 +export SYSDIR=`echo $builddir | sed 's#/sys.*#/sys#'` +kldstat -v | grep -q pty || { kldload pty || exit 0; } + +. ../default.cfg + +odir=`pwd` +dir=$RUNDIR/fpclone +[ ! -d $dir ] && mkdir -p $dir + +cd $dir +cat > Makefile < +EOF + +sed '1,/^EOF2/d' < $odir/$0 > fpclone.c +make +kldload $dir/fpclone.ko + +cd $odir +for i in `jot 10`; do + dd if=/dev/fpclone bs=1m count=10 > /dev/null 2>&1 & +done + +export runRUNTIME=2m +cd ..; ./run.sh pty.cfg + +for i in `jot 10`; do + wait +done +kldstat +dd if=/dev/fpclone bs=1m count=1k > /dev/null 2>&1 & +kldunload $dir/fpclone.ko +rm -rf $dir +exit + +EOF2 +#include +#include +#include +#include +#include +#include +#include +#include + +static d_open_t fpclone_open; +static d_close_t fpclone_close; +static d_read_t fpclone_read; + +static struct cdevsw fpclone_cdevsw = { + .d_open = fpclone_open, + .d_close = fpclone_close, + .d_read = fpclone_read, + .d_name = "fpclone", + .d_version = D_VERSION, + .d_flags = D_TRACKCLOSE +}; + +MALLOC_DEFINE(M_FPCLONESC, "fpclone memory", "fpclone memory"); + +struct fpclone_sc +{ + int pos; +}; + +static struct cdev *fpclone_dev; +static struct mtx me; + +static void +fpclone_cdevpriv_dtr(void *data) +{ + free(data, M_FPCLONESC); +} + +static int +fpclone_open(struct cdev *dev, int oflags, int devtype, struct thread *td) +{ + struct fpclone_sc *sc; + int error; + + sc = malloc(sizeof(struct fpclone_sc), M_FPCLONESC, + M_WAITOK | M_ZERO); + error = devfs_set_cdevpriv(sc, fpclone_cdevpriv_dtr); + if (error) + fpclone_cdevpriv_dtr(sc); + return (error); +} + +static int +fpclone_close(struct cdev *dev, int fflag, int devtype, struct thread *td) +{ + + devfs_clear_cdevpriv(); + return (0); +} + +static char rdata[] = "fpclone sample data string\n"; + +static int +fpclone_read(struct cdev *dev, struct uio *uio, int ioflag) +{ + struct fpclone_sc *sc; + int rv, amnt, svpos, error; + + error = devfs_get_cdevpriv((void **)&sc); + if (error) + return (error); + + rv = 0; + while (uio->uio_resid > 0) { + svpos = sc->pos; + amnt = MIN(uio->uio_resid, sizeof(rdata) - svpos); + rv = uiomove(rdata + svpos, amnt, uio); + if (rv != 0) + break; + mtx_lock(&me); + sc->pos += amnt; + sc->pos %= sizeof(rdata); + mtx_unlock(&me); + } + return (rv); +} + +static int +fpclone_modevent(module_t mod, int what, void *arg) +{ + switch (what) { + case MOD_LOAD: + mtx_init(&me, "fp_ref", NULL, MTX_DEF); + fpclone_dev = make_dev(&fpclone_cdevsw, 0, 0, 0, 0666, + "fpclone"); + return(0); + + case MOD_UNLOAD: + destroy_dev(fpclone_dev); + mtx_destroy(&me); + return (0); + + default: + break; + } + + return (0); +} + +moduledata_t fpclone_mdata = { + "fpclone", + fpclone_modevent, + NULL +}; + +DECLARE_MODULE(fpclone, fpclone_mdata, SI_SUB_DRIVERS, SI_ORDER_MIDDLE); +MODULE_VERSION(fpclone, 1); diff --git a/tools/test/stress2/misc/fpclone2.sh b/tools/test/stress2/misc/fpclone2.sh new file mode 100755 index 000000000000..b03f5cced96f --- /dev/null +++ b/tools/test/stress2/misc/fpclone2.sh @@ -0,0 +1,117 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 scenario by kib@freebsd.org + +# Test of patch for Giant trick in cdevsw + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -d /usr/src/sys ] || exit 0 +builddir=`sysctl kern.version | grep @ | sed 's/.*://'` +[ -d "$builddir" ] && export KERNBUILDDIR=$builddir || exit 0 +export SYSDIR=`echo $builddir | sed 's#/sys.*#/sys#'` + +. ../default.cfg + +odir=`pwd` +dir=$RUNDIR/fpclone +[ ! -d $dir ] && mkdir -p $dir + +cd $dir +cat > Makefile < +EOF + +sed '1,/^EOF2/d' < $odir/fpclone.sh > fpclone.c +make +kldload $dir/fpclone.ko + +sed '1,/^EOF2/d' < $odir/$0 > fpclone2.c +mycc -o /tmp/fpclone2 -Wall fpclone2.c +rm -f fpclone2.c + +cd $odir +for i in `jot 10`; do + /tmp/fpclone2 & +done + +for i in `jot 10`; do + wait +done +kldstat +kldunload $dir/fpclone.ko +rm -rf $dir /tmp/fpclone2 +exit + +EOF2 +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int fd; + int i; + char buf[80]; + + for (i = 0; i < 10000; i++) { + if ((fd = open("/dev/fpclone", O_RDONLY)) == -1) + err(1, "open(/dev/fpclone"); + if (read(fd, buf, sizeof(buf)) <= 0) + err(1, "read"); + if (dup2(fd, 10) == -1) + err(1, "dup"); + if (dup2(fd, 11) == -1) + err(1, "dup"); + if (dup2(fd, 12) == -1) + err(1, "dup"); + if (close(fd) == -1) + err(1, "close(%d)", fd); + if (close(10) == -1) + err(1, "close(%d)", 10); + if (close(11) == -1) + err(1, "close(%d)", 11); + if (close(12) == -1) + err(1, "close(%d)", 12); + } + if ((fd = open("/dev/fpclone", O_WRONLY)) == -1) + err(1, "open(/dev/fpclone"); + if (write(fd, "xxx", 3) == -1 && errno != ENODEV) + err(1, "write"); + if (close(fd) == -1) + err(1, "close(%d)", fd); + + return (0); +} diff --git a/tools/test/stress2/misc/fpu.sh b/tools/test/stress2/misc/fpu.sh new file mode 100755 index 000000000000..f4bc53d2f67f --- /dev/null +++ b/tools/test/stress2/misc/fpu.sh @@ -0,0 +1,103 @@ +#!/bin/sh + +# +# Copyright (c) 2010 Peter Holm +# All rights reserved. +# +# 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 FPU changes in r208833 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > fpu.c +mycc -o fpu -Wall -O2 fpu.c +rm -f fpu.c +[ -d $RUNDIR ] || mkdir -p $RUNDIR +cd $RUNDIR + +r=`/tmp/fpu` +[ "$r" = "-0.000000017, 0.000000000, 0.000000000" ] || echo $r + +cd $here +rm -f /tmp/fpu + +exit 0 +EOF +#include +#include +#include +#include +#include +#include + +void +handler(int i) +{ +} + +void +test() +{ + float val = 0; + double lval = 0; + long double llval = 0; + int i, j; + + for (i = 0; i < 100000; i++) { + for (j = 0; j < 100000; j++) { + val = val + 0.00001; + lval = lval + 0.00001; + llval = llval + 0.00001; + } + for (j = 0; j < 100000; j++) { + val = val - 0.00001; + lval = lval - 0.00001; + llval = llval - 0.00001; + } + } + printf("%.9f, %.9f, %.9Lf\n", val, lval, llval); + exit(0); + +} + +int +main() +{ + pid_t pid; + int i; + + signal(SIGHUP, handler); + + if ((pid = fork()) == 0) + test(); + + for (i = 0; i < 10000; i++) + kill(pid, SIGHUP); + + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/fragments.sh b/tools/test/stress2/misc/fragments.sh new file mode 100755 index 000000000000..ea1d095081c6 --- /dev/null +++ b/tools/test/stress2/misc/fragments.sh @@ -0,0 +1,275 @@ +#!/bin/sh + +# +# Copyright (c) 2010 Peter Holm +# All rights reserved. +# +# 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. +# + +# Scenario that causes "panic: brelse: free buffer onto another queue???" +# Idea for scenario by kib@. Fixed in r203818 + +# When UFS partition is full, then some high load causes +# panic: brelse: free buffer onto another queue??? + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > fragments.c +rm -f /tmp/fragments +mycc -o fragments -Wall -Wextra -O2 -g fragments.c +rm -f fragments.c +cd $here + +mount | grep "$mntpoint" | grep -q md$mdstart && umount -f $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags -m 0 md${mdstart}$part > /dev/null 2>&1 +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +cd $mntpoint +su $testuser -c "/tmp/fragments" +cd $here + +umount $mntpoint +mount | grep "$mntpoint" | grep -q md$mdstart && umount -f $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +rm -f /tmp/fragments +exit +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 600 +#define PARALLEL 8 + +static pid_t pid; +static char *buf; + +static volatile sig_atomic_t stop; + +void +handler(int i __unused) { + stop = 1; +} + +void +cleanup(int n) +{ + int i, j, start; + int nb = 0; + char file[128]; + struct statfs sbuf; + struct stat sb; + + if (n == -1) { + for (i = 0; i < LOOPS; i++) { + sprintf(file,"t%05d", i); + unlink(file); + } + return; + } + + start = arc4random() % n; + for (i = 0; i < LOOPS; i++) { + j = (start + i) % LOOPS; + sprintf(file,"t%05d", j); + if (stat(file, &sb) != 0) + continue; + + if (sb.st_size == 0) { + unlink(file); + continue; + } + if (truncate(file, 0) == 0) { + nb++; + continue; + } + if (nb > 10) + break; + } + + for (i = 0; i < 10; i++) { + if (statfs(".", &sbuf) < 0) + err(1, "statfs(%s)", "."); + + if (sbuf.f_bfree > 8) + return; + } + + for (i = 0; i < LOOPS; i++) { + j = (start + i) % LOOPS; + sprintf(file,"t%05d", j); + if (unlink(file) == 0) { + return; + } + } +} + +void +fragments(void) +{ + int i, len; + char file[128]; + int fd; + + for (i = 0;; i++) { + sprintf(file,"d%d/f%05d.%05d", i/1000, pid, i); + + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) { + if (errno != ENOSPC) + warn("open(%s)", file); + break; + } + + len = 2 * 1024; + if (write(fd, buf, len) != len) { + } + + close(fd); + } +} + +void +blocks(void) +{ + int i, len; + char file[128]; + int fd; + + for (i = 0;; i++) { + sprintf(file,"d%d/b%05d.%05d", i/1000, pid, i); + + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) { + if (errno != ENOSPC) + warn("open(%s)", file); + break; + } + + len = 16 * 1024; + if (write(fd, buf, len) != len) { + } + + close(fd); + } +} + +void +setup(void) +{ + int i; + char file[128]; + + for (i = 0; i < 300; i++) { + sprintf(file,"d%d", i); + if (mkdir(file, 0700) == -1) + warn("mkdir(%s)", file); + } + + blocks(); + fragments(); + + for (i = 0;i < 8; i++) { + sprintf(file,"d%d/b%05d.%05d", i/1000, pid, i); + unlink(file); + } + for (i = 0;i < 1; i++) { + sprintf(file,"d%d/f%05d.%05d", i/1000, pid, i); + unlink(file); + } + +} + +int +test(void) +{ + int i, len, n; + char file[128]; + int fd; + + for (i = 0; i < LOOPS; i++) { + sprintf(file,"t%05d", i); + + if ((fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) { + continue; + } +// n = arc4random() % (12 + 1); + n = 0; + len = (arc4random() % (16 * 1024) + 1) + n * 16; + while (len > 0) { + if (write(fd, buf, len) == len) + break; + len = len / 2; + usleep(1000); + } + close(fd); + if (len == 0) { + cleanup(i); + } + } + + exit(0); + + return (0); +} + +int +main() +{ + int i, j, status; + + pid = getpid(); + if ((buf = malloc(12 * 16 * 1024)) == NULL) + err(1, "malloc()"); + + setup(); + signal(SIGALRM, handler); + alarm(30 * 60); + for (j = 0; j < 50 && stop == 0; j++) { + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + test(); + } + for (i = 0; i < PARALLEL; i++) + wait(&status); + cleanup(-1); + } + return (0); +} diff --git a/tools/test/stress2/misc/freepages.sh b/tools/test/stress2/misc/freepages.sh new file mode 100755 index 000000000000..4aaea7453b1c --- /dev/null +++ b/tools/test/stress2/misc/freepages.sh @@ -0,0 +1,130 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Free page shortage test scenario +# No problems seen + +. ../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/freepages.c +mycc -o freepages -Wall -Wextra -O0 -g freepages.c || exit 1 +rm -f freepages.c +cd $odir + +$dir/freepages `sysctl -n hw.usermem` +s=$? +[ -f freepages.core -a $s -eq 0 ] && + { ls -l freepages.core; mv freepages.core /tmp; s=1; } + +rm -rf $dir/freepages +exit $s +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; + +#define PARALLEL 6 +#define RUNTIME (5 * 60) +#define SYNC 0 + +static void +test(char *s) +{ + time_t start; + size_t i, len; + char *cp; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + start = time(NULL); + while ((time(NULL) - start) < RUNTIME) { + len = atol(s) / PARALLEL; + len = len / 10 * 8; + if ((cp = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap(%zd)", len); + for (i = 0; i < len; i += PAGE_SIZE) + cp[i] = 1; + if (munmap(cp, len) == -1) + err(1, "unmap"); + } + + _exit(0); +} + +int +main(int argc __unused, char *argv[]) +{ + pid_t pids[PARALLEL]; + size_t len; + 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"); + + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(argv[1]); + 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); +} diff --git a/tools/test/stress2/misc/fs.sh b/tools/test/stress2/misc/fs.sh new file mode 100755 index 000000000000..dde3f39ed3ef --- /dev/null +++ b/tools/test/stress2/misc/fs.sh @@ -0,0 +1,91 @@ +#!/bin/sh + +# +# Copyright (c) 2008, 2011 Peter Holm +# All rights reserved. +# +# 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. +# + +# Run a simple test on different FS variations, with and without disk full. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg +flag=/tmp/fs.sh.flag + +ftest () { # option, disk full + local args="$@" + [ $2 -eq 1 ] && df=", disk full" || df="" + echo "`date '+%T'` newfs $1 md${mdstart}${part}$df" + newfs $1 md${mdstart}$part > /dev/null + mount /dev/md${mdstart}$part $mntpoint + chmod 777 $mntpoint + + export RUNDIR=$mntpoint/stressX + export runRUNTIME=1m + disk=$(($2 + 1)) # 1 or 2 + set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` + export KBLOCKS=$(($1 * disk)) + export INODES=$(($2 * disk)) + + for i in `jot 2`; do + rm -rf /tmp/stressX.control $RUNDIR + su $testuser -c "(cd ..; ./run.sh disk.cfg)" > \ + /dev/null 2>&1 & + sleep 60 + ../tools/killall.sh + wait + done + + for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 + if [ $i -eq 6 ]; then + touch $flag + echo "Test \"$args\" FAIL" + fstat -mf $mntpoint + umount -f $mntpoint + fi + done + checkfs /dev/md${mdstart}$part || touch $flag +} + +mount | grep "on $mntpoint " | grep -q md${mdstart}$part && umount $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 20m -u $mdstart +bsdlabel -w md$mdstart auto + +ftest "-O 1" 0 # ufs1 +ftest "-O 1" 1 # ufs1, disk full +ftest "-O 2" 0 # ufs2 +ftest "-O 2" 1 # ufs2, disk full +ftest "-U" 0 # ufs2 + soft update +ftest "-U" 1 # ufs2 + soft update, disk full +ftest "-j" 0 # ufs2 + SU+J +ftest "-j" 1 # ufs2 + SU+J, disk full + +mdconfig -d -u $mdstart +[ -f $flag ] && s=1 || s=0 +rm -f $flag +exit $s diff --git a/tools/test/stress2/misc/fsck.sh b/tools/test/stress2/misc/fsck.sh new file mode 100755 index 000000000000..a007e722988e --- /dev/null +++ b/tools/test/stress2/misc/fsck.sh @@ -0,0 +1,149 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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) test. +# "UFS /dev/md11 (/mnt11) cylinder checksum failed" seen. +# Fixed by r341510. + +# 'panic: invalid counts on struct mount' seen: +# https://people.freebsd.org/~pho/stress/log/fsck-4.txt + +[ $DEBUG ] || exit 0 # Still WiP + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +cc -o /tmp/flip -Wall -Wextra -O2 ../tools/flip.c || exit 1 + +echo 'int sync(void) { return (0); }' > /tmp/fsck_preload.c +mycc -o /tmp/fsck_preload.so -shared -fpic /tmp/fsck_preload.c || exit 1 +cc -o /tmp/fsck_preload.so -shared -fpic /tmp/fsck_preload.c || exit 1 +rm /tmp/fsck_preload.c + +set -e +u1=$mdstart +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 +asbs=0 +cleans=0 +reruns=0 +waccess=0 + +max=$((10 * 1024 * 1024)) +[ "$newfs_flags" = "-j" ] && + max=$((20 * 1024 * 1024)) + +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 1g -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 $newfs_flags md$u2 | grep -A1 "super-block backups" | \ + tail -1 | sed 's/,//g'` +newfs $newfs_flags md$u2 > /dev/null +mount /dev/md$u2 $mp2 +[ -d /usr/include/sys ] && cp -r /usr/include/sys $mp2 +umount $mp2 + +chk() { + local i + + LD_PRELOAD=/tmp/fsck_preload.so \ + fsck_ffs -fy $1 > $log 2>&1 + r=$? + if grep -qE "Cannot find file system superblock|Superblock check-hash failed" $log; then + for b in $backups; do + echo "Using alternate SB $b" + asbs=$((asbs + 1)) + LD_PRELOAD=/tmp/fsck_preload.so \ + fsck_ffs -b $b -fy $1 > $log 2>&1 + r=$? + grep -qE "Cannot find file system superblock|Superblock check-hash 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=$? + ! grep -q RERUN $log; rerun=$? + ! grep -q "NO WRITE ACCESS" $log; waccess=$? + [ $r -ne 0 -a $clean -eq 1 ] && echo "Exit code $r w/ clean == 1" + +} + +cd /tmp +s=0 +start=`date +%s` +while [ $((`date +%s` - start)) -lt 60 ]; do + gzip < $diskimage > $backup + fsync $backup; sync # ; sleep .2; sync; sleep .2; sync + mount /dev/md$u2 $mp2 || { s=101; break; } + touch $mp2/`jot -rc 8 a z | tr -d '\n'` + umount $mp2 + /tmp/flip -n 4 $diskimage + for i in `jot 3`; do + chk /dev/md$u2 + [ $clean -eq 1 ] && { cleans=$((cleans + 1)); break; } + [ $rerun -eq 1 ] && { reruns=$((reruns + 1)); continue; } + done + [ $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=103; } + [ $waccess -eq 1 ] && { echo "No write access"; s=555; } + break +done +[ $DEBUG ] && + echo "$cleans cleans, $reruns reruns, $asbs alternate SBs." && cat $log +if [ $clean -ne 1 ]; then + echo "FS still not clean. Last fsck_ffs exit code was $r." + cat $log + cp -v $log /tmp || rm $log + [ $s -eq 0 ] && s=104 +fi +mdconfig -d -u $u2 || exit 1 +[ -f fsck_ffs.core ] && ls -l fsck_ffs.core + +umount $mp1 +mdconfig -d -u $u1 +rm -f /tmp/fsck_preload.so $backup /tmp/flip +exit $s diff --git a/tools/test/stress2/misc/fsck2.sh b/tools/test/stress2/misc/fsck2.sh new file mode 100755 index 000000000000..313efec490d1 --- /dev/null +++ b/tools/test/stress2/misc/fsck2.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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 fsck_ffs exit code + +unit=55 +[ -c /dev/md$unit ] && exit 0 + +fsck_ffs /dev/md$unit > /dev/null 2>&1 +s=$? +[ $s -eq 0 ] && { echo "Bad exit code $s. Expected non zero."; s=1; } || s=0 +exit $s diff --git a/tools/test/stress2/misc/fsck3.sh b/tools/test/stress2/misc/fsck3.sh new file mode 100755 index 000000000000..f9bd29017e35 --- /dev/null +++ b/tools/test/stress2/misc/fsck3.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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 test. +# Test scenario broken superblock, use backup SB. + +. ../default.cfg +set -e +u1=$mdstart +u2=$((mdstart + 1)) +mp1=${mntpoint}$u1 +mp2=${mntpoint}$u2 +mkdir -p $mp1 $mp2 +log=$mp1/fsck3.sh.log +diskimage=$mp1/diskimage + +max=$((10 * 1024 * 1024)) +[ "$newfs_flags" = "-j" ] && + max=$((20 * 1024 * 1024)) + +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 1g -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 $newfs_flags md$u2 | grep -A1 "super-block backups" | \ + tail -1 | sed 's/,//g'` +newfs $newfs_flags md$u2 > /dev/null +sblock=`dumpfs md$u2 | grep -m1 "superblock location" | awk '{print $3}'` +mount /dev/md$u2 $mp2 || s=100 +touch $mp2/file +umount $mp2 +set +e + +s=0 +fsck_ffs -y /dev/md$u2 > $log 2>&1 +r=$? +for i in $backups; do + dd if=/dev/random of=$diskimage oseek=$sblock bs=1 count=8 \ + conv=notrunc status=none + fsck_ffs -y /dev/md$u2 > $log 2>&1 + r=$? + echo "fsck_ffs -b $i -y /dev/md$u2" + fsck_ffs -b $i -y /dev/md$u2 > $log 2>&1 + r=$? + mount /dev/md$u2 $mp2 || s=100 + [ -f $mp2/file ] || { echo "$mp2/file not found"; s=101; } + umount $mp2 +done + +mdconfig -d -u $u2 +[ -f fsck_ffs.core ] && { ls -l fsck_ffs.core; s=102; } + +umount $mp1 +mdconfig -d -u $u1 +rm -f $diskimage +exit $s diff --git a/tools/test/stress2/misc/fsck4.sh b/tools/test/stress2/misc/fsck4.sh new file mode 100755 index 000000000000..3e97f7b54340 --- /dev/null +++ b/tools/test/stress2/misc/fsck4.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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_valloc: dup alloc" seen: +# https://people.freebsd.org/~pho/stress/log/kostik1128.txt + +. ../default.cfg +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +md5=c2e2d89745914bf12c5b251c358e1b3f +size=$(((5368709120 + 13964088) / 1024 + 1)) +zimg=tmp.disk.xz +log=fsck4.sh.log + +[ `df -k $(dirname $diskimage) | tail -1 | awk '{print $4}'` -lt $size ] && +{ echo "Not enough disk space."; exit 0; } +[ -z "`which fetch`" ] && exit 0 + +cd `dirname $diskimage` +trap "rm -f $diskimage $zimg" EXIT INT +fetch -q https://people.freebsd.org/~pho/$zimg || exit 0 + +m=`md5 < $zimg` +[ $m != $md5 ] && { echo "md5 diff"; rm $zimg; exit 1; } +unxz < $zimg > $diskimage +rm $zimg + +mdconfig -a -t vnode -f $diskimage -u $mdstart +fsck_ffs -fy $diskimage > $log 2>&1 +if grep -q "MARKED CLEAN" $log; then + mount /dev/md$mdstart $mntpoint + touch $mntpoint/xxxxxxxx # Panics here + umount $mntpoint + s=0 +else + cat $log + s=1 +fi +mdconfig -d -u $mdstart + +exit $s diff --git a/tools/test/stress2/misc/fsck5.sh b/tools/test/stress2/misc/fsck5.sh new file mode 100755 index 000000000000..35381c8c55e7 --- /dev/null +++ b/tools/test/stress2/misc/fsck5.sh @@ -0,0 +1,72 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# "INODE 3: FILE SIZE 1073741824 BEYOND END OF ALLOCATED FILE, SIZE SHOULD +# BE 268435456" seen. +# Original test scenario by Jamie Landeg-Jones +# Fixed by r346185 + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 + +log1=/tmp/fsck5.sh.1.log +log2=/tmp/fsck5.sh.2.log +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 1g -u $mdstart +newfs $newfs_flags -n md$mdstart > /dev/null +mount /dev/md$mdstart $mntpoint +set +e + +cd $mntpoint +truncate -s 1g test +ls -lis test > $log1 +sha256 -r test > sha256.out +cd / +umount $mntpoint + +( + fsck -fy /dev/md$mdstart + fsck -fy /dev/md$mdstart + fsck -fy /dev/md$mdstart +) > $log2 2>&1 + +mount /dev/md$mdstart $mntpoint +cd $mntpoint +ls -lis test >> $log1 +sha256 -r test > sha256-2.out +s=0 +cmp sha256.out sha256-2.out || + { cat $log2 $log1 sha256.out sha256-2.out; s=1; } +cd / +umount $mntpoint +mdconfig -d -u $mdstart +rm -f $log1 $log2 +exit $s diff --git a/tools/test/stress2/misc/fsck6.sh b/tools/test/stress2/misc/fsck6.sh new file mode 100755 index 000000000000..e1c5a4f36559 --- /dev/null +++ b/tools/test/stress2/misc/fsck6.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# +# fsck_ffs -p test + +# /dev/md10: CANNOT READ BLK: 320 +# /dev/md10: UNEXPECTED SOFT UPDATE INCONSISTENCY; RUN fsck MANUALLY. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +# Check for lingering threads from the last run +pgrep -x mount && { pgrep -x mount | xargs ps -lp; exit 1; } +../tools/killall.sh || exit 1 + +fsck=/sbin/fsck_ffs +log=/tmp/fsck6.log +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 5g -u $mdstart || exit 1 +md=md$mdstart +newfs -U /dev/$md > /dev/null 2>&1 || exit 1 + +gnop create /dev/$md || exit 1 +mount /dev/$md.nop $mntpoint || exit 1 + +for i in `jot 5`; do + cp -a /usr/include $mntpoint/d$i +done +(cd $mntpoint; umount $mntpoint) +ls -lR $mntpoint > /dev/null +touch $mntpoint/x +sync; sleep 1; sync; sleep 1; sync + +gnop destroy -f /dev/$md.nop + +# Wait until forcible unmount, may be up to about 30 seconds, +# but typically very quick if I/O is in progress +s=`date +%s` +n=0 +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` - s)) -ge 180 ]; then + echo "Giving up on waiting for umount of $mntpoint" + umount $mntpoint || umount -f $mntpoint + break + fi +done +[ $n -ne 0 ] && echo + +$fsck -p /dev/$md; s=$? +mdconfig -d -u ${md#md} +rm -f $log +exit $s diff --git a/tools/test/stress2/misc/fsgs.sh b/tools/test/stress2/misc/fsgs.sh new file mode 100755 index 000000000000..ba9e81de392d --- /dev/null +++ b/tools/test/stress2/misc/fsgs.sh @@ -0,0 +1,135 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 r322799: +# Ensure that fs/gs bases are stored in pcb before copying the pcb for +# new process or thread. + +# "Exit status is 139" seen. + +# Test scenario suggestion by kib@ + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/fsgs.c +mycc -o fsgs -Wall -Wextra -O0 -g fsgs.c || exit 1 +rm -f fsgs.c +cd $odir + +$dir/fsgs +s=$? +[ -f $dir/fsgs.core ] && + { file $dir/fsgs.core; s=1; } + +rm -rf $dir/fsgs $dir/fsgs.core +exit $s + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; + +#define PARALLEL 4 +#define RUNTIME (1 * 60) +#define SYNC 0 + +static void +test(void) +{ + pid_t pid; + int i, status; + volatile char *cp; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + for (i = 0; i < 100; i++) { + if ((pid = fork()) == 0) { + cp = malloc(2); + _exit(0); + } + if (waitpid(pid, &status, 0) != pid) + err(1, "waitpid(%d)", pid); + if (status != 0) { + fprintf(stderr, "Exit status is %d\n", status); + exit(1); + } + } + + _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]); + e += status == 0 ? 0 : 1; + } + } + + return (e); +} diff --git a/tools/test/stress2/misc/fstat.sh b/tools/test/stress2/misc/fstat.sh new file mode 100755 index 000000000000..441065f8e769 --- /dev/null +++ b/tools/test/stress2/misc/fstat.sh @@ -0,0 +1,178 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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 r368486 +# https://reviews.freebsd.org/D27513 + +# Problem not seen. + +. ../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/fstat.c +mycc -o fstat -Wall -Wextra -O0 -g fstat.c || exit 1 +rm -f fstat.c +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 ../testcases/swap; ./swap -t 10m -i 20 > /dev/null 2>&1) & +cd $mntpoint +$dir/fstat +s=$? +while pkill swap; do :; done +wait +[ -f fstat.core -a $s -eq 0 ] && + { ls -l fstat.core; mv fstat.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 +rm -rf $dir/fstat +exit $s + +EOF +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static _Atomic(int) *share; + +#define PARALLEL 5 +#define RUNTIME (2 * 60) +#define SYNC 0 +#define DONE 1 + +static void +test(void) +{ + pid_t pid; + time_t start; + int fd[2], i; + char cmd[60]; + + (void)atomic_fetch_add(&share[SYNC], 1); + while (atomic_load(&share[SYNC]) != PARALLEL) + usleep(10); + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + share[DONE] = 0; + if ((pid = fork()) == 0) { + (void)atomic_fetch_add(&share[DONE], 1); + for (i = 0; i < 1000; i++) { + if (socketpair(PF_UNIX, SOCK_STREAM, 0, fd) == -1) + err(1, "socketpair()"); + usleep(arc4random() % 1000); + close(fd[0]); + close(fd[1]); + } + (void)atomic_fetch_add(&share[DONE], 1); + _exit(0); + } + if (pid == -1) + err(1, "fork()"); + setproctitle("master"); + while (atomic_load(&share[DONE]) == 0) + usleep(10); + snprintf(cmd, sizeof(cmd), "fstat -p %d > /dev/null 2>&1", + pid); + while (atomic_load(&share[DONE]) == 1) + system(cmd); + system(cmd); + if (waitpid(pid, NULL, 0) != pid) + err(1, "waitpid()"); + } + + _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); +} diff --git a/tools/test/stress2/misc/fsync.sh b/tools/test/stress2/misc/fsync.sh new file mode 100755 index 000000000000..c8c5a8243ae1 --- /dev/null +++ b/tools/test/stress2/misc/fsync.sh @@ -0,0 +1,91 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# vfs_write_suspend() test scenario. +# The unusual combination of newfs(8) flags: J and j triggers: +# fsync: giving up on dirty +# GEOM_JOURNAL: Cannot suspend file system /mnt (error=35). (EAGAIN) + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ $((`sysctl -n hw.usermem` / 1024 / 1024 / 1024)) -le 10 ] && + exit 0 + +md1=$mdstart +md2=$((mdstart + 1)) + +size=5g +jsize=3g + +for u in $md1 $md2; do + [ -c /dev/md$u ] && mdconfig -d -u $u + mdconfig -a -t swap -s $size -u $u +done + +gmirror load > /dev/null 2>&1 && unload=1 +gmirror label -v -b split -s 2048 data /dev/md$md1 /dev/md$md2 \ + || exit 1 +[ "`sysctl -in kern.geom.mirror.launch_mirror_before_timeout`" = "0" ] && + sleep $((`sysctl -n kern.geom.mirror.timeout` + 1)) + +gjournal load > /dev/null 2>&1 +gjournal label -s $jsize /dev/mirror/data > /dev/null || + { gmirror stop data; exit 1; } +sleep .5 +s=1 +if [ -c /dev/mirror/data.journal ]; then + newfs -J -j /dev/mirror/data.journal > /dev/null + mount -o async /dev/mirror/data.journal $mntpoint || exit 1 + + chmod 777 $mntpoint + + export runRUNTIME=10m + export RUNDIR=$mntpoint/stressX + + su $testuser -c 'cd ..; ./run.sh disk.cfg' + s=0 + + gjournal sync + umount $mntpoint + while mount | grep $mntpoint | grep -q /mirror/data; do + umount $mntpoint || sleep 1 + done +else + echo "FAIL /dev/mirror/data.journal not found" +fi +gjournal stop /dev/mirror/data +gjournal unload +gmirror stop data +[ $unload ] && gmirror unload + +for u in $md2 $md1; do + mdconfig -d -u $u +done +exit $s diff --git a/tools/test/stress2/misc/fsync2.sh b/tools/test/stress2/misc/fsync2.sh new file mode 100755 index 000000000000..f2e846c4aa20 --- /dev/null +++ b/tools/test/stress2/misc/fsync2.sh @@ -0,0 +1,138 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +# Deadlock seen: https://people.freebsd.org/~pho/stress/log/mark169.txt +# Test scenario based on the syzkaller reproducer syzkaller21.sh and comments +# by markj@. + +. ../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/fsync2.c +mycc -o fsync2 -Wall -Wextra -O0 -g fsync2.c -lpthread || exit 1 +rm -f fsync2.c +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/fsync2) + +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/fsync2 +exit 0 +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define RUNTIME 60 + +static time_t start; +static volatile int fd; + +static void * +t1(void *data __unused) +{ + char cwd[1024]; + + if (getcwd(cwd, sizeof(cwd)) == NULL) + err(1, "getcwd()"); + while (time(NULL) - start < RUNTIME) { + if (mkdir("./file0", 0740) == -1) + err(1, "mkdir(file0)"); + if (mkdir("./file1", 0740) == -1) + err(1, "mkdir(file2)"); + if (rename("./file1", "./file0/file0") == -1) + err(1, "rename()"); + if ((fd = open("./file0/file0", O_RDONLY)) == -1) + err(1, "open()"); + if (chdir("./file0/file0") == -1) + err(1, "chdir()"); + if (chdir(cwd) == -1) + err(1, "chdir(HOME)"); + close(fd); + rmdir("./file0/file0"); + rmdir("./file0"); + } + + return (NULL); +} + +static void * +t2(void *data __unused) +{ + while (time(NULL) - start < RUNTIME) { + fsync(fd); + } + + return (NULL); +} + +int +main(void) +{ + pthread_t tid[2]; + int r; + + 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/ftruncate.sh b/tools/test/stress2/misc/ftruncate.sh new file mode 100755 index 000000000000..ddec85b6745a --- /dev/null +++ b/tools/test/stress2/misc/ftruncate.sh @@ -0,0 +1,189 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# ftruncate(2) fuzz. + +# "panic: softdep_deallocate_dependencies: dangling deps" seen in +# 10.3-STABLE: +# https://people.freebsd.org/~pho/stress/log/ftruncate.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +dir=$RUNDIR + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > ftruncate.c +rm -f /tmp/ftruncate +mycc -o ftruncate -Wall -Wextra -O2 -g ftruncate.c -lpthread || exit 1 +rm -f ftruncate.c + +rm -rf $dir +mkdir -p $dir +chmod 777 $dir + +cd $dir +jot 500 | xargs touch +jot 500 | xargs chmod 666 +cd $odir + +(cd /tmp; /tmp/ftruncate $dir) +e=$? + +rm -rf $dir + +rm -f /tmp/ftruncate +exit $e +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +#define RUNTIME 180 +#define THREADS 2 + +static int fd[900]; +static u_int32_t r[N]; +static char *args[2]; + +static unsigned long +makearg(void) +{ + unsigned long val; + + val = arc4random(); +#if defined(__LP64__) + val = (val << 32) | arc4random(); + val = val & 0x00007fffffffffffUL; +#endif + + return(val); +} + +static void * +test(void *arg __unused) +{ + FTS *fts; + FTSENT *p; + int ftsoptions, i, n; + + ftsoptions = FTS_PHYSICAL; + + for (;;) { + for (i = 0; i < N; i++) + r[i] = arc4random(); + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + i = n = 0; + while ((p = fts_read(fts)) != NULL) { + if (fd[i] > 0) + close(fd[i]); + if ((fd[i] = open(p->fts_path, O_RDWR)) == -1) + if ((fd[i] = open(p->fts_path, O_WRONLY)) == -1) + continue; + i++; + i = i % nitems(fd); + } + + if (fts_close(fts) == -1) + err(1, "fts_close()"); + sleep(1); + } + return(0); +} + +static void * +calls(void *arg __unused) +{ + off_t offset; + time_t start; + int fd2; + + start = time(NULL); + while ((time(NULL) - start) < RUNTIME) { + fd2 = makearg() % nitems(fd) + 3; + offset = makearg(); + if (ftruncate(fd2, offset) == 0) { + if (lseek(fd2, offset - 1, SEEK_SET) != -1) + write(fd2, "x", 1); + } + + } + + return (0); +} + +int +main(int argc, char **argv) +{ + struct passwd *pw; + pthread_t rp, cp[THREADS]; + int e, i; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + args[0] = argv[1]; + args[1] = 0; + + if ((pw = getpwnam("nobody")) == NULL) + err(1, "failed to resolve nobody"); + 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(); + + if ((e = pthread_create(&rp, NULL, test, NULL)) != 0) + errc(1, e, "pthread_create"); + usleep(1000); + for (i = 0; i < THREADS; i++) + if ((e = pthread_create(&cp[i], NULL, calls, NULL)) != 0) + errc(1, e, "pthread_create"); + for (i = 0; i < THREADS; i++) + pthread_join(cp[i], NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/ftruncate2.sh b/tools/test/stress2/misc/ftruncate2.sh new file mode 100755 index 000000000000..c8c89e7ea5bd --- /dev/null +++ b/tools/test/stress2/misc/ftruncate2.sh @@ -0,0 +1,205 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 fuzz test triggered a failed block allocation unwinding problem. + +# "panic: ffs_blkfree_cg: freeing free block" seen: +# https://people.freebsd.org/~pho/stress/log/kostik923.txt +# Fixed by r304232. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > ftruncate2.c +rm -f /tmp/ftruncate2 +mycc -o ftruncate2 -Wall -Wextra -O2 -g ftruncate2.c -lpthread || exit 1 +rm -f ftruncate2.c + +echo "Expect: \"/mnt: write failed, filesystem is full\"" +mount | grep $mntpoint | grep -q "on $mntpoint " && umount -f $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs md${mdstart}$part > /dev/null # Non SU panics +mount /dev/md${mdstart}$part $mntpoint + +dir=$mntpoint +chmod 777 $dir + +cd $dir +jot 500 | xargs touch +jot 500 | xargs chmod 666 +cd $odir + +(cd /tmp; /tmp/ftruncate2 $dir) +e=$? + +rm -rf $dir/* + +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/ftruncate2 +exit $e +EOF +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +#define RUNTIME 180 +#define THREADS 2 + +static int fd[900]; +static u_int32_t r[N]; +static char *args[2]; + +static unsigned long +makearg(void) +{ + unsigned long val; + + val = arc4random(); +#if defined(__LP64__) + val = (val << 32) | arc4random(); + val = val & 0x00007fffffffffffUL; +#endif + + return(val); +} + +static void * +test(void *arg __unused) +{ + FTS *fts; + FTSENT *p; + int ftsoptions, i, n; + + ftsoptions = FTS_PHYSICAL; + + for (;;) { + for (i = 0; i < N; i++) + r[i] = arc4random(); + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + i = n = 0; + while ((p = fts_read(fts)) != NULL) { + if (fd[i] > 0) + close(fd[i]); + if ((fd[i] = open(p->fts_path, O_RDWR)) == -1) + if ((fd[i] = open(p->fts_path, O_WRONLY)) == -1) + continue; + if (ftruncate(fd[i], 0) != 0) + err(1, "ftruncate"); + i++; + i = i % nitems(fd); + } + + if (fts_close(fts) == -1) + err(1, "fts_close()"); + sleep(1); + } + return(0); +} + +static void * +calls(void *arg __unused) +{ + off_t offset; + time_t start; + int fd2; + + start = time(NULL); + while ((time(NULL) - start) < RUNTIME) { + fd2 = makearg() % nitems(fd) + 3; + offset = makearg(); + if (lseek(fd2, offset - 1, SEEK_SET) != -1) { + if (write(fd2, "x", 1) != 1) + if (errno != EBADF && errno != ENOSPC && errno != E2BIG && + errno != ESTALE && errno != EFBIG) + warn("write"); + } else + if (errno != EBADF) + warn("lseek"); + if (fsync(fd2) == -1) + if (errno != EBADF) + warn("x"); + } + + return (0); +} + +int +main(int argc, char **argv) +{ + struct passwd *pw; + pthread_t rp, cp[THREADS]; + int e, i; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + args[0] = argv[1]; + args[1] = 0; + + if ((pw = getpwnam("nobody")) == NULL) + err(1, "failed to resolve nobody"); + 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(); + + if ((e = pthread_create(&rp, NULL, test, NULL)) != 0) + errc(1, e, "pthread_create"); + usleep(1000); + for (i = 0; i < THREADS; i++) + if ((e = pthread_create(&cp[i], NULL, calls, NULL)) != 0) + errc(1, e, "pthread_create"); + for (i = 0; i < THREADS; i++) + pthread_join(cp[i], NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/fts.sh b/tools/test/stress2/misc/fts.sh new file mode 100755 index 000000000000..b823517f7c3c --- /dev/null +++ b/tools/test/stress2/misc/fts.sh @@ -0,0 +1,144 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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 + +# Run with marcus.cfg on a 1g swap backed MD +# "panic: vm_radix_remove: invalid key found" seen. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > fts1.c +mycc -o fts1 -Wall -Wextra fts1.c || exit 1 +rm -f fts1.c +cd $here + +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=20m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null & +pid=$! +while kill -0 $pid 2> /dev/null; do + /tmp/fts1 $mntpoint + sleep 1 +done +wait + +s=0 +for i in `jot 6`; do + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && s=1 +mdconfig -d -u $mdstart +rm -f /tmp/fts1 +exit $s +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +test(char *path) +{ + + FTS *fts; + FTSENT *p; + int ftsoptions; + char *args[2]; + + ftsoptions = FTS_PHYSICAL; + args[0] = path; + args[1] = 0; + + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) { + switch (p->fts_info) { + case FTS_F: /* Ignore. */ + break; + case FTS_D: /* Ignore. */ + break; + case FTS_DP: + break; + case FTS_DC: /* Ignore. */ + break; + case FTS_SL: /* Ignore. */ + break; + case FTS_DNR: /* Warn, continue. */ + case FTS_ERR: + case FTS_NS: + case FTS_DEFAULT: + break; + default: + printf("%s: default, %d\n", getprogname(), p->fts_info); + break; + } + } + + if (errno != 0 && errno != ENOENT) + err(1, "fts_read"); + if (fts_close(fts) == -1) + err(1, "fts_close()"); + + return (0); +} + +int +main(int argc, char **argv) +{ + int i; + + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + alarm(600); + for (i = 0; i < 100; i++) + test(argv[1]); + + return (0); +} diff --git a/tools/test/stress2/misc/fts2.sh b/tools/test/stress2/misc/fts2.sh new file mode 100755 index 000000000000..d155393e66ba --- /dev/null +++ b/tools/test/stress2/misc/fts2.sh @@ -0,0 +1,285 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Show invalid fts_info value: + +# FAULT +# -rw------- 1 root wheel - 4 13 jan 09:25 ./lockf.0.3676 +# fts_path: ./lockf.0.3676 +# fts_info: 13 FTS_SLNONE +# fts_errno: 0 No error: 0 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +cat > /tmp/fts2.c < +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 1 +#define PARALLEL 7 + +pid_t pid; +time_t start; +int fd; +char file[128]; + +char *txt[] = { + "NULL", + "FTS_D", + "FTS_DC", + "FTS_DEFAULT", + "FTS_DNR", + "FTS_DOT", + "FTS_DP", + "FTS_ERR", + "FTS_F", + "FTS_INIT", + "FTS_NS", + "FTS_NSOK", + "FTS_SL", + "FTS_SLNONE", + "FTS_W", + "15", + "16", + "17", +}; + +int +get(void) { + int sem; + if (lockf(fd, F_LOCK, 0) == -1) + err(1, "lockf(%s, F_LOCK)", file); + if (read(fd, &sem, sizeof(sem)) != sizeof(sem)) + err(1, "get: read(%d)", fd); + if (lseek(fd, 0, SEEK_SET) == -1) + err(1, "lseek"); + if (lockf(fd, F_ULOCK, 0) == -1) + err(1, "lockf(%s, F_ULOCK)", file); + return (sem); +} + +void +incr(void) { + int sem; + if (lockf(fd, F_LOCK, 0) == -1) + err(1, "lockf(%s, F_LOCK)", file); + if (read(fd, &sem, sizeof(sem)) != sizeof(sem)) + err(1, "incr: read(%d)", fd); + if (lseek(fd, 0, SEEK_SET) == -1) + err(1, "lseek"); + sem++; + if (write(fd, &sem, sizeof(sem)) != sizeof(sem)) + err(1, "incr: read"); + if (lseek(fd, 0, SEEK_SET) == -1) + err(1, "lseek"); + if (lockf(fd, F_ULOCK, 0) == -1) + err(1, "lockf(%s, F_ULOCK)", file); +} + +void +tlockf(void) +{ + int i; + int sem = 0; + + usleep(arc4random() % 10000); + sprintf(file, "lockf.0.%d", getpid()); + if ((fd = open(file,O_CREAT | O_TRUNC | O_RDWR, 0600)) == -1) + err(1, "creat(%s)", file); + if (write(fd, &sem, sizeof(sem)) != sizeof(sem)) + err(1, "write"); + if (lseek(fd, 0, SEEK_SET) == -1) + err(1, "lseek"); + + pid = fork(); + if (pid == -1) { + perror("fork"); + exit(2); + } + + if (pid == 0) { /* child */ + for (i = 0; i < 100; i++) { + while ((get() & 1) == 0) + ; + incr(); + } + exit(0); + } else { /* parent */ + for (i = 0; i < 100; i++) { + while ((get() & 1) == 1) + ; + incr(); + } + } + close(fd); + waitpid(pid, &i, 0); + unlink(file); +} + +void +tmkdir(void) +{ + pid_t pid; + int i, j; + char name[80]; + + setproctitle(__func__); + usleep(arc4random() % 10000); + pid = getpid(); + for (j = 0; j < LOOPS; j++) { + for (i = 0; i < 1000; i++) { + snprintf(name, sizeof(name), "dir.%d.%06d", pid, i); + if (mkdir(name, 0644) == -1) + err(1, "mkdir(%s)", name); + } + for (i = 0; i < 1000; i++) { + snprintf(name, sizeof(name), "dir.%d.%06d", pid, i); + if (rmdir(name) == -1) + err(1, "unlink(%s)", name); + } + } +} + +void +tfts(void) +{ + FTS *fts; + FTSENT *p; + int ftsoptions, i; + char *args[2]; + char help[80]; + + usleep(arc4random() % 10000); + ftsoptions = FTS_LOGICAL; + args[0] = "."; + args[1] = 0; + + for (i = 0; i < 10; i++) { + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) { + if (p->fts_info == FTS_D || /* preorder directory */ + p->fts_info == FTS_DNR || /* unreadable directory */ + p->fts_info == FTS_DOT || /* dot or dot-dot */ + p->fts_info == FTS_DP || /* postorder directory */ + p->fts_info == FTS_F || /* regular file */ + p->fts_info == FTS_NS) /* stat(2) failed */ + continue; + fprintf(stderr, "FAULT\n"); + sprintf(help, "ls -lo %s", p->fts_path); + system(help); + fprintf(stderr, "fts_path: %s\n", p->fts_path); + fprintf(stderr, "fts_info: %d %s\n", p->fts_info, + txt[p->fts_info]); + fprintf(stderr, "fts_errno: %d %s\n", p->fts_errno, + strerror(p->fts_errno)); + } + + if (errno != 0 && errno != ENOENT) + err(1, "fts_read"); + if (fts_close(fts) == -1) + err(1, "fts_close()"); + } +} + +void +test(void) +{ + + start = time(NULL); + if (fork() == 0) { + while (time(NULL) - start < 60) + tmkdir(); + _exit(0); + } + if (fork() == 0) { + while (time(NULL) - start < 60) + tlockf(); + _exit(0); + } + if (fork() == 0) { + while (time(NULL) - start < 60) + tfts(); + _exit(0); + } + + wait(NULL); + wait(NULL); + wait(NULL); + + _exit(0); +} + +int +main(void) +{ + int i; + + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + test(); + for (i = 0; i < PARALLEL; i++) + wait(NULL); + + return (0); +} +EOF +mycc -o /tmp/fts2 -Wall -Wextra -O0 -g /tmp/fts2.c || exit 1 + +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +(cd $mntpoint; /tmp/fts2) + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm /tmp/fts2 /tmp/fts2.c diff --git a/tools/test/stress2/misc/fts3.sh b/tools/test/stress2/misc/fts3.sh new file mode 100755 index 000000000000..4cb75d8bf6e6 --- /dev/null +++ b/tools/test/stress2/misc/fts3.sh @@ -0,0 +1,133 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 + +# No problems seen. + +. ../default.cfg + +[ -d /usr/include ] || exit 0 +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > fts3.c +mycc -o fts3 -Wall -Wextra fts3.c || exit 1 +rm -f fts3.c +cd $here + +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 3g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 120 ]; do + pids= + for i in `jot 20`; do + cp -r /usr/include $mntpoint/$i & + pids="$pids $!" + done + for p in $pids; do + wait $p + done + (cd $mntpoint && rm -rf *) +done & + +pid=$! +s=0 +while kill -0 $pid 2> /dev/null; do + /tmp/fts3 $mntpoint || { s=1; break; } +done +kill $pid > /dev/null 2>&1 +wait $pid + +for i in `jot 6`; do + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && s=2 +mdconfig -d -u $mdstart +rm -f /tmp/fts3 +exit $s +EOF +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +test(char *path) +{ + + FTS *fts; + FTSENT *p; + int ftsoptions; + char *args[2]; + + ftsoptions = FTS_PHYSICAL; + args[0] = path; + args[1] = 0; + + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) + ; + + if (errno != 0 && errno != ENOENT) + err(1, "fts_read"); + if (fts_close(fts) == -1) + err(1, "fts_close()"); + + return (0); +} + +int +main(int argc, char **argv) +{ + int i; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + alarm(120); + for (i = 0; i < 100; i++) + test(argv[1]); + + return (0); +} diff --git a/tools/test/stress2/misc/full.sh b/tools/test/stress2/misc/full.sh new file mode 100755 index 000000000000..ec99ff88138a --- /dev/null +++ b/tools/test/stress2/misc/full.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC +# All rights reserved. +# +# 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 + +# Run all tests from testcases on a 2g swap backed MD with UFS SU fs. + +# "panic: SACK scoreboard must not be empty" seen: +# https://people.freebsd.org/~pho/stress/log/full.txt +# Fixed by r310547. + +. ../default.cfg +kldstat -v | grep -q pty || kldload pty # ignore any load failure + +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export LOAD=80 +export rwLOAD=80 +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX +export MAXSWAPPCT=80 +export TESTPROGS=`cd ..; find testcases/ -perm -1 -type f | \ + egrep -v "/run/"` + +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' + +../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 +checkfs /dev/md${mdstart}$part; s=$? +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/fullpath.sh b/tools/test/stress2/misc/fullpath.sh new file mode 100755 index 000000000000..88cee4795009 --- /dev/null +++ b/tools/test/stress2/misc/fullpath.sh @@ -0,0 +1,111 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 scenario by marcus@freebsd.org + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -z "`type perl 2>/dev/null`" ] && exit 0 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > fullpath.c +mycc -o fullpath -Wall fullpath.c +rm -f fullpath.c +cd /proc + +for i in `jot 5`; do + /tmp/fullpath & +done + +for i in `jot 30`; do + for j in `jot 25`; do + pid=`perl -e 'print splice(@ARGV,rand(@ARGV),1), " ";' $(echo [0-9]*)` +# echo $pid + procstat -f $pid > /dev/null 2>&1 + procstat -f $pid > /dev/null 2>&1 + procstat -f $pid > /dev/null 2>&1 + procstat -f $pid > /dev/null 2>&1 + procstat -f $pid > /dev/null 2>&1 + done +done + +for i in `jot 5`; do + wait +done + +rm -f /tmp/fullpath +exit +EOF + +#include +#include +#include +#include +#include +#include +#include + +char buf[4096]; + +void +handler(int i) { + exit(0); +} + +int +test(void) { + pid_t r; + int status; + + for (;;) { + r = fork(); + if (r == 0) { + bzero(buf, sizeof(buf)); + exit(0); /*child dies */ + } + if (r < 0) { + perror("fork"); + exit(2); + } + wait(&status); + } + return 0; +} + +int main(int argc, char **argv) +{ + int i; + + i = 0; + signal(SIGALRM, handler); + alarm(60); + + return test(); +} diff --git a/tools/test/stress2/misc/fullpath2.sh b/tools/test/stress2/misc/fullpath2.sh new file mode 100755 index 000000000000..e4024c32f317 --- /dev/null +++ b/tools/test/stress2/misc/fullpath2.sh @@ -0,0 +1,214 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# fullpath NULL reference problem hunt. + +# From the commit log of r308407: +# vn_fullpath1() checked VV_ROOT and then unreferenced +# vp->v_mount->mnt_vnodecovered unlocked. This allowed unmount to race. +# Lock vnode after we noticed the VV_ROOT flag. See comments for +# explanation why unlocked check for the flag is considered safe. + +# 'panic: namei: garbage in ni_resflags: 1': +# https://people.freebsd.org/~pho/stress/log/fullpath2.txt +# Fixed by r367130 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +cont=/tmp/fullpath2.continue +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/fullpath2.c +mycc -o fullpath2 -Wall -Wextra -O2 -g fullpath2.c -lprocstat || exit 1 +rm -f fullpath2.c +cd $odir + +mount | grep -q "on $mntpoint " && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +gpart create -s GPT md$mdstart > /dev/null || exit 1 +gpart add -t freebsd-ufs md$mdstart > /dev/null || exit 1 +newfs -n $newfs_flags md${mdstart}p1 > /dev/null || exit 1 +mount /dev/md${mdstart}p1 $mntpoint +touch $mntpoint/marker $cont +trap "rm -f $cont" EXIT INT + +daemon sh -c "(cd $odir/../testcases/swap; ./swap -t 4m -i 10 -l 100)" > \ + /dev/null 2>&1 + +for i in `jot $(jot -r 1 2 10)`; do + /tmp/fullpath2 $mntpoint & + pids="$pids $!" +done + +for i in `jot $(jot -r 1 2 5)`; do + while [ -e $cont ]; do find $mntpoint -ls > /dev/null 2>&1; done & + pidf="$pidf $!" +done + +umounts=0 +while pgrep -q fullpath2; do + for i in `jot 30`; do + umount -f $mntpoint && umounts=$((umounts+1)) && + mount /dev/md${mdstart}p1 $mntpoint + sleep 2 + done +done +echo "$umounts umounts" +rm -f $cont +while mount | grep -q "on $mntpoint "; do + umount -f $mntpoint +done +for i in $pids; do + wait $i +done +while pgrep -q swap; do + pkill -9 swap +done + +kill $pidp $pidf > /dev/null 2>&1 +wait + +rm -f $mntpoint/file.* /tmp/fullpath2 fullpath2.core +mdconfig -d -u $mdstart + +exit 0 +EOF +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; + +#define NB 1024 +#define RUNTIME 300 + +/* dtrace -w -n 'fbt::*vn_fullpath1:entry {@rw[execname,probefunc] = count(); }' */ + +static void +getfiles(pid_t pid) +{ + struct filestat_list *head; + struct kinfo_proc *p; + struct procstat *prstat; + unsigned int cnt; + + if ((prstat = procstat_open_sysctl()) == NULL) + err(1, "procstat_open_sysctl"); + + if ((p = procstat_getprocs(prstat, KERN_PROC_PID, + pid, &cnt)) == NULL) + err(1, "procstat_getprocs"); + + if ((head = procstat_getfiles(prstat, p, 0)) == NULL) + err(1, "procstat_getfiles"); + + procstat_freefiles(prstat, head); + procstat_freeprocs(prstat, p); + procstat_close(prstat); +} + +int +main(int argc, char *argv[]) +{ + size_t len; + time_t start; + int fd[NB], i, n; + pid_t pid; + + len = PAGE_SIZE; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + if ((pid = fork()) == 0) { + setproctitle("getfiles"); + while (share[0] == 0) + getfiles(pid); + _exit(0); + } + + char file[MAXPATHLEN + 1]; + char marker[MAXPATHLEN + 1]; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + memset(fd, 0, sizeof(fd)); + snprintf(marker, sizeof(marker), "%s/marker", argv[1]); + i = n = 0; + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + snprintf(file, sizeof(file), "%s/file.%06d.%02d", argv[1], getpid(), i); + if (access(marker, R_OK) == -1) + continue; + if (fd[i] > 0) + close(fd[i]); + if ((fd[i] = open(file, O_RDWR | O_CREAT | O_APPEND, + DEFFILEMODE)) == -1) { + if (errno != ENOENT && errno != EBUSY) + warn("open(%s)", file); + continue; + } + n++; + write(fd[i], "a", 1); + usleep(arc4random() % 400); + if (arc4random() % 100 < 10) { + close(fd[i]); + unlink(file); + fd[i] = 0; + } + i++; + i = i % NB; + } + share[0] = 1; + + if (waitpid(pid, NULL, 0) != pid) + err(1, "waitpid"); + if (n < 100) + errx(1, "Short run: %d", n); + + return (0); +} diff --git a/tools/test/stress2/misc/fuse.sh b/tools/test/stress2/misc/fuse.sh new file mode 100755 index 000000000000..682fdb122845 --- /dev/null +++ b/tools/test/stress2/misc/fuse.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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. +# + +# General Fuse test scenario + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "`type mkntfs 2>/dev/null`" ] && exit 0 +[ -c /dev/fuse ] || kldload fuse.ko + +MOUNT=/usr/local/bin/ntfs-3g + +mount | grep -q "$mntpoint" && umount $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +mkntfs -Ff /dev/md$mdstart > /dev/null 2>&1 || exit 1 + +$MOUNT /dev/md$mdstart $mntpoint || exit 1 + +export RUNDIR=$mntpoint/stressX +export runRUNTIME=20m +(cd ..; ./run.sh marcus.cfg) +rm -rf $RUNDIR + +for i in `jot 10`; do + umount $mntpoint || sleep 2 + mount | grep -q $mntpoint || break +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/fuse2.sh b/tools/test/stress2/misc/fuse2.sh new file mode 100755 index 000000000000..3bd54fa080f5 --- /dev/null +++ b/tools/test/stress2/misc/fuse2.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 +# livelock seen + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +[ -z "`type mkntfs 2>/dev/null`" ] && exit 0 +[ -c /dev/fuse ] || kldload fuse.ko + +. ../default.cfg + +[ -c /dev/fuse ] || kldload fuse.ko +MOUNT=/usr/local/bin/ntfs-3g +mounts=15 # Number of parallel scripts +mdstart=$mdstart # Use md unit numbers from this point + +if [ $# -eq 0 ]; then + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + [ ! -d ${mntpoint}$m ] && mkdir ${mntpoint}$m + mount | grep "$mntpoint" | grep -q md$m && umount ${mntpoint}$m + mdconfig -l | grep -q md$m && mdconfig -d -u $m + + mdconfig -a -t swap -s 1g -u $m + mkntfs -Ff /dev/md$m > /dev/null 2>&1 || exit 1 + + done + + # start the parallel tests + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + ./$0 $m & + ./$0 find & + done + wait + + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + mdconfig -d -u $m + done + +else + if [ $1 = find ]; then + while mount | grep -q fusefs; do + find ${mntpoint}* -type f > /dev/null 2>&1 + sleep 1 + done + else + + # The test: Parallel mount and unmounts + for i in `jot 100`; do + m=$1 + $MOUNT /dev/md$m ${mntpoint}$m || continue + cp -r /usr/include/sys ${mntpoint}$m/file.$m 2>/dev/null + sleep .5 + while mount | grep -q ${mntpoint}$m; do + umount ${mntpoint}$m > /dev/null 2>&1 || + sleep 1 + done + done + fi +fi diff --git a/tools/test/stress2/misc/fuse3.sh b/tools/test/stress2/misc/fuse3.sh new file mode 100755 index 000000000000..d11e9f4140f7 --- /dev/null +++ b/tools/test/stress2/misc/fuse3.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 FUSE memory corruption. +# http://people.freebsd.org/~pho/stress/log/fuse3.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +# Start page stealer +(cd ../testcases/swap; ./swap -t 10m -i 20 -h) & +sleep 10 + +while pgrep -q swap; do + kldload fuse.ko + kldunload fuse.ko +done +wait diff --git a/tools/test/stress2/misc/fuzz.sh b/tools/test/stress2/misc/fuzz.sh new file mode 100755 index 000000000000..bfe783752280 --- /dev/null +++ b/tools/test/stress2/misc/fuzz.sh @@ -0,0 +1,180 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Stress test UFS2 file systems by introducing single bit errors in the FS +# fsck should fix the FS no matter how damaged, but e.g. this panic has been seen: +# +# panic(c0912b65,dfe96000,0,c09e4060,ef48c778,...) at panic+0x14b +# vm_fault(c1868000,dfe96000,1,0) at vm_fault+0x1e0 +# trap_pfault(ef48c894,0,dfe96000) at trap_pfault+0x137 +# trap(dfe90008,ef480028,c0690028,d0560000,dfe96000,...) at trap+0x341 +# calltrap() at calltrap+0x5 +# --- trap 0xc, eip = 0xc08785a6, esp = 0xef48c8d4, ebp = 0xef48c958 --- +# generic_bcopy(c81cd570,d0508000,c5ead600,c87b81c0,0,...) at generic_bcopy+0x1a +# ffs_mount(d0508000,c5ead600,0,c09b0860,c5ecfc3c,...) at ffs_mount+0xa14 +# vfs_domount(c5ead600,cd8c7280,ccb75080,0,...) at vfs_domount+0x687 +# vfs_donmount(c5ead600,0,ef48cc04) at vfs_donmount+0x2ef +# kernel_mount(c5660960,0,bfbfec86,0,fffffffe,...) at kernel_mount+0x6d +# ffs_cmount(c5660960,bfbfde50,0,c5ead600,c09b0860,...) at ffs_cmount+0x5d +# mount(c5ead600,ef48cd04) at mount+0x156 +# syscall(3b,3b,3b,804abcf,bfbfe8e4,...) at syscall+0x22f + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +D=$diskimage + +tst() { + rm -f $D + truncate -s 2M $D + mdconfig -a -t vnode -f $D -u $mdstart + bsdlabel -w md$mdstart auto + newfs -b 8192 -f 1024 $newfs_flags /dev/md${mdstart}$part > /dev/null 2>&1 + mount /dev/md${mdstart}$part $mntpoint + cp /etc/passwd /etc/group /etc/hosts $mntpoint + cp -r /usr/include/ufs $mntpoint + umount $mntpoint + + for i in `jot 50`; do + ./fuzz -n 50 $D + if fsck -f -y /dev/md${mdstart}$part 2>&1 | egrep "^[A-Z]" > /dev/null; then + if fsck -f -y /dev/md${mdstart}$part 2>&1 | egrep "^[A-Z]" > /dev/null; then + if fsck -f -y /dev/md${mdstart}$part 2>&1 | egrep "^[A-Z]" > /dev/null; then + echo "fsck is giving up in loop $i!" + break + fi + fi + fi + sync;sync;sync + if mount /dev/md${mdstart}$part $mntpoint; then + ls -l $mntpoint > /dev/null + find $mntpoint -exec dd if={} of=/dev/null bs=1m count=3 \; > /dev/null 2>&1 + umount $mntpoint + else + echo "Giving up at loop $i" + break + fi + done + mdconfig -d -u $mdstart + rm -f $D +} + +odir=`pwd` +dir=/tmp + +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/fuzz.c +mycc -o fuzz -Wall fuzz.c +rm -f fuzz.c + +for j in `jot 10`; do + date '+%T' + tst +done +rm -f fuzz + +exit + +EOF +#include + +#include +#include +#include +#include +#include + +static void +usage(void) +{ + fprintf(stderr, "%s {-n \n", getprogname()); + exit(1); +} + +static long +random_long(long mi, long ma) +{ + return (arc4random() % (ma - mi + 1) + mi); +} + +int +main(int argc, char **argv) +{ + long pos; + int ch, fd, i, times = 1, verbose = 0; + unsigned char bit, buf, mask, old; + struct stat sb; + + while ((ch = getopt(argc, argv, "n:v")) != -1) { + switch(ch) { + case 'n': /* Bits to alter */ + if (sscanf(optarg, "%d", ×) != 1) + usage(); + break; + case 'v': /* verbose flag */ + verbose += 1; + break; + default: + usage(); + } + } + argc -= optind; + argv += optind; + + if (argc == 0) + usage(); + + if ((fd = open(argv[0], O_RDWR)) == -1) + err(1, "open(%s)", argv[0]); + if (fstat(fd, &sb) == -1) + err(1, "stat(%s)", argv[0]); + + for (i = 0; i < times; i++) { + pos = random_long(0, sb.st_size - 1); + if (lseek(fd, pos, SEEK_SET) == -1) + err(1, "fseek(%d, %ld)", fd, pos); + if (read(fd, &buf, 1) != 1) + err(1, "read(%d)", fd); + bit = random_long(0,7); + mask = ~(1 << bit); + old = buf; + buf = (buf & mask) | (~buf & ~mask); + if (verbose > 0) + printf("Change %2x to %2x at %4ld " + "by flipping bit %d\n", + old, buf, pos, bit); + if (lseek(fd, pos, SEEK_SET) == -1) + err(1, "fseek(%d, %ld)", fd, pos); + if (write(fd, &buf, 1) != 1) + err(1, "write(%d)", fd); + } + close(fd); + + return (0); +} diff --git a/tools/test/stress2/misc/gbde.sh b/tools/test/stress2/misc/gbde.sh new file mode 100755 index 000000000000..f47d8e9e15bf --- /dev/null +++ b/tools/test/stress2/misc/gbde.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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: 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 +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/geli.sh b/tools/test/stress2/misc/geli.sh new file mode 100755 index 000000000000..381bd1ea5f8e --- /dev/null +++ b/tools/test/stress2/misc/geli.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 + +# Simple geli(8) test +# WIP No problems seen. + +. ../default.cfg + +kldstat -v | grep -q g_eli || + { geli load && unload=1 || exit 0; } +set -e +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart + +dd if=/dev/random of=/tmp/geli.key bs=64 count=1 > /dev/null 2>&1 +echo test | geli init -s 4096 -J - -K /tmp/geli.key /dev/md$mdstart > \ + /dev/null +echo test | geli attach -j - -k /tmp/geli.key /dev/md$mdstart +newfs $newfs_flags /dev/md$mdstart.eli > /dev/null + +mount /dev/md${mdstart}.eli $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=5m + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1 & +sleep 300 +../tools/killall.sh +wait + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +set +e +checkfs /dev/md${mdstart}.eli; s=$? +geli kill /dev/md$mdstart.eli +mdconfig -d -u $mdstart +rm -f /tmp/geli.key +[ $unload ] && geli unload +exit $s diff --git a/tools/test/stress2/misc/geomleak.sh b/tools/test/stress2/misc/geomleak.sh new file mode 100755 index 000000000000..0961bc58f8bf --- /dev/null +++ b/tools/test/stress2/misc/geomleak.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# GEOM leak regression test. +# The problem was introduced in r328426 and fixed by r329375. + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 + +set -e +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +old=`vmstat -m | awk '/GEOM/{print $2}'` +for i in `jot 50`; do + mdconfig -a -t swap -s 500m -u $mdstart + newfs $newfs_flags /dev/md$mdstart > /dev/null 2>&1 + mdconfig -d -u $mdstart +done +set +e +new=`vmstat -m | awk '/GEOM/{print $2}'` +if [ $((new - old)) -gt 5 ]; then + s=1 + echo "InUse changed from $old to $new, leaking $((new - old)) GEOMs" +else + s=0 +fi +exit $s diff --git a/tools/test/stress2/misc/geomleak2.sh b/tools/test/stress2/misc/geomleak2.sh new file mode 100755 index 000000000000..19b6f03d6333 --- /dev/null +++ b/tools/test/stress2/misc/geomleak2.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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 + +old=`vmstat -m | awk '/GEOM/{print $2}'` +set -e +mount | grep -q "on $mntpoint " && umount $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart +newfs -U /dev/md$mdstart > /dev/null +set +e +start=` date +%s` +while [ $((`date +%s` - start)) -lt 60 ]; do + mount /dev/md$mdstart $mntpoint + while mount | grep -q "on $mntpoint "; do + umount $mntpoint + done +done +mdconfig -d -u $mdstart + +new=`vmstat -m | awk '/GEOM/{print $2}'` +if [ $((new - old)) -gt 5 ]; then + s=1 + vmstat -m | sed -n '1p;/GEOM/p' +else + s=0 +fi +exit $s diff --git a/tools/test/stress2/misc/getrandom.sh b/tools/test/stress2/misc/getrandom.sh new file mode 100755 index 000000000000..fe30a688decb --- /dev/null +++ b/tools/test/stress2/misc/getrandom.sh @@ -0,0 +1,142 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# getrandom() non threaded test +# Reset seen on i386 + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 +[ `uname -m` = "i386" ] || exit 0 + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/getrandom.c +mycc -o getrandom -Wall -Wextra -O0 -g getrandom.c || exit 1 +rm -f getrandom.c +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +set +e + +(cd $odir/../testcases/swap; ./swap -t 5m -i 40 -l 100) & +cd $mntpoint +timeout 5m limits -c 0 $dir/getrandom +s=0 +while pgrep -q swap; do pkill swap; done +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 +rm -rf $dir/getrandom +exit $s + +EOF +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; + +#define PARALLEL 50 +#define RUNTIME (5 * 60) +#define SYNC 0 + +static void +test(void) +{ + time_t start; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + alarm(65); + start = time(NULL); + while ((time(NULL) - start) < 60) + getrandom((void *)arc4random(), arc4random(), arc4random() & 3); + + _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) { + 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]); + e += status == 0 ? 0 : 1; + } + } + + return (e); +} diff --git a/tools/test/stress2/misc/getrandom2.sh b/tools/test/stress2/misc/getrandom2.sh new file mode 100755 index 000000000000..941ffb737a6d --- /dev/null +++ b/tools/test/stress2/misc/getrandom2.sh @@ -0,0 +1,188 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +# getrandom(2) DoS scenario. + +# panic: pmap_growkernel: no memory to grow kernel +# cpuid = 8 +# time = 1582102582 +# KDB: stack backtrace: +# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe03e6992450 +# vpanic() at vpanic+0x185/frame 0xfffffe03e69924b0 +# panic() at panic+0x43/frame 0xfffffe03e6992510 +# pmap_growkernel() at pmap_growkernel+0x2d4/frame 0xfffffe03e6992550 +# vm_map_insert() at vm_map_insert+0x296/frame 0xfffffe03e69925f0 +# vm_map_find() at vm_map_find+0x617/frame 0xfffffe03e69926d0 +# kva_import() at kva_import+0x3c/frame 0xfffffe03e6992710 +# vmem_try_fetch() at vmem_try_fetch+0xde/frame 0xfffffe03e6992760 +# vmem_xalloc() at vmem_xalloc+0x4bb/frame 0xfffffe03e69927e0 +# kva_import_domain() at kva_import_domain+0x36/frame 0xfffffe03e6992810 +# vmem_try_fetch() at vmem_try_fetch+0xde/frame 0xfffffe03e6992860 +# vmem_xalloc() at vmem_xalloc+0x4bb/frame 0xfffffe03e69928e0 +# vmem_alloc() at vmem_alloc+0x8a/frame 0xfffffe03e6992930 +# kmem_malloc_domainset() at kmem_malloc_domainset+0x92/frame 0xfffffe03e69929a0 +# malloc() at malloc+0x162/frame 0xfffffe03e69929f0 +# read_random_uio() at read_random_uio+0xa5/frame 0xfffffe03e6992a40 +# sys_getrandom() at sys_getrandom+0x7b/frame 0xfffffe03e6992ac0 +# amd64_syscall() at amd64_syscall+0x183/frame 0xfffffe03e6992bf0 +# fast_syscall_common() at fast_syscall_common+0x101/frame 0xfffffe03e6992bf0 +# --- syscall (563, FreeBSD ELF64, sys_getrandom), rip = 0x80041899a, rsp = 0x7ffffffc3cb8, rbp = 0x7ffffffc3cd0 --- +# KDB: enter: panic +# [ thread pid 12095 tid 186584 ] +# Stopped at kdb_enter+0x37: movq $0,0x1084916(%rip) +# db> x/s version +# version: FreeBSD 13.0-CURRENT #0 r358094: Wed Feb 19 06:25:16 CET 2020\012 pho@t2.osted.lan:/usr/src/sys/amd64/compile/PHO\012 +# db> + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/getrandom2.c +mycc -o getrandom2 -Wall -Wextra -O0 -g getrandom2.c || exit 1 +rm -f getrandom2.c +cd $odir + +cd /tmp +$dir/getrandom2 +s=$? +[ -f getrandom2.core -a $s -eq 0 ] && + { ls -l getrandom2.core; s=1; } +cd $odir + +rm -rf $dir/getrandom2 +exit $s + +EOF +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static size_t mx; +static _Atomic(int) *share; +static int parallel; +static char *bp; + +#define PARALLEL 40000 /* Arbitrary cap */ +#define SYNC 0 + +static void +test(void) +{ + int i; + + alarm(180); + (void)atomic_fetch_add(&share[SYNC], 1); + while (atomic_load(&share[SYNC]) != parallel) + usleep(200000); + for (i = 0; i < 10; i++) + getrandom(bp, mx, 0); +// close(66); + + _exit(0); +} + +int +main(void) +{ + pid_t *pids; + struct rlimit rlp; + size_t len; + size_t f, vsz; + u_int pages; + 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"); + + if (getrlimit(RLIMIT_NPROC, &rlp) < 0) + err(1, "getrlimit"); + parallel = rlp.rlim_cur / 100 * 80; + if (parallel > PARALLEL) + parallel = PARALLEL; + pids = calloc(parallel, sizeof(pid_t)); + + vsz = sizeof(pages); + if (sysctlbyname("vm.stats.vm.v_free_count", &pages, &vsz, NULL, 0) != 0) + err(1, "sysctl(vm.stats.vm.v_free_count)"); + f = pages; + f *= PAGE_SIZE; + + if (getrlimit(RLIMIT_DATA, &rlp) < 0) + err(1,"getrlimit"); + mx = rlp.rlim_cur; + if (mx > f / parallel) + mx = f / parallel; + if ((bp = mmap(NULL, mx, PROT_READ | PROT_WRITE, MAP_ANON, -1, + 0)) == MAP_FAILED) + err(1, "mmap"); + for (;;) { + if (getrandom(bp, mx, 0) != -1) + break; + mx = mx / 2; + } + printf("Max getrandom() buffer size is %zu, %d threads\n", mx, + parallel); + 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); +} diff --git a/tools/test/stress2/misc/gjournal.sh b/tools/test/stress2/misc/gjournal.sh new file mode 100755 index 000000000000..7ccc7a70760e --- /dev/null +++ b/tools/test/stress2/misc/gjournal.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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. +# + +# Deadlock scenario based on kern/154228, fixed in r217880. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +size="2g" +[ `swapinfo | wc -l` -eq 1 ] && exit 0 +[ `swapinfo -k | tail -1 | awk '{print int($4/1024/1024)}'` -lt \ + ${size%g} ] && exit 0 +m=$((mdstart + 1)) +mp2=${mntpoint}$m +mount | grep $mp2 | grep -q /dev/md && umount -f $mp2 +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +[ -c /dev/md$m ] && mdconfig -d -u $m +mkdir -p $mp2 +mdconfig -a -t swap -s $size -u $mdstart || exit 1 + +gjournal load +gjournal label -s 512m md$mdstart +sleep .5 +newfs -J /dev/md$mdstart.journal > /dev/null +mount -o async /dev/md$mdstart.journal $mntpoint + +here=`pwd` +cd $mntpoint +dd if=/dev/zero of=image bs=1m count=1k status=none +mdconfig -a -t vnode -f image -u $m +bsdlabel -w md$m auto +newfs md${m}$part > /dev/null +mount /dev/md${m}$part $mp2 +# dd will suspend in wdrain +echo "Expect \"$mp2: write failed, filesystem is full\"" +dd if=/dev/zero of=$mp2/zero bs=1M > /dev/null 2>&1 +while mount | grep $mp2 | grep -q /dev/md; do + umount $mp2 || sleep 1 +done +mdconfig -d -u $m +cd $here + +gjournal sync +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +gjournal stop md$mdstart +gjournal unload +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/gjournal2.sh b/tools/test/stress2/misc/gjournal2.sh new file mode 100755 index 000000000000..48d45dc4fab5 --- /dev/null +++ b/tools/test/stress2/misc/gjournal2.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# File system corruption seen + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ `swapinfo | wc -l` -eq 1 ] && exit 0 +size="5g" +jsize="3g" +[ $((`sysctl -n hw.usermem` / 1024 / 1024 / 1024)) -le ${size%g} ] && exit 0 +[ `swapinfo -k | tail -1 | awk '{print int($4/1024/1024)}'` -lt \ + ${size%g} ] && exit 0 +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s $size -u $mdstart || exit 1 + +gjournal load +gjournal label -s $jsize md$mdstart +sleep .5 +newfs -J /dev/md$mdstart.journal > /dev/null +mount -o async /dev/md$mdstart.journal $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1 + +gjournal sync +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +gjournal stop md$mdstart +gjournal unload +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/gjournal3.sh b/tools/test/stress2/misc/gjournal3.sh new file mode 100755 index 000000000000..a2ed7f57098c --- /dev/null +++ b/tools/test/stress2/misc/gjournal3.sh @@ -0,0 +1,85 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# Deadlock seen: http://people.freebsd.org/~pho/stress/log/gjournal3.txt +# Fixed in r244925 + +# panic: Bio not on queue +# https://people.freebsd.org/~pho/stress/log/gjournal3-2.txt + +# kib@ wrote: +# gjournal is good for exposing the suspension problems. The frequency +# of the suspensions called from the gjournal is not achievable by other +# methods, so the tests allow to uncover the problems. More, the gjournal +# only establishes the suspension, without snapshotting, which also +# makes it easier to see the issues. + +# gjournal / ffs snapshot suspension deadlock: +# https://people.freebsd.org/~pho/stress/log/gjournal3-4.txt +# Originally reported as kern/164252. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ `swapinfo | wc -l` -eq 1 ] && exit 0 +size="12g" +jsize="8g" +[ $((`sysctl -n hw.usermem` / 1024 / 1024 / 1024)) -le ${size%g} ] && exit 0 +[ `swapinfo -k | tail -1 | awk '{print int($4/1024/1024)}'` -lt \ + ${size%g} ] && exit 0 +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/mdmd$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s $size -u $mdstart || exit 1 + +gjournal load +gjournal label -s $jsize md$mdstart +sleep .5 +newfs -J /dev/md$mdstart.journal > /dev/null +mount -o async /dev/md$mdstart.journal $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ../testcases/rw + ./rw -t 2m -i 10 -l 100 > /dev/null 2>&1' & +while kill -0 $! 2>/dev/null; do + mksnap_ffs $mntpoint $mntpoint/.snap/snap + sleep .2 + rm -f $mntpoint/.snap/snap +done +wait + +gjournal sync +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +gjournal stop md$mdstart +gjournal unload +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/gjournal4.sh b/tools/test/stress2/misc/gjournal4.sh new file mode 100755 index 000000000000..80dbcafba904 --- /dev/null +++ b/tools/test/stress2/misc/gjournal4.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Experiment with a sparse MD disk. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `sysctl -n vm.swap_total` -eq 0 ] && exit 0 +[ `sysctl -n hw.physmem` -lt $(( 4 * 1024 * 1024 * 1024)) ] && exit 0 + +. ../default.cfg + +size="100g" +jsize="10g" +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s $size -u $mdstart || exit 1 + +gjournal load +gjournal label -s $jsize md$mdstart +sleep .5 +newfs -J /dev/md$mdstart.journal > /dev/null +mount -o async /dev/md$mdstart.journal $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX +export CTRLDIR=$mntpoint/stressX.control +export swapINCARNATIONS=5 + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1 + +gjournal sync +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +checkfs /dev/md$mdstart.journal && s=0 || s=$? +gjournal stop md$mdstart +gjournal unload +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/gnop.sh b/tools/test/stress2/misc/gnop.sh new file mode 100755 index 000000000000..216bcf481ea0 --- /dev/null +++ b/tools/test/stress2/misc/gnop.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 with different sector size using gnop(8). +# Out of VM seen: +# https://people.freebsd.org/~pho/stress/log/gnop.txt + +flag=/tmp/gnop.sh.flag +test() { + . ../default.cfg + + start=`date +%s` + set -e + mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint + [ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + + mdconfig -a -t swap -s 2g -u $mdstart + gnop create -S $1 /dev/md$mdstart + newfs $newfs_flags /dev/md$mdstart.nop > /dev/null + mount /dev/md$mdstart.nop $mntpoint + chmod 777 $mntpoint + set +e + + export runRUNTIME=4m + export RUNDIR=$mntpoint/stressX + + su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1 + + while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 + done + checkfs /dev/md$mdstart.nop || touch $flag + gnop destroy /dev/md$mdstart.nop + mdconfig -d -u $mdstart + t=`date +%s` + echo "Elapsed `date -u -j -f '%s' '+%H:%M' $((t - start))`" +} + +kldstat | grep -q geom_nop || { gnop load 2>/dev/null || exit 0 && + notloaded=1; } +gnop status || exit 1 + +for i in 1k 2k 4k 8k; do + test $i +done + +[ $notloaded ] && gnop unload +[ -f $flag ] && s=1 || s=0 +rm -f $flag +exit $s diff --git a/tools/test/stress2/misc/gnop10.sh b/tools/test/stress2/misc/gnop10.sh new file mode 100755 index 000000000000..80ddc2fe1216 --- /dev/null +++ b/tools/test/stress2/misc/gnop10.sh @@ -0,0 +1,139 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# fsck test with forced unmount of a SUJ FS. +# Variation of gnop8.sh by Kirk McKusick + +# Copy of gnop9.sh. Uses SU instead of SUJ. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +# Check for lingering threads from the last run +pgrep -x mount && { pgrep -x mount | xargs ps -lp; exit 1; } +../tools/killall.sh || exit 1 + +fsck=/sbin/fsck_ffs +fsck_loops=10 +exp=/sbin/fsck_ffs.exp # Experimental version +log=/tmp/gnop10.log +[ -f $exp ] && { echo "Using $exp"; fsck=$exp; } +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 5g -u $mdstart || exit 1 +md=md$mdstart +newfs -U /dev/$md > /dev/null 2>&1 || exit 1 + +export LOAD=80 +export rwLOAD=80 +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX +export CTRLDIR=$mntpoint/stressX.control +export MAXSWAPPCT=80 +export TESTPROGS=' +testcases/lockf2/lockf2 +testcases/symlink/symlink +testcases/openat/openat +testcases/socket/socket +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 +' + +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$(($1 / 10 * 7)) +export INODES=$(($2 / 10 * 7)) + +start=`date +%s` +while [ $((`date +%s` - start)) -lt 600 ]; do + gnop create /dev/$md || exit 1 + mount /dev/$md.nop $mntpoint || exit 1 + mkdir -p $RUNDIR $CTRLDIR + chmod 777 $RUNDIR $CTRLDIR + + # start your favorite I/O test here + rm -rf /tmp/stressX.control + (cd $RUNDIR && find . -delete) + + su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' & + + # after some number of seconds + sleep `jot -r 1 30 90` + gnop destroy -f /dev/$md.nop + ../tools/killall.sh || exit 1 + wait + + # Wait until forcible unmount, may be up to about 30 seconds, + # but typically very quick if I/O is in progress + s=`date +%s` + n=0 + 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` - s)) -ge 180 ]; then + echo "Giving up on waiting for umount of $mntpoint" + umount $mntpoint || umount -f $mntpoint + break + fi + done + [ $n -ne 0 ] && echo + + # first fsck will attempt journal recovery + $fsck -fy /dev/$md > $log 2>&1 + + # The second fsck will do traditional check for any errors + # from journal recovery + + # There seems to be a gnop cache issue, which resolves by adding + # delays between each fsck run + for i in `jot $fsck_loops`; do + sleep $((i * i)) # gnop workaround + [ $i -ne 1 ] && + echo "`date +%T` $fsck loop #$((i + 1))" + $fsck -fy /dev/$md > $log 2>&1 + grep -Eq "IS CLEAN|MARKED CLEAN" $log && break + [ $i -eq $fsck_loops ] && + { echo "$fsck did not mark FS as clean"; exit 1; } + [ $i -ne 1 ] && tail -3 $log + sync; sleep 5; sync; sleep 5 + done +done +echo "Final $fsck" +sleep 3; # gnop workaround +$fsck -fy /dev/$md > $log || { tail -5 $log; exit 1; } +mdconfig -d -u ${md#md} +rm -f $log +exit 0 diff --git a/tools/test/stress2/misc/gnop2.sh b/tools/test/stress2/misc/gnop2.sh new file mode 100755 index 000000000000..d38754d58456 --- /dev/null +++ b/tools/test/stress2/misc/gnop2.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC +# All rights reserved. +# +# 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 + +# "panic: vnode_pager_generic_getpages: sector size 8192 too large" seen +# with an 8k sector size: +# https://people.freebsd.org/~pho/stress/log/gnop2.txt +# Fixed by r307626 + +. ../default.cfg + +kldstat | grep -q geom_nop || { gnop load 2>/dev/null || exit 0 && + notloaded=1; } +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/mmap5.sh > $dir/gnop2.c +mycc -o gnop2 -Wall -Wextra gnop2.c || exit 1 +rm -f gnop2.c +cd $odir + +test() { + . ../default.cfg + + mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint + [ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + + set -e + mdconfig -a -t swap -s 2g -u $mdstart + gnop create -S $1 /dev/md$mdstart + newfs $newfs_flags /dev/md$mdstart.nop > /dev/null + mount /dev/md$mdstart.nop $mntpoint + chmod 777 $mntpoint + set +e + + dd if=/dev/zero of=$mntpoint/file bs=1k count=333 status=none + /tmp/gnop2 $mntpoint/file + + while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 + done + gnop destroy /dev/md$mdstart.nop + mdconfig -d -u $mdstart +} + +gnop status || exit 1 + +for i in 1k 2k 4k 8k; do + test $i +done + +[ $notloaded ] && gnop unload +rm -f /tmp/gnop2 +exit 0 diff --git a/tools/test/stress2/misc/gnop3.sh b/tools/test/stress2/misc/gnop3.sh new file mode 100755 index 000000000000..3d22e4a74331 --- /dev/null +++ b/tools/test/stress2/misc/gnop3.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC +# All rights reserved. +# +# 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 + +# A 8k sector size test. +# "panic: run 8 0xfffff80ff3d1e040 invalid" seen during fix development. + +# OOM: https://people.freebsd.org/~pho/stress/log/gnop3.txt + +. ../default.cfg + +# OOM seen with RAM == 32g +[ $((`sysctl -n hw.usermem` / 1024 / 1024 / 1024)) -lt 32 ] && exit 0 +[ $((`sysctl -n vm.swap_total` / 1024 / 1024 / 1024)) -lt 9 ] && exit 0 + +kldstat | grep -q geom_nop || { gnop load 2>/dev/null || exit 0 && + notloaded=1; } +gnop status || exit 1 + +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +set -e +mdconfig -a -t swap -s 8g -u $mdstart +gnop create -S 8k /dev/md$mdstart +newfs $newfs_flags /dev/md$mdstart.nop > /dev/null +mount /dev/md$mdstart.nop $mntpoint +chmod 777 $mntpoint +set +e + +cp -a ../../stress2 $mntpoint +here=`pwd` +cd $mntpoint/stress2/misc + +export runRUNTIME=20m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' + +cd $here +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +gnop destroy /dev/md$mdstart.nop +mdconfig -d -u $mdstart +[ $notloaded ] && gnop unload +exit 0 diff --git a/tools/test/stress2/misc/gnop4.sh b/tools/test/stress2/misc/gnop4.sh new file mode 100755 index 000000000000..2e4cc1a5df35 --- /dev/null +++ b/tools/test/stress2/misc/gnop4.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC +# All rights reserved. +# +# 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 + +# A 8k sector size test using buildworld. + +# "panic: DI already started" seen: +# https://people.freebsd.org/~pho/stress/log/kostik1017.txt +# Fixed by r322175 + +. ../default.cfg + +gigs=9 +[ $((`sysctl -n vm.swap_total` / 1024 / 1024 / 1024)) -lt $gigs ] && exit 0 +[ -d /usr/src/sys ] || exit 0 + +kldstat | grep -q geom_nop || { gnop load 2>/dev/null || exit 0 && + notloaded=1; } +gnop status || exit 1 + +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +set -e +mdconfig -a -t swap -s ${gigs}g -u $mdstart +gnop create -S 8k /dev/md$mdstart +newfs $newfs_flags /dev/md$mdstart.nop > /dev/null +mount /dev/md$mdstart.nop $mntpoint +chmod 777 $mntpoint +set +e + +start=`date '+%s'` +(cd /usr; tar --exclude compile -cf - src) | (cd $mntpoint; tar xf -) + +cd $mntpoint/src +export MAKEOBJDIRPREFIX=$mntpoint/obj + +p=$((`sysctl -n hw.ncpu`+ 1)) +make -i -j $p buildworld DESTDIR=$mntpoint TARGET=amd64 TARGET_ARCH=amd64 \ + > /dev/null & +e=$((`date '+%s'` - start)) +sleep $((15 * 60 - e)) +kill $! +wait + +cd / +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +gnop destroy /dev/md$mdstart.nop +mdconfig -d -u $mdstart +[ $notloaded ] && gnop unload +exit 0 diff --git a/tools/test/stress2/misc/gnop5.sh b/tools/test/stress2/misc/gnop5.sh new file mode 100755 index 000000000000..2acd0244d80a --- /dev/null +++ b/tools/test/stress2/misc/gnop5.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 newfs with different sector size. +# newfs(8) issue fixed by r323157. +# mount(8) still fails with a sector size > 8k. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +kldstat | grep -q geom_nop || { gnop load 2>/dev/null || exit 0 && + loaded=1; } +gnop status > /dev/null || exit 1 + +s=0 +set -e +# Fails with a sector size > 8k. +#for i in 1k 2k 4k 8k 16k 32k 64k; do +for i in 1k 2k 4k 8k; do + echo $i + mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint + [ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + + mdconfig -a -t swap -s 2g -u $mdstart + gnop create -S $i /dev/md$mdstart + newfs $newfs_flags /dev/md$mdstart.nop > /dev/null || + { s=1; continue; } + mount /dev/md$mdstart.nop $mntpoint || + { gnop destroy /dev/md$mdstart.nop; mdconfig -d -u $mdstart + s=1; break; } + chmod 777 $mntpoint + + (cd $mntpoint; jot 100 | xargs touch) + + while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 + done + checkfs /dev/md$mdstart.nop || s=1 + gnop destroy /dev/md$mdstart.nop + mdconfig -d -u $mdstart +done + +[ $loaded ] && gnop unload +exit $s diff --git a/tools/test/stress2/misc/gnop6.sh b/tools/test/stress2/misc/gnop6.sh new file mode 100755 index 000000000000..63301d8fe841 --- /dev/null +++ b/tools/test/stress2/misc/gnop6.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# Read and write delay +# No problems seen + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +kldstat | grep -q geom_nop || { gnop load 2>/dev/null || exit 0 && + notloaded=1; } +gnop status || exit 1 + +. ../default.cfg + +delay=`jot -r 1 1 10` # ms delay +rprob=`jot -r 1 0 100` # read delay in % +wprob=`jot -r 1 0 100` # write delay in % +set -e +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 2g -u $mdstart +gnop create -d $delay -q $rprob -x $wprob /dev/md$mdstart +newfs $newfs_flags /dev/md$mdstart.nop > /dev/null +mount /dev/md$mdstart.nop $mntpoint +chmod 777 $mntpoint +set +e + +export runRUNTIME=5m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1 + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +checkfs /dev/md$mdstart.nop || s=1 && s=0 +gnop destroy /dev/md$mdstart.nop +mdconfig -d -u $mdstart + +[ $notloaded ] && gnop unload +exit $s diff --git a/tools/test/stress2/misc/gnop7.sh b/tools/test/stress2/misc/gnop7.sh new file mode 100755 index 000000000000..3f3118ff0fab --- /dev/null +++ b/tools/test/stress2/misc/gnop7.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# Failed Disk Test. +# "panic: witness_warn" seen in WiP kernel code. +# https://people.freebsd.org/~pho/stress/log/kirk102.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +kldstat | grep -q geom_nop || { gnop load 2>/dev/null || exit 0 && + notloaded=1; } +gnop status || exit 1 + +. ../default.cfg + +set -e +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 2g -u $mdstart +gnop create /dev/md$mdstart +newfs $newfs_flags /dev/md$mdstart.nop > /dev/null +mount /dev/md$mdstart.nop $mntpoint +chmod 777 $mntpoint +set +e + +export runRUNTIME=3m +export RUNDIR=$mntpoint/stressX +echo "Expect: + g_vfs_done():md10.nop[READ(offset=1077805056, length=32768)]error = 5 + g_vfs_done():md10.nop[WRITE(offset=553680896, length=32768)]error = 5" + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1 & +sleep `jot -r 1 60 120` +gnop configure -e 5 -r 100 -w 100 /dev/md$mdstart.nop +sleep 2 +gnop configure -e 0 -r 0 -w 0 /dev/md$mdstart.nop +wait + +while mount | grep -q "on $mntpoint "; do + umount $mntpoint && break + sleep 1 + [ $((n += 1)) -le 10 ] && continue + echo "umount $mntpoint failed" + s=1 + umount -f $mntpoint + break +done +fsck_ffs -Rfy /dev/md$mdstart.nop || s=2 +gnop destroy /dev/md$mdstart.nop +mdconfig -d -u $mdstart + +[ $notloaded ] && gnop unload +exit $s diff --git a/tools/test/stress2/misc/gnop8.sh b/tools/test/stress2/misc/gnop8.sh new file mode 100755 index 000000000000..6916c14e41f4 --- /dev/null +++ b/tools/test/stress2/misc/gnop8.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 Kirk McKusick +# +# 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: Lock (lockmgr) ufs not locked @ kern/kern_lock.c:1271' seen: +# https://people.freebsd.org/~pho/stress/log/gnop8.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +fsck=/sbin/fsck_ffs +exp=/sbin/fsck_ffs.exp # Experimental version +[ -f $exp ] && { echo "Using $exp"; fsck=$exp; } +mdconfig -a -t swap -s 5g -u $mdstart || exit 1 +md=md$mdstart +newfs -j /dev/$md || exit 1 +start=`date +%s` +while [ $((`date +%s` - start)) -lt 120 ]; do + gnop create /dev/$md || exit 1 + mount /dev/$md.nop /mnt || exit 1 + + # start your favorite I/O test here + cp -rp /[a-l]* /[n-z]* /mnt & + + # after some number of seconds + sleep 1 + gnop destroy -f /dev/$md.nop + kill $! + + # wait until forcible unmount, may be up to about 30 seconds, + # but typically very quick if I/O is in progress + while (a=`mount | egrep /mnt`) do sleep 1; done + + # first fsck will attempt journal recovery + $fsck -d -y /dev/$md + + # second fsck will do traditional fsck to check for any errors + # from journal recovery + $fsck -d -y /dev/$md + wait +done +mdconfig -d -u ${md#md} +exit 0 diff --git a/tools/test/stress2/misc/gnop9.sh b/tools/test/stress2/misc/gnop9.sh new file mode 100755 index 000000000000..0389391398f3 --- /dev/null +++ b/tools/test/stress2/misc/gnop9.sh @@ -0,0 +1,139 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +# fsck test with forced unmount of a SUJ FS. +# Variation of gnop8.sh by Kirk McKusick + +# https://people.freebsd.org/~pho/stress/log/gnop9.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +# Check for lingering threads from the last run +pgrep -x mount && { pgrep -x mount | xargs ps -lp; exit 1; } +../tools/killall.sh || exit 1 + +fsck=/sbin/fsck_ffs +fsck_loops=10 +exp=/sbin/fsck_ffs.exp # Experimental version +log=/tmp/gnop9.log +[ -f $exp ] && { echo "Using $exp"; fsck=$exp; } +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 5g -u $mdstart || exit 1 +md=md$mdstart +newfs -j /dev/$md > /dev/null 2>&1 || exit 1 + +export LOAD=80 +export rwLOAD=80 +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX +export CTRLDIR=$mntpoint/stressX.control +export MAXSWAPPCT=80 +export TESTPROGS=' +testcases/lockf2/lockf2 +testcases/symlink/symlink +testcases/openat/openat +testcases/socket/socket +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 +' + +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$(($1 / 10 * 7)) +export INODES=$(($2 / 10 * 7)) + +start=`date +%s` +while [ $((`date +%s` - start)) -lt 600 ]; do + gnop create /dev/$md || exit 1 + mount /dev/$md.nop $mntpoint || exit 1 + mkdir -p $RUNDIR $CTRLDIR + chmod 777 $RUNDIR $CTRLDIR + + # start your favorite I/O test here + rm -rf /tmp/stressX.control + (cd $RUNDIR && find . -delete) + + su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' & + + # after some number of seconds + sleep `jot -r 1 30 90` + gnop destroy -f /dev/$md.nop + ../tools/killall.sh || exit 1 + wait + + # Wait until forcible unmount, may be up to about 30 seconds, + # but typically very quick if I/O is in progress + s=`date +%s` + n=0 + 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` - s)) -ge 180 ]; then + echo "Giving up on waiting for umount of $mntpoint" + umount $mntpoint || umount -f $mntpoint + break + fi + done + [ $n -ne 0 ] && echo + + # first fsck will attempt journal recovery + $fsck -fy /dev/$md > $log 2>&1 + + # The second fsck will do traditional check for any errors + # from journal recovery + + # There seems to be a gnop cache issue, which resolves by adding + # delays between each fsck run + for i in `jot $fsck_loops`; do + sleep $((i * i)) # gnop workaround + [ $i -ne 1 ] && + echo "`date +%T` $fsck loop #$((i + 1))" + $fsck -fy /dev/$md > $log 2>&1 + grep -Eq "IS CLEAN|MARKED CLEAN" $log && break + [ $i -eq $fsck_loops ] && + { echo "$fsck did not mark FS as clean"; exit 1; } + [ $i -ne 1 ] && tail -3 $log + sync; sleep 5; sync; sleep 5 + done +done +echo "Final $fsck" +sleep 3; # gnop workaround +$fsck -fy /dev/$md > $log || { tail -5 $log; exit 1; } +mdconfig -d -u ${md#md} +rm -f $log +exit 0 diff --git a/tools/test/stress2/misc/gpt.sh b/tools/test/stress2/misc/gpt.sh new file mode 100755 index 000000000000..51b4ba39afda --- /dev/null +++ b/tools/test/stress2/misc/gpt.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# Bug 237269 - panic in glabel (g_label_destroy) stop after resizing GPT +# partition. +# "panic: vm_fault_hold: fault on nofault entry, addr: 0 from +# g_slice_spoiled+0x7" +# Test scenario by andrew@tao11.riddles.org.uk + +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 +md_unit=$(mdconfig -t swap -s 30MB) +geom part create -s GPT "$md_unit" +geom part add -s 10M -t linux-swap -l tst0 "$md_unit" +geom part resize -i 1 -s 20M "$md_unit" + +# at this point "glabel status" shows two gpt/tst0 entries, +# one of which has no consumer; trying to correct this causes +# a panic: + +glabel stop gpt/tst0 +glabel stop gpt/tst0 # BOOM + +mdconfig -d -u $md_unit + +exit 0 diff --git a/tools/test/stress2/misc/graid0.sh b/tools/test/stress2/misc/graid0.sh new file mode 100755 index 000000000000..5887d50f5739 --- /dev/null +++ b/tools/test/stress2/misc/graid0.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Protection fault seen: +# https://people.freebsd.org/~pho/stress/log/graid0.txt +# Fixed by r327721-23 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +md1=$mdstart +md2=$((mdstart + 1)) +md3=$((mdstart + 2)) + +size=1g +[ $((`sysctl -n hw.usermem` / 1024 / 1024 / 1024)) -le 4 ] && + size=512m + +for u in $md1 $md2 $md3; do + mdconfig -l | grep -q md$u && mdconfig -d -u $u + mdconfig -a -t swap -s $size -u $u +done + +gstripe load > /dev/null 2>&1 && unload=1 +gstripe label -v -s 131072 data /dev/md$md1 /dev/md$md2 /dev/md$md3 > \ + /dev/null || exit 1 +[ -c /dev/stripe/data ] || exit 1 +newfs $newfs_flags /dev/stripe/data > /dev/null +mount /dev/stripe/data $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' +while mount | grep $mntpoint | grep -q /stripe/; do + umount $mntpoint || sleep 1 +done +gstripe stop data && s=0 || s=1 +[ $unload ] && gstripe unload + +for u in $md3 $md2 $md1; do + mdconfig -d -u $u +done +exit $s diff --git a/tools/test/stress2/misc/graid1.sh b/tools/test/stress2/misc/graid1.sh new file mode 100755 index 000000000000..eea4aa80b97b --- /dev/null +++ b/tools/test/stress2/misc/graid1.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# No problems seen. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +md1=$mdstart +md2=$((mdstart + 1)) +md3=$((mdstart + 2)) + +s=0 +size=1g +[ $((`sysctl -n hw.usermem` / 1024 / 1024 / 1024)) -le 4 ] && + size=512m + +for u in $md1 $md2 $md3; do + mdconfig -l | grep -q md$u && mdconfig -d -u $u + mdconfig -a -t swap -s $size -u $u +done + +gmirror load > /dev/null 2>&1 && unload=1 +old=`sysctl -n kern.geom.mirror.debug` +sysctl kern.geom.mirror.debug=-1 | grep -q -- -1 || + sysctl kern.geom.mirror.debug=$old > /dev/null +gmirror label -v -b split -s 2048 data /dev/md$md1 /dev/md$md2 \ + /dev/md$md3 > /dev/null || exit 1 +[ "`sysctl -in kern.geom.mirror.launch_mirror_before_timeout`" = "0" ] && + sleep $((`sysctl -n kern.geom.mirror.timeout` + 1)) +[ -c /dev/mirror/data ] || exit 1 +newfs $newfs_flags /dev/mirror/data > /dev/null +mount /dev/mirror/data $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' +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 +checkfs /dev/mirror/data || s=1 +gmirror stop data || s=2 +gmirror destroy data 2>/dev/null +[ $unload ] && gmirror unload + +for u in $md3 $md2 $md1; do + mdconfig -d -u $u || s=3 +done +exit $s diff --git a/tools/test/stress2/misc/graid1_10.sh b/tools/test/stress2/misc/graid1_10.sh new file mode 100755 index 000000000000..51a5e0260914 --- /dev/null +++ b/tools/test/stress2/misc/graid1_10.sh @@ -0,0 +1,96 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Read error handling for synchronization requests +# Test scenario by Mark Johnston +# Fixed by r327779 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +md1=$mdstart +md2=$((mdstart + 1)) + +s=0 +size=1g +[ $((`sysctl -n hw.usermem` / 1024 / 1024 / 1024)) -le 4 ] && + size=512m + +for u in $md1 $md2; do + mdconfig -l | grep -q md$u && mdconfig -d -u $u + mdconfig -a -t swap -s $size -u $u +done + +gmirror load > /dev/null 2>&1 && unload=1 +old=`sysctl -n kern.geom.mirror.debug` +sysctl kern.geom.mirror.debug=-1 | grep -q -- -1 || + sysctl kern.geom.mirror.debug=$old > /dev/null +gmirror label -v -b split -s 2048 test /dev/md$md1 /dev/md$md2 \ + > /dev/null || exit 1 +[ "`sysctl -in kern.geom.mirror.launch_mirror_before_timeout`" = "0" ] && + sleep $((`sysctl -n kern.geom.mirror.timeout` + 1)) +[ -c /dev/mirror/test ] || exit 1 +newfs /dev/mirror/test > /dev/null +mount /dev/mirror/test $mntpoint + +gpid=`pgrep -fS "g_mirror test"` +s=0 +start=`date +%s` +roid=debug.fail_point.g_mirror_regular_request_read +while [ $((`date +%s` - start)) -lt 120 ]; do + gmirror forget test md$md2 2>/dev/null + gmirror remove test md$md2 2>/dev/null + sysctl $roid="1%return(5)[pid $gpid]" > /dev/null + gmirror insert test md$md2 + sleep 10 + sysctl $roid="off" > /dev/null + n=0 + while gmirror status test | grep -q DEGRADED; do + sleep 2 + [ $((n += 1)) -gt 30 ] && { s=1; break 2; } + done + sysctl $roid="off" > /dev/null +done +[ $s -ne 0 ] && { echo "Timed out"; gmirror status test; } + +for i in `jot 12`; do + gmirror status test | grep -q SYNCHRONIZING || break + sleep 10 +done +while mount | grep $mntpoint | grep -q /mirror/; do + umount $mntpoint || sleep 1 +done +gmirror stop test || s=2 +gmirror destroy test 2>/dev/null +[ $unload ] && gmirror unload + +for u in $md2 $md1; do + mdconfig -d -u $u || s=3 +done +exit $s diff --git a/tools/test/stress2/misc/graid1_2.sh b/tools/test/stress2/misc/graid1_2.sh new file mode 100755 index 000000000000..94d43d1646c5 --- /dev/null +++ b/tools/test/stress2/misc/graid1_2.sh @@ -0,0 +1,131 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 scenario by Mark Johnston +# "physwr DL /tmp/graid1_2 /dev/mirror/test" seen. +# Fixed by r307691. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/graid1_2.c +mycc -o graid1_2 -Wall -Wextra -O0 -g graid1_2.c || exit 1 +rm -f graid1_2.c +cd $odir + +gmirror load > /dev/null 2>&1 && unload=1 +[ -c /dev/mirror/test ] && { gmirror stop test; gmirror destroy test; } +old=`sysctl -n kern.geom.mirror.debug` +sysctl kern.geom.mirror.debug=-1 | grep -q -- -1 || + sysctl kern.geom.mirror.debug=$old > /dev/null + +md1=$mdstart +md2=$((mdstart + 1)) +s=0 +size=$((128 * 1024)) + +for u in $md1 $md2; do + dd if=/dev/zero of=/tmp/graid1_2_di$u bs=$size count=1 status=none + [ -c /dev/md$u ] && mdconfig -d -u $u + mdconfig -a -t vnode -f /tmp/graid1_2_di$u -u $u +done +gmirror label test /dev/md$md1 /dev/md$md2 || exit 1 +[ "`sysctl -in kern.geom.mirror.launch_mirror_before_timeout`" = "0" ] && + sleep $((`sysctl -n kern.geom.mirror.timeout` + 1)) +[ -c /dev/mirror/test ] || exit 1 + +for i in `jot 150`; do /tmp/graid1_2 /dev/mirror/test; done & + +sleep 5 +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 300 ]; do + gmirror rebuild test /dev/md$md1 + sleep 2 + n=0 + while ps -lx | grep -v grep | grep graid1_2 | grep -q D; do + opid=$pid + pid=`pgrep graid1_2` + [ -z "$pid" -o "$pid" != "$opid" ] && n=0 + sleep 1 + n=$((n + 1)) + if [ $n -gt 180 ]; then + echo FAIL + ps -lx | grep -v grep | grep graid1_2 | grep D + exit 1 + fi + done +done +kill $! 2>/dev/null +pkill graid1_2 +wait + +while mount | grep $mntpoint | grep -q /mirror/; do + umount $mntpoint || sleep 1 +done +gmirror stop test || s=2 +[ $unload ] && gmirror unload + +for u in $md2 $md1; do + mdconfig -d -u $u || s=4 +done +rm -f /tmp/graid1_2 /tmp/graid1_2_di* +exit $s +EOF +/* Write last sector on disk */ +#include +#include +#include +#include +#include +#include + +static char buf[512]; + +int +main(int argc __unused, char *argv[]) +{ + time_t start; + int fd; + + if ((fd = open(argv[1], O_RDWR)) == -1) + err(1, "open(%s)", argv[1]); + start = time(NULL); + while (time(NULL) - start < 2) { + if (lseek(fd, 254 * sizeof(buf), SEEK_SET) == -1) + err(1, "seek"); + if (write(fd, buf, sizeof(buf)) != sizeof(buf)) + err(1, "write"); + } + close(fd); + + return (0); +} diff --git a/tools/test/stress2/misc/graid1_3.sh b/tools/test/stress2/misc/graid1_3.sh new file mode 100755 index 000000000000..088e395b1f2e --- /dev/null +++ b/tools/test/stress2/misc/graid1_3.sh @@ -0,0 +1,93 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 scenario by Mark Johnston + +# Page fault seen: +# https://people.freebsd.org/~pho/stress/log/graid1_3.txt + +. ../default.cfg + +gmirror load > /dev/null 2>&1 && unload=1 +[ -c /dev/mirror/markj-mirror ] && + { gmirror stop markj-mirror; gmirror destroy markj-mirror; } +old=`sysctl -n kern.geom.mirror.debug` +sysctl kern.geom.mirror.debug=-1 | grep -q -- -1 || + sysctl kern.geom.mirror.debug=$old > /dev/null +u1=$mdstart +u2=$((mdstart + 1)) +size=$((5 * 1024 * 1024)) +for u in $u1 $u2; do + dd if=/dev/zero of=/tmp/graid1_2_di$u bs=$size count=1 \ + status=none + [ -c /dev/md$u ] && mdconfig -d -u $u + mdconfig -a -t vnode -f /tmp/graid1_2_di$u -u $u +done +set -e + +( +gpart create -s GPT md$u1 +gpart create -s GPT md$u2 +gpart add -t freebsd-ufs -s 1M md$u1 +gpart add -t freebsd-ufs -s 1M md$u2 +) > /dev/null + +gmirror label markj-mirror md${u1}p1 +set +e + +while true; do + gmirror label markj-mirror md${u1}p1 + gmirror destroy markj-mirror +done 2>/dev/null & +pid1=$! +while true; do + gmirror insert markj-mirror md${u2}p1 + gmirror remove markj-mirror md${u2}p1 +done 2>/dev/null & +pid2=$! + +for i in `jot 60`; do + gmirror list markj-mirror + sleep 1 +done > /dev/null 2>&1 +sleep 60 + +kill $pid1 $pid2 +wait +sleep 1 + +gmirror remove markj-mirror md${u2}p1 > /dev/null 2>&1 +gmirror destroy markj-mirror > /dev/null 2>&1 + +mdconfig -d -u $u1 || exit 1 +mdconfig -d -u $u2 || exit 1 +rm -f /tmp/graid1_2_di* +[ $unload ] && gmirror unload +exit 0 diff --git a/tools/test/stress2/misc/graid1_4.sh b/tools/test/stress2/misc/graid1_4.sh new file mode 100755 index 000000000000..9f410ef9a645 --- /dev/null +++ b/tools/test/stress2/misc/graid1_4.sh @@ -0,0 +1,97 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Non UFS SU gmirror stop -f test. + +# Page fault seen: +# https://people.freebsd.org/~pho/stress/log/graid1_4.txt +# Fixed in r316867 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +rm -f $diskimage* +need=1024 # MB +[ `df -k $(dirname $diskimage) | tail -1 | awk '{print int($4 / 1024)}'` -lt \ + $need ] && printf "Need %d MB on %s.\n" $need `dirname $diskimage` && exit + +gmirror load > /dev/null 2>&1 && unload=1 +[ -c /dev/mirror/test ] && { gmirror stop test; gmirror destroy test; } +old=`sysctl -n kern.geom.mirror.debug` +sysctl kern.geom.mirror.debug=-1 | grep -q -- -1 || + sysctl kern.geom.mirror.debug=$old > /dev/null + +md1=$mdstart +md2=$((mdstart + 1)) + +s=0 +for u in $md1 $md2; do + disk="$diskimage.$u" + dd if=/dev/zero of=$disk bs=1m count=512 status=none + [ -c /dev/md$u ] && mdconfig -d -u $u + mdconfig -a -t vnode -f $disk -u $u +done + +gmirror label -v -b split -s 2048 test /dev/md$md1 /dev/md$md2 \ + > /dev/null || exit 1 +[ "`sysctl -in kern.geom.mirror.launch_mirror_before_timeout`" = "0" ] && + sleep $((`sysctl -n kern.geom.mirror.timeout` + 1)) +[ -c /dev/mirror/test ] || exit 1 +# Soft Updates issues with removal of backing media +newfs /dev/mirror/test > /dev/null +mount /dev/mirror/test $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' & + +while kill -0 $! > /dev/null 2>&1; do + sleep `jot -r 1 1 5` + gmirror remove test md$md2 + sleep `jot -r 1 1 5` + gmirror insert test md$md2 +done +wait + +gmirror stop -f test # Note the stop *before* umount + +while mount | grep $mntpoint | grep -q /mirror/; do + umount $mntpoint || sleep 1 +done +gmirror stop test || s=1 +gmirror destroy test 2>/dev/null +[ $unload ] && gmirror unload + +for u in $md2 $md1; do + mdconfig -d -u $u || s=3 +done +rm -f $diskimage* +exit $s diff --git a/tools/test/stress2/misc/graid1_5.sh b/tools/test/stress2/misc/graid1_5.sh new file mode 100755 index 000000000000..4200a64150b8 --- /dev/null +++ b/tools/test/stress2/misc/graid1_5.sh @@ -0,0 +1,116 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Mirror tests with gnop(8) errors introduced in 2 out of three partitions. + +# https://people.freebsd.org/~pho/stress/log/graid1_5-2.txt +# Fixed by r327698 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +gmirror load > /dev/null 2>&1 && unload=1 +gmirror status > /dev/null || exit 0 + +gnop load > /dev/null && unload2=1; +gnop status > /dev/null || exit 0 + +[ -c /dev/mirror/test ] && { gmirror stop test; gmirror destroy test; } +old=`sysctl -n kern.geom.mirror.debug` +sysctl kern.geom.mirror.debug=-1 | grep -q -- -1 || + sysctl kern.geom.mirror.debug=$old > /dev/null + +u1=$mdstart +u2=$((mdstart + 1)) +u3=$((mdstart + 2)) +s=0 +for u in $u1 $u2 $u3; do + [ -c /dev/md$u ] && mdconfig -d -u $u + mdconfig -a -t swap -s 341m -u $u + gpart create -s GPT md$u +done > /dev/null + +set -e +( +gpart add -t freebsd-ufs -s 340m md$u1 +gpart add -t freebsd-ufs -s 340m md$u2 +gpart add -t freebsd-ufs -s 340m md$u3 +) > /dev/null +gnop create md$u2 +gnop create md$u3 +gmirror label test md${u1}p1 md$u2.nopp1 md$u3.nopp1 +[ "`sysctl -in kern.geom.mirror.launch_mirror_before_timeout`" = "0" ] && + sleep $((`sysctl -n kern.geom.mirror.timeout` + 1)) +[ -c /dev/mirror/test ] || exit 1 + +newfs /dev/mirror/test > /dev/null +mount /dev/mirror/test $mntpoint +set +e +chmod 777 $mntpoint + +export runRUNTIME=5m +export RUNDIR=$mntpoint/stressX +rm -rf /tmp/stressX.control + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1 & +pid=$! + +gnop configure -r 0 -w 1 md$u2.nop +gnop configure -r 0 -w 1 md$u3.nop +while kill -0 $pid > /dev/null 2>&1; do + if ! gmirror status test | grep -q md$u2.nopp1; then + gmirror forget test + gmirror remove test md$u2.nopp1 2>/dev/null + gmirror insert test md$u2.nopp1 2>/dev/null + fi + if ! gmirror status test | grep -q md$u3.nopp1; then + gmirror forget test + gmirror remove test md$u3.nopp1 2>/dev/null + gmirror insert test md$u3.nopp1 2>/dev/null + fi + sleep 1 +done +wait + +while mount | grep $mntpoint | grep -q /mirror/; do + umount $mntpoint || sleep 5 +done +while gmirror status test | grep -q SYNCHRONIZING; do sleep 10; done +for i in `jot 10`; do + gmirror stop test && break || sleep 30 +done +[ $i -eq 10 ] && s=1 +gmirror destroy test 2>/dev/null +[ $unload ] && gmirror unload + +for u in $u1 $u2 $u3; do + mdconfig -d -u $u || s=3 +done +[ $unload2 ] && gnop unload +exit $s diff --git a/tools/test/stress2/misc/graid1_6.sh b/tools/test/stress2/misc/graid1_6.sh new file mode 100755 index 000000000000..dc85c51dad04 --- /dev/null +++ b/tools/test/stress2/misc/graid1_6.sh @@ -0,0 +1,106 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 graid1_4.sh + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +rm -f $diskimage* +need=1024 # MB +[ `df -k $(dirname $diskimage) | tail -1 | awk '{print int($4 / 1024)}'` -lt \ + $need ] && printf "Need %d MB on %s.\n" $need `dirname $diskimage` && exit + +gmirror load > /dev/null 2>&1 && unload=1 +[ -c /dev/mirror/test ] && { gmirror stop test; gmirror destroy test; } +old=`sysctl -n kern.geom.mirror.debug` +sysctl kern.geom.mirror.debug=-1 | grep -q -- -1 || + sysctl kern.geom.mirror.debug=$old > /dev/null + +md1=$mdstart +md2=$((mdstart + 1)) + +s=0 +for u in $md1 $md2; do + disk="$diskimage.$u" + dd if=/dev/zero of=$disk bs=1m count=512 status=none + [ -c /dev/md$u ] && mdconfig -d -u $u + mdconfig -a -t vnode -f $disk -u $u +done + +gmirror label -v -b split -s 2048 test /dev/md$md1 /dev/md$md2 \ + > /dev/null || exit 1 +[ "`sysctl -in kern.geom.mirror.launch_mirror_before_timeout`" = "0" ] && + sleep $((`sysctl -n kern.geom.mirror.timeout` + 1)) +[ -c /dev/mirror/test ] || exit 1 +newfs $newfs_flags /dev/mirror/test > /dev/null +mount /dev/mirror/test $mntpoint +chmod 777 $mntpoint + +mlog=/tmp/graid1_6.log +tail -F -n 0 /var/log/messages > $mlog & mpid=$! +export runRUNTIME=4m +export RUNDIR=$mntpoint/stressX +su $testuser -c 'cd ..; ./run.sh marcus.cfg > /dev/null' & + +while kill -0 $! > /dev/null 2>&1; do + sleep `jot -r 1 1 5` + gmirror remove test md$md2 + sleep `jot -r 1 1 5` + gmirror insert test md$md2 +done +wait $! +i=0 +while ! gmirror status test | grep -q COMPLETE; do + sleep 10 + if [ $((i += 1)) -gt 20 ]; then + echo "FAIL to COMPLETE" + graid status test + s=1 + break + fi +done + +while mount | grep $mntpoint | grep -q /mirror/; do + umount $mntpoint || sleep 1 +done +checkfs /dev/mirror/test || s=2 +gmirror stop -f test ||s=3 +gmirror destroy test 2>/dev/null +[ $unload ] && gmirror unload + +for u in $md2 $md1; do + mdconfig -d -u $u || s=4 +done +rm -f $diskimage* +grep -m 1 "check-hash" $mlog && s=5 +kill $mpid +wait +rm -f $mlog +exit $s diff --git a/tools/test/stress2/misc/graid1_7.sh b/tools/test/stress2/misc/graid1_7.sh new file mode 100755 index 000000000000..8280afb97e3b --- /dev/null +++ b/tools/test/stress2/misc/graid1_7.sh @@ -0,0 +1,127 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Component looses it's name: +# g_dev_taste: make_dev_p() failed +# (gp->name=gptid/7c598e03-19cb-11e7-b62b-001e6756c168, error=17) + +# Deadlock seen: +# https://people.freebsd.org/~pho/stress/log/graid1_7.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +gmirror load > /dev/null 2>&1 && unload=1 +[ -c /dev/mirror/test ] && { gmirror stop test; gmirror destroy test; } +old=`sysctl -n kern.geom.mirror.debug` +sysctl kern.geom.mirror.debug=-1 | grep -q -- -1 || + sysctl kern.geom.mirror.debug=$old > /dev/null + +u1=$mdstart +s=0 +[ -c /dev/md$u1 ] && mdconfig -d -u $u1 +mdconfig -a -t swap -s 1g -u $u1 + +set -e +( +gpart create -s GPT md$u1 +gpart add -t freebsd-ufs -s 341m md$u1 +gpart add -t freebsd-ufs -s 341m md$u1 +gpart add -t freebsd-ufs -s 341m md$u1 +) > /dev/null +gmirror label test md${u1}p1 md${u1}p2 md${u1}p3 +[ "`sysctl -in kern.geom.mirror.launch_mirror_before_timeout`" = "0" ] && + sleep $((`sysctl -n kern.geom.mirror.timeout` + 1)) +[ -c /dev/mirror/test ] || exit 1 + +newfs /dev/mirror/test > /dev/null +mount /dev/mirror/test $mntpoint +set +e +chmod 777 $mntpoint + +export runRUNTIME=5m +export RUNDIR=$mntpoint/stressX +rm -rf /tmp/stressX.control + +su $testuser -c 'cd ..; ./run.sh io.cfg' > /dev/null 2>&1 & +pid=$! + +mlog=/tmp/graid1_6.log +tail -F -n 0 /var/log/messages > $mlog & mpid=$! +sleep 2 +cont=/tmp/graid1_7.cont +touch $cont +for i in `jot 8`; do + while [ -f $cont ]; do + for u in md${u1}p2 md${u1}p3; do + gmirror forget test + gmirror remove test $u + gmirror insert test $u + id=`gmirror status test | grep gptid | awk '{print $1}'` + if [ $i -eq 1 -a -n "$id" ]; then + echo "FAIL Remove component $id" + gmirror remove test $id + fi + done 2>/dev/null + done & +done +while kill -0 $pid 2>/dev/null; do sleep 5; done +rm $cont +wait $! +gmirror status test | grep -qw md${u1}p2 || gmirror insert test md${u1}p2 +gmirror status test | grep -qw md${u1}p3 || gmirror insert test md${u1}p3 +i=0 +while ! gmirror status test | grep -q COMPLETE; do + sleep 5 + if [ $((i += 1)) -gt 20 ]; then + echo "FAIL to COMPLETE" + gmirror status test + s=1 + break + fi +done + +while mount | grep $mntpoint | grep -q /mirror/; do + umount $mntpoint || sleep 5 +done +checkfs /dev/mirror/test || s=2 +while gmirror status test | grep -q SYNCHRONIZING; do sleep 10; done +for i in `jot 10`; do + gmirror stop test && break || sleep 30 +done +[ $i -eq 10 ] && s=3 +gmirror destroy test 2>/dev/null +[ $unload ] && gmirror unload + +mdconfig -d -u $mdstart || s=4 +grep -m 1 "check-hash" $mlog && s=5 +kill $mpid +wait +rm -f $mlog +exit $s diff --git a/tools/test/stress2/misc/graid1_8.sh b/tools/test/stress2/misc/graid1_8.sh new file mode 100755 index 000000000000..d130a6152cf2 --- /dev/null +++ b/tools/test/stress2/misc/graid1_8.sh @@ -0,0 +1,102 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Mirror test where the third disk is partially wiped: +# Silent Data Corruption. +# fsck() will trash your FS in this scenario. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +gmirror load > /dev/null 2>&1 && unload=1 +mount | grep -q "on $mntpoint " && umount $mntpoint +[ -c /dev/mirror/test ] && { gmirror stop test; gmirror destroy test; } +old=`sysctl -n kern.geom.mirror.debug` +sysctl kern.geom.mirror.debug=-1 | grep -q -- -1 || + sysctl kern.geom.mirror.debug=$old > /dev/null + +u1=$mdstart +u2=$((mdstart + 1)) +u3=$((mdstart + 2)) + +for u in $u1 $u2 $u3; do + [ -c /dev/md$u ] && mdconfig -d -u $u + dd if=/dev/zero of=$diskimage.$u bs=1m count=100 status=none + mdconfig -a -t vnode -f $diskimage.$u -u $u +done > /dev/null + +gmirror label test md$u1 md$u2 md$u3 || exit 1 +[ "`sysctl -in kern.geom.mirror.launch_mirror_before_timeout`" = "0" ] && + sleep 5 +( +gpart create -s BSD mirror/test +gpart add -t freebsd-ufs -s 99m mirror/test +) > /dev/null +[ -c /dev/mirror/testa ] || exit 1 + +newfs -n /dev/mirror/testa > /dev/null +mount /dev/mirror/testa $mntpoint +jot 10 | xargs -P0 -I% cp /etc/passwd $mntpoint/% + +# The test: zap part of the third disk +dd if=/dev/random of=$diskimage.$u3 bs=1m count=80 conv=notrunc status=none +umount $mntpoint +log=/tmp/graid1_8.sh.log + +if [ $# -eq 1 ]; then # This will fix the mirror + gmirror remove test md$u3 + gmirror insert test md$u3 + while gmirror status test | grep -q SYNCHRONIZING; do + sleep 2 + done +fi + +fsck -fy /dev/mirror/testa > $log 2>&1 +grep -q RERUN $log && fsck -fy /dev/mirror/testa > /dev/null 2>&1 +grep -Eq "MODIFIED|BAD" $log && + { s=1; head -5 $log; } || + s=0 +rm $log +mount /dev/mirror/testa $mntpoint +[ `ls $mntpoint | wc -l` -lt 10 ] && ls -l $mntpoint +umount $mntpoint + +while gmirror status test | grep -q SYNCHRONIZING; do sleep 10; done +for i in `jot 10`; do + gmirror stop test && break || sleep 30 +done +[ $i -eq 10 ] && s=1 +gmirror destroy test 2>/dev/null +[ $unload ] && gmirror unload + +for u in $u1 $u2 $u3; do + mdconfig -d -u $u || s=3 + rm $diskimage.$u +done +exit $s diff --git a/tools/test/stress2/misc/graid1_9.sh b/tools/test/stress2/misc/graid1_9.sh new file mode 100755 index 000000000000..8d8d447b25b0 --- /dev/null +++ b/tools/test/stress2/misc/graid1_9.sh @@ -0,0 +1,114 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Copy of graid1.sh with fail points added. +# https://people.freebsd.org/~pho/stress/log/mark015.txt +# Fixed by r327779 + +# Problem also seen with non SU: +# https://people.freebsd.org/~pho/stress/log/numa027.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +md1=$mdstart +md2=$((mdstart + 1)) +md3=$((mdstart + 2)) + +s=0 +size=1g +[ $((`sysctl -n hw.usermem` / 1024 / 1024 / 1024)) -le 4 ] && + size=512m + +for u in $md1 $md2 $md3; do + mdconfig -l | grep -q md$u && mdconfig -d -u $u + mdconfig -a -t swap -s $size -u $u +done + +gmirror load > /dev/null 2>&1 && unload=1 +old=`sysctl -n kern.geom.mirror.debug` +sysctl kern.geom.mirror.debug=-1 | grep -q -- -1 || + sysctl kern.geom.mirror.debug=$old > /dev/null +gmirror label -v -b split -s 2048 test /dev/md$md1 /dev/md$md2 \ + /dev/md$md3 > /dev/null || exit 1 +[ "`sysctl -in kern.geom.mirror.launch_mirror_before_timeout`" = "0" ] && + sleep $((`sysctl -n kern.geom.mirror.timeout` + 1)) +[ -c /dev/mirror/test ] || exit 1 +# Do not use SU as it is more intolerant to FS corruption +newfs /dev/mirror/test > /dev/null +mount /dev/mirror/test $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX + +woid=debug.fail_point.g_mirror_regular_request_write +roid=debug.fail_point.g_mirror_regular_request_read +gpid=`pgrep -fS "g_mirror test"` +sysctl $woid="0.0005%return(5)[pid $gpid]" > /dev/null +sysctl $roid="0.0005%return(5)[pid $gpid]" > /dev/null + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null & + +while kill -0 $! 2>/dev/null; do + if gmirror status test | grep -q DEGRADED; then + for i in $md1 $md2 $md3; do + if ! gmirror status test | grep -q md$i; then + gmirror forget test md$i 2>/dev/null + gmirror remove test md$i 2>/dev/null + gmirror insert test md$i + fi + done + else + sleep 5 + fi +done +wait + +sysctl $woid=off > /dev/null +sysctl $roid=off > /dev/null + +for i in `jot 12`; do + gmirror status test | grep -q SYNCHRONIZING || break + sleep 10 +done +gmirror status test | grep -q SYNCHRONIZING && + { s=1; gmirror status test; } +while mount | grep $mntpoint | grep -q /mirror/; do + umount $mntpoint || sleep 1 +done +# The FS is most likely corrupted at this point, so do not run fsck(8). +gmirror stop test || s=2 +gmirror destroy test 2>/dev/null +[ $unload ] && gmirror unload + +for u in $md3 $md2 $md1; do + mdconfig -d -u $u || s=3 +done +exit $s diff --git a/tools/test/stress2/misc/graid3.sh b/tools/test/stress2/misc/graid3.sh new file mode 100755 index 000000000000..f67ac819a47d --- /dev/null +++ b/tools/test/stress2/misc/graid3.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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. +# + +# Probably unrelated mkfifo() problem seen: +# http://people.freebsd.org/~pho/stress/log/graid3.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +md1=$mdstart +md2=$((mdstart + 1)) +md3=$((mdstart + 2)) + +size=1g +[ $((`sysctl -n hw.usermem` / 1024 / 1024 / 1024)) -le 4 ] && + size=512m + +for u in $md1 $md2 $md3; do + mdconfig -l | grep -q md$u && mdconfig -d -u $u + mdconfig -a -t swap -s $size -u $u +done + +graid3 load > /dev/null 2>&1 && unload=1 +graid3 label -v -r data md$md1 md$md2 md$md3 > /dev/null || exit 1 +[ -c /dev/raid3/data ] || exit 1 +newfs $newfs_flags /dev/raid3/data > /dev/null +mount /dev/raid3/data $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 raid3; do + umount $mntpoint || sleep 1 +done + +graid3 stop data && s=0 || s=1 +[ $unload ] && graid3 unload + +for u in $md3 $md2 $md1; do + mdconfig -d -u $u +done +exit $s diff --git a/tools/test/stress2/misc/growfs.sh b/tools/test/stress2/misc/growfs.sh new file mode 100755 index 000000000000..5a2ec3f609d3 --- /dev/null +++ b/tools/test/stress2/misc/growfs.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 +# "checksum failed: cg 52, cgp: 0x0 != bp: 0xe35de2ca" seen. +# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=222876 +# Fixed by r324499 + +. ../default.cfg +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +s=0 +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 32g -u $mdstart +/sbin/gpart create -s GPT md$mdstart +/sbin/gpart add -t freebsd-ufs -s 2g -a 4k md$mdstart +set +e + +newfs $newfs_flags md${mdstart}p1 > /dev/null +mount /dev/md${mdstart}p1 $mntpoint +cp -r /usr/include $mntpoint/inc1 +umount $mntpoint +checkfs /dev/md${mdstart}p1 || { s=1; echo "Initial fsck 1 fail"; } + +gpart resize -i 1 -s 31g -a 4k md$mdstart +growfs -y md${mdstart}p1 > /dev/null +# This fsck make the checksum error go away +#checkfs /dev/md${mdstart}p1 || { s=1; echo "fsck after growfs fail"; } + +mount /dev/md${mdstart}p1 $mntpoint +cp -r /usr/include $mntpoint/inc2 +umount $mntpoint +checkfs /dev/md${mdstart}p1 || { s=1; echo "Final fsck fail"; } + +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/holdcnt0.sh b/tools/test/stress2/misc/holdcnt0.sh new file mode 100755 index 000000000000..7a35eb1dbf5f --- /dev/null +++ b/tools/test/stress2/misc/holdcnt0.sh @@ -0,0 +1,261 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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: cluster_wbuild: page 0xc2eebc10 failed shared busing" seen. +# "panic: vdrop: holdcnt 0" seen. +# "panic: cleaned vnode isn't" seen. +# OoVM seen with r285808: +# https://people.freebsd.org/~pho/stress/log/holdcnt0.txt + +# Test scenario suggestion by alc@ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `swapinfo | wc -l` -eq 1 ] && exit 0 +[ `sysctl -n hw.physmem` -lt $((32 * 1024 * 1024 * 1024)) ] && exit 0 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > holdcnt0.c +mycc -o holdcnt0 -Wall -Wextra -g holdcnt0.c || exit 1 +rm -f holdcnt0.c +cd $here + +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 5g -u $mdstart +bsdlabel -w md$mdstart auto +newfs md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +(cd $mntpoint; /tmp/holdcnt0) & +pid=$! +sleep 5 +while kill -0 $! 2> /dev/null; do + (cd ../testcases/swap; ./swap -t 1m -i 1) > /dev/null 2>&1 +done +wait $pid; s=$? + +while mount | grep -q md${mdstart}$part; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/holdcnt0 +exit $s +EOF +/* + A test that causes the page daemon to generate cached pages + within a bunch of files and has some consumer that is trying to + allocate new pages to the same files. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE (1024 * 1024) +#define FILES 200 +#define RPARALLEL 8 +#define WPARALLEL 2 + +static jmp_buf jbuf; +static off_t maxsize; +static int ps; +static char *buf; +static volatile char val; + +static void +hand(int i __unused) { /* handler */ + +#if defined(DEBUG) + fprintf(stderr, "%d ", i); +#endif + longjmp(jbuf, 1); +} + +static void +cleanup(void) +{ + int i; + char file[80]; + + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + unlink(file); + } +} + +static void +init(void) +{ + int fd, i; + char file[80]; + + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0644)) == + -1) + err(1, "open(%s)", file); + if (write(fd, buf, BUFSIZE) != BUFSIZE) + err(1, "write"); + close(fd); + } + +} + +static void +writer(void) +{ + struct stat statbuf; + time_t start; + int fd, i; + char file[80]; + + setproctitle("writer"); + start = time(NULL); + while (time(NULL) - start < 600) { + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if ((fd = open(file, O_RDWR | O_APPEND)) == -1) { + if (errno != ENOENT) + err(1, "open(%s) append", file); + goto err; + } + if (fstat(fd, &statbuf) < 0) + err(1, "fstat error"); + if (statbuf.st_size < maxsize) { + if (write(fd, buf, ps) != ps) { + warn("writer"); + goto err; + } + } + close(fd); + } + } +err: + cleanup(); + + _exit(0); +} + +static void +reader(void) +{ + struct stat statbuf; + void *p; + size_t len; + int fd, i, j, n; + char file[80]; + + setproctitle("reader"); + signal(SIGSEGV, hand); + signal(SIGBUS, hand); + fd = 0; + for (;;) { + (void)setjmp(jbuf); + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if (fd > 0) + close(fd); + if ((fd = open(file, O_RDWR)) == -1) { + if (errno != ENOENT) + warn("reader(%s)", file); + _exit(0); + } + if (fstat(fd, &statbuf) < 0) + err(1, "fstat error"); + if (statbuf.st_size >= maxsize) { + if (ftruncate(fd, ps) == -1) + err(1, "ftruncate"); + continue; + } + len = statbuf.st_size; + if ((p = mmap(p, len, PROT_READ, MAP_SHARED, fd, 0)) + == MAP_FAILED) + err(1, "mmap()"); + close(fd); + n = statbuf.st_size / ps; + for (j = 0; j < n; j++) { + val = *(char *)p; + p = p + ps; + } +#if 0 + if (munmap(p, len) == -1) + perror("munmap"); +#endif + } + } + _exit(0); +} +int +main(void) +{ + pid_t rpid[RPARALLEL], wpid[WPARALLEL]; + int e, i, s; + + maxsize = 2LL * 1024 * 1024 * 1024 / FILES; + buf = malloc(BUFSIZE); + ps = getpagesize(); + + init(); + e = 0; + for (i = 0; i < WPARALLEL; i++) { + if ((wpid[i] = fork()) == 0) + writer(); + } + for (i = 0; i < RPARALLEL; i++) { + if ((rpid[i] = fork()) == 0) + reader(); + } + + for (i = 0; i < WPARALLEL; i++) { + waitpid(wpid[i], &s, 0); + if (e == 0) + e = s; + } + for (i = 0; i < RPARALLEL; i++) { + waitpid(rpid[i], &s, 0); + if (e == 0) + e = s; + } + free(buf); + + return (e); +} diff --git a/tools/test/stress2/misc/holdcnt02.sh b/tools/test/stress2/misc/holdcnt02.sh new file mode 100755 index 000000000000..671d068917f0 --- /dev/null +++ b/tools/test/stress2/misc/holdcnt02.sh @@ -0,0 +1,238 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Copy of holdcnt0.sh, but without the memory disk usage. + +# Test scenario suggestion by alc@ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `swapinfo | wc -l` -eq 1 ] && exit 0 +[ `sysctl -n hw.physmem` -lt $((32 * 1024 * 1024 * 1024)) ] && exit 0 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > holdcnt02.c +mycc -o holdcnt02 -Wall -Wextra -g holdcnt02.c || exit 1 +rm -f holdcnt02.c +cd $here + +trap "rm -f /tmp/holdcnt02 `dirname $diskimage`/f000???" EXIT INT +(cd `dirname $diskimage`; /tmp/holdcnt02) & +pid=$! +sleep 5 +while kill -0 $! 2> /dev/null; do + (cd ../testcases/swap; ./swap -t 1m -i 1) > /dev/null 2>&1 +done +wait $pid +exit +EOF +/* + A test that causes the page daemon to generate cached pages + within a bunch of files and has some consumer that is trying to + allocate new pages to the same files. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE (1024 * 1024) +#define FILES 200 +#define RPARALLEL 8 +#define WPARALLEL 2 + +static jmp_buf jbuf; +static off_t maxsize; +static int ps; +static char *buf; +static volatile char val; + +static void +hand(int i __unused) { /* handler */ + longjmp(jbuf, 1); +} + +static void +cleanup(void) +{ + int i; + char file[80]; + + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + unlink(file); + } +} + +static void +init(void) +{ + int fd, i; + char file[80]; + + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0644)) == + -1) + err(1, "open(%s)", file); + if (write(fd, buf, BUFSIZE) != BUFSIZE) + err(1, "write"); + close(fd); + } + +} + +static void +writer(void) +{ + int fd, i; + char file[80]; + time_t start; + struct stat statbuf; + + setproctitle("writer"); + start = time(NULL); + while (time(NULL) - start < 600) { + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if ((fd = open(file, O_RDWR | O_APPEND)) == -1) { + if (errno != ENOENT) + err(1, "open(%s) append", file); + goto err; + } + if (fstat(fd, &statbuf) < 0) + err(1, "fstat error"); + if (statbuf.st_size < maxsize) { + if (write(fd, buf, ps) != ps) { + warn("writer"); + goto err; + } + } + close(fd); + } + } +err: + cleanup(); + + _exit(0); +} + +static void +reader(void) +{ + int fd, i, j, n; + void *p; + size_t len; + char file[80]; + struct stat statbuf; + + setproctitle("reader"); + signal(SIGSEGV, hand); + signal(SIGBUS, hand); + fd = 0; + for (;;) { + (void)setjmp(jbuf); + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if (fd > 0) + close(fd); + if ((fd = open(file, O_RDWR)) == -1) { + if (errno != ENOENT) + warn("reader(%s)", file); + _exit(0); + } + if (fstat(fd, &statbuf) < 0) + err(1, "fstat error"); + if (statbuf.st_size >= maxsize) { + if (ftruncate(fd, ps) == -1) + err(1, "ftruncate"); + continue; + } + len = statbuf.st_size; + if ((p = mmap(p, len, PROT_READ, MAP_SHARED, fd, 0)) + == MAP_FAILED) + err(1, "mmap()"); + close(fd); + n = statbuf.st_size / ps; + for (j = 0; j < n; j++) { + val = *(char *)p; + p = p + ps; + } +#if 0 + if (munmap(p, len) == -1) + perror("munmap"); +#endif + } + } + _exit(0); +} +int +main(void) +{ + pid_t rpid[RPARALLEL], wpid[WPARALLEL]; + int e, i, s; + + maxsize = 2LL * 1024 * 1024 * 1024 / FILES; + buf = malloc(BUFSIZE); + ps = getpagesize(); + + init(); + e = 0; + for (i = 0; i < WPARALLEL; i++) { + if ((wpid[i] = fork()) == 0) + writer(); + } + for (i = 0; i < RPARALLEL; i++) { + if ((rpid[i] = fork()) == 0) + reader(); + } + + for (i = 0; i < WPARALLEL; i++) + waitpid(wpid[i], &s, 0); + e += s == 0 ? 0 : 1; + for (i = 0; i < RPARALLEL; i++) + waitpid(rpid[i], &s, 0); + e += s == 0 ? 0 : 1; + + free(buf); + + return (e); +} diff --git a/tools/test/stress2/misc/holdcnt03.sh b/tools/test/stress2/misc/holdcnt03.sh new file mode 100755 index 000000000000..35437c06e707 --- /dev/null +++ b/tools/test/stress2/misc/holdcnt03.sh @@ -0,0 +1,237 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Copy of holdcnt02.sh, but with mmap'ed write. +# Use 16 GB RAM or less. +# Deadlock seen: +# https://people.freebsd.org/~pho/stress/log/alan018.txt + +# Test scenario suggestion by alc@ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `swapinfo | wc -l` -eq 1 ] && exit 0 +[ `sysctl -n hw.physmem` -lt $((32 * 1024 * 1024 * 1024)) ] && exit 0 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > holdcnt03.c +mycc -o holdcnt03 -Wall -Wextra -g holdcnt03.c || exit 1 +rm -f holdcnt03.c +cd $here + +trap "rm -f /tmp/holdcnt03 `dirname $diskimage`/f000???" EXIT INT +(cd `dirname $diskimage`; /tmp/holdcnt03) & +pid=$! +sleep 5 +while kill -0 $! 2> /dev/null; do + (cd ../testcases/swap; ./swap -t 1m -i 1) > /dev/null 2>&1 +done +wait $pid +exit +EOF +/* + A test that causes the page daemon to generate cached pages + within a bunch of files and has some consumer that is trying to + allocate new pages to the same files. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE (1024 * 1024) +#define FILES 200 +#define RPARALLEL 8 +#define WPARALLEL 2 + +static jmp_buf jbuf; +static off_t maxsize; +static int ps; +static char *buf; + +static void +hand(int i __unused) { /* handler */ + longjmp(jbuf, 1); +} + +static void +cleanup(void) +{ + int i; + char file[80]; + + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + unlink(file); + } +} + +static void +init(void) +{ + char file[80]; + int fd, i; + + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1) + err(1, "open(%s)", file); + if (write(fd, buf, BUFSIZE) != BUFSIZE) + err(1, "write"); + close(fd); + } + +} + +static void +writer(void) +{ + int fd, i; + char file[80]; + time_t start; + struct stat statbuf; + + setproctitle("writer"); + start = time(NULL); + while (time(NULL) - start < 600) { + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if ((fd = open(file, O_RDWR | O_APPEND)) == -1) { + if (errno != ENOENT) + err(1, "open(%s) append", file); + goto err; + } + if (fstat(fd, &statbuf) < 0) + err(1, "fstat error"); + if (statbuf.st_size < maxsize) { + if (write(fd, buf, ps) != ps) { + warn("writer"); + goto err; + } + } + close(fd); + } + } +err: + cleanup(); + + _exit(0); +} + +static void +touch(void) +{ + int fd, i, j, n; + void *p; + size_t len; + char file[80]; + struct stat statbuf; + + setproctitle("touch"); + signal(SIGSEGV, hand); + signal(SIGBUS, hand); + fd = 0; + for (;;) { + (void)setjmp(jbuf); + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if (fd > 0) + close(fd); + if ((fd = open(file, O_RDWR)) == -1) { + if (errno != ENOENT) + warn("touch(%s)", file); + _exit(0); + } + if (fstat(fd, &statbuf) < 0) + err(1, "fstat error"); + if (statbuf.st_size >= maxsize) { + if (ftruncate(fd, ps) == -1) + err(1, "ftruncate"); + continue; + } + len = statbuf.st_size; + if ((p = mmap(p, len, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) + err(1, "mmap()"); + close(fd); + n = statbuf.st_size / ps; + for (j = 0; j < n; j++) { + *(char *)p = 1; + p = p + ps; + } + if (munmap(p, len) == -1) + perror("munmap"); + } + } + _exit(0); +} + +int +main(void) +{ + pid_t rpid[RPARALLEL], wpid[WPARALLEL]; + int e, i, s; + + maxsize = 2LL * 1024 * 1024 * 1024 / FILES; + buf = malloc(BUFSIZE); + ps = getpagesize(); + + init(); + e = 0; + for (i = 0; i < WPARALLEL; i++) { + if ((wpid[i] = fork()) == 0) + writer(); + } + for (i = 0; i < RPARALLEL; i++) { + if ((rpid[i] = fork()) == 0) + touch(); + } + + for (i = 0; i < WPARALLEL; i++) + waitpid(wpid[i], &s, 0); + e += s == 0 ? 0 : 1; + for (i = 0; i < RPARALLEL; i++) + waitpid(rpid[i], &s, 0); + e += s == 0 ? 0 : 1; + + free(buf); + + return (e); +} diff --git a/tools/test/stress2/misc/holdcnt04.sh b/tools/test/stress2/misc/holdcnt04.sh new file mode 100755 index 000000000000..52aff0e3816d --- /dev/null +++ b/tools/test/stress2/misc/holdcnt04.sh @@ -0,0 +1,248 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Lite version of holdcnt0.sh + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `sysctl -n vm.swap_total` -ne 0 ] && exit 0 +[ `sysctl -n hw.physmem` -lt 5250000000 ] && exit 0 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > holdcnt04.c +mycc -o holdcnt04 -Wall -Wextra -g holdcnt04.c || exit 1 +rm -f holdcnt04.c +cd $here + +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 +bsdlabel -w md$mdstart auto +newfs md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +(cd $mntpoint; /tmp/holdcnt04) & +pid=$! +sleep 5 +while kill -0 $! 2> /dev/null; do + (cd ../testcases/swap; ./swap -t 1m -i 1) > /dev/null 2>&1 +done +wait $pid; s=$? + +while mount | grep -q md${mdstart}$part; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/holdcnt04 +exit $s +EOF +/* + A test that causes the page daemon to generate cached pages + within a bunch of files and has some consumer that is trying to + allocate new pages to the same files. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE (1024 * 1024) +#define FILES 20 +#define RPARALLEL 8 +#define WPARALLEL 2 + +static jmp_buf jbuf; +static off_t maxsize; +static int ps; +static char *buf; +static volatile char val; + +static void +hand(int i __unused) { /* handler */ + longjmp(jbuf, 1); +} + +static void +cleanup(void) +{ + int i; + char file[80]; + + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + unlink(file); + } +} + +static void +init(void) +{ + int fd, i; + char file[80]; + + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0644)) == + -1) + err(1, "open(%s)", file); + if (write(fd, buf, BUFSIZE) != BUFSIZE) + err(1, "write"); + close(fd); + } + +} + +static void +writer(void) +{ + struct stat statbuf; + time_t start; + int fd, i; + char file[80]; + + setproctitle("writer"); + start = time(NULL); + while (time(NULL) - start < 600) { + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if ((fd = open(file, O_RDWR | O_APPEND)) == -1) { + if (errno != ENOENT) + err(1, "open(%s) append", file); + goto err; + } + if (fstat(fd, &statbuf) < 0) + err(1, "fstat error"); + if (statbuf.st_size < maxsize) { + if (write(fd, buf, ps) != ps) { + warn("writer"); + goto err; + } + } + close(fd); + } + } +err: + cleanup(); + + _exit(0); +} + +static void +reader(void) +{ + struct stat statbuf; + void *p; + size_t len; + int fd, i, j, n; + char file[80]; + + setproctitle("reader"); + signal(SIGSEGV, hand); + signal(SIGBUS, hand); + fd = 0; + for (;;) { + (void)setjmp(jbuf); + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if (fd > 0) + close(fd); + if ((fd = open(file, O_RDWR)) == -1) { + if (errno != ENOENT) + warn("reader(%s)", file); + _exit(0); + } + if (fstat(fd, &statbuf) < 0) + err(1, "fstat error"); + if (statbuf.st_size >= maxsize) { + if (ftruncate(fd, ps) == -1) + err(1, "ftruncate"); + continue; + } + len = statbuf.st_size; + if ((p = mmap(p, len, PROT_READ, MAP_SHARED, fd, 0)) + == MAP_FAILED) + err(1, "mmap()"); + close(fd); + n = statbuf.st_size / ps; + for (j = 0; j < n; j++) { + val = *(char *)p; + p = p + ps; + } +#if 0 + if (munmap(p, len) == -1) + perror("munmap"); +#endif + } + } + _exit(0); +} +int +main(void) +{ + pid_t rpid[RPARALLEL], wpid[WPARALLEL]; + int e, i, s; + + maxsize = 1LL * 1024 * 1024 * 1024 / FILES; + buf = malloc(BUFSIZE); + ps = getpagesize(); + + init(); + e = 0; + for (i = 0; i < WPARALLEL; i++) { + if ((wpid[i] = fork()) == 0) + writer(); + } + for (i = 0; i < RPARALLEL; i++) { + if ((rpid[i] = fork()) == 0) + reader(); + } + + for (i = 0; i < WPARALLEL; i++) + waitpid(wpid[i], &s, 0); + e += s == 0 ? 0 : 1; + for (i = 0; i < RPARALLEL; i++) + waitpid(rpid[i], &s, 0); + e += s == 0 ? 0 : 1; + + free(buf); + + return (e); +} diff --git a/tools/test/stress2/misc/holdcnt05.sh b/tools/test/stress2/misc/holdcnt05.sh new file mode 100755 index 000000000000..efafa984bdd8 --- /dev/null +++ b/tools/test/stress2/misc/holdcnt05.sh @@ -0,0 +1,249 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# Tmpfs version of holdcnt0.sh +# Test scenario suggestion by alc@ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `swapinfo | wc -l` -eq 1 ] && exit 0 +[ `sysctl -n hw.physmem` -lt $((32 * 1024 * 1024 * 1024)) ] && exit 0 + +. ../default.cfg +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > holdcnt05.c +cc -o holdcnt05 -Wall -Wextra -g holdcnt05.c || exit 1 +rm -f holdcnt05.c +cd $here + +mount | grep $mntpoint && umount -f $mntpoint +mount -t tmpfs null $mntpoint + +cd $mntpoint +/tmp/holdcnt05 +s=$? + +cd / +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +rm -f /tmp/holdcnt05 +[ $s -ne 0 ] && echo "Exit status $s" +exit $s +EOF +/* + A test that causes the page daemon to generate cached pages + within a bunch of files and has some consumer that is trying to + allocate new pages to the same files. +*/ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFSIZE (1024 * 1024) +#define FILES 200 +#define RPARALLEL 8 +#define WPARALLEL 2 + +static jmp_buf jbuf; +static off_t maxsize; +static int ps; +static char *buf; +static volatile char val; + +static void +hand(int i __unused) { /* handler */ + +#if defined(DEBUG) + fprintf(stderr, "%d ", i); +#endif + longjmp(jbuf, 1); +} + +static void +cleanup(void) +{ + int i; + char file[80]; + + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + unlink(file); + } +} + +static void +init(void) +{ + int fd, i; + char file[80]; + + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0644)) == + -1) + err(1, "open(%s)", file); + if (write(fd, buf, BUFSIZE) != BUFSIZE) + err(1, "write"); + close(fd); + } + +} + +static void +writer(void) +{ + struct stat statbuf; + time_t start; + int fd, i; + char file[80]; + + setproctitle("writer"); + start = time(NULL); + while (time(NULL) - start < 600) { + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if ((fd = open(file, O_RDWR | O_APPEND)) == -1) { + if (errno != ENOENT) + err(1, "open(%s) append", file); + goto err; + } + if (fstat(fd, &statbuf) < 0) + err(1, "fstat error"); + if (statbuf.st_size < maxsize) { + if (write(fd, buf, ps) != ps) { + warn("writer"); + goto err; + } + } + close(fd); + } + } +err: + cleanup(); + + _exit(0); +} + +static void +reader(void) +{ + struct stat statbuf; + void *p; + size_t len; + int fd, i, j, n; + char file[80]; + + setproctitle("reader"); + signal(SIGSEGV, hand); + signal(SIGBUS, hand); + fd = 0; + for (;;) { + (void)setjmp(jbuf); + for (i = 0; i < FILES; i++) { + snprintf(file, sizeof(file), "f%06d", i); + if (fd > 0) + close(fd); + if ((fd = open(file, O_RDWR)) == -1) { + if (errno != ENOENT) + warn("reader(%s)", file); + _exit(0); + } + if (fstat(fd, &statbuf) < 0) + err(1, "fstat error"); + if (statbuf.st_size >= maxsize) { + if (ftruncate(fd, ps) == -1) + err(1, "ftruncate"); + continue; + } + len = statbuf.st_size; + if ((p = mmap(p, len, PROT_READ, MAP_SHARED, fd, 0)) + == MAP_FAILED) + err(1, "mmap()"); + close(fd); + n = statbuf.st_size / ps; + for (j = 0; j < n; j++) { + val = *(char *)p; + p = p + ps; + } +#if 0 + if (munmap(p, len) == -1) + perror("munmap"); +#endif + } + } + _exit(0); +} +int +main(void) +{ + pid_t rpid[RPARALLEL], wpid[WPARALLEL]; + int e, i, s; + + maxsize = 2LL * 1024 * 1024 * 1024 / FILES; + buf = malloc(BUFSIZE); + ps = getpagesize(); + + init(); + e = 0; + for (i = 0; i < WPARALLEL; i++) { + if ((wpid[i] = fork()) == 0) + writer(); + } + for (i = 0; i < RPARALLEL; i++) { + if ((rpid[i] = fork()) == 0) + reader(); + } + + for (i = 0; i < WPARALLEL; i++) { + waitpid(wpid[i], &s, 0); + if (e == 0) + e = s; + } + for (i = 0; i < RPARALLEL; i++) { + waitpid(rpid[i], &s, 0); + if (e == 0) + e = s; + } + free(buf); + + return (e); +} diff --git a/tools/test/stress2/misc/ifconfig.sh b/tools/test/stress2/misc/ifconfig.sh new file mode 100755 index 000000000000..6359711a0445 --- /dev/null +++ b/tools/test/stress2/misc/ifconfig.sh @@ -0,0 +1,60 @@ +#!/bin/sh +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# Test scenario from D17599 "Fix for double free when deleting entries from +# epoch managed lists" +# by Hans Petter Selasky + +# "panic: starting DAD on non-tentative address 0xfffff8010c311000" seen. +# https://people.freebsd.org/~pho/stress/log/epoch.txt + +# Fatal trap 9: general protection fault while in kernel mode +# https://people.freebsd.org/~pho/stress/log/epoch-2.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +if=`ifconfig | grep -w mtu | grep -v RUNNING | sed 's/:.*//' | head -1` +[ -z "$if" ] && + if=`ifconfig | \ + awk '/^[a-z].*: / {gsub(":", ""); ifn = $1}; /no car/{print ifn; exit}'` + +[ -z "$if" ] && exit 0 +echo "Using $if for test." +ifconfig $if | grep -q RUNNING && running=1 + +start=`date +%s` +while [ $((`date +%s` - start)) -lt 300 ]; do + for i in `jot 255`; do + (ifconfig $if.$i create + ifconfig $if.$i inet 224.0.0.$i + ifconfig $if.$i destroy) > /dev/null 2>&1 & + done + wait +done +[ $running ] || ifconfig $if down + +exit 0 diff --git a/tools/test/stress2/misc/ifconfig2.sh b/tools/test/stress2/misc/ifconfig2.sh new file mode 100755 index 000000000000..61abbab3dd54 --- /dev/null +++ b/tools/test/stress2/misc/ifconfig2.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# +# Test scenario from D17599 "Fix for double free when deleting entries from +# epoch managed lists" +# by Hans Petter Selasky + +# Page fault in nd6_dad_timer+0x6b seen: +# https://people.freebsd.org/~pho/stress/log/ifconfig2.txt +# https://people.freebsd.org/~pho/stress/log/log0051.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +if=`ifconfig | grep -w mtu | grep -v RUNNING | sed 's/:.*//' | head -1` +[ -z "$if" ] && + if=`ifconfig | \ + awk '/^[a-z].*: / {gsub(":", ""); ifn = $1}; /no car/{print ifn; exit}'` + +[ -z "$if" ] && exit 0 +echo "Using $if for test." +ifconfig $if | grep -q RUNNING && running=1 + +sync=/tmp/`basename $0`.sync +rm -f $sync +for i in `jot 5`; do + ( + while [ ! -f $sync ]; do + sleep .1 + done + while [ -f $sync ]; do + ifconfig $if.$i create + ifconfig $if.$i inet 224.0.0.$i + ifconfig $if.$i destroy + done + ) > /dev/null 2>&1 & +done +touch $sync +sleep 120 +rm -f $sync +wait +[ $running ] || ifconfig $if down + +exit 0 diff --git a/tools/test/stress2/misc/indir.sh b/tools/test/stress2/misc/indir.sh new file mode 100755 index 000000000000..d2d28cd650ab --- /dev/null +++ b/tools/test/stress2/misc/indir.sh @@ -0,0 +1,201 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +# Hunt for "panic: ufsdirhash_dirtrunc: bad offset" +# by making the directory inode grow into the indirect blocks. + +# Truncate directories larger than 12 * block_size bytes +# default is 12 * 32768 = 393216, 384k + +# No problems seen. + +. ../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/indir.c +sed -i '' -e "s#MNTPOINT#$mntpoint#g" $dir/indir.c +mycc -o indir -Wall -Wextra -O0 -g indir.c || exit 1 +rm -f indir.c +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 1g -u $mdstart +newfs -j -n -b 16384 -f 2048 -i 2048 md$mdstart > /dev/null +mount /dev/md$mdstart $mntpoint +ifree=`df -i $mntpoint | tail -1 | awk '{print $7 - 50}'` +set +e + +if [ $dtrace ]; then + dtrace -w -n '*ufsdirhash_dirtrunc:entry {@rw[execname,probefunc] = \ + count(); }' & + dpid=$! + sleep 2 +fi + +/tmp/indir $mntpoint $ifree + +if [ $dtrace ]; then + kill -s TERM $dpid + wait $dpid +fi + +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/indir +if [ $dtrace ]; then + while pgrep -q dtrace; do sleep 1; done + kldstat | grep -q dtraceall && + kldunload dtraceall.ko +fi +exit 0 +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static long files; +static char *path; + +#define PARALLEL 64 +#define RUNTIME (10 * 60) + +static void +test(int idx) +{ + long j; + int fd; + pid_t pid; + char dir[128], file[128], new[128]; + + sleep(1); + + snprintf(dir, sizeof(dir), "%s/d%d", path, idx); + if (mkdir(dir, 0755) == -1) { + if (errno != EEXIST) + err(1, "mkdir(%s)", dir); + } + if (chdir(dir) == -1) + err(1, "chdir(%s)", dir); + + pid = getpid(); + for (j = 0; j < files; j++) { + sprintf(file,"p%05d.%05ld", pid, j); + if ((fd = creat(file, 0660)) == -1) + err(1, "creat(%s). %s:%d", file, __FILE__, __LINE__); + if (fd != -1 && close(fd) == -1) + err(2, "close(%ld)", j); + } + + for (j = 0; j < files; j++) { + sprintf(file,"p%05d.%05ld", pid, j); + sprintf(new,"p%05d.%05ld.old", pid, j); + if (rename(file, new) == -1) + err(1, "rename(%s, %s)", file, new); + } + + for (j = 0; j < files; j++) { + sprintf(file,"p%05d.%05ld", pid, j); + sprintf(new,"p%05d.%05ld.old", pid, j); + if (rename(new, file) == -1) + err(1, "rename(%s, %s)", new, file); + } + + for (j = 0; j < files; j++) { + sprintf(file,"p%05d.%05ld", pid, j); + if (unlink(file) == -1) + warn("unlink(%s)", file); + + } + if (chdir("..") == -1) + err(1, "chdir .."); + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + pid_t pids[PARALLEL]; + time_t start; + int e, i, n, status; + + if (argc != 3) { + fprintf(stderr, "Usage %s \n", argv[0]); + exit(1); + } + path = argv[1]; + files = atol(argv[2]) / PARALLEL; + fprintf(stderr, "Using %ld inodes per dir. %d threads. %ld inodes in total\n", + files, PARALLEL, files * PARALLEL); + e = n = 0; + start = time(NULL); + while ((time(NULL) - start) < RUNTIME && e == 0) { + fprintf(stderr, "Loop #%d\n", ++n); + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(i); + 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; + } +// system("(cd MNTPOINT; umount MNTPOINT) > /dev/null 2>&1"); + } + + return (e); +} diff --git a/tools/test/stress2/misc/indir_trunc.sh b/tools/test/stress2/misc/indir_trunc.sh new file mode 100755 index 000000000000..64c11f3570ee --- /dev/null +++ b/tools/test/stress2/misc/indir_trunc.sh @@ -0,0 +1,231 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# No problems seen. +# Test scenario inspired by: +# syzbot+6532e9aab8911f58beeb@syzkaller.appspotmail.com + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 +[ `uname -m` = "i386" ] && exit 0 # OOM killing + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/indir_trunc.c +mycc -o indir_trunc -Wall -Wextra -O0 -g indir_trunc.c -lpthread || exit 1 +rm -f indir_trunc.c +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 40g -u $mdstart +newfs $newfs_flags -n md$mdstart > /dev/null +mount /dev/md$mdstart $mntpoint +set +e + +###(cd ../testcases/swap; ./swap -t 5m -i 20) & +cd $mntpoint +$dir/indir_trunc +s=$? +while pkill swap; do :; done +wait +[ -f indir_trunc.core -a $s -eq 0 ] && + { ls -l indir_trunc.core; mv indir_trunc.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 +rm -rf $dir/indir_trunc +exit $s + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; + +#if defined(__LP64__) +#define MASK 0x7ffffffffffffULL +#else +#define MASK 0xffffffff +#endif +#define PARALLEL 64 +#define RUNTIME (5 * 60) +#define SYNC 0 + +static int fd; + +static void * +t1(void *data __unused) +{ + off_t offset; + time_t start; + char *cmdline[] = { "/usr/bin/true", NULL }; + + start = time(NULL); + while (time(NULL) - start < 60) { + offset = arc4random(); + offset = (offset << 32) | arc4random(); + offset &= MASK; + if (lseek(fd, offset, SEEK_SET) == -1) + err(1, "lseek(%jd)", offset); + if (write(fd, "a", 1) != 1) + err(1, "write"); + usleep(10); + if (arc4random() % 1000 < 2) { + if (execve(cmdline[0], cmdline, NULL) == -1) + err(1, "execve"); + } + } + + return (NULL); +} +static void * +t2(void *data __unused) +{ + off_t offset, old; + time_t start; + void *p; + char *c; + + old = 0; + start = time(NULL); + while (time(NULL) - start < 60) { + if (old != 0) + munmap(p, old); + offset = arc4random(); + offset = (offset << 32) | arc4random(); + offset &= MASK; + if (ftruncate(fd, offset) == -1) + err(1, "ftruncate(%jd)", offset); + write(fd, "b", 1); + p = mmap(NULL, offset, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, 0); + if (p == MAP_FAILED) + old = 0; + else { + old = offset; + c = p; + c[offset / 2] = 1; + if (offset > 0) + c[offset - 1] = 2; + } + usleep(10); + } + return (NULL); +} + +static void +test(void) +{ + pthread_t tid[2]; + int r; + char file[80]; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + snprintf(file, sizeof(file), "file.%d", getpid()); + if ((fd = open(file, O_RDWR | O_CREAT, DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + + 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"); + close(fd); + unlink(file); + + _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); +} diff --git a/tools/test/stress2/misc/inversion.sh b/tools/test/stress2/misc/inversion.sh new file mode 100755 index 000000000000..759549af0233 --- /dev/null +++ b/tools/test/stress2/misc/inversion.sh @@ -0,0 +1,97 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Provokes a deadlock by lower priority process holding a lock and +# never beeing run + +. ../default.cfg + +dir=$RUNDIR +N=5 # Number of CPUs + 1 +M=25 # Number of lower priority jobs + +odir=`pwd` +mkdir -p $dir || exit 1 +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/inversion.c +mycc -o inversion -Wall inversion.c +rm -f inversion.c + +mp=`df $dir | tail -1 | awk '{print $NF}'` +mp=`mount | grep "on $mp "` +if echo $mp | grep -wq nfs; then + pgrep -q lockd || { echo "lockd not running"; exit 0; } +fi + +for i in `jot $N`; do + ./inversion 600 & +done + +while pgrep inversion > /dev/null; do + ( + for i in `jot $M`; do + nice -n 20 lockf -s -t 0 .lock pwd > /dev/null & + done + for i in `jot $M`; do + wait + done + ) +done + +for i in `jot $N`; do + wait +done +rm -f inversion +exit + +EOF +#include +#include +#include + +void +handler(int i) +{ + exit(0); +} + +int +main(int argc, char **argv) +{ + + int t; + if (argc == 2) + t = atoi(argv[1]); + else + t = 60; + signal(SIGALRM, handler); + alarm(t); + for (;;) + ; + return (0); +} diff --git a/tools/test/stress2/misc/isofs.sh b/tools/test/stress2/misc/isofs.sh new file mode 100755 index 000000000000..5f5c26e00b4c --- /dev/null +++ b/tools/test/stress2/misc/isofs.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 not be root!" && exit 1 + +[ -z "`type mkisofs 2>/dev/null`" ] && echo "mkisofs not found" && exit 0 + +. ../default.cfg + +D=`dirname $diskimage`/dir +I=`dirname $diskimage`/dir.iso +export here=`pwd` +cd /tmp + +mycc -o fstool $here/../tools/fstool.c + +rm -rf $D $I +mkdir $D + +(cd $D; /tmp/fstool -n 10 -l -f 512) + +mkisofs -o $I -r $D > /dev/null 2>&1 + +mdconfig -a -t vnode -f $I -u $mdstart +mount -t cd9660 /dev/md$mdstart $mntpoint + +for i in `jot 64`; do + find /$mntpoint -type f > /dev/null 2>&1 & +done +wait + +umount $mntpoint +mdconfig -d -u $mdstart + +rm -rf $D $I fstool diff --git a/tools/test/stress2/misc/isofs2.sh b/tools/test/stress2/misc/isofs2.sh new file mode 100755 index 000000000000..ad03e7e410b0 --- /dev/null +++ b/tools/test/stress2/misc/isofs2.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Run program from isofs file system +# "panic: userret: returning with the following locks held:" +# https://people.freebsd.org/~pho/stress/log/isofs2.txt +# Fixed by: r292772. + +[ `id -u ` -ne 0 ] && echo "Must not be root!" && exit 1 + +[ -z "`type mkisofs 2>/dev/null`" ] && echo "mkisofs not found" && exit 0 + +. ../default.cfg + +D=`dirname $diskimage`/dir +I=`dirname $diskimage`/dir.iso +here=`pwd` +cd /tmp +rm -rf $D $I +mkdir $D +cp `which date` $D +mkisofs -o $I -r $D > /dev/null 2>&1 +mdconfig -a -t vnode -f $I -u $mdstart +mount -t cd9660 /dev/md$mdstart $mntpoint + +cd $mntpoint +./date > /dev/null +cd $here + +umount $mntpoint +mdconfig -d -u $mdstart + +rm -rf $D $I diff --git a/tools/test/stress2/misc/isofs3.sh b/tools/test/stress2/misc/isofs3.sh new file mode 100755 index 000000000000..476c729568ac --- /dev/null +++ b/tools/test/stress2/misc/isofs3.sh @@ -0,0 +1,66 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC +# All rights reserved. +# +# 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. +# + +# Simple isofs / union test scenario + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -z "`which mkisofs`" ] && echo "mkisofs not found" && exit 0 + +. ../default.cfg + +D=`dirname $diskimage`/dir +I=`dirname $diskimage`/dir.iso + +rm -rf $D $I +mkdir -p $D +cp -r ../../stress2 $D 2>/dev/null + +mkisofs -o $I -r $D > /dev/null 2>&1 + +mount | grep -q /dev/md${mdstart}$part && umount -f /dev/md${mdstart}$part +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t vnode -f $I -u $mdstart || exit 1 +mount -t cd9660 /dev/md$mdstart $mntpoint || exit 1 + +m2=$((mdstart + 1)) +mdconfig -s 1g -u $m2 +bsdlabel -w md$m2 auto +newfs $newfs_flags md${m2}$part > /dev/null + +mount -o union /dev/md${m2}$part $mntpoint || exit 1 + +export RUNDIR=$mntpoint/stressX +export runRUNTIME=5m +(cd $mntpoint/stress2; ./run.sh marcus.cfg) > /dev/null + +umount $mntpoint +mdconfig -d -u $m2 +umount $mntpoint +mdconfig -d -u $mdstart +rm -rf $D $I +exit 0 diff --git a/tools/test/stress2/misc/jail.sh b/tools/test/stress2/misc/jail.sh new file mode 100755 index 000000000000..2c77033d10a2 --- /dev/null +++ b/tools/test/stress2/misc/jail.sh @@ -0,0 +1,66 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 problem found with the syscall.sh test + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > jail.c +mycc -o jail -Wall jail.c +rm -f jail.c +cd $RUNDIR +/tmp/jail +rm -f /tmp/jail +exit +EOF +#include +#include +#include + +int +main() +{ + struct jail j; + + j.version = 2; + j.path = (char *)0xa000000; + j.hostname = (char *)1; + j.jailname = (char *)0; + j.ip4s = 0; + j.ip6s = 0; + j.ip4 = (struct in_addr *)0x58000000; + j.ip6 = (struct in6_addr *)0x33000001; + + if (jail(&j) == -1) + err(1, "jail()"); + + return (0); +} diff --git a/tools/test/stress2/misc/jail2.sh b/tools/test/stress2/misc/jail2.sh new file mode 100755 index 000000000000..7247eacb73b6 --- /dev/null +++ b/tools/test/stress2/misc/jail2.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 problem found with the syscall.sh test + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > jail2.c +mycc -o jail2 -Wall jail2.c +rm -f jail2.c +cd $odir +/tmp/jail2 +rm -f /tmp/jail2 +exit +EOF +#include +#include +#include + +int +main() +{ + struct jail j; + + /* + version = 0x2, + path = 0x0, + hostname = 0x0, + jailname = 0x50000000
    , + ip4s = 0xf7000004, + ip6s = 0x1, + ip4 = 0x0, + ip6 = 0x0 + */ + j.version = 2; + j.path = 0; + j.hostname = 0; + j.jailname = (char *)0x50000000; + j.ip4s = 0xf7000004; + j.ip6s = 1; + j.ip4 = 0; + j.ip6 = 0; + + if (jail(&j) == -1) + err(1, "jail()"); + + return (0); +} diff --git a/tools/test/stress2/misc/jail3.sh b/tools/test/stress2/misc/jail3.sh new file mode 100755 index 000000000000..97bc078e8e89 --- /dev/null +++ b/tools/test/stress2/misc/jail3.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 problem found with the syscall.sh test + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > jail3.c +mycc -o jail3 -Wall jail3.c +rm -f jail3.c +cd $odir +/tmp/jail3 +rm -f /tmp/jail3 +exit +EOF +#include +#include +#include + +int +main() +{ + struct jail j; + + /* + version = 0x0, + path = 0x2809cd61
    , + hostname = 0x2809b650
    , + jailname = 0x0, + ip4s = 0x1, + ip6s = 0x0, + ip4 = 0x0, + ip6 = 0x0 + */ + j.version = 0; + j.path = (char *)0x2809cd61; + j.hostname = (char *)0x2809b650; + j.jailname = 0; + j.ip4s = 1; + j.ip6s = 0; + j.ip4 = 0; + j.ip6 = 0; + + if (jail(&j) == -1) + err(1, "jail()"); + + return (0); +} diff --git a/tools/test/stress2/misc/jail4.sh b/tools/test/stress2/misc/jail4.sh new file mode 100755 index 000000000000..c641c957997d --- /dev/null +++ b/tools/test/stress2/misc/jail4.sh @@ -0,0 +1,78 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 problem found with the syscall.sh test + +# "panic: kern_jail: too many iovecs (28)" seen. + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > jail4.c +mycc -o jail4 -Wall jail4.c +rm -f jail4.c +cd $odir +/tmp/jail4 +rm -f /tmp/jail4 +exit +EOF +#include +#include +#include + +int +main() +{ + struct jail j; + + /* + version = 0x2, + path = 0x28190cb1
    , + hostname = 0x28167b90
    , + jailname = 0x28198700
    , + ip4s = 0x0, + ip6s = 0x0, + ip4 = 0x0, + ip6 = 0x0} + */ + j.version = 2; + j.path = (char *)0x28190cb1; + j.hostname = (char *)0x28167b90; + j.jailname = (char *)0x28198700; + j.ip4s = 0; + j.ip6s = 0; + j.ip4 = 0; + j.ip6 = 0; + + if (jail(&j) == -1) + err(1, "jail()"); + + return (0); +} diff --git a/tools/test/stress2/misc/jexec.sh b/tools/test/stress2/misc/jexec.sh new file mode 100755 index 000000000000..c5c2ab605e08 --- /dev/null +++ b/tools/test/stress2/misc/jexec.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +# Bug 238032 - "jexec pr_ref leak" by bz@ +# "foo DYING" seen. +# Fixed by r358676 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 +mount | grep "$mntpoint" | grep -q nfs && umount $mntpoint +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export $mntpoint + +here=`pwd` +cd $mntpoint +(cd $here/../testcases/swap; ./swap -t 2m -i 20) & +sleep 10 +jail -c name=foo persist +start=`date +%s` +while [ $((`date +%s`- start)) -lt 120 ]; do + jexec foo <<-EOF + sleep .2 +EOF +done > /dev/null 2>&1 +jail -r foo +jls -dv | grep foo && s=1 || s=0 + +cd $here +for i in `jot 5`; do + umount $mntpoint && break + sleep 2 +done +wait + +# Break into kgdb and type "show prison" +# Check ref count growth + +exit $s diff --git a/tools/test/stress2/misc/jumbo.sh b/tools/test/stress2/misc/jumbo.sh new file mode 100755 index 000000000000..8dcc5aa7aca3 --- /dev/null +++ b/tools/test/stress2/misc/jumbo.sh @@ -0,0 +1,221 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Stress the jumbo mbuf allocation +# vmstat -z | sed -n '1p;/jumbo/p' + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > jumbo.c +mycc -o jumbo -Wall -Wextra -O2 jumbo.c || exit 1 +rm -f jumbo.c + +log=/tmp/mbuf.log +nb=80 +host=localhost +[ $# -eq 1 ] && host=$1 +( + for i in `jot $nb 0`; do + /tmp/jumbo $((12345 + $i)) & + done + sleep 30 + for i in `jot $nb 0`; do + /tmp/jumbo $host $((12345 + $i)) & + done + for i in `jot $nb 0`; do + wait + done +) > $log 2>&1 + +rm -f /tmp/jumbo +grep -q FAIL $log && { cat $log 1>&2; exit 1; } +rm -f $log +exit 0 +EOF +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MX (1024 * 1024) +#define RETRIES 5 +#define TIMEOUT 1200 + +char *host; +int loops, port, server; + +void +ahandler(int s __unused) +{ + if (server) + fprintf(stderr, "FAIL Server timed out after %d loops.\n", + loops); + else + fprintf(stderr, "FAIL Client timed out after %d loops.\n", + loops); + _exit(0); +} + +static void +reader(void) { + socklen_t len; + struct sockaddr_in inetaddr, inetpeer; + int *buf, i, n, msgsock, on, tcpsock; + + setproctitle("reader - init"); + 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); + + signal(SIGALRM, ahandler); + alarm(TIMEOUT); + 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 ((buf = malloc(MX)) == NULL) + err(1, "malloc(%d), %s:%d", MX, __FILE__, __LINE__); + setproctitle("reader"); + for (i = 4096; i < MX; i += 1024) { + alarm(TIMEOUT); + if ((n = recvfrom(msgsock, buf, i, MSG_WAITALL, NULL, + NULL)) < 0) { + if (errno == EAGAIN) + continue; + err(1, "read(), %s:%d", __FILE__, __LINE__); + } + if (n == 0) + break; + + loops++; + } + close(msgsock); + _exit(0); +} + +static void +writer(void) { + struct sockaddr_in inetaddr; + struct hostent *hostent; + int i, on, r, tcpsock; + char *line; + + setproctitle("writer - init"); + signal(SIGALRM, ahandler); + alarm(TIMEOUT); + on = 1; + for (i = 0; i < RETRIES; 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__); + + if ((hostent = gethostbyname (host)) == NULL) + err(1, "gethostbyname(%s)", host); + bzero((char *) &inetaddr, sizeof(inetaddr)); + 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), %s:%d", host, port, __FILE__, + __LINE__); + + setproctitle("writer"); + if ((line = malloc(MX)) == NULL) + err(1, "malloc(%d), %s:%d", MX, __FILE__, __LINE__); + alarm(TIMEOUT); + for (i = sysconf(_SC_PAGESIZE); i < MX; i += 1024) { + if (write(tcpsock, line, i) < 0) + err(1, "socket write(). %s:%d", __FILE__, __LINE__); + loops++; + } + close(tcpsock); + + return; +} + +int +main(int argc, char **argv) +{ + + if (argc == 2) { + server = 1; + port = atoi(argv[1]); + reader(); + } else if (argc == 3) { + host = argv[1]; + port = atoi(argv[2]); + writer(); + } else + errx(1, "Usage: %s {} \n", argv[0]); + + return (0); +} diff --git a/tools/test/stress2/misc/kern_umtx_inf_loop.sh b/tools/test/stress2/misc/kern_umtx_inf_loop.sh new file mode 100755 index 000000000000..b8088814d7b2 --- /dev/null +++ b/tools/test/stress2/misc/kern_umtx_inf_loop.sh @@ -0,0 +1,148 @@ +#!/bin/sh + +# The program is a test case by Eric which demonstrates the +# bug, unkillable spinning thread, owning a spinlock. + +# "panic: spin lock held too long" seen. +# Fixed in r277970. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > kern_umtx_inf_loop.c +mycc -o kern_umtx_inf_loop -Wall -Wextra -O0 -g kern_umtx_inf_loop.c \ + -lpthread || exit 1 +rm -f kern_umtx_inf_loop.c + +/tmp/kern_umtx_inf_loop + +rm -f /tmp/kern_umtx_inf_loop +exit 0 +EOF +/*- + * Copyright (c) 2015 Eric van Gyzen + * All rights reserved. + * + * 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. + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +pthread_mutex_t the_mutex = PTHREAD_MUTEX_INITIALIZER; + +pthread_t contender; + +static void * +contender_func(void *arg) +{ + int error; + + (void) arg; + + error = pthread_mutex_lock(&the_mutex); + if (error) errc(1, error, "pthread_mutex_lock contender"); + + fprintf(stderr, "contender lock succeeded\n"); + + error = pthread_mutex_unlock(&the_mutex); + if (error) errc(1, error, "pthread_mutex_unlock contender"); + + fprintf(stderr, "contender unlock succeeded; exiting\n"); + + return (NULL); +} + +static void * +signaler_func(void *arg __unused) +{ + int error; + + // Wait for the main thread to sleep. + usleep(100000); + + error = pthread_kill(contender, SIGHUP); + if (error) errc(1, error, "pthread_kill"); + + // Wait for the contender to lock umtx_lock + // in umtx_repropagate_priority. + usleep(100000); + + error = pthread_mutex_lock(&the_mutex); + if (error) errc(1, error, "pthread_mutex_lock signaler"); + + return (NULL); +} + +int +main(void) +{ + int error; + + pthread_mutexattr_t mattr; + + error = pthread_mutexattr_init(&mattr); + if (error) errc(1, error, "pthread_mutexattr_init"); + + error = pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT); + if (error) errc(1, error, "pthread_mutexattr_setprotocol"); + + error = pthread_mutex_init(&the_mutex, &mattr); + if (error) errc(1, error, "pthread_mutex_init"); + + error = pthread_mutexattr_destroy(&mattr); + if (error) errc(1, error, "pthread_mutexattr_destroy"); + + //error = pthread_mutex_lock(&the_mutex); + //if (error) errc(1, error, "pthread_mutex_lock"); + + // Hack lock. + *(int *)the_mutex = pthread_getthreadid_np(); + + error = pthread_create(&contender, NULL, contender_func, NULL); + if (error) errc(1, error, "pthread_create"); + + // Wait for the contender to sleep. + usleep(100000); + + pthread_t signaler; + error = pthread_create(&signaler, NULL, signaler_func, NULL); + if (error) errc(1, error, "pthread_create"); + + error = pthread_mutex_lock(&the_mutex); + if (error) errc(1, error, "pthread_mutex_lock recurse"); + + return (0); +} + diff --git a/tools/test/stress2/misc/kevent.sh b/tools/test/stress2/misc/kevent.sh new file mode 100755 index 000000000000..ebcaca639849 --- /dev/null +++ b/tools/test/stress2/misc/kevent.sh @@ -0,0 +1,174 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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: KN_INFLUX set when not suppose to be + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kevent.c +mycc -o kevent -Wall kevent.c -pthread || exit 1 +rm -f kevent.c +[ -d "$RUNDIR" ] || mkdir -p $RUNDIR +cd $RUNDIR + +for i in `jot 10`; do + for j in `jot 12`; do + /tmp/kevent > /dev/null 2>&1 & + done + wait +done +rm -f /tmp/kevent +exit +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static int waiting; + +static int fd1[2]; +static int fd2[2]; +static int fd3[2]; + +#define RUNTIME 12 + +static void * +thr1(void *arg) +{ + struct kevent ev[3]; + int kq, n, r; + + if ((kq = kqueue()) < 0) + err(1, "kqueue(). %s:%d", __FILE__, __LINE__); + + n = 0; + EV_SET(&ev[n], fd1[1], EVFILT_WRITE, + EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0); + n++; + EV_SET(&ev[n], fd2[1], EVFILT_WRITE, + EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0); + n++; + EV_SET(&ev[n], fd3[1], EVFILT_WRITE, + EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0); + n++; + + if (kevent(kq, ev, n, NULL, 0, NULL) < 0) + err(1, "kevent(). %s:%d", __FILE__, __LINE__); + + if ((r = pthread_mutex_lock(&mutex)) != 0) + errc(1, r, "pthread_mutex_lock"); + waiting = 0; + if ((r = pthread_cond_signal(&cond)) != 0) + errc(1, r, "pthread_cond_signal"); + if ((r = pthread_mutex_unlock(&mutex)) != 0) + errc(1, r, "pthread_mutex_unlock"); + + n = 0; + EV_SET(&ev[n], fd1[1], EVFILT_WRITE, + EV_DELETE, 0, 0, 0); + n++; + if (kevent(kq, ev, n, NULL, 0, NULL) < 0) + warn("kevent(). %s:%d", __FILE__, __LINE__); + close(kq); + + return (0); +} + +static void * +thr2(void *arg) +{ + int r; + + if ((r = pthread_mutex_lock(&mutex)) != 0) + errc(1, r, "pthread_mutex_lock"); + while (waiting == 1) { + if ((r = pthread_cond_wait(&cond, &mutex)) != 0) + errc(1, r, "pthread_cond_wait"); + } + if ((r = pthread_mutex_unlock(&mutex)) != 0) + errc(1, r, "pthread_mutex_unlock"); + close(fd1[0]); + close(fd1[1]); + close(fd2[0]); + close(fd2[1]); + close(fd3[0]); + close(fd3[1]); + return (0); +} + +int +main(int argc, char **argv) +{ + pthread_t threads[2]; + time_t start; + int r; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + waiting = 1; + if (pipe(fd1) == -1) + err(1, "pipe()"); + if (pipe(fd2) == -1) + err(1, "pipe()"); + if (pipe(fd3) == -1) + err(1, "pipe()"); + + if ((r = pthread_mutex_init(&mutex, 0)) != 0) + errc(1, r, "pthread_mutex_init"); + if ((r = pthread_cond_init(&cond, NULL)) != 0) + errc(1, r, "pthread_cond_init"); + + if ((r = pthread_create(&threads[0], NULL, thr1, 0)) != 0) + errc(1, r, "pthread_create()"); + if ((r = pthread_create(&threads[1], NULL, thr2, 0)) != 0) + errc(1, r, "pthread_create()"); + + if ((r = pthread_join(threads[0], NULL)) != 0) + errc(1, r, "pthread_join(%d)", 0); + if ((r = pthread_join(threads[1], NULL)) != 0) + errc(1, r, "pthread_join(%d)", 1); + if ((r = pthread_mutex_destroy(&mutex)) != 0) + errc(1, r, "pthread_mutex_destroy"); + if ((r = pthread_cond_destroy(&cond)) != 0) + errc(1, r, "pthread_cond_destroy)"); + } + + return (0); +} diff --git a/tools/test/stress2/misc/kevent10.sh b/tools/test/stress2/misc/kevent10.sh new file mode 100755 index 000000000000..d746897cddcf --- /dev/null +++ b/tools/test/stress2/misc/kevent10.sh @@ -0,0 +1,96 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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 +# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=217435 +# by Tim Newsham + +# panic: Assertion size > 0 failed at ../../../kern/subr_vmem.c:1082 +# cpuid = 2 +# time = 1501182301 +# KDB: stack backtrace: +# db_trace_self_wrapper() at db_trace_self_wrapper+0x2b/frame 0xfffffe0173117650 +# vpanic() at vpanic+0x19c/frame 0xfffffe01731176d0 +# kassert_panic() at kassert_panic+0x126/frame 0xfffffe0173117740 +# vmem_alloc() at vmem_alloc+0x11b/frame 0xfffffe0173117780 +# kmem_malloc() at kmem_malloc+0x33/frame 0xfffffe01731177b0 +# uma_large_malloc() at uma_large_malloc+0x48/frame 0xfffffe01731177f0 +# malloc() at malloc+0xe3/frame 0xfffffe0173117840 +# ktrgenio() at ktrgenio+0x60/frame 0xfffffe0173117880 +# sys_kevent() at sys_kevent+0x12f/frame 0xfffffe0173117930 +# amd64_syscall() at amd64_syscall+0x7d2/frame 0xfffffe0173117ab0 + +# Fixed by r315155. + +. ../default.cfg + +cat > /tmp/kevent10.c < +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +int +main(void) +{ + struct kevent changes; + struct kevent events; + char *fn = "/tmp/kevent10.trace"; + + if (open(fn, O_RDWR | O_CREAT, 0666) == -1) + err(1, "%s", fn); + if (ktrace(fn, KTRFLAG_DESCEND | KTROP_SET, KTRFAC_GENIO, 0) == -1) + err(1, "ktrace"); + memset(&changes, 0, sizeof(struct kevent)); + memset(&events, 0, sizeof(struct kevent)); + if (kevent(0, &changes, -1, &events, 1, 0) == -1) + if (errno != EBADF) + err(1, "kevent"); + + return (0); +} +EOF + +mycc -o /tmp/kevent10 -Wall -Wextra -O2 /tmp/kevent10.c || exit 1 +rm /tmp/kevent10.c + +/tmp/kevent10 +s=$? + +rm /tmp/kevent10 /tmp/kevent10.trace +exit $s diff --git a/tools/test/stress2/misc/kevent11.sh b/tools/test/stress2/misc/kevent11.sh new file mode 100755 index 000000000000..f3a319f2ecff --- /dev/null +++ b/tools/test/stress2/misc/kevent11.sh @@ -0,0 +1,178 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 kevent5.sh +# OOM seen: https://people.freebsd.org/~pho/stress/log/mark018.txt + +. ../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/kevent11.c +mycc -o kevent11 -Wall -Wextra -O0 -g kevent11.c || exit 1 +rm -f kevent11.c +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +set +e + +(cd $odir/../testcases/swap; ./swap -t 5m -i 20 -h -l 100 > /dev/null) & +cd $mntpoint +$dir/kevent11 +s=$? +[ -f kevent11.core -a $s -eq 0 ] && + { ls -l kevent11.core; mv kevent11.core /tmp; s=1; } +cd $odir +while pkill -9 swap; do :; done +wait + +for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && exit 1 +mdconfig -d -u $mdstart +rm -rf $dir/kevent11 +exit $s + +EOF +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; +static char *file = "file"; + +#define PARALLEL 256 +#define RUNTIME (3 * 60) +#define SYNC 0 + +static void +test(void) +{ + struct kevent ev[2]; + struct timespec ts; + int kq, fd, n; + + if ((fd = open(file, O_RDONLY, 0)) == -1) + err(1, "open(%s). %s:%d", file, __func__, __LINE__); + + if ((kq = kqueue()) < 0) + err(1, "kqueue()"); + + n = 0; + EV_SET(&ev[n], fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, + NOTE_DELETE, 0, 0); + n++; + + if (kevent(kq, ev, n, NULL, 0, NULL) < 0) + err(1, "kevent()"); + + setproctitle("presync"); + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + usleep(10000); + setproctitle("postsync"); + + memset(&ev, 0, sizeof(ev)); + n = kevent(kq, NULL, 0, ev, 1, &ts); + close(fd); + close(kq); + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + size_t len; + time_t start; + int e, fd, 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) { + if ((fd = open(file, O_CREAT | O_TRUNC | O_RDWR, 0660)) == + -1) + err(1, "open(%s)", file); + close(fd); + share[SYNC] = 0; + for (i = 0; i < PARALLEL; i++) { + + if ((pids[i] = fork()) == 0) + test(); + if (pids[i] == -1) + err(1, "fork()"); + } + while (share[SYNC] != PARALLEL) + usleep(10000); + if (unlink(file) == -1) + err(1, "unlink(%s). %s:%d\n", file, + __FILE__, __LINE__); + 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); +} diff --git a/tools/test/stress2/misc/kevent12.sh b/tools/test/stress2/misc/kevent12.sh new file mode 100755 index 000000000000..3ae0085f1e5d --- /dev/null +++ b/tools/test/stress2/misc/kevent12.sh @@ -0,0 +1,233 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# Bug 228858 - panic when delivering knote to a process who has opened a +# kqueue() is dying +# Page fault seen: https://people.freebsd.org/~pho/stress/log/mark052.txt +# Fixed by r340897. + +# Test scenario based on analysis by siddharthtuli gmail com + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kevent12.c +mycc -o kevent12 -Wall -Wextra -O2 -g kevent12.c || exit 1 +rm -f kevent12.c +cd $odir + +(cd $odir/../testcases/swap; ./swap -t 5m -i 20 -l 100 > /dev/null 2>&1) & +pid=$! +/tmp/kevent12 +while pgrep -q swap; do + pkill -9 swap +done +wait $pid + +rm -f /tmp/kevent12 +exit 0 +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 64 +#define RUNTIME (5 * 60) + +static pid_t parent; +static int kq; + +static void +hand(int i __unused) { /* handler */ + kill(parent, SIGINT); + _exit(1); +} + +static void +init_kq() +{ + kq = kqueue(); + if (kq == -1) + err(1, "kqueue"); +} + +static void +add_watch(pid_t pid) +{ + struct kevent kev; + char msg[64]; + + bzero(&kev, sizeof(kev)); + kev.ident = pid; + kev.flags = EV_ADD | EV_ENABLE; + kev.filter = EVFILT_PROC; + kev.fflags = NOTE_EXIT | NOTE_EXEC | NOTE_TRACK | NOTE_TRACKERR; + + for (;;) { + int res = kevent(kq, &kev, 1, NULL, 0, NULL); + if (res == -1) { + if (errno == EINTR) + continue; + if (errno == ESRCH) + break; + + snprintf(msg, sizeof(msg), + "kevent - add watch for pid %u", pid); + err(1, "%s", msg); + } + else + break; + } +} + +static void +polling() +{ + struct kevent kev[10]; +#if defined(DEBUG) + pid_t pid; + int i; +#endif + + for (;;) { + bzero(&kev, sizeof(kev)); + if (arc4random() % 100 < 10) { + signal(SIGALRM, hand); + ualarm(10000, 0); + } + int res = kevent(kq, NULL, 0, kev, + sizeof(kev) / sizeof(kev[0]), NULL); + if (res == -1) { + if (errno == EINTR) + continue; + + if (errno == ESRCH) + continue; + + err(1, "kevent"); + } + +#if defined(DEBUG) + for (i = 0; i < res; i++) { + pid = kev[i].ident; + if (kev[i].fflags & NOTE_CHILD) { + add_watch(pid); + printf("%u - new process, parent %u\n", pid, + (unsigned int)kev[i].data); + } + if (kev[i].fflags & NOTE_FORK) { + printf("%u forked\n", pid); + } + if (kev[i].fflags & NOTE_EXEC) { + printf("%u called exec\n", pid); + } + if (kev[i].fflags & NOTE_EXIT) { + printf("%u exited\n", pid); + if (parent == pid) + return; + } + if (kev[i].fflags & NOTE_TRACK) { + printf("%u forked - track\n", pid); + } + if (kev[i].fflags & NOTE_TRACKERR) { + fprintf(stderr, "%u - track error\n", pid); + } + } +#endif + } +} + +void +churn(void) +{ + pid_t pid; + time_t start; + char *cmdline[] = { "/usr/bin/true", NULL }; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if ((pid = fork()) == -1) + err(1, "fork"); + if (pid == 0) { + if (execve(cmdline[0], cmdline, NULL) == -1) + err(1, "execve"); + } + if (waitpid(pid, NULL, 0) != pid) + err(1, "waitpid(%d):%d", pid, __LINE__); + } + + _exit(0); +} + +int +test(void) +{ + if ((parent = fork()) == 0) + churn(); + + init_kq(); + add_watch(parent); + polling(); + if (waitpid(parent, NULL, 0) != parent) + err(1, "waitpid(%d):%d", parent, __LINE__); + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + time_t start; + int i; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + for (i = 0; i < PARALLEL; i++) + if (waitpid(pids[i], NULL, 0) != pids[i]) + err(1, "waitpid(%d):%d", pids[i], __LINE__); + } + + return (0); +} diff --git a/tools/test/stress2/misc/kevent13.sh b/tools/test/stress2/misc/kevent13.sh new file mode 100755 index 000000000000..82a7a10b983c --- /dev/null +++ b/tools/test/stress2/misc/kevent13.sh @@ -0,0 +1,141 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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 based on scenario by Babcia Padlina + +# "panic: mutex pipe mutex not owned at sys_pipe.c:1769" seen: +# https://people.freebsd.org/~pho/stress/log/kevent13.txt +# Fixed by r235640. + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kevent13.c +cc -o kevent13 -Wall kevent13.c -lpthread +rm -f kevent13.c + +[ -d "$RUNDIR" ] || mkdir -p $RUNDIR +cd $RUNDIR +start=`date +%s` +while [ $((`date +%s` - start)) -lt 300 ]; do + for i in `jot 10`; do + /tmp/kevent13 & + /tmp/kevent13 & + wait + done +done + +rm -f /tmp/kevent13 +exit 0 +EOF +/* + * 29.08.2009, babcia padlina + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define LOOPS 200000 + +struct kevent kev[2], ke[2]; +struct timespec timeout; +volatile int go; +int fd[2], kq; + +void +do_thread(void) { + int i; + + go = 1; + for (i = 0; i < LOOPS; i++) { + if (pipe(fd) < 0) + err(1, "pipe"); + memset(&kev, 0, sizeof(kev)); + EV_SET(&kev[0], fd[0], EVFILT_READ, EV_ADD | EV_CLEAR, 0, 0, NULL); + EV_SET(&kev[1], fd[1], EVFILT_WRITE, EV_ADD | EV_CLEAR, 0, 0, NULL); + + if (kevent(kq, kev, 2, ke, 2, &timeout) < 0) + err(1, "kevent"); + + close(fd[0]); + close(fd[1]); + } +} + +void +do_thread2(void) { + int i; + + while (go == 0) + usleep(10); + for (i = 0; i < LOOPS; i++) { + if (arc4random() % 2 == 0) { + close(fd[0]); + close(fd[1]); + } else { + close(fd[1]); + close(fd[0]); + } + } +} + +int +main(void) { + pthread_t pth, pth2; + int r; + + if ((kq = kqueue()) < 0) + err(1, "kqueue"); + + if ((r = pthread_create(&pth, NULL, (void *)do_thread, NULL)) != 0) + errc(1, r, "pthread_create"); + if ((r = pthread_create(&pth2, NULL, (void *)do_thread2, NULL)) != 0) + errc(1, r, "pthread_create"); + + timeout.tv_sec = 0; + timeout.tv_nsec = 1; + + if ((r = pthread_join(pth, NULL)) != 0) + errc(1, r, "pthread_join"); + if ((r = pthread_join(pth2, NULL)) != 0) + errc(1, r, "pthread_join"); + + return (0); +} diff --git a/tools/test/stress2/misc/kevent14.sh b/tools/test/stress2/misc/kevent14.sh new file mode 100755 index 000000000000..2531b15caecf --- /dev/null +++ b/tools/test/stress2/misc/kevent14.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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: Bad tailq NEXT(0xfffff815a589e238->tqh_last) != NULL" seen. +# https://people.freebsd.org/~pho/stress/log/kevent14.txt +# Fixed by r340734. + +# Test scenario by: Mark Johnston + +cat > /tmp/kevent14.c < + +#include +#include +#include + +int +main(void) +{ + struct kevent ev[2]; + time_t start; + int kq, ret; + + kq = kqueue(); + if (kq < 0) + err(1, "kqueue"); + + EV_SET(&ev[0], 42, EVFILT_TIMER, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, + 0, 0); + + start = time(NULL); + while (time(NULL) - start < 120) { + ret = kevent(kq, &ev[0], 1, &ev[1], 1, NULL); + if (ret < 0) + err(1, "kevent"); + if (ret == 0) + errx(1, "no events"); + if (ret == 1 && (ev[1].flags & EV_ERROR) != 0) + errc(1, ev[1].data, "kevent"); + } + + return (0); +} +EOF +cc -o /tmp/kevent14 -Wall -Wextra -g -O2 /tmp/kevent14.c +rm /tmp/kevent14.c + +/tmp/kevent14 + +rm -f /tmp/kevent14 +exit 0 diff --git a/tools/test/stress2/misc/kevent15.sh b/tools/test/stress2/misc/kevent15.sh new file mode 100755 index 000000000000..52925365c865 --- /dev/null +++ b/tools/test/stress2/misc/kevent15.sh @@ -0,0 +1,161 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +# No problems seen. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/kevent15.c +mycc -o kevent15 -Wall -Wextra -O0 -g kevent15.c || exit 1 +rm -f kevent15.c +cd $odir + +(cd ../testcases/swap; ./swap -t 3m -i 20 -l 80) & +sleep 2 +cd $dir +timeout 5m ./kevent15 +s=$? +while pkill swap; do sleep .1; done +wait +[ -f kevent15.core -a $s -eq 0 ] && + { ls -l kevent15.core; s=1; } +cd $odir + +rm -rf $dir/kevent15 +exit $s + +EOF +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static _Atomic(int) *share; + +#define PARALLEL 800 +#define RUNTIME (3 * 60) +#define SYNC 0 +#define ACT 1 + +static void +handler(int i __unused) { + _exit(0); +} + +static void +test(void) +{ + struct kevent ev[2]; + struct timespec ts; + time_t start; + int kq, ret; + + signal(SIGUSR1, handler); + (void)atomic_fetch_add(&share[SYNC], 1); + while (atomic_load(&share[SYNC]) != PARALLEL) + usleep(1); + (void)atomic_fetch_add(&share[ACT], 1); + + if ((kq = kqueue()) < 0) + err(1, "kqueue"); + + EV_SET(&ev[0], 42, EVFILT_TIMER, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, + 0, 0); + + start = time(NULL); + while (time(NULL) - start < 30) { + ts.tv_sec = 0; + ts.tv_nsec = arc4random() % 2000; + if ((ret = kevent(kq, &ev[0], 1, &ev[1], 1, &ts)) == -1) + err(1, "kevent"); + if (ret == 1 && (ev[1].flags & EV_ERROR) != 0) + errc(1, ev[1].data, "kevent"); + } + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + size_t len; + time_t start; + int i, status; + + 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) { + share[ACT] = share[SYNC] = 0; + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + if (pids[i] == -1) + err(1, "fork()"); + } + while (share[ACT] != PARALLEL) + usleep(1); + usleep(arc4random() % 50000); + for (i = 0; i < PARALLEL; i++) { + if (kill(pids[i], SIGUSR1) == -1) + err(1, "kill"); + } + + 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) && WTERMSIG(status) != 2) + fprintf(stderr, + "pid %d exit signal %d\n", + pids[i], WTERMSIG(status)); + } + } + } + + return (0); +} diff --git a/tools/test/stress2/misc/kevent2.sh b/tools/test/stress2/misc/kevent2.sh new file mode 100755 index 000000000000..b2ae2a97e422 --- /dev/null +++ b/tools/test/stress2/misc/kevent2.sh @@ -0,0 +1,170 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kevent2.c +mycc -o kevent2 -Wall kevent2.c -pthread || exit 1 +rm -f kevent2.c +cd $RUNDIR + +for i in `jot 10`; do + for j in `jot 12`; do + /tmp/kevent2 > /dev/null 2>&1 & + done + wait +done +rm -f /tmp/kevent2 +exit +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +static int waiting; + +static int fd1[2]; +static int fd2[2]; +static int fd3[2]; + +static void * +thr1(void *arg) +{ + struct kevent ev[3]; + struct timespec ts; + int kq, n, r; + + if ((kq = kqueue()) < 0) + err(1, "kqueue(). %s:%d", __FILE__, __LINE__); + + n = 0; + EV_SET(&ev[n], fd1[1], EVFILT_WRITE, + EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0); + n++; + EV_SET(&ev[n], fd2[1], EVFILT_WRITE, + EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0); + n++; + EV_SET(&ev[n], fd3[1], EVFILT_WRITE, + EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0); + n++; + + if (kevent(kq, ev, n, NULL, 0, NULL) < 0) + err(1, "kevent(). %s:%d", __FILE__, __LINE__); + + if ((r = pthread_mutex_lock(&mutex)) != 0) + errc(1, r, "pthread_mutex_lock"); + waiting = 0; + if ((r = pthread_cond_signal(&cond)) != 0) + errc(1, r, "pthread_cond_signal"); + if ((r = pthread_mutex_unlock(&mutex)) != 0) + errc(1, r, "pthread_mutex_unlock"); + + n = 0; + EV_SET(&ev[n], fd1[1], EVFILT_WRITE, + EV_DELETE, 0, 0, 0); + n++; + ts.tv_sec = 0; + ts.tv_nsec = 0; + if (kevent(kq, ev, n, NULL, 0, &ts) < 0) + err(1, "kevent(). %s:%d", __FILE__, __LINE__); + close(kq); + + close(fd1[1]); + close(fd2[1]); + close(fd3[1]); + return (0); +} + +static void * +thr2(void *arg) +{ + int r; + + if ((r = pthread_mutex_lock(&mutex)) != 0) + errc(1, r, "pthread_mutex_lock"); + while (waiting == 1) { + if ((r = pthread_cond_wait(&cond, &mutex)) != 0) + errc(1, r, "pthread_cond_wait"); + } + if ((r = pthread_mutex_unlock(&mutex)) != 0) + errc(1, r, "pthread_mutex_unlock"); + close(fd1[0]); + close(fd2[0]); + close(fd3[0]); + return (0); +} + +int +main(int argc, char **argv) +{ + pthread_t threads[2]; + int i, r; + + for (i = 0; i < 1000; i++) { + waiting = 1; + if (pipe(fd1) == -1) + err(1, "pipe()"); + if (pipe(fd2) == -1) + err(1, "pipe()"); + if (pipe(fd3) == -1) + err(1, "pipe()"); + + if ((r = pthread_mutex_init(&mutex, 0)) != 0) + errc(1, r, "pthread_mutex_init"); + if ((r = pthread_cond_init(&cond, NULL)) != 0) + errc(1, r, "pthread_cond_init"); + + if ((r = pthread_create(&threads[0], NULL, thr1, 0)) != 0) + errc(1, r, "pthread_create()"); + if ((r = pthread_create(&threads[1], NULL, thr2, 0)) != 0) + errc(1, r, "pthread_create()"); + + if ((r = pthread_join(threads[0], NULL)) != 0) + errc(1, r, "pthread_join(%d)", 0); + if ((r = pthread_join(threads[1], NULL)) != 0) + errc(1, r, "pthread_join(%d)", 1); + if ((r = pthread_mutex_destroy(&mutex)) != 0) + errc(1, r, "pthread_mutex_destroy"); + if ((r = pthread_cond_destroy(&cond)) != 0) + errc(1, r, "pthread_condattr_destroy"); + } + + return (0); +} diff --git a/tools/test/stress2/misc/kevent3.sh b/tools/test/stress2/misc/kevent3.sh new file mode 100755 index 000000000000..0ee9706a27b1 --- /dev/null +++ b/tools/test/stress2/misc/kevent3.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kevent3.c +mycc -o kevent3 -Wall kevent3.c -pthread || exit 1 +rm -f kevent3.c +cd $RUNDIR + +for i in `jot 64`; do + for j in `jot 12`; do + /tmp/kevent3 > /dev/null 2>&1 & + done + for j in `jot 12`; do + wait + done +done +rm -f /tmp/kevent3 +exit 0 +EOF +/* + * Obtained from: + * http://projects.info-pull.com/mokb/MOKB-24-11-2006.html + */ +#include +#include +#include + +#include +#include + +int main(void) +{ + struct kevent ke; + int kq; + + kq = kqueue(); + EV_SET(&ke, getpid(), EVFILT_PROC, EV_ADD, + NOTE_EXIT|NOTE_EXEC|NOTE_TRACK, 0, NULL); + kevent(kq, &ke, 1, NULL, 0, NULL); + if (fork() != 0) + kevent(kq, NULL, 0, &ke, 1, NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/kevent4.sh b/tools/test/stress2/misc/kevent4.sh new file mode 100755 index 000000000000..87f421322ed5 --- /dev/null +++ b/tools/test/stress2/misc/kevent4.sh @@ -0,0 +1,174 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 scenario by kib@ + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kevent4.c +mycc -o kevent4 -Wall kevent4.c -pthread || exit 1 +rm -f kevent4.c + +cd $odir +export runRUNTIME=3m +(cd ..; ./run.sh > /dev/null 2>&1) & +rpid=$! + +(cd $RUNDIR; /tmp/kevent4 $rpid > /dev/null) & + +sleep 120 +kill $rpid +../tools/killall.sh > /dev/null 2>&1 +kill $! +wait +rm -f /tmp/kevent4 + +exit +EOF +#include +#include + +#include +#include +#include +#include +#include +#ifndef true +# define true 1 +#endif + +static int kq; + +static void +err(const char *msg, int err_no) +{ + fprintf(stderr, "%s: %s\n", msg, strerror(err_no)); + exit(1); +} + +static void +init_kq() +{ + kq = kqueue(); + if (kq == -1) + err("kqueue", errno); +} + +static void +add_watch(pid_t pid) +{ + struct kevent kev; + + bzero(&kev, sizeof(kev)); + kev.ident = pid; + kev.flags = EV_ADD | EV_ENABLE; + kev.filter = EVFILT_PROC; + kev.fflags = NOTE_EXIT | NOTE_FORK | NOTE_EXEC | NOTE_TRACK; + + while (true) { + int res = kevent(kq, &kev, 1, NULL, 0, NULL); + if (res == -1) { + if (errno == EINTR) + continue; + if (errno == ESRCH) + break; + + int err_no = errno; + char msg[64]; + snprintf(msg, sizeof(msg), + "kevent - add watch for pid %u", pid); + err(msg, err_no); + } + else + break; + } +} + +static void polling() +{ + struct kevent kev[10]; + pid_t pid; + int i; + + while (true) { + bzero(&kev, sizeof(kev)); + int res = kevent(kq, NULL, 0, kev, + sizeof(kev) / sizeof(kev[0]), NULL); + if (res == -1) { + if (errno == EINTR) + continue; + + if (errno == ESRCH) + continue; + + err("kevent", errno); + } + + for (i = 0; i < res; i++) { + pid = kev[i].ident; + if (kev[i].fflags & NOTE_CHILD) { + add_watch(pid); + printf("%u - new process, parent %u\n", pid, + (unsigned int)kev[i].data); + } + if (kev[i].fflags & NOTE_FORK) { + printf("%u forked\n", pid); + } + if (kev[i].fflags & NOTE_EXEC) { + printf("%u called exec\n", pid); + } + if (kev[i].fflags & NOTE_EXIT) { + printf("%u exited\n", pid); + } + if (kev[i].fflags & NOTE_TRACK) { + printf("%u forked - track\n", pid); + } + if (kev[i].fflags & NOTE_TRACKERR) { + fprintf(stderr, "%u - track error\n", pid); + } + } + } +} + +int main(int argc, char *argv[]) +{ + if (argc != 2) { + fprintf(stderr, "pid ?\n"); + return (2); + } + pid_t parent = atoi(argv[1]); + + init_kq(); + add_watch(parent); + polling(); + + return (0); +} diff --git a/tools/test/stress2/misc/kevent5.sh b/tools/test/stress2/misc/kevent5.sh new file mode 100755 index 000000000000..35a9e6e78e72 --- /dev/null +++ b/tools/test/stress2/misc/kevent5.sh @@ -0,0 +1,183 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 EVFILT_VNODE. Found page fault in knlist_add+0x39 +# Test scenario by kib@ + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kevent5.c +mycc -o kevent5 -Wall -Wextra -O2 -g kevent5.c || exit 1 +rm -f kevent5.c + +[ -d $RUNDIR ] || mkdir -p $RUNDIR +cd $RUNDIR +/tmp/kevent5 kevent5.xxx kevent5.yyy +s=$? + +rm -f /tmp/kevent5 kevent.xxx kevent.yyy + +exit $s +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +volatile u_int *share; + +static char *file1, *file2; + +#define N 1000 +#define SYNC 0 + +static void +test(void) { + + struct kevent ev[2]; + struct timespec ts; + int fd, kq, n; + + if ((fd = open(file1, O_RDONLY, 0)) == -1) + err(1, "open(%s)(2)", file1); + atomic_add_int(&share[SYNC], 1); + + if ((kq = kqueue()) < 0) + err(1, "kqueue()"); + + n = 0; + EV_SET(&ev[n], fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, + NOTE_DELETE, 0, 0); + n++; + + ts.tv_sec = 5; + ts.tv_nsec = 0; + + if (kevent(kq, ev, n, NULL, 0, &ts) < 0) + err(1, "kevent()"); + + memset(&ev, 0, sizeof(ev)); + n = kevent(kq, NULL, 0, ev, 1, NULL); + close(fd); + close(kq); + +/* Once the rendezvous file is gone create a new kevent */ + + if ((fd = open(file2, O_RDONLY, 0)) == -1) + err(1, "open(%s)(2)", file2); + + if ((kq = kqueue()) < 0) + err(1, "kqueue()"); + + n = 0; + EV_SET(&ev[n], fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, + NOTE_DELETE, 0, 0); + n++; + + if (kevent(kq, ev, n, NULL, 0, NULL) < 0) + err(1, "kevent()"); + + memset(&ev, 0, sizeof(ev)); + n = kevent(kq, NULL, 0, ev, 1, &ts); + close(fd); + close(kq); +} + +int +main(int argc, char **argv) { + size_t len; + int e, fd, i, j, status; + + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", + argv[0]); + return (1); + } + len = PAGE_SIZE; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + e = 0; + file1 = argv[1]; + file2 = argv[2]; + + for (j = 0; j < 100 && e == 0; j++) { + if ((fd = open(file1, O_CREAT | O_TRUNC | O_RDWR, 0660)) == + -1) + err(1, "open(%s)", file1); + close(fd); + if ((fd = open(file2, O_CREAT | O_TRUNC | O_RDWR, 0660)) == + -1) + err(1, "open(%s)", file2); + close(fd); + + share[SYNC] = 0; + for (i = 0; i < N; i++) { + if (fork() == 0) { + test(); + return (0); + } + } + + while (share[SYNC] != N) + usleep(200); + + sleep(1); + if (unlink(file1) == -1) + err(1, "unlink(%s). %s:%d\n", file1, __FILE__, + __LINE__); + sleep(2); + if (unlink(file2) == -1) + err(1, "unlink(%s). %s:%d\n", file2, __FILE__, + __LINE__); + + for (i = 0; i < N; i++) { + if (wait(&status) == -1) + err(1, "wait(), %s:%d", __FILE__, __LINE__); + if (status != 0) + e = 1; + } + } + + return (e); +} diff --git a/tools/test/stress2/misc/kevent6.sh b/tools/test/stress2/misc/kevent6.sh new file mode 100755 index 000000000000..528bde5e78a1 --- /dev/null +++ b/tools/test/stress2/misc/kevent6.sh @@ -0,0 +1,168 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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. +# + +# "Sleeping thread (tid 101094, pid 13104) owns a non-sleepable lock" seen. +# Fixed in r255798. + +# panic: Memory modified after free: +# https://people.freebsd.org/~pho/stress/log/alan011.txt +# https://people.freebsd.org/~pho/stress/log/kevent6.txt +# Fixed by: r286921 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kevent6.c +mycc -o kevent6 -Wall -Wextra -O2 -g kevent6.c -lpthread || exit 1 +rm -f kevent6.c +cd $odir + +mount | grep "on $mntpoint " | grep -q md$mdstart && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 2g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +su $testuser -c "(cd $mntpoint; /tmp/kevent6)" + +while mount | grep -q $mntpoint; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart + +mount -o size=1g -t tmpfs tmpfs $mntpoint +chmod 777 $mntpoint +su $testuser -c "(cd $mntpoint; /tmp/kevent6)" +while mount | grep -q $mntpoint; do + umount $mntpoint || sleep 1 +done +rm -f /tmp/kevent6 + +exit +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 500000 +#define PARALLEL 8 + +static int fd; +static char path[80]; + +static void * +spin(void *arg __unused) +{ + int i; + + for (i= 0;; i++) { + snprintf(path, sizeof(path), "file.%06d.%d", getpid(), i); + if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == + -1) + err(1, "creat()"); + close(fd); + usleep(10000); + fd = 0; + unlink(path); + } + return (NULL); +} + +static void * +test(void *arg __unused) +{ + int kq; + int i, n; + struct kevent ev; + struct timespec ts; + + for (i = 0; i < LOOPS; i++) { + if ((kq = kqueue()) < 0) + err(1, "kqueue()"); + + n = 0; + memset(&ev, 0, sizeof(ev)); + EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, + NOTE_DELETE|NOTE_RENAME|NOTE_EXTEND, 0, 0); + n++; + + if (kevent(kq, &ev, n, NULL, 0, NULL) < 0) { + close(kq); + continue; + } + + memset(&ev, 0, sizeof(ev)); + ts.tv_sec = 0; + ts.tv_nsec = 1000000; + if ((n = kevent(kq, NULL, 0, &ev, 1, &ts)) == -1) + err(1, "kevent()"); + + close(kq); + } + return (NULL); +} + +int +main(void) +{ + pthread_t cp[PARALLEL], sp; + int e, i; + + if ((e = pthread_create(&sp, NULL, spin, NULL)) != 0) + errc(1, e, "pthread_create"); + + for (i = 0; i < PARALLEL; i++) { + if ((e = pthread_create(&cp[i], NULL, test, NULL)) != 0) + errc(1, e, "pthread_create"); + } + + for (i = 0; i < PARALLEL; i++) + pthread_join(cp[i], NULL); + + close(fd); + + return (0); +} diff --git a/tools/test/stress2/misc/kevent7.sh b/tools/test/stress2/misc/kevent7.sh new file mode 100755 index 000000000000..9383918ea134 --- /dev/null +++ b/tools/test/stress2/misc/kevent7.sh @@ -0,0 +1,281 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Threaded syscall(2) fuzz test inspired by the iknowthis test suite +# by Tavis Ormandy + +# kevent(2) with random arguments. +# Spinning threads seen. +# Fixed in r255877. + +# "panic: softclock_call_cc: act 0xfffff801219a0840 0" seen: +# https://people.freebsd.org/~pho/stress/log/kevent7.txt +# Fixed by r315289 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +ulimit -t 200 +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kevent7.c +rm -f /tmp/kevent7 +mycc -o kevent7 -Wall -Wextra -O2 -g kevent7.c -lpthread || exit 1 +rm -f kevent7.c + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +for i in `jot 5`; do + (cd $mntpoint; /tmp/kevent7 $* < /dev/null) & + sleep 60 + while pgrep -q kevent7; do + pkill -9 kevent7 + sleep 1 + done +done + +for i in `jot 5`; do + mount | grep -q md${mdstart}$part && \ + umount $mntpoint && mdconfig -d -u $mdstart && break + sleep 10 +done +if mount | grep -q md${mdstart}$part; then + fstat $mntpoint + echo "umount $mntpoint failed" + exit 1 +fi +rm -f /tmp/kevent7 +exit 0 +EOF +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define THREADS 50 + +int fd[900], fds[2], socketpr[2]; +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +static u_int32_t r[N]; +static int syscallno; + +static void +hand(int i __unused) { /* handler */ + _exit(1); +} + +static unsigned long +makearg(void) +{ + unsigned int i; + unsigned long val; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return(val); +} + +static void * +test(void *arg __unused) +{ + + FTS *fts; + FTSENT *p; + int ftsoptions; + int i; + char *args[5]; + + ftsoptions = FTS_PHYSICAL; + args[0] = "/dev"; + args[1] = "/proc"; + args[2] = "/usr/compat/linux/proc"; + args[3] = "."; + args[4] = 0; + + for (;;) { + for (i = 0; i < N; i++) + r[i] = arc4random(); + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + i = 0; + while ((p = fts_read(fts)) != NULL) { + if (fd[i] > 0) + close(fd[i]); + if ((fd[i] = open(p->fts_path, O_RDWR)) == -1) + if ((fd[i] = open(p->fts_path, O_WRONLY)) == + -1) + if ((fd[i] = open(p->fts_path, + O_RDONLY)) == -1) + continue; + i++; + i = i % nitems(fd); + } + + if (fts_close(fts) == -1) + if (errno != ENOTDIR) + warn("fts_close()"); + if (pipe(fds) == -1) + err(1, "pipe()"); + if (socketpair(PF_UNIX, SOCK_SEQPACKET, 0, socketpr) == -1) + err(1, "socketpair()"); + sleep(1); + close(socketpr[0]); + close(socketpr[1]); + close(fds[0]); + close(fds[1]); + } + return(0); +} + +static void * +calls(void *arg __unused) +{ + unsigned long arg1, arg2, arg3, arg4, arg5, arg6, arg7; + int i, kq, num; + + if ((kq = kqueue()) < 0) + err(1, "kqueue()"); + for (i = 0; i < 1000; i++) { + if (i == 0) + usleep(1000); + num = syscallno; + arg1 = makearg(); + arg2 = makearg(); + arg3 = makearg(); + arg4 = makearg(); + arg5 = makearg(); + arg6 = makearg(); + arg7 = makearg(); + +#if 0 + fprintf(stderr, "%2d : syscall(%3d, %lx, %lx, %lx, %lx, %lx," + " %lx, %lx)\n", + i, num, arg1, arg2, arg3, arg4, arg5, arg6, arg7); +#endif + alarm(1); + syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7); + num = 0; + } + close(kq); + + return (0); +} + +int +main(void) +{ + struct passwd *pw; + time_t start; + pthread_t rp, cp[THREADS]; + int e, j, n; + + if ((pw = getpwnam("nobody")) == NULL) + err(1, "no such user: nobody"); + + 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(); + + signal(SIGALRM, hand); + signal(SIGILL, hand); + signal(SIGFPE, hand); + signal(SIGSEGV, hand); + signal(SIGBUS, hand); + signal(SIGURG, hand); + signal(SIGSYS, hand); + signal(SIGTRAP, hand); + + syscallno = SYS_kevent; + + n = 0; + start = time(NULL); + while (time(NULL) - start < 120) { + if (fork() == 0) { + if ((e = pthread_create(&rp, NULL, test, NULL)) != 0) + errc(1, e, "pthread_create"); + usleep(1000); + 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"); + _exit(0); + } + wait(NULL); + if (n++ > 5000) + break; + } + + return (0); +} diff --git a/tools/test/stress2/misc/kevent8.sh b/tools/test/stress2/misc/kevent8.sh new file mode 100755 index 000000000000..66007eb5a2b1 --- /dev/null +++ b/tools/test/stress2/misc/kevent8.sh @@ -0,0 +1,163 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Out of VM seen due to missing close of kqueue handle. +# Fixed in 256849 + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +ulimit -k 5000 || { echo FAIL; exit 1; } + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kevent8.c +mycc -o kevent8 -Wall -Wextra -O2 -g kevent8.c -lpthread || exit 1 +rm -f kevent8.c +cd $odir + +mount | grep "on $mntpoint " | grep -q md$mdstart && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 2g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +su $testuser -c "(cd $mntpoint; /tmp/kevent8)" & +for i in `jot 99`; do + sleep 1 + kill -0 $! 2>/dev/null || break +done +umount -f $mntpoint +pkill kevent8 +wait + +while mount | grep -q $mntpoint; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/kevent8 + +exit +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 64 + +static int fd; +static char path[80]; + +static void * +spin(void *arg __unused) +{ + int i; + setproctitle("spin"); + + for (i= 0;; i++) { + snprintf(path, sizeof(path), "file.%06d.%d", getpid(), i); + if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == + -1) + err(1, "creat()"); + close(fd); + fd = 0; + unlink(path); + } + return (NULL); +} + +static void * +test(void *arg __unused) +{ + int kq; + int i, n; + struct kevent ev; + struct timespec ts; + + for (i = 0; i < 500000; i++) { + if ((kq = kqueue()) < 0) + if (errno != ENOMEM) + err(1, "kqueue()"); + + n = 0; + memset(&ev, 0, sizeof(ev)); + EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_ENABLE | EV_CLEAR, + NOTE_DELETE|NOTE_RENAME|NOTE_EXTEND, 0, 0); + n++; + + if (kevent(kq, &ev, n, NULL, 0, NULL) < 0) + continue; /* Note: missing close(kq)! */ + + memset(&ev, 0, sizeof(ev)); + ts.tv_sec = 0; + ts.tv_nsec = 1000000; + if ((n = kevent(kq, NULL, 0, &ev, 1, &ts)) == -1) + err(1, "kevent()"); + + close(kq); + } + return (NULL); +} + +int +main(void) +{ + pthread_t cp[PARALLEL], sp; + int e, i; + + if ((e = pthread_create(&sp, NULL, spin, NULL)) != 0) + errc(1, e, "pthread_create"); + + for (i = 0; i < PARALLEL; i++) { + if ((e = pthread_create(&cp[i], NULL, test, NULL)) != 0) + errc(1, e, "pthread_create"); + } + + for (i = 0; i < PARALLEL; i++) + pthread_join(cp[i], NULL); + + close(fd); + + return (0); +} diff --git a/tools/test/stress2/misc/kevent9.sh b/tools/test/stress2/misc/kevent9.sh new file mode 100755 index 000000000000..e7b88a06ec1b --- /dev/null +++ b/tools/test/stress2/misc/kevent9.sh @@ -0,0 +1,206 @@ +#!/bin/sh + +# Test scenario by Eric Badger + +# userret: returning with the following locks held: +# exclusive sleep mutex process lock (process lock) r = 0 (0xcb714758) +# locked @ kern/kern_event.c:2125 +# panic: witness_warn + +# https://people.freebsd.org/~pho/stress/log/kevent9.txt +# Fixed in r302235. + +. ../default.cfg + +[ `sysctl -n hw.ncpu` -ne 4 ] && echo "For best results use hw.ncpu == 4" + +cd /tmp +cat > /tmp/kevent9-1.c < +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define NUM_PROCS 4000 + +void *procmaker(void *arg __unused) +{ + pthread_set_name_np(pthread_self(), "procmaker"); + for (int i = 0; i < NUM_PROCS; ++i) + { + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 50000; + nanosleep(&ts, NULL); + switch(fork()) + { + case -1: + err(1, "fork"); + break; + case 0: + execl("./kevent9-2", "kevent9-2", NULL); + _exit(127); + break; + default: + break; + } + } + printf("done forking\n"); + return NULL; +} + +void *reaper(void *arg __unused) +{ + pthread_set_name_np(pthread_self(), "reaper"); + int counter = 0; + while (counter < NUM_PROCS) + { + int status; + if (wait(&status) > 0) + { + ++counter; + } + } + printf("Reaped %d\n", counter); + return NULL; +} + +int main() +{ + pthread_set_name_np(pthread_self(), "main"); + + int kqfd = kqueue(); + if (kqfd == -1) + { + err(1, "kqueue()"); + } + + struct kevent change; + memset(&change, 0, sizeof(change)); + change.ident = getpid(); + change.filter = EVFILT_PROC; + change.flags = EV_ADD | EV_ENABLE; + change.fflags = NOTE_EXIT | NOTE_EXEC | NOTE_FORK | NOTE_TRACK; + + if (kevent(kqfd, &change, 1, NULL, 0, NULL) == -1) + { + err(1, "kevent change"); + } + + pthread_t t; + pthread_create(&t, NULL, procmaker, NULL); + pthread_create(&t, NULL, reaper, NULL); + + int numexecs = 0; + int numexits = 0; + int numforks = 0; + int nummults = 0; + int numchlds = 0; + int numterrs = 0; + + while (1) + { + struct kevent event; + struct timespec to; + to.tv_sec = 1; + to.tv_nsec = 0; + int ret = kevent(kqfd, NULL, 0, &event, 1, &to); + if (ret == -1) + { + err(1, "kevent event"); + } + else if (ret == 0) + { + printf("numexecs: %d numexits: %d numforks: %d numchlds: %d numterrs: %d nummults: %d\n", + numexecs, numexits, numforks, numchlds, numterrs, nummults); + + // Sometimes we miss a NOTE_EXIT. If it hasn't arrived by the timeout, bail out since + // it will probably never arrive. + break; + /* + if (numexits == NUM_PROCS) + { + break; + } + else + { + continue; + } + */ + } + + int numflags = 0; + if (event.fflags & NOTE_EXEC) + { + ++numflags; + ++numexecs; + } + if (event.fflags & NOTE_EXIT) + { + ++numflags; + ++numexits; + } + if (event.fflags & NOTE_FORK) + { + ++numflags; + ++numforks; + } + if (event.fflags & NOTE_CHILD) + { + ++numflags; + ++numchlds; + } + if (event.fflags & NOTE_TRACKERR) + { + ++numflags; + ++numterrs; + } + if (numflags > 1) + { + ++nummults; + } + + /* + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 50000; + nanosleep(&ts, NULL); + */ + } + return 0; +} +EOF + +cat > /tmp/kevent9-2.c < + +int main() +{ + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = 1000; + nanosleep(&ts, NULL); + return 0; +} +EOF + +mycc -o kevent9-1 -Wall -Wextra -O2 -g kevent9-1.c -lpthread || exit 1 +mycc -o kevent9-2 -Wall -Wextra -O2 -g kevent9-2.c || exit 1 +rm kevent9-1.c kevent9-2.c + +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 300 ]; do + ./kevent9-1 > /dev/null +done +rm kevent9-1 kevent9-2 +exit 0 diff --git a/tools/test/stress2/misc/killpg.sh b/tools/test/stress2/misc/killpg.sh new file mode 100755 index 000000000000..c6af55a3d593 --- /dev/null +++ b/tools/test/stress2/misc/killpg.sh @@ -0,0 +1,155 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 r241859: +# Return EPERM if processes were found but they were unable to be signaled. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > killpg.c +mycc -o killpg -Wall -Wextra killpg.c || exit 1 +rm -f killpg.c + +/tmp/killpg + +rm -f /tmp/killpg +exit 0 +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static pid_t gid, pid; + +#define LOOPS 100 + +static void +hand(int i __unused) { /* handler */ + _exit(0); +} + +static void +nlooper(void) +{ + int i; + + setproctitle("nlooper"); + setpgrp(0, getpid()); + for (i = 0; i < LOOPS; i++) { + if ((pid = fork()) == 0) { + signal(SIGINFO, hand); + if (arc4random() % 100 < 10) + usleep(arc4random() % 100); + _exit(0); + } + wait(NULL); + } + _exit(0); +} + +static void +looper(void) +{ + int i; + + setproctitle("looper"); + setpgrp(0, getpid()); + for (i = 0; i < LOOPS; i++) { + if ((pid = fork()) == 0) { + signal(SIGINFO, hand); + if (arc4random() % 100 < 10) + usleep(arc4random() % 100); + _exit(0); + } + wait(NULL); + } + unlink("cont"); + _exit(0); +} + +static void +killer(void) +{ + struct passwd *pw; + + setproctitle("killer"); + if ((pw = getpwnam("nobody")) == NULL) + err(1, "no such user: nobody"); + + 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(); + + if ((gid = fork()) == 0) + nlooper(); /* nobody looper */ + + sleep(1); + while (access("cont", R_OK) == 0) { + if (killpg(gid, SIGINFO) == -1) { + if (errno == EPERM) + continue; + warn("FAIL killpg"); + } + } + _exit(0); +} + +int +main(void) +{ + int fd; + + if ((fd = open("cont", O_RDWR | O_CREAT, 0666)) == -1) + err(1, "creat"); + close(fd); + signal(SIGINFO, SIG_IGN); + + if ((gid = fork()) == 0) + looper(); + if (fork() == 0) + killer(); + + wait(NULL); + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/kinfo.sh b/tools/test/stress2/misc/kinfo.sh new file mode 100755 index 000000000000..8cd5bdf0fb54 --- /dev/null +++ b/tools/test/stress2/misc/kinfo.sh @@ -0,0 +1,162 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 scenario by marcus@freebsd.org + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kinfo.c +mycc -o kinfo -Wall kinfo.c -lutil || exit 1 +rm -f kinfo.c + +mount | grep -q procfs || mount -t procfs procfs /proc +for i in `jot 20`; do + for j in `jot 5`; do + /tmp/kinfo & + done + + for j in `jot 5`; do + wait + done +done + +rm -f /tmp/kinfo +exit +EOF + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char buf[8096]; + +void +handler(int i) { + exit(0); +} + +/* Stir /dev/proc */ +int +churning(void) { + pid_t r; + int fd, status; + + for (;;) { + r = fork(); + if (r == 0) { + if ((fd = open("/proc/curproc/mem", O_RDONLY)) == -1) + err(1, "open(/proc/curproc/mem)"); + bzero(buf, sizeof(buf)); + exit(0); + } + if (r < 0) { + perror("fork"); + exit(2); + } + wait(&status); + } +} + +/* Get files for each proc */ +void +list(void) +{ + struct kinfo_file *freep; + struct kinfo_vmentry *freep_vm; + long i; + int cnt, name[4]; + struct kinfo_proc *kipp; + size_t len; + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_PROC; + + len = 0; + if (sysctl(name, 3, NULL, &len, NULL, 0) < 0) + err(-1, "sysctl: kern.proc.all"); + + kipp = malloc(len); + if (kipp == NULL) + err(1, "malloc"); + + if (sysctl(name, 3, kipp, &len, NULL, 0) < 0) { + free(kipp); +// warn("sysctl: kern.proc.all"); + return; + } + + for (i = 0; i < len / sizeof(*kipp); i++) { + + /* The test starts here */ + freep = kinfo_getfile(kipp[i].ki_pid, &cnt); + free(freep); + + freep_vm = kinfo_getvmmap(kipp[i].ki_pid, &cnt); + free(freep_vm); + /* End test */ + } + free(kipp); +} + +int +main(int argc, char **argv) +{ + pid_t r; + signal(SIGALRM, handler); + alarm(60); + + if ((r = fork()) == 0) { + alarm(60); + for (;;) + churning(); + } + if (r < 0) { + perror("fork"); + exit(2); + } + + for (;;) + list(); + + return (0); +} diff --git a/tools/test/stress2/misc/kinfo2.sh b/tools/test/stress2/misc/kinfo2.sh new file mode 100755 index 000000000000..307763d88144 --- /dev/null +++ b/tools/test/stress2/misc/kinfo2.sh @@ -0,0 +1,186 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 scenario by marcus@freebsd.org + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kinfo2.c +mycc -o kinfo2 -Wall -Wextra kinfo2.c -lutil || exit 1 +rm -f kinfo2.c + +mount | grep -q procfs || mount -t procfs procfs /proc +s=0 +for i in `jot 15`; do + pids="" + for j in `jot 5`; do + /tmp/kinfo2 & + pids="$pids $!" + done + for p in $pids; do + wait $p + [ $? -ne 0 ] && s=1 + done +done + +rm -f /tmp/kinfo2 +exit $s +EOF + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static char buf[8096]; + +static void +handler(int i __unused) { + _exit(0); +} + +/* Stir /dev/proc */ +static void +churning(void) { + pid_t r; + int fd, status; + + for (;;) { + r = fork(); + if (r == 0) { + if ((fd = open("/proc/curproc/mem", O_RDONLY)) == -1) + err(1, "open(/proc/curproc/mem)"); + bzero(buf, sizeof(buf)); + _exit(0); + } + if (r < 0) { + perror("fork"); + exit(2); + } + wait(&status); + } +} + +/* Get files for each proc */ +void +list(void) +{ + struct dirent *dp; + struct kinfo_file *freep; + struct kinfo_vmentry *freep_vm; + struct stat sb; + pid_t pid; + off_t base; + long l; + int cnt, fd, n; + int space = sizeof(buf); + char *bp = buf; + char *dummy; + + if ((fd = open("/proc", O_RDONLY)) == -1) + err(1, "open(%s)", "/proc"); + + if (fstat(fd, &sb) == -1) + err(1, "fstat()"); + do { + if ((n = getdirentries(fd, bp, space, &base)) == -1) + err(1, "getdirentries"); + space = space - n; + if (space < sb.st_blksize) + break; + bp = bp + n; + } while (n != 0); + close(fd); + + bp = buf; + dp = (struct dirent *)bp; + for (;;) { +#if defined(DEBUG) + printf("name: %-10s, inode %7ju, type %2d, namelen %d, " + "d_reclen %d\n", + dp->d_name, (uintmax_t)dp->d_fileno, dp->d_type, + dp->d_namlen, dp->d_reclen); fflush(stdout); +#endif + + if (dp->d_type == DT_DIR && + (dp->d_name[0] >= '0' && dp->d_name[0] <= '9')) { + l = strtol(dp->d_name, &dummy, 10); + pid = l; + + /* The tests start here */ + freep = kinfo_getfile(pid, &cnt); + free(freep); + + freep_vm = kinfo_getvmmap(pid, &cnt); + free(freep_vm); + /* End test */ + } + + bp = bp + dp->d_reclen; + dp = (struct dirent *)bp; + if (dp->d_reclen <= 0) + break; + } +} + +int +main(void) +{ + pid_t r; + + signal(SIGALRM, handler); + alarm(60); + + if ((r = fork()) == 0) { + alarm(60); + for (;;) + churning(); + } + if (r < 0) { + perror("fork"); + exit(2); + } + + for (;;) + list(); + + return (0); +} diff --git a/tools/test/stress2/misc/kinfo3.sh b/tools/test/stress2/misc/kinfo3.sh new file mode 100755 index 000000000000..9f4d00dbf2fb --- /dev/null +++ b/tools/test/stress2/misc/kinfo3.sh @@ -0,0 +1,197 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 scenario by marcus@freebsd.org and kib@freebsd.org + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > kinfo3.c +mycc -o kinfo3 -Wall -Wextra kinfo3.c -lutil -pthread || exit 1 +rm -f kinfo3.c + +s=0 +mount | grep -q procfs || mount -t procfs procfs /proc +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 1200 ]; do + pids="" + for i in `jot 5`; do + timeout 5m /tmp/kinfo3 & + pids="$pids $!" + done + for pid in $pids; do + wait $pid + r=$? + [ $r -ne 0 ] && { s=1; echo "Exit code $r"; break; } + done +done + +rm -f /tmp/kinfo3 +exit $s +EOF + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char buf[8096]; +static volatile sig_atomic_t more; + +static void +handler(int i __unused) { + + more = 0; +} + +static void * +thr(void *arg __unused) +{ + int fd; + + if ((fd = open("/proc/curproc/mem", O_RDONLY)) == -1) + err(1, "open(/proc/curproc/mem)"); + close(fd); + return (0); +} + +/* Stir /dev/proc */ +static int +churning(void) { + pid_t r; + pthread_t threads[5]; + int i, status;; + + while(more) { + r = fork(); + if (r == 0) { + for (i = 0; i < 5; i++) { + if ((r = pthread_create(&threads[i], NULL, thr, 0)) != 0) + errc(1, r, "pthread_create()"); + } + for (i = 0; i < 5; i++) { + if ((r = pthread_join(threads[i], NULL)) != 0) + errc(1, r, "pthread_join(%d)", i); + } + + bzero(buf, sizeof(buf)); + _exit(0); + } + if (r < 0) { + perror("fork"); + exit(2); + } + wait(&status); + } + _exit(0); +} + +/* Get files for each proc */ +static void +list(void) +{ + struct kinfo_proc *kipp; + struct kinfo_vmentry *freep_vm; + struct kinfo_file *freep, *kif; + size_t len; + long i, j; + int cnt, name[4]; + + name[0] = CTL_KERN; + name[1] = KERN_PROC; + name[2] = KERN_PROC_PROC; + + len = 0; + if (sysctl(name, 3, NULL, &len, NULL, 0) < 0) + err(-1, "sysctl: kern.proc.all"); + + kipp = malloc(len); + if (kipp == NULL) + err(1, "malloc"); + + if (sysctl(name, 3, kipp, &len, NULL, 0) < 0) { + free(kipp); +// warn("sysctl: kern.proc.all"); + return; + } + + for (i = 0; i < (long)(len / sizeof(*kipp)); i++) { + + /* The test starts here */ + freep = kinfo_getfile(kipp[i].ki_pid, &cnt); + for (j = 0; j < cnt && freep; j++) { + kif = &freep[j]; +// printf("%d : %s\n", kif->kf_fd, kif->kf_path); + } + free(freep); + + freep_vm = kinfo_getvmmap(kipp[i].ki_pid, &cnt); + free(freep_vm); + /* End test */ + } + free(kipp); +} + +int +main(void) +{ + pid_t r; + + signal(SIGALRM, handler); + alarm(30); + + more = 1; + if ((r = fork()) == 0) { + alarm(30); + while(more) + churning(); + } + if (r < 0) { + perror("fork"); + exit(2); + } + + while(more) + list(); + + return (0); +} diff --git a/tools/test/stress2/misc/kpti.sh b/tools/test/stress2/misc/kpti.sh new file mode 100755 index 000000000000..c5ca254a48d6 --- /dev/null +++ b/tools/test/stress2/misc/kpti.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# Simple test of kpti (Kernel page-table isolation) enable / disable + +# Page fault seen: https://people.freebsd.org/~pho/stress/log/dougm061.txt +# Fixed by r354132 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +proccontrol -m kpti -q 2> /dev/null || exit 0 +[ `sysctl -n vm.pmap.pti` -eq 1 ] && echo "Page Table Isolation enabled" || + echo "Page Table Isolation disabled" + +prog=date +[ $# -eq 1 ] && prog=$1 +start=`date +%s` +while [ $((`date +%s` - start)) -lt 120 ]; do + for i in `jot 50`; do + proccontrol -m kpti -s disable $prog & + proccontrol -m kpti -s enable $prog & + done > /dev/null + wait +done +exit 0 diff --git a/tools/test/stress2/misc/largepage.sh b/tools/test/stress2/misc/largepage.sh new file mode 100755 index 000000000000..3c8e745ff3ab --- /dev/null +++ b/tools/test/stress2/misc/largepage.sh @@ -0,0 +1,152 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +# Test scenario for of non-transparent superpages. + +# No problems seen. + +. ../default.cfg +[ `uname -p` = "i386" ] && exit 0 +[ -z "`sysctl -i vm.largepages`" ] && exit 0 + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > largepage.c +mycc -o largepage -Wall -Wextra -g -O0 largepage.c || exit 1 +rm -f largepage.c +cd $odir + +/tmp/largepage +s=$? + +for path in `posixshmcontrol ls | grep largepage | awk '{print $NF}'`; do + echo "posixshmcontrol rm $path" + posixshmcontrol rm $path +done +rm -f ./largepage /tmp/largepage.0* /tmp/largepage +exit 0 + +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static size_t ps[MAXPAGESIZES]; +static int fd; + +#define PARALLEL 4 +#define RUNTIME 60 + +static void +work(int idx) +{ + size_t len; + int i,r; + char *p; + volatile char val; + char path[PATH_MAX]; + + len = ps[idx]; + sprintf(path, "/tmp/largepage.%06d", getpid()); + if ((fd = shm_create_largepage(path, O_CREAT | O_RDWR, idx, + SHM_LARGEPAGE_ALLOC_DEFAULT, 0600)) == -1) + err(1,"shm_create_largepage(%zu)", len); + + for (i = 0; i < 100; i++) { + r = ftruncate(fd, len); + if (r == 0) + break; + usleep(200000); + } + if (r == -1) { + shm_unlink(path); + err(1, "ftruncate(%zu)", len); + } + close(fd); + if ((fd = shm_open(path, O_RDWR, 0)) == -1) + err(1, "shm_open()"); + + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == + MAP_FAILED) { + if (errno == ENOMEM) + return; + err(1, "mmap()"); + } + + val = p[arc4random() % len]; + + close(fd); + if (munmap(p, len) == -1) + err(1, "munmap(%p)", p); + if (shm_unlink(path) == -1) + err(1, "shm_unlink()"); + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + time_t start; + int e, i, n, nps, status; + + nps = getpagesizes(ps, MAXPAGESIZES); + e = 0; + n = 1; + start = time(NULL); + while (time(NULL) - start < RUNTIME && e == 0) { + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + work(n); + } + + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], &status, 0) != pids[i]) + err(1, "waitpid(%d)", pids[i]); + if (status != 0) e = 1; + } + n++; + n = n % nps; + if (n == 0) /* skip 4k pages */ + n = 1; + } + close(fd); + + return (e); +} diff --git a/tools/test/stress2/misc/laundry.sh b/tools/test/stress2/misc/laundry.sh new file mode 100755 index 000000000000..5d368432ac3c --- /dev/null +++ b/tools/test/stress2/misc/laundry.sh @@ -0,0 +1,177 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# vm.stats.vm.v_laundry_count test. WiP. No problems seen. + +. ../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/laundry.c +mycc -o laundry -Wall -Wextra -O0 -g laundry.c || exit 1 +rm -f laundry.c +cd $odir + +size=`sysctl -n hw.usermem` +swaptotal=`sysctl -n vm.swap_total` +[ $swaptotal -eq 0 ] && exit 0 +[ $size -gt $swaptotal ] && size=$swaptotal +size=$((size / 10 * 8)) +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 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +set +e + +cd $mntpoint +$dir/laundry $size +s=$? +[ -f laundry.core -a $s -eq 0 ] && + { ls -l laundry.core; s=1; } +cd $odir + +for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && exit 1 +mdconfig -d -u $mdstart +rm -rf $dir/laundry +exit $s + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; +size_t size; + +#define PARALLEL 4 +#define RUNTIME (5 * 60) +#define SYNC 0 + +static void +test(void) +{ + size_t i, sz; + time_t start; + int n; + char *cp; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + sz = size; + if ((cp = mmap(0, sz, PROT_READ|PROT_WRITE, MAP_ANON, -1, 0)) == + (caddr_t) - 1) + err(1, "mmap size %zd", sz); + + n = 0; + start = time(NULL); + while ((time(NULL) - start) < RUNTIME) { + n++; + n = n & 0xff; + for (i = 0; i < sz; i += PAGE_SIZE) + cp[i] = n; + usleep(100); + } + munmap(cp, sz); + + _exit(0); +} + +int +main(int argc __unused, char *argv[]) +{ + pid_t pids[PARALLEL]; + size_t len; + time_t start; + int e, status; + u_int i; + + sscanf(argv[1], "%zd", &size); + size /= PARALLEL; + 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 (WIFEXITED(status)) { + printf("exited, status=%d\n", + WEXITSTATUS(status)); + } else if (WIFSIGNALED(status)) { + printf("killed by signal %d\n", + WTERMSIG(status)); + } else if (WIFSTOPPED(status)) { + printf("stopped by signal %d\n", + WSTOPSIG(status)); + } else if (WIFCONTINUED(status)) { + printf("continued\n"); + } + fprintf(stderr, "pid %d exit code %d\n", + pids[i], status); + } + e += status == 0 ? 0 : 1; + } + } + + return (e); +} + diff --git a/tools/test/stress2/misc/ldt.sh b/tools/test/stress2/misc/ldt.sh new file mode 100755 index 000000000000..21c7055d76fe --- /dev/null +++ b/tools/test/stress2/misc/ldt.sh @@ -0,0 +1,370 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 the amd64 implementation of: +# 1. Per-process private ldt and corresponding i386 arch syscalls. +# 2. Per-process private io permission bitmap and corresponding +# i386 arch syscalls. +# 3. Sigcontext + +# The tests must be compiled on i386 and run on amd64 + +# All tests by kib@ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +cd /tmp +if [ "`uname -p`" = "i386" ]; then + cat > ldt.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char stack[64 * 1024]; + +char a[1]; + +int +s2ds(int sel) +{ + + return (LSEL(sel, SEL_UPL)); +} + +unsigned char +readbyte(int sel, int offset) +{ + unsigned char res; + + __asm__ volatile( + "\tpushl %%es\n" + "\tmovl %1,%%es\n" + "\tmovb %%es:(%2),%0\n" + "\tpopl %%es\n" + : "=r"(res) : "r"(s2ds(sel)), "r"(offset)); + + return (res); +} + +void +writebyte(int sel, int offset, unsigned char val) +{ + + __asm__ volatile( + "\tpushl %%es\n" + "\tmovl %0,%%es\n" + "\tmovb %2,%%es:(%1)\n" + "\tpopl %%es\n" + : : "r"(s2ds(sel)), "r"(offset), "r"(val) : "memory"); +} + +int +alloc_sel(char *base, size_t len, int type, int p) +{ + int sel; + union descriptor descs[1], descsk[1]; + uintptr_t pb; + + memset(descs, 0, sizeof(descs)); + if (len > PAGE_SIZE) { + len = roundup(len, PAGE_SIZE); + len /= PAGE_SIZE; + descs[0].sd.sd_lolimit = len & 0xffff; + descs[0].sd.sd_hilimit = (len >> 16) & 0xf; + descs[0].sd.sd_gran = 1; + } else { + descs[0].sd.sd_lolimit = len; + descs[0].sd.sd_hilimit = 0; + descs[0].sd.sd_gran = 0; + } + pb = (uintptr_t)base; + descs[0].sd.sd_lobase = pb & 0xffffff; + descs[0].sd.sd_hibase = (pb >> 24) & 0xff; + descs[0].sd.sd_type = type; + descs[0].sd.sd_dpl = SEL_UPL; + descs[0].sd.sd_p = p; + descs[0].sd.sd_def32 = 1; + + if ((sel = i386_set_ldt(LDT_AUTO_ALLOC, descs, 1)) == -1) + fprintf(stderr, "i386_set_ldt: %s\n", strerror(errno)); + else if (i386_get_ldt(sel, descsk, 1) == -1) { + fprintf(stderr, "i386_get_ldt: %s\n", strerror(errno)); + sel = -1; + } else if (memcmp(descs, descsk, sizeof(descs)) != 0) { + fprintf(stderr, "descs != descsk\n"); + sel = -1; + } else + fprintf(stderr, "selector %d\n", sel); + + return (sel); +} + +int +test1(int tnum, int sel) +{ + unsigned char ar; + + writebyte(sel, 0, '1'); + ar = readbyte(sel, 0); + if (ar == '1') + fprintf(stderr, "test %d.1 ok\n", tnum); + else + fprintf(stderr, "test%d.1 failed, ar %x\n", tnum, ar); + writebyte(sel, 0, '2'); + ar = readbyte(sel, 0); + if (ar == '2') + fprintf(stderr, "test %d.2 ok\n", tnum); + else + fprintf(stderr, "test%d.2 failed, ar %x\n", tnum, ar); + return (sel); +} + +int +test2_func(void *arg) +{ + int *sel; + + sel = arg; + test1(2, *sel); + rfork(0); + test1(3, *sel); + return (0); +} + +void +test2(int sel) +{ + pid_t r; + int status; + + r = rfork_thread(RFPROC | RFMEM, stack + sizeof(stack), + test2_func, &sel); + if (r == -1) { + fprintf(stderr, "rfork(RFPROC): %s\n", strerror(errno)); + return; + } else { + waitpid(r, &status, 0); + if (WIFSIGNALED(status)) { + fprintf(stderr, "test2: child terminated by %s\n", + strsignal(WTERMSIG(status))); + } + } +} + +int +main(int argc, char *argv[]) +{ + int sel; + + sel = alloc_sel(a, 1, SDT_MEMRWA, 1); + if (sel == -1) + return (1); + + test1(1, sel); + test2(sel); + return (0); +} +EOF + cc -o ldt_static_i386 -Wall -static ldt.c + rm ldt.c + + cat > ioperm.c < +#include +#include +#include +#include +#include + +static const unsigned int port_num = 0x130; + +unsigned char +inb(unsigned int port) +{ + unsigned char data; + + __asm __volatile("inb %%dx,%0" : "=a" (data) : "d" (port)); + return (data); +} + +void +sigbus_handler(int signo) +{ + + fprintf(stderr, "Got SIGBUS\n"); + exit(0); +} + +int +main(int argc, char *argv[]) +{ + struct sigaction sa; + unsigned int length1; + int enable1; + + if (i386_get_ioperm(port_num, &length1, &enable1) == -1) { + fprintf(stderr, "get 1: %s\n", strerror(errno)); + return (1); + } + if (length1 != 0 && enable1 != 0) { + fprintf(stderr, "enable1: enabled\n"); + return (1); + } + if (i386_set_ioperm(port_num, 1, 1) == -1) { + fprintf(stderr, "set 1: %s\n", strerror(errno)); + return (1); + } + inb(port_num); + if (i386_set_ioperm(port_num, 1, 0) == -1) { + fprintf(stderr, "set 2: %s\n", strerror(errno)); + return (1); + } + if (i386_get_ioperm(port_num, &length1, &enable1) == -1) { + fprintf(stderr, "get 1: %s\n", strerror(errno)); + return (1); + } + if (enable1 != 0) { + fprintf(stderr, "enable2: enabled\n"); + return (1); + } + fprintf(stderr, "And now we should get SIGBUS\n"); + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = sigbus_handler; + if (sigaction(SIGBUS, &sa, NULL) == -1) { + fprintf(stderr, "sigaction(SIGBUS): %s\n", strerror(errno)); + return (1); + } + inb(port_num); + + return (0); +} +EOF + cc -o ioperm_static_i386 -Wall -static ioperm.c + rm ioperm.c + + cat > fault.c < +#include +#include +#include +#include +#include +#include +#include + +extern char *fault_instr; +int run; + +void +sigsegv_sigaction(int signo, siginfo_t *si, void *c) +{ + ucontext_t *uc; + mcontext_t *mc; + + uc = c; + mc = &uc->uc_mcontext; + printf("SIGSEGV run %d err %x ds %x ss %x es %x fs %x gs %x\n", + run, mc->mc_err, mc->mc_ds, mc->mc_ss, mc->mc_es, mc->mc_fs, + mc->mc_gs); + switch (run) { + case 0: + mc->mc_ds = 0x1111; + break; + case 1: + mc->mc_es = 0x1111; + break; + case 2: + mc->mc_fs = 0x1111; + break; + case 3: + mc->mc_gs = 0x1111; + break; + case 4: + mc->mc_ss = 0x1111; + break; + case 5: + _exit(11); + } + run++; +} + +void +fault(void) +{ + + __asm__ volatile(".globl\tfault_instr;fault_instr:\ttestl\t\$0,0\n"); +} + +int +main(int argc, char *argv[]) +{ + struct sigaction sa; + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = sigsegv_sigaction; + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGSEGV, &sa, NULL) == -1) { + fprintf(stderr, "sigaction: %s\n", strerror(errno)); + return (1); + } + if (sigaction(SIGBUS, &sa, NULL) == -1) { + fprintf(stderr, "sigaction: %s\n", strerror(errno)); + return (1); + } + + fault(); + + return (0); +} +EOF + cc -o fault_static_i386 -Wall -static fault.c + rm fault.c +fi + +if [ "`uname -p`" = "amd64" ]; then + [ -x ldt_static_i386 ] && ./ldt_static_i386 + [ -x ioperm_static_i386 ] && ./ioperm_static_i386 + [ -x fault_static_i386 ] && { ./fault_static_i386; rm fault_static_i386.core; } +fi +exit 0 diff --git a/tools/test/stress2/misc/ldt2.sh b/tools/test/stress2/misc/ldt2.sh new file mode 100755 index 000000000000..31ee4725bd52 --- /dev/null +++ b/tools/test/stress2/misc/ldt2.sh @@ -0,0 +1,99 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 the implementation of i386_get_ldt() and i386_set_ldt() for 32 bit +# processes on amd64 by running wine and mplayer with a 32 bit codec. + +# This is not a test script, but more of a howto document. + +[ `uname -p` != "amd64" ] && echo "Must run on amd64" && exit + +exit 0 + +This are notes of how to perform the test. + +First of all you will need a i386 jail on amd64. This could be build like +this: + +cat > jailbuild.sh < mplayer.sh <:0 +while true;do + pos=100 + for i in `jot 5`; do + mplayer -vc rv40win -geometry $pos:$pos /root/samples/Real_Media.rm < \ + /dev/null > /dev/null 2>&1 & + pos=$((pos + 50)) + done + for i in `jot 5`; do + wait + done +done +EOF diff --git a/tools/test/stress2/misc/libMicro.sh b/tools/test/stress2/misc/libMicro.sh new file mode 100755 index 000000000000..dc60dfd1c304 --- /dev/null +++ b/tools/test/stress2/misc/libMicro.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 using the OpenSolaris libmicro benchmark +# Has shown page fault with the cascade_lockf test + +if [ $# -eq 0 ]; then + . ../default.cfg + + [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + + [ -x /usr/local/bin/libmicro-bench ] || + { echo "ports/benchmarks/libmicro is not installed"; exit 0; } + + [ `id -un` = $testuser ] && + { echo "\$testuser is identical to current id"; exit 1; } + + rm -f /tmp/libmicro.log + trap "rm -rf /var/tmp/libmicro.[0-9]*" 0 + su $testuser -c "$0 x" + echo "" +else + /usr/local/bin/libmicro-bench > /tmp/libmicro.log & + # Temp. work-around for hanging "c_lockf_10" test. + sleep 60 + kill 0 + wait +fi diff --git a/tools/test/stress2/misc/linger.sh b/tools/test/stress2/misc/linger.sh new file mode 100755 index 000000000000..fee2524ffd3b --- /dev/null +++ b/tools/test/stress2/misc/linger.sh @@ -0,0 +1,168 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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 + +# Demonstrate premature "out of inodes" problem with SU + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > linger.c +mycc -o linger -Wall -O2 linger.c +rm -f linger.c +cd $here + +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 +bsdlabel -w md$mdstart auto +[ $# -eq 1 ] && opt="$1" +[ $# -eq 0 ] && opt=$newfs_flags # No argument == default flag +echo "newfs $opt md${mdstart}$part" +newfs $opt md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +if ! su $testuser -c "cd $mntpoint; /tmp/linger $size"; then + min=2 + [ -r $mntpoint/.sujournal ] && min=3 + r=`df -hi $mntpoint | head -1` + echo " $r" + for i in `jot 10`; do + r=`df -hi $mntpoint | tail -1` + echo "`date '+%T'` $r" + [ `echo $r | awk '{print $6}'` = $min ] && break + sleep 10 + done + ls -lR $mntpoint +fi + +while mount | grep "$mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/linger +exit +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 10 +#define TIMEOUT 1200 +static int size = 6552; /* 10 free inodes */ + +static int +test(void) +{ + int fd, i, j; + pid_t pid; + char file[128]; + + for (;;) { + if (access("rendezvous", R_OK) == 0) + break; + sched_yield(); + } + pid = getpid(); + for (j = 0; j < size; j++) { + sprintf(file,"p%05d.%05d", pid, j); + if ((fd = creat(file, 0660)) == -1) { + if (errno != EINTR) { + warn("creat(%s). %s:%d", file, __FILE__, __LINE__); + unlink("continue"); + break; + } + } + if (fd != -1 && close(fd) == -1) + err(2, "close(%d)", j); + + } + sleep(3); + + for (i = --j; i >= 0; i--) { + sprintf(file,"p%05d.%05d", pid, i); + if (unlink(file) == -1) + warn("unlink(%s)", file); + + } + return (0); +} + +int +main(void) +{ + time_t start; + int error = 0, fd, i, j, status; + + umask(0); + if ((fd = open("continue", O_CREAT, 0644)) == -1) + err(1, "open()"); + close(fd); + start = time(NULL); + for (i = 0; i < 100; i++) { + for (j = 0; j < PARALLEL; j++) { + if (fork() == 0) { + test(); + exit(0); + } + } + + if ((fd = open("rendezvous", O_CREAT, 0644)) == -1) + err(1, "open()"); + close(fd); + + for (j = 0; j < PARALLEL; j++) { + wait(&status); + error += status; + } + + unlink("rendezvous"); + if (access("continue", R_OK) == -1) + break; + if (time(NULL) - start > TIMEOUT) { + fprintf(stderr, "FAIL Timeout\n"); + break; + } + } + unlink("continue"); + + return (error != 0); +} diff --git a/tools/test/stress2/misc/linger2.sh b/tools/test/stress2/misc/linger2.sh new file mode 100755 index 000000000000..e5dad8d7e21d --- /dev/null +++ b/tools/test/stress2/misc/linger2.sh @@ -0,0 +1,172 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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 + +# Variation of linger.sh, with emphasis on blocks. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > linger2.c +mycc -o linger2 -Wall -O2 linger2.c +rm -f linger2.c +cd $here + +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 +bsdlabel -w md$mdstart auto +[ $# -eq 1 ] && opt="$1" +[ $# -eq 0 ] && opt=$newfs_flags # No argument == default flag +newfs $opt -n md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint +set `df -i $mntpoint | tail -1 | awk '{print $3, $6}'` + +min=24 +[ -r $mntpoint/.sujournal ] && { size=88; min=8232; } +if ! su $testuser -c "cd $mntpoint; /tmp/linger2 $size 2>/dev/null"; then + r=`df -i $mntpoint | head -1` + echo " $r" + for i in `jot 12`; do + r=`df -ik $mntpoint | tail -1` + [ "$r" != "$old" ] && echo "`date '+%T'` $r" + old=$r + [ `echo $r | awk '{print $3}'` -le $min ] && break + sleep 10 + done +fi + +while mount | grep "$mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/linger2 +exit +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 10 +static int size = 89; + +int +test(void) +{ + int error = 0, fd, i, j; + pid_t pid; + char file[128]; + char *buf; + + for (;;) { + if (access("rendezvous", R_OK) == 0) + break; + sched_yield(); + } + pid = getpid(); + buf = malloc(1024 * 1024); + for (j = 0; j < size; j++) { + sprintf(file,"p%05d.%05d", pid, j); + if ((fd = creat(file, 0660)) == -1) { + if (errno != EINTR) { + warn("creat(%s). %s:%d", file, __FILE__, __LINE__); + unlink("continue"); + error = 1; + break; + } + } + if (write(fd, buf, 1024 * 1024) != 1024 * 1024) { + warn("write()"); + unlink("continue"); + error = 1; + break; + } + if (fd != -1 && close(fd) == -1) + err(2, "close(%d)", j); + + } + sleep(3); + + if (error == 0) + j--; + for (i = j; i >= 0; i--) { + sprintf(file,"p%05d.%05d", pid, i); + if (unlink(file) == -1) + warn("unlink(%s)", file); + + } + return (error); +} + +int +main(int argc, char **argv) +{ + int error = 0, fd, i, j, status; + + if (argc == 2) + size = atoi(argv[1]); + + umask(0); + if ((fd = open("continue", O_CREAT, 0644)) == -1) + err(1, "open()"); + close(fd); + for (i = 0; i < 200; i++) { + for (j = 0; j < PARALLEL; j++) { + if (fork() == 0) + exit(test()); + } + + if ((fd = open("rendezvous", O_CREAT, 0644)) == -1) + err(1, "open()"); + close(fd); + + for (j = 0; j < PARALLEL; j++) { + wait(&status); + error += status; + } + + unlink("rendezvous"); + if (access("continue", R_OK) == -1) { + break; + } + } + unlink("continue"); + + return (error != 0); +} diff --git a/tools/test/stress2/misc/linger3.sh b/tools/test/stress2/misc/linger3.sh new file mode 100755 index 000000000000..c888d992138a --- /dev/null +++ b/tools/test/stress2/misc/linger3.sh @@ -0,0 +1,134 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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 for SU problem with false EMLINK + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > linger3.c +mycc -o linger3 -Wall -Wextra -O2 linger3.c +rm -f linger3.c + +mount | grep "$mntpoint" | grep -q md$mdstart && umount $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 2g -u $mdstart +bsdlabel -w md$mdstart auto +[ $# -eq 1 ] && opt="$1" +[ $# -eq 0 ] && opt=$newfs_flags # No argument == default flag +echo "newfs $opt md${mdstart}$part" +newfs $opt md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +cd $mntpoint +chmod 777 $mntpoint + +su $testuser -c "/tmp/linger3" + +cd $here + +while mount | grep -q $mntpoint; do + umount $mntpoint 2> /dev/null || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/linger3 +exit 0 +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 4 +#define ND ((32767 / PARALLEL) - 2) + +static pid_t p; + +void +setup(int loop) +{ + int d; + char name[128]; + + for (d = 0; d < ND; d++) { + snprintf(name, sizeof(name), "d%06d.%03d", p, d); + if (mkdir(name, 00700) == -1) + err(1, "mkdir(%s) @ loop #%d", name, loop); + } +} + +void +prune(int loop) +{ + int d; + char name[128]; + + for (d = 0; d < ND; d++) { + snprintf(name, sizeof(name), "d%06d.%03d", p, d); + if (rmdir(name) == -1) + err(1, "rmdir(%s) @ loop #%d", name, loop); + } +} + +int +main() +{ + int i, j; + int linger = 0; + + if (getenv("LINGER")) + linger = atoi(getenv("LINGER")); + + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) { + p = getpid(); + for (j = 0; j < 10; j++) { + setup(j); + prune(j); + if (linger != 0) + sleep(linger); + } + _exit(0); + } + } + + for (i = 0; i < PARALLEL; i++) + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/linger4.sh b/tools/test/stress2/misc/linger4.sh new file mode 100755 index 000000000000..1578575fa387 --- /dev/null +++ b/tools/test/stress2/misc/linger4.sh @@ -0,0 +1,155 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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 for SU problem with "out of inodes" for CREAT + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > linger4.c +mycc -o linger4 -Wall -Wextra -O2 linger4.c +rm -f linger4.c + +mount | grep "$mntpoint" | grep -q md$mdstart && umount $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 2g -u $mdstart +bsdlabel -w md$mdstart auto +[ $# -eq 1 ] && opt="$1" +[ $# -eq 0 ] && opt="$newfs_flags -n" # No argument == default flag +echo "newfs $opt md${mdstart}$part" +newfs $opt md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +cd $mntpoint +chmod 777 $mntpoint + +su $testuser -c "/tmp/linger4" || + { ls -la $mntpoint; df -i $mntpoint; } + +cd $here + +while mount | grep -q $mntpoint; do + umount $mntpoint 2> /dev/null || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/linger4 +exit 0 +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 300 +#define NUMBER 80000 / PARALLEL /* Number of files to use. Max is 131068 */ +#define PARALLEL 4 +#define TIMEOUT (20 * 60) + +void +Creat(int loopno) +{ + int e, fd, i, j; + char file[128]; + char path[128]; + pid_t pid; + + e = 0; + pid = getpid(); + sprintf(path, "f%06d", pid); + if (mkdir(path, 0770) == -1) + warn("mkdir(%s), %s:%d, loop #%d", path, __FILE__, __LINE__, loopno); + chdir(path); + + for (j = 0; j < NUMBER; j++) { + sprintf(file,"p%05d.%05d", pid, j); + if ((fd = creat(file, 0660)) == -1) { + if (errno != EINTR) { + warn("creat(%s). %s:%d, loop #%d", file, __FILE__, __LINE__, loopno); + e = 1; + break; + } + } + if (fd != -1 && close(fd) == -1) + err(2, "close(%d)", j); + + } + + for (i = --j; i >= 0; i--) { + sprintf(file,"p%05d.%05d", pid, i); + if (unlink(file) == -1) + err(3, "unlink(%s)", file); + + } + chdir (".."); + if (rmdir(path) == -1) + err(1, "rmdir(%s), %s:%d, loop #%d", path, __FILE__, __LINE__, loopno); + + _exit(e); +} + +int +main() +{ + time_t start; + int e, i, j, status; + + e = 0; + start = time(NULL); + for (j = 0; j < LOOPS; j++) { + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + Creat(j); + } + + for (i = 0; i < PARALLEL; i++) { + wait(&status); + e += WEXITSTATUS(status); + } + if (e != 0) + break; +// sleep(60); /* No problems if this is included */ + if (time(NULL) - start > TIMEOUT) { + fprintf(stderr, "Timeout.\n"); + e++; + break; + } + } + + return (e); +} diff --git a/tools/test/stress2/misc/link.sh b/tools/test/stress2/misc/link.sh new file mode 100755 index 000000000000..64f76ca5f3b0 --- /dev/null +++ b/tools/test/stress2/misc/link.sh @@ -0,0 +1,193 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Deadlock seen for file systems which suspend writes on unmount, such as +# UFS and tmpfs. +# http://people.freebsd.org/~pho/stress/log/link.txt +# Fixed by r272130 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > link.c +mycc -o link -Wall -Wextra -O2 -g link.c || exit 1 +rm -f link.c + +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +daemon sh -c "(cd $here/../testcases/swap; ./swap -t 5m -i 20 -h -l 100)" \ + > /dev/null 2>&1 +/tmp/link $mntpoint > /dev/null 2>&1 & + +for i in `jot 100`; do + umount -f $mntpoint && + mount /dev/md${mdstart}$part $mntpoint + sleep .1 +done +pkill -9 link +wait + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart + +# tmpfs +mount -t tmpfs tmpfs $mntpoint + +/tmp/link $mntpoint > /dev/null 2>&1 & + +for i in `jot 100`; do + umount -f $mntpoint && + mount -t tmpfs tmpfs $mntpoint + sleep .1 +done +pkill -9 link swap +wait + +while pkill -9 swap; do + : +done > /dev/null 2>&1 +while mount | grep $mntpoint | grep -q tmpfs; do + umount $mntpoint || sleep 1 +done +[ -d "$mntpoint" ] && (cd $mntpoint && find . -delete) +rm -f /tmp/link +exit 0 +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 16 +#define RUNTIME 300 + +time_t start; +char *dir; + +void +trename(void) +{ + int fd; + char name1[MAXPATHLEN + 1]; + char name2[MAXPATHLEN + 1]; + + setproctitle(__func__); + snprintf(name1, sizeof(name1), "%s/r1.%05d", dir, getpid()); + snprintf(name2, sizeof(name2), "%s/r2.%05d", dir, getpid()); + if ((fd = open(name1, O_RDWR | O_CREAT, 0644)) == -1) + err(1, "open(%s)", name1); + close(fd); + + while (time(NULL) - start < RUNTIME) { + if (rename(name1, name2) == -1) { + if (errno == ENOENT) { + if ((fd = open(name1, O_RDWR | O_CREAT, 0644)) == -1) + err(1, "open(%s)", name1); + close(fd); + continue; + } else + warn("link(%s, %s)", name1, name2); + } + if (rename(name2, name1) == -1) + warn("link(%s, %s)", name2, name1); + } + unlink(name1); + unlink(name2); + _exit(0); +} + +void +tlink(void) +{ + int fd; + char name1[MAXPATHLEN + 1]; + char name2[MAXPATHLEN + 1]; + + setproctitle(__func__); + snprintf(name1, sizeof(name1), "%s/f1.%05d", dir, getpid()); + snprintf(name2, sizeof(name2), "%s/f2.%05d", dir, getpid()); + if ((fd = open(name1, O_RDWR | O_CREAT, 0644)) == -1) + err(1, "open(%s)", name1); + close(fd); + + while (time(NULL) - start < RUNTIME) { + unlink(name2); + if (link(name1, name2) == -1) { + if (errno == ENOENT) { + if ((fd = open(name1, O_RDWR | O_CREAT, 0644)) == -1) + err(1, "open(%s)", name1); + close(fd); + continue; + } else + warn("link(%s, %s)", name1, name2); + } + } + unlink(name1); + unlink(name2); + _exit(0); +} + +int +main(int argc, char **argv) +{ + int i, type; + + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + dir = argv[1]; + type = arc4random() % 2; /* test either link() or rename() */ + + start = time(NULL); + for (i = 0; i < PARALLEL; i++) { + if (type == 0 && fork() == 0) + tlink(); + if (type == 1 && fork() == 0) + trename(); + } + for (i = 0; i < PARALLEL; i++) + wait(NULL); + + return(0); +} diff --git a/tools/test/stress2/misc/link2.sh b/tools/test/stress2/misc/link2.sh new file mode 100755 index 000000000000..94116c0dc081 --- /dev/null +++ b/tools/test/stress2/misc/link2.sh @@ -0,0 +1,78 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Copy of link.sh with leak detection added + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/link.sh > link.c +mycc -o link -Wall -Wextra -O2 -g link.c || exit 1 +rm -f link.c + +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +daemon sh -c "(cd $here/../testcases/swap; ./swap -t 5m -i 20 -h -l 100)" \ + > /dev/null 2>&1 +/tmp/link $mntpoint > /dev/null 2>&1 & + +m1=`vmstat -m | awk '/ mount/ {print $2}'` +for i in `jot 100`; do + umount -f $mntpoint && + mount /dev/md${mdstart}$part $mntpoint + sleep .1 +done +m2=`vmstat -m | awk '/ mount/ {print $2}'` +pkill -9 link +while pgrep -q swap; do + pkill -9 swap +done +wait + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart + +[ -d "$mntpoint" ] && (cd $mntpoint && find . -delete) +rm -f /tmp/link +leak=$((m2 - m1)) +[ $leak -gt 2 ] && + { echo "Leaked $leak InUse \"mount\""; s=1; vmstat -m | \ + sed -n '1p;/ mount/p'; } || + s=0 +exit $s diff --git a/tools/test/stress2/misc/linux.sh b/tools/test/stress2/misc/linux.sh new file mode 100755 index 000000000000..1cbbfb8b27a1 --- /dev/null +++ b/tools/test/stress2/misc/linux.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# Bug 230144 - Linux emulator does not work on Ryzen / Epic processors +# No problems seen. + +[ -x /compat/linux/bin/date ] || exit 0 +kldstat | grep -q linux.ko && exit 0 + +set -e +kldload linux.ko +mount -t linprocfs linprocfs /compat/linux/proc +mount -t linsysfs linsysfs /compat/linux/sys +mount -t tmpfs -o rw,mode=1777 tmpfs /compat/linux/dev/shm +[ `uname -m` = amd64 ] && kldload linux64.ko +set +e +[ -x /compat/linux/bin/bash ] && + /compat/linux/bin/bash -c "/compat/linux/bin/date" + +[ `uname -m` = amd64 ] && kldunload linux64.ko +umount /compat/linux/dev/shm +kldstat | grep -q tmpfs.ko && kldunload tmpfs.ko +umount /compat/linux/sys +kldunload linsysfs.ko +umount /compat/linux/proc +kldunload linprocfs.ko +kldunload linux.ko + +exit 0 diff --git a/tools/test/stress2/misc/lockd.sh b/tools/test/stress2/misc/lockd.sh new file mode 100755 index 000000000000..01866e39ef74 --- /dev/null +++ b/tools/test/stress2/misc/lockd.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 rpc memory leak when remote lockd & statd are not running. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +pgrep -q lockd || { echo "lockd not running."; exit 0; } + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 +mount -t nfs -o tcp -o nfsv3 -o retrycnt=1 -o soft,timeout=1 \ + -o rw $nfs_export $mntpoint || exit 0 + +lockf -t 10 $mntpoint/$$.lock sleep 2 > /tmp/$$.log 2>&1 +if grep -q "No locks available" /tmp/$$.log; then + echo "Is lockd running on the remote host?" + rm /tmp/$$.log +fi + +rpc1=`vmstat -m | grep rpc | tail -1 | awk '{print $2}'` +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 60 ]; do + for i in `jot 10`; do + rm -f $mntpoint/$0.$$.$i + lockf -t 10 $mntpoint/$0.$$.$i sleep 2 & + done + wait +done +rm -f $mntpoint/$0.$$* + +s=0 +for i in `jot 6`; do + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && s=1 +rpc2=`vmstat -m | grep rpc | tail -1 | awk '{print $2}'` +if [ $((rpc2 - rpc1)) -gt 2 ]; then + echo "rpc memory leak. Was $rpc1, is $rpc2" + s=2 +fi +exit $s diff --git a/tools/test/stress2/misc/lockf.sh b/tools/test/stress2/misc/lockf.sh new file mode 100755 index 000000000000..347bd063bfe1 --- /dev/null +++ b/tools/test/stress2/misc/lockf.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Page fault seen: +# http://people.freebsd.org/~pho/stress/log/lockf.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +pgrep -q lockd || { echo "lockd not running"; exit 0; } +trap "rm -f /tmp/$0.$$.*" EXIT INT +mount | grep "$mntpoint" | grep nfs > /dev/null && umount $mntpoint + +mount -t nfs -o tcp -o retrycnt=3 -o intr -o soft \ + -o rw $nfs_export $mntpoint +sleep .5 +lockf -t 10 $mntpoint/$$.lock sleep 2 || fail=1 +umount $mntpoint +[ $fail ] && exit 1 + +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 300 ] ; do + mount -t nfs -o tcp -o retrycnt=3 -o intr -o soft \ + -o rw $nfs_export $mntpoint || break + sleep 1 + + for j in `jot 50`; do + lockf -t 10 $mntpoint/$0.$$.$j sleep 3 & + done + + while mount | grep -q $mntpoint; do + umount -f $mntpoint > /dev/null 2>&1 + done + wait +done 2>/dev/null +mount -t nfs -o tcp -o retrycnt=3 -o intr -o soft \ + -o rw $nfs_export $mntpoint || break +sleep .5 +rm $mntpoint/$0.* +while mount | grep -q $mntpoint; do + umount -f $mntpoint > /dev/null 2>&1 +done +exit 0 diff --git a/tools/test/stress2/misc/lockf2.sh b/tools/test/stress2/misc/lockf2.sh new file mode 100755 index 000000000000..6d1501d581b0 --- /dev/null +++ b/tools/test/stress2/misc/lockf2.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +for i in `jot 100`; do + for j in `jot 50`; do + file=/tmp/lockf2.$$.$j + touch $file + lockf -t 10 $file sleep 3 & + done + + for j in `jot 50`; do + rm -f /tmp/lockf2.$$.$j + done + + for j in `jot 50`; do + wait + done +done diff --git a/tools/test/stress2/misc/lockf3.sh b/tools/test/stress2/misc/lockf3.sh new file mode 100755 index 000000000000..4493fa214a33 --- /dev/null +++ b/tools/test/stress2/misc/lockf3.sh @@ -0,0 +1,163 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > lockf3.c +mycc -o lockf3 -Wall -Wextra -O2 lockf3.c || exit 1 +rm -f lockf3.c + +mount | grep -q "$mntpoint" && umount $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 40m -u $mdstart +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +cd $mntpoint +for i in `jot 3`; do + $here/../testcases/swap/swap -t 10m -i 200 > /dev/null & + /tmp/lockf3 || break + pkill swap + wait +done +while pgrep -q swap; do + pkill swap +done +pkill lockf3 +wait +cd $here + +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +rm -rf /tmp/lockf3 +exit 0 +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 10000 +#define PIDS 100 + +void +handler(int s __unused) +{ +} + +void +int_handler(int s __unused) +{ + _exit(0); +} + +void +ahandler(int s __unused) +{ + fprintf(stderr, "FAIL timed out\n"); + _exit(1); +} + +int +main(void) +{ + int fd, i, j; + char name[128]; + pid_t pid[PIDS]; + struct sigaction sa; + int status; + + signal(SIGALRM, ahandler); + alarm(15 * 60); + for (i = 0; i < PIDS; i++) { + sprintf(name, "lock.%06d", getpid()); + if ((fd = open(name, O_CREAT | O_TRUNC | O_RDWR, 0640)) == -1) + err(1, "open(%s)", name); + if (lockf(fd, F_LOCK, 0) == -1) + err(1, "flock 1"); + + if ((pid[i] = fork()) == -1) + err(1, "fork"); + + if (pid[i] == 0) { + memset(&sa, 0, sizeof(sa)); + sa.sa_handler = handler; + if (sigaction(SIGHUP, &sa, NULL) == -1) + err(1, "signal"); + sa.sa_handler = int_handler; + if (sigaction(SIGINT, &sa, NULL) == -1) + err(1, "signal"); + + for (;;) { + if (lockf(fd, F_LOCK, 0) == -1) + if (errno != EINTR) + warn("lockf"); + } + _exit(0); + } + unlink(name); + } + + usleep(10000); + + for (i = 0; i < LOOPS; i++) { + for (j = 0; j < PIDS; j++) { + if (kill(pid[j], SIGHUP) == -1) { + warn("kill(%d), i = %d, j = %d", pid[j], i, j); + pid[j] = 0; + } + } + } + for (j = 0; j < PIDS; j++) { + if (kill(pid[j], SIGINT) == -1) { + warn("kill(%d), i = %d, j = %d", pid[j], i, j); + pid[j] = 0; + } + } + + for (j = 0; j < PIDS; j++) { + if (waitpid(pid[j], &status, 0) == -1) + err(1, "waitpid(%d)", pid[j]); + } + + return (0); +} diff --git a/tools/test/stress2/misc/lockf4.sh b/tools/test/stress2/misc/lockf4.sh new file mode 100755 index 000000000000..690bad033cf4 --- /dev/null +++ b/tools/test/stress2/misc/lockf4.sh @@ -0,0 +1,183 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# lockf(3) test scenario. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > lockf4.c +rm -f /tmp/lockf4 +mycc -o lockf4 -Wall -Wextra -g -O2 lockf4.c || exit 1 +rm -f lockf4.c +cd $odir + +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +su $testuser -c "(cd $mntpoint; /tmp/lockf4)" & +su $testuser -c "(cd $mntpoint; /tmp/lockf4)" & +su $testuser -c "(cd $mntpoint; /tmp/lockf4)" & +wait + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/lockf4 +exit 0 +EOF +#include +#include +#include +#include +#include +#include +#include + +#define N (5 * 1024 * 1024) /* 40 MB */ +int fd; +int idx[N]; +char file[] = "lockf4.file"; + +#define TIMEOUT 600 + +int64_t +add(int ix, int val) +{ + int64_t v; + off_t offset; + time_t start; + int r; + + offset = ix * sizeof(v); + if (lseek(fd, offset, SEEK_SET) == -1) + err(1, "lseek"); + start = time(NULL); + while (lockf(fd, F_LOCK, sizeof(v)) == -1) { + if (errno != EDEADLK) + err(1, "lockf(%s, F_LOCK)", file); + if (time(NULL) - start > TIMEOUT) + errx(1, "lockf timedout"); + } + v = 0; + r = read(fd, &v, sizeof(v)); + if (r == 0) + v = 0; + else + if (r == -1) + err(1, "read"); + v += val; + + if (lseek(fd, offset, SEEK_SET) == -1) + err(1, "lseek"); + if (write(fd, &v, sizeof(v)) < 0) + err(1, "write"); + if (lseek(fd, offset, SEEK_SET) == -1) + err(1, "lseek"); + if (lockf(fd, F_ULOCK, sizeof(v)) == -1) + err(1, "lockf(%s, F_ULOCK)", file); + + return (v); +} + +int +check(void) +{ + int64_t v; + int i; + + setproctitle("check"); + if (lseek(fd, 0, SEEK_SET) == -1) + err(1, "lseek"); + for (i = 1; i < N; i++) { + if (read(fd, &v, sizeof(v)) < 0) + err(1, "read"); + if (v != 0) + return (1); + } + + return (0); +} + +int +main(void) +{ + int64_t r; + int e, i, j, t; + char help[80]; + + for (i = 1; i < N; i++) + idx[i] = i; + + for (i = 1; i < N; i++) { + j = arc4random() % (N - 1) + 1; + t = idx[i]; + idx[i] = idx[j]; + idx[j] = t; + } + + if ((fd = open(file, O_RDWR | O_CREAT, 0644)) == -1) + err(1, "open(%s)", file); + + add(0, 1); + for (i = 1; i < N; i++) { + if (i % 500 == 0) { + snprintf(help, sizeof(help), "add %d%%", i * 100 / N); + setproctitle("%s", help); + } + add(idx[i], 1); + } + for (i = 1; i < N; i++) { + if (i % 500 == 0) { + snprintf(help, sizeof(help), "sub %d%%", i * 100 / N); + setproctitle("%s", help); + } + add(idx[i], -1); + } + + e = 0; + if ((r = add(0, -1)) == 0) { + e = check(); + if (e == 0) + unlink(file); + else + fprintf(stderr, "FAIL\n"); + } + + close(fd); + + return (e); +} diff --git a/tools/test/stress2/misc/lockf5.sh b/tools/test/stress2/misc/lockf5.sh new file mode 100755 index 000000000000..5b5dbad1015c --- /dev/null +++ b/tools/test/stress2/misc/lockf5.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 9: general protection fault while in kernel mode" seen: +# https://people.freebsd.org/~pho/stress/log/lockf5.txt + +# Test scenario by: ngie@FreeBSD.org. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +pgrep -q lockd || { echo "lockd not running."; exit 1; } + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +mount | grep -q "on $mntpoint " && umount -f $mntpoint +mount -t nfs $nfs_export $mntpoint || exit 1 +sleep .5 +rm -rf $mntpoint/$0 +mkdir -p $mntpoint/$0 + +for i in `jot 100`; do + (cd $mntpoint/$0; lockf -t 10 f$i sleep 5) > /dev/null 2>&1 & +done +sleep 3 + +umount -f $mntpoint +wait + +mount -t nfs $nfs_export $mntpoint || exit 1 +sleep .5 +rm -rf $mntpoint/$0 +umount $mntpoint +exit 0 diff --git a/tools/test/stress2/misc/lookup_shared.sh b/tools/test/stress2/misc/lookup_shared.sh new file mode 100755 index 000000000000..935811bee719 --- /dev/null +++ b/tools/test/stress2/misc/lookup_shared.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2011 Peter Holm +# All rights reserved. +# +# 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 +[ -z "`sysctl -in vfs.lookup_shared`" ] && exit 0 + +saved=`sysctl vfs.lookup_shared | awk '{print $NF}'` +trap "sysctl vfs.lookup_shared=$saved" EXIT INT + +export runRUNTIME=10m # Run tests for 10 minutes +sysctl vfs.lookup_shared=0 +(cd ..; ./run.sh disk.cfg) +exit 0 diff --git a/tools/test/stress2/misc/lstat.sh b/tools/test/stress2/misc/lstat.sh new file mode 100755 index 000000000000..f89886a4556e --- /dev/null +++ b/tools/test/stress2/misc/lstat.sh @@ -0,0 +1,236 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Hunt for; +# Bug 204764 - Filesystem deadlock, process in vodead state +# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=204764 +# No problem seen. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/lstat.c +mycc -o lstat -Wall -Wextra -O0 -g lstat.c || exit 1 +rm -f lstat.c +cd $odir + +mount | grep "on $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 || exit 1 +bsdlabel -w md$mdstart auto +newfs -n -b 4096 -f 512 -i 1024 md${mdstart}$part > /dev/null +mount -o async /dev/md${mdstart}$part $mntpoint || exit 1 + +path=$mntpoint/a/b/c +mkdir -p $path + +$dir/lstat $path + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -rf $dir/lstat $wdir/lstat.tmp.* +exit + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *dirs, *share; +static char *arg; + +#define R1 0 +#define R2 1 + +#define MXDIRS 3000 +#define PARALLEL 2 +#define RUNTIME 600 +#define SLPTIME 400 + +static void +tfts(int idx) +{ + FTS *fts; + FTSENT *p; + struct stat sb; + int ftsoptions; + char *args[2]; + + if (idx != 0) + _exit(0); + + ftsoptions = FTS_PHYSICAL; + args[0] = arg, + args[1] = 0; + + setproctitle("fts"); + while (share[R2] == 0) { + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) { + lstat(fts->fts_path, &sb); + if (share[R2] == 1) + break; + } + + if (fts_close(fts) == -1) + err(1, "fts_close()"); + } + + _exit(0); +} + +static int +test(int idx) +{ + struct stat sb; + pid_t fpid, pd, pid; + size_t len; + int i, n, r; + char dir[128], path[128]; + + atomic_add_int(&share[R1], 1); + while (share[R1] != PARALLEL) + ; + + len = PAGE_SIZE; + if ((dirs = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + if ((fpid = fork()) == 0) + tfts(idx); + + pid = getpid(); + snprintf(dir, sizeof(dir), "%s/dir.%d", arg, pid); + if (mkdir(dir, 0777) == -1) + err(1, "mkdir(%s)", dir); + if (chdir(dir) == -1) + err(1, "chdir(%s)", dir); + if ((pd = fork()) == 0) { + setproctitle("mkdir"); + i = 0; + while (share[R2] == 0) { + snprintf(path, sizeof(path), "%s/d.%d.%d", arg, pid, + i); + n = 0; + while (dirs[0] > MXDIRS && share[R2] == 0) + usleep(SLPTIME); + while ((r = mkdir(path, 0777)) == -1) { + if (errno != EMLINK) + err(1, "mkdir(%s) @ %d", path, + __LINE__); + usleep(SLPTIME); + if (share[2] == 1) + break; + } + if (r == 0) { + atomic_add_int(&dirs[0], 1); + i++; + } + } + + _exit(0); + } + + i = 0; + setproctitle("rmdir"); + while (dirs[0] > 0 || share[R2] == 0) { + n = 0; + if (dirs[0] < MXDIRS / 2) + usleep(SLPTIME); + snprintf(path, sizeof(path), "%s/d.%d.%d", arg, pid, i); + while (lstat(path, &sb) == -1 && share[R2] == 0) { + usleep(SLPTIME); + } + if (rmdir(path) == -1) { + if (errno != ENOENT) + err(1, "rmdir(%s)", path); + } else { + atomic_add_int(&dirs[0], -1); + i++; + } + } + waitpid(pd, NULL, 0); + waitpid(fpid, NULL, 0); + + chdir(".."); + if ((rmdir(dir)) == -1) + err(1, "unlink(%s)", dir); + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + size_t len; + int e, i, pids[PARALLEL], status; + + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + arg = argv[1]; + + 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"); + + share[R1] = 0; + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(i); + } + sleep(RUNTIME); + share[R2] = 1; + for (i = 0; i < PARALLEL; i++) { + waitpid(pids[i], &status, 0); + e += status == 0 ? 0 : 1; + } + + return (e); +} diff --git a/tools/test/stress2/misc/mac.sh b/tools/test/stress2/misc/mac.sh new file mode 100755 index 000000000000..48fc8a323f0e --- /dev/null +++ b/tools/test/stress2/misc/mac.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 + +if sysctl security.mac.test 2>&1 | grep -q unknown; then + echo "Kernel must be configured with MAC and MAC_TEST!" + exit 0 +fi + +./crossmp.sh + +sysctl security.mac.test diff --git a/tools/test/stress2/misc/mac_chkexec.sh b/tools/test/stress2/misc/mac_chkexec.sh new file mode 100755 index 000000000000..d3e961b02200 --- /dev/null +++ b/tools/test/stress2/misc/mac_chkexec.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 panic in second ls + +exit 0 # Not part of the kernel +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +sysctl -a | ! grep -q security.mac.chkexec && echo "chkexec.ko must be loaded" && exit 1 + +mount | grep "$mntpoint" | grep -q md${mdstart}$part && umount $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 12m -u $mdstart +bsdlabel -w md$mdstart auto + +newfs md${mdstart}$part > /dev/null +tunefs -l enable /dev/md${mdstart}$part +mount /dev/md${mdstart}$part $mntpoint + +cp /bin/ls $mntpoint +setfmac chkexec/md5:`md5 -q $mntpoint/ls` $mntpoint/ls +sysctl security.mac.chkexec.enforce=1 +$mntpoint/ls $mntpoint/ls +setfmac chkexec/none $mntpoint/ls +$mntpoint/ls $mntpoint/ls +sysctl security.mac.chkexec.enforce=0 + +umount $mntpoint +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/machipc.sh b/tools/test/stress2/misc/machipc.sh new file mode 100755 index 000000000000..09294d0d0295 --- /dev/null +++ b/tools/test/stress2/misc/machipc.sh @@ -0,0 +1,184 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Threaded Mach IPC test scenario +# https://people.freebsd.org/~pho/stress/log/kip014.txt + +ps -p1 | grep -q launchd || exit 0 + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > machipc.c +cc -o machipc -Wall -Wextra -O2 -g machipc.c -lmach -lpthread || exit 1 +rm machipc.c +cd $odir + +(cd ../testcases/swap; ./swap -t 20m -i 20 -h -v) > /dev/null 2>&1 & +sleep 5 +/tmp/machipc +pkill swap +wait +rm -f /tmp/machipc +exit 0 +EOF +#include + +#include + +#include +#include +#include +#include +#include +#include + +typedef struct { + unsigned int msgt_name : 8, + msgt_size : 8, + msgt_number : 12, + msgt_inline : 1, + msgt_longform : 1, + msgt_deallocate : 1, + msgt_unused : 1; +} mach_msg_type_t; + +struct integer_message { + mach_msg_header_t head; + mach_msg_type_t type; + + int inline_integer; +}; + +struct message_recv +{ + mach_msg_header_t head; + mach_msg_type_t type; + int inline_integer; + mach_msg_trailer_t trailer; +}; + +mach_port_t bootstrap_port; + +#define MACH_MSG_TYPE_INTEGER_32 2 +#define N 100000000 + +static void +error(int exitcode, int macherr, const char *funcname) +{ + printf("%s failed with %x\n", funcname, macherr); + exit(exitcode); +} + +void * +client(void *arg) +{ + mach_port_t port = *(mach_port_t *) arg; + struct message_recv message = {}; + int err, i; + + message.head.msgh_local_port = port; + message.head.msgh_size = sizeof(message); + + for (i = 0; i < N; i++) { + /* Receive a message */ + err = mach_msg(&message.head, /* The header */ + MACH_RCV_MSG, /* Flags */ + 0, /* Send size */ + sizeof(message), /* Max receive size */ + port, /* Receive port */ + MACH_MSG_TIMEOUT_NONE, /* No timeout */ + MACH_PORT_NULL); /* No notification */ + if (err) + error(1, err, "server mach_msg MACH_RCV_MSG"); + if (message.inline_integer != i) + errx(1, "FAIL message.inline_integer = %d, i = %d", + message.inline_integer, i); + } + + return(0); +} + +int +main(void) +{ + pthread_t ptd; + mach_port_t port; + struct integer_message message; + int err, i; + + /* Allocate a port */ + err = mach_port_allocate(mach_task_self(), + MACH_PORT_RIGHT_RECEIVE, &port); + if (err) + error(1, err, "mach_port_allocate"); + + err = mach_port_insert_right(mach_task_self(), + port, port, MACH_MSG_TYPE_MAKE_SEND); + + if (err) + error(10, err, "mach_port_insert_right"); + + if ((err = pthread_create(&ptd, NULL, client, &port)) != 0) { + errc(1, err, "pthread_create failed"); + } + + /* Fill the header fields : */ + message.head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND); + message.head.msgh_size = sizeof( struct integer_message ); + message.head.msgh_local_port = MACH_PORT_NULL; + message.head.msgh_remote_port = port; + message.head.msgh_id = 0; /* Message id */ + message.head.msgh_size = sizeof(message); /* Message size */ + + /* Set the message type */ + message.type.msgt_name = MACH_MSG_TYPE_INTEGER_32; + message.type.msgt_size = sizeof(message); + message.type.msgt_number = 1; + message.type.msgt_inline = TRUE; + message.type.msgt_longform = FALSE; + message.type.msgt_deallocate = FALSE; + + for (i = 0; i < N; i++) { + + message.inline_integer = i; + + /* Send the message */ + err = mach_msg(&message.head, /* The header */ + MACH_SEND_MSG, /* Flags */ + sizeof(message), /* Send size */ + 0, /* Max receive Size */ + port, /* Send port */ + MACH_MSG_TIMEOUT_NONE, /* No timeout */ + MACH_PORT_NULL); /* No notification */ + if (err) + error(3, err, "client mach_msg"); + } + pthread_join(ptd, NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/machipc2.sh b/tools/test/stress2/misc/machipc2.sh new file mode 100755 index 000000000000..bfa4e288495a --- /dev/null +++ b/tools/test/stress2/misc/machipc2.sh @@ -0,0 +1,292 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Non threaded Mach IPC test scenario +# https://people.freebsd.org/~pho/stress/log/kip018.txt + +ps -p1 | grep -q launchd || exit 0 + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > machipc2.c +# Test fails without the -lpthread. Need to investigate why. +cc -o machipc2 -Wall -Wextra -O2 -g machipc2.c -lmach -lpthread || exit 1 +rm machipc2.c +cd $odir + +(cd ../testcases/swap; ./swap -t 5m -i 20 -h -v) & +sleep 5 +/tmp/machipc2 +pkill swap +rm -f /tmp/machipc2 +exit 0 +EOF +/* + Inspired by: Michael Weber: http://www.foldr.org/~michaelw/log/2009/03/13/ + */ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#define MACH_MSG_TYPE_INTEGER_32 2 +#define N 200000000 + +typedef struct { + unsigned int msgt_name : 8, + msgt_size : 8, + msgt_number : 12, + msgt_inline : 1, + msgt_longform : 1, + msgt_deallocate : 1, + msgt_unused : 1; +} mach_msg_type_t; + +struct integer_message { + mach_msg_header_t head; + mach_msg_type_t type; + + int inline_integer; +}; + +struct message_recv +{ + mach_msg_header_t head; + mach_msg_type_t type; + int inline_integer; + mach_msg_trailer_t trailer; +}; + +static task_t child_task = MACH_PORT_NULL; + +mach_port_t bootstrap_port; + +#define CHECK_MACH_ERROR(err, s) \ + do { \ + if (err != KERN_SUCCESS) { \ + fprintf(stderr, "%s: %s", s, mach_error_string(err)); \ + exit(1); \ + } \ + } while (0) + +static int +setup_recv_port (mach_port_t *recv_port) +{ + kern_return_t kerr; + mach_port_t port = MACH_PORT_NULL; + kerr = mach_port_allocate (mach_task_self (), + MACH_PORT_RIGHT_RECEIVE, &port); + CHECK_MACH_ERROR (kerr, "mach_port_allocate failed:"); + + kerr = mach_port_insert_right (mach_task_self (), + port, port, MACH_MSG_TYPE_MAKE_SEND); + CHECK_MACH_ERROR (kerr, "mach_port_insert_right failed:"); + + *recv_port = port; + + return (0); +} + +static int +send_port (mach_port_t remote_port, mach_port_t port) +{ + kern_return_t kerr; + + struct { + mach_msg_header_t header; + mach_msg_body_t body; + mach_msg_port_descriptor_t task_port; + } msg; + + msg.header.msgh_remote_port = remote_port; + msg.header.msgh_local_port = MACH_PORT_NULL; + msg.header.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0) | + MACH_MSGH_BITS_COMPLEX; + msg.header.msgh_size = sizeof msg; + + msg.body.msgh_descriptor_count = 1; + msg.task_port.name = port; + msg.task_port.disposition = MACH_MSG_TYPE_COPY_SEND; + msg.task_port.type = MACH_MSG_PORT_DESCRIPTOR; + + kerr = mach_msg_send (&msg.header); + CHECK_MACH_ERROR(kerr, "mach_msg_send failed:"); + + return (0); +} + +static int +recv_port(mach_port_t recv_port, mach_port_t *port) +{ + kern_return_t kerr; + struct { + mach_msg_header_t header; + mach_msg_body_t body; + mach_msg_port_descriptor_t task_port; + mach_msg_trailer_t trailer; + } msg; + + kerr = mach_msg(&msg.header, MACH_RCV_MSG, + 0, sizeof msg, recv_port, + MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + CHECK_MACH_ERROR(kerr, "mach_msg failed:"); + + *port = msg.task_port.name; + return (0); +} + +void +writeint(mach_port_t port) +{ + struct integer_message message; + int kerr, i; + + /* Fill the header fields : */ + message.head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND); + message.head.msgh_size = sizeof( struct integer_message ); + message.head.msgh_local_port = MACH_PORT_NULL; + message.head.msgh_remote_port = port; + message.head.msgh_id = 0; /* Message id */ + message.head.msgh_size = sizeof(message); /* Message size */ + + /* Set the message type */ + message.type.msgt_name = MACH_MSG_TYPE_INTEGER_32; + message.type.msgt_size = sizeof(message); + message.type.msgt_number = 1; + message.type.msgt_inline = TRUE; + message.type.msgt_longform = FALSE; + message.type.msgt_deallocate = FALSE; + + for (i = 0; i < N; i++) { + message.inline_integer = i; + + /* Send the message */ + kerr = mach_msg(&message.head, /* The header */ + MACH_SEND_MSG, /* Flags */ + sizeof(message), /* Send size */ + 0, /* Max receive Size */ + port, /* Send port */ + MACH_MSG_TIMEOUT_NONE, /* No timeout */ + MACH_PORT_NULL); /* No notification */ + if (kerr) + errx(1, "client mach_msg: %s", mach_error_string(kerr)); + } +} + +void +readint(mach_port_t port) +{ + struct message_recv rmessage = {}; + int kerr, i; + + rmessage.head.msgh_local_port = port; + rmessage.head.msgh_size = sizeof(rmessage); + + for (i = 0; i < N; i++) { + /* Receive a message */ + kerr = mach_msg(&rmessage.head, /* The header */ + MACH_RCV_MSG, /* Flags */ + 0, /* Send size */ + sizeof(rmessage), /* Max receive size */ + port, /* Receive port */ + MACH_MSG_TIMEOUT_NONE, /* No timeout */ + MACH_PORT_NULL); /* No notification */ + if (kerr) + errx(1, "client mach_msg MACH_RCV_MSG: %s", mach_error_string(kerr)); + if (rmessage.inline_integer != i) + errx(1, "FAIL message.inline_integer = %d, i = %d", + rmessage.inline_integer, i); + } +} + +void +sampling_fork(void) +{ + pid_t pid; + kern_return_t kerr; + mach_port_t parent_recv_port = MACH_PORT_NULL; + mach_port_t child_recv_port = MACH_PORT_NULL; + + if (setup_recv_port(&parent_recv_port) != 0) + return; + kerr = task_set_bootstrap_port(mach_task_self(), parent_recv_port); + CHECK_MACH_ERROR(kerr, "task_set_bootstrap_port failed:"); + + if ((pid = fork()) == -1) + err(1, "fork"); + + if (pid == 0) { + kerr = task_get_bootstrap_port(mach_task_self(), &parent_recv_port); + CHECK_MACH_ERROR(kerr, "task_get_bootstrap_port failed:"); + if (setup_recv_port(&child_recv_port) != 0) + return; + if (send_port(parent_recv_port, mach_task_self()) != 0) + return; + if (send_port(parent_recv_port, child_recv_port) != 0) + return; + if (recv_port(child_recv_port, &bootstrap_port) != 0) + return; + kerr = task_set_bootstrap_port(mach_task_self(), bootstrap_port); + CHECK_MACH_ERROR(kerr, "task_set_bootstrap_port failed:"); + + readint(child_recv_port); + + _exit(0); + } + + /* parent */ + kerr = task_set_bootstrap_port(mach_task_self(), bootstrap_port); + CHECK_MACH_ERROR(kerr, "task_set_bootstrap_port failed:"); + if (recv_port(parent_recv_port, &child_task) != 0) + return; + if (recv_port(parent_recv_port, &child_recv_port) != 0) + return; + if (send_port(child_recv_port, bootstrap_port) != 0) + return; + kerr = mach_port_deallocate(mach_task_self(), parent_recv_port); + CHECK_MACH_ERROR(kerr, "mach_port_deallocate failed:"); + + writeint(child_recv_port); +} + +int +main(void) +{ + sampling_fork(); + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/marcus.sh b/tools/test/stress2/misc/marcus.sh new file mode 100755 index 000000000000..727b1ad56c17 --- /dev/null +++ b/tools/test/stress2/misc/marcus.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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 + +# Run with marcus.cfg on a 1g swap backed MD with UFS SU fs. + +. ../default.cfg + +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=20m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' + +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}$part; s=$? +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/marcus2.sh b/tools/test/stress2/misc/marcus2.sh new file mode 100755 index 000000000000..1e58c52ddfde --- /dev/null +++ b/tools/test/stress2/misc/marcus2.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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 + +# Run with marcus.cfg on a 2g swap backed MD with UFS SU fs. +# Copy of marcus.sh, but with maximum load. + +# "panic: vm_radix_remove: invalid key found" seen. +# watchdog fired: https://people.freebsd.org/~pho/stress/log/marcus2.txt + +. ../default.cfg + +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=20m +export RUNDIR=$mntpoint/stressX + +n=`find ../testcases -perm -1 -type f | wc -l` +m=`su $testuser -c "limits | awk '/maxprocesses/ {print \\$NF}'"` +export INCARNATIONS=$((m / n)) +export swapINCARNATIONS=$INCARNATIONS + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' & + +sleep 10 +start=`date '+%s'` +while pgrep -q run; do + [ $((`date '+%s'` - start)) -gt 1500 ] && + ../tools/killall.sh + sleep 10 +done +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 +checkfs /dev/md${mdstart}$part; s=$? +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/marcus3.sh b/tools/test/stress2/misc/marcus3.sh new file mode 100755 index 000000000000..f870ebe89115 --- /dev/null +++ b/tools/test/stress2/misc/marcus3.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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 + +# Watchdog fired: +# https://people.freebsd.org/~pho/stress/log/kostik853.txt +# but runs for a long time without watchdogd and deadlkres. + +. ../default.cfg + +dev=$(df -h `dirname $RUNDIR` | tail -1 | awk '{print $1}') +mount | grep $dev | grep -q journaled && exit 0 +size=$((`sysctl -n hw.physmem` / 1024 / 1024)) +[ $size -gt $((4 * 1024)) ] && + echo "RAM should be capped to 4GB for this test." +[ "`sysctl -n debug.deadlkres.sleepfreq 2>/dev/null`" = "3" ] && + { echo "deadlkres must be disabled for this test."; exit 0; } + +n=`find ../testcases -perm -1 -type f | wc -l` +m=`su $testuser -c "limits | grep maxprocesses | awk '{print \\$NF}'"` +export runRUNTIME=15m +export INCARNATIONS=$((m / n)) +export swapINCARNATIONS=$INCARNATIONS + +timeout 16m su $testuser -c 'cd ..; ./run.sh marcus.cfg' +exit 0 diff --git a/tools/test/stress2/misc/marcus4.sh b/tools/test/stress2/misc/marcus4.sh new file mode 100755 index 000000000000..60f0e4c87605 --- /dev/null +++ b/tools/test/stress2/misc/marcus4.sh @@ -0,0 +1,86 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 + +# Copy of marcus3.sh, but without the VM (page stealer) pressure. +# Deadlock and "panic: smp_targeted_tlb_shootdown: interrupts disabled" +# https://people.freebsd.org/~pho/stress/log/marcus4.txt + +# "panic: spin lock held too long" seen. +# Fixed in r313472. + +. ../default.cfg + +pgrep -q watchdogd && { service watchdogd stop > /dev/null && restart=1; } +dev=$(df -h `dirname $RUNDIR` | tail -1 | awk '{print $1}') +mount | grep $dev | grep -q journaled && exit 0 +size=$((`sysctl -n hw.physmem` / 1024 / 1024)) +[ $size -gt $((4 * 1024)) ] && + { echo "RAM should be capped to 4GB for this test."; } +[ "`sysctl -n debug.deadlkres.sleepfreq 2>/dev/null`" = "3" ] && + { echo "deadlkres must be disabled for this test."; exit 0; } + +n=`find ../testcases -perm -1 -type f | wc -l` +m=`su $testuser -c "limits | grep maxprocesses | awk '{print \\$NF}'"` +m=$((m / 2)) + +export INCARNATIONS=$((m / n)) +export runRUNTIME=15m +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 +" + +start=`date +%s` +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' & + +sleep $((16 * 60)) +../tools/killall.sh; s=$? +wait +./cleanup.sh +elapsed=$((`date +%s` - start)) +if [ $elapsed -gt $((30 * 60)) ]; then + echo "Runtime is $elapsed seconds" + s=100 +fi + +[ $restart ] && service watchdogd start > /dev/null +exit $s diff --git a/tools/test/stress2/misc/marcus5.sh b/tools/test/stress2/misc/marcus5.sh new file mode 100755 index 000000000000..97c2465ba49c --- /dev/null +++ b/tools/test/stress2/misc/marcus5.sh @@ -0,0 +1,85 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 +[ `swapinfo | wc -l` -eq 1 ] && exit 0 + +# Copy of marcus4.sh, but with a md(4) disk. +# "panic: userret: Returning with SU cleanup request not handled" seen: +# https://people.freebsd.org/~pho/stress/log/marcus5.txt +# Fixed by r292541. + +. ../default.cfg + +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 5g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +size=$((`sysctl -n hw.physmem` / 1024 / 1024)) +[ $size -gt $((4 * 1024)) ] && + echo "RAM should be capped to 4GB for this test." +[ "`sysctl -n debug.deadlkres.sleepfreq 2>/dev/null`" = "3" ] && + { echo "deadlkres must be disabled for this test."; exit 0; } + +n=`find ../testcases -perm -1 -type f | wc -l` +m=`su $testuser -c "limits | awk '/maxprocesses/ {print \\$NF}'"` + +export RUNDIR=$mntpoint/stressX +export INCARNATIONS=$((m / n)) +export runRUNTIME=15m +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 +" + +timeout 20m su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' + +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}$part; s=$! +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/marcus6.sh b/tools/test/stress2/misc/marcus6.sh new file mode 100755 index 000000000000..076a51e1e4a4 --- /dev/null +++ b/tools/test/stress2/misc/marcus6.sh @@ -0,0 +1,83 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `swapinfo | wc -l` -eq 1 ] && exit 0 + +# Variation of marcus5.sh +# "panic: Assertion pgrp->pg_jobc > 0 failed at kern_proc.c:740" seen. + +. ../default.cfg + +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 5g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +size=$((`sysctl -n hw.physmem` / 1024 / 1024)) +[ "`sysctl -n debug.deadlkres.sleepfreq 2>/dev/null`" = "3" ] && + { echo "deadlkres must be disabled for this test."; exit 0; } + +m=`su $testuser -c "limits | awk '/maxprocesses/ {print \\$NF}'"` +[ $m -gt 100000 ] && m=100000 + +rm -rf /tmp/stressX.control +export RUNDIR=$mntpoint/stressX +export INCARNATIONS=$((m / 11)) +export runRUNTIME=3m +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 +" + +timeout -s SIGINT -k 2m 1m su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' + +n=0 +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 + [ $((n += 1)) -gt 60 ] && { echo "Timed out"; exit 1; } +done +checkfs /dev/md${mdstart}$part; s=$! +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/marcus7.sh b/tools/test/stress2/misc/marcus7.sh new file mode 100755 index 000000000000..94800c5c5f60 --- /dev/null +++ b/tools/test/stress2/misc/marcus7.sh @@ -0,0 +1,90 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# Variation of marcus5.sh with more rename tests. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `swapinfo | wc -l` -eq 1 ] && exit 0 + +# Copy of marcus4.sh, but with a md(4) disk. +# "panic: userret: Returning with SU cleanup request not handled" seen: +# https://people.freebsd.org/~pho/stress/log/marcus5.txt +# Fixed by r292541. + +. ../default.cfg + +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 5g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +size=$((`sysctl -n hw.physmem` / 1024 / 1024)) +[ $size -gt $((4 * 1024)) ] && + echo "RAM should be capped to 4GB for this test." +[ "`sysctl -n debug.deadlkres.sleepfreq 2>/dev/null`" = "3" ] && + { echo "deadlkres must be disabled for this test."; exit 0; } + +n=`find ../testcases -perm -1 -type f | wc -l` +m=`su $testuser -c "limits | awk '/maxprocesses/ {print \\$NF}'"` + +export RUNDIR=$mntpoint/stressX +export INCARNATIONS=$((m / n)) +export runRUNTIME=10m +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 +" + +timeout 12m su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' + +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}$part; s=$! +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/maxmemdom.sh b/tools/test/stress2/misc/maxmemdom.sh new file mode 100755 index 000000000000..661de87410f2 --- /dev/null +++ b/tools/test/stress2/misc/maxmemdom.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 "options MAXMEMDOM" is broken. (NUMA test) +# panic: vm_page_alloc: missing page +# https://people.freebsd.org/~pho/stress/log/maxmemdom.txt +# Fixed in r293640. + +. ../default.cfg + +[ `sysctl -n vm.ndomains` -eq 1 ] && exit 0 +size=$((`sysctl -n hw.physmem` / 1024 / 1024)) +need=$((size * 2)) +d1=$diskimage.1 +d2=$diskimage.2 +rm -f $d1 $d2 +[ `df -k $(dirname $diskimage) | tail -1 | awk '{print int($4 / 1024)}'` -lt \ + $need ] && printf "Need %d MB on %s.\n" $need `dirname $diskimage` && exit +timeout 30m sh -ce " + dd if=/dev/zero of=$d1 bs=1m count=$size status=none + cp $d1 $d2 +" +s=$? +[ $s -eq 124 ] && echo "Timed out" + +rm -f $d1 $d2 +exit $s diff --git a/tools/test/stress2/misc/maxproc.sh b/tools/test/stress2/misc/maxproc.sh new file mode 100755 index 000000000000..c425c307e06b --- /dev/null +++ b/tools/test/stress2/misc/maxproc.sh @@ -0,0 +1,167 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 that a non root user can at most have maxproc - 10 processes. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > maxproc.c +mycc -o maxproc -Wall -Wextra maxproc.c -lkvm || exit 1 +rm -f maxproc.c +[ `sysctl -n kern.maxproc` -gt 37028 ] && exit 0 # Excessive run time +cd $here + +/tmp/maxproc + +rm -f /tmp/maxproc +exit +EOF +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +enum { + NL_NPROCS, + NL_MAXPROC, + NL_MARKER +}; + +static struct { + int order; + const char *name; +} namelist[] = { + { NL_NPROCS, "_nprocs" }, + { NL_MAXPROC, "_maxproc" }, + { NL_MARKER, "" }, +}; + +#define NNAMES (sizeof(namelist) / sizeof(*namelist)) +#define MULTIUSERFUZZ 5 + +static struct nlist nl[NNAMES]; + +static void +t2(void) +{ + pid_t p; + + for (;;) { + if ((p = fork()) == 0) { + sleep(2); + _exit(0); + } + if (p == -1) + break; + } +} + +static void +t1(int priv) +{ + pid_t p; + struct passwd *pw; + + if ((p = fork()) == 0) { + if ((pw = getpwnam("nobody")) == NULL) + err(1, "no such user: nobody"); + + if (priv == 0) { + 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(); + + t2(); + _exit(0); + } + waitpid(p, NULL, 0); +} + +int +getprocs(void) +{ + kvm_t *kd; + int i, nprocs, maxproc; + char buf[_POSIX2_LINE_MAX]; + char *nlistf, *memf; + + nlistf = memf = NULL; + for (i = 0; i < (int)NNAMES; i++) + nl[namelist[i].order].n_name = strdup(namelist[i].name); + + if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, buf)) == NULL) + errx(1, "kvm_openfile(%s, %s): %s", nlistf, memf, buf); + if (kvm_nlist(kd, nl) == -1) + errx(1, "kvm_nlist: %s", kvm_geterr(kd)); + if (kvm_read(kd, nl[NL_NPROCS].n_value, &nprocs, + sizeof(nprocs)) != sizeof(nprocs)) + errx(1, "kvm_read(): %s", kvm_geterr(kd)); + if (kvm_read(kd, nl[NL_MAXPROC].n_value, &maxproc, + sizeof(maxproc)) != sizeof(maxproc)) + errx(1, "kvm_read(): %s", kvm_geterr(kd)); + kvm_close(kd); + + return (maxproc - nprocs - 1); +} + +int +main(void) +{ + int i, n; + + alarm(1200); + n = getprocs(); + for (i = 0; i < n / 10 * 8; i++) { + if (fork() == 0) { + sleep(2); + _exit(0); + } + } + + t1(0); + + n = getprocs(); + if (n < 10 - MULTIUSERFUZZ) + errx(1, "FAIL: nprocs = %d\n", n); + + return (0); +} diff --git a/tools/test/stress2/misc/maxvnodes.sh b/tools/test/stress2/misc/maxvnodes.sh new file mode 100755 index 000000000000..b962310cbb0e --- /dev/null +++ b/tools/test/stress2/misc/maxvnodes.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 dynamic kern.maxvnodes implementation. + +# "panic: vm_fault_hold: fault on nofault entry, addr: 0xfffffe00b1b3c000" +# seen: https://people.freebsd.org/~pho/stress/log/kostik1175.txt + +. ../default.cfg + +kldstat | grep -q tmpfs.ko || notloaded=1 +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +mount -o size=2g -t tmpfs tmpfs $mntpoint || exit 1 +chmod 777 $mntpoint + +oldmx=`sysctl -n kern.maxvnodes` +trap "sysctl kern.maxvnodes=$oldmx > /dev/null" EXIT SIGINT + +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX +export TESTPROGS=" +testcases/creat/creat +testcases/mkdir/mkdir +testcases/swap/swap +" +export creatINCARNATIONS=50 +export creatLOAD=100 + +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > /dev/null 2>&1 & + +min=1000 +max=$((oldmx * 4)) +while kill -0 $! 2>/dev/null; do + sysctl kern.maxvnodes=`jot -r 1 $min $max` > /dev/null + sleep `jot -r 1 1 3` +done +wait + +while mount | grep $mntpoint | grep -q tmpfs; do + umount $mntpoint || sleep 1 +done +[ $notloaded ] && kldunload tmpfs.ko +exit 0 diff --git a/tools/test/stress2/misc/maxvnodes2.sh b/tools/test/stress2/misc/maxvnodes2.sh new file mode 100755 index 000000000000..798eff1bffd6 --- /dev/null +++ b/tools/test/stress2/misc/maxvnodes2.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC Isilon +# All rights reserved. +# +# 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 + +# "panic: Bad link elm 0xfffff8015ea20000 prev->next != elm" seen: +# https://people.freebsd.org/~pho/stress/log/mjguzik005.txt +# Fixed by r309067. + +oldmx=`sysctl -n kern.maxvnodes` +trap "sysctl kern.maxvnodes=$oldmx > /dev/null" EXIT SIGINT + +sysctl kern.maxvnodes=2000 + +timeout 10m ../misc/msdos6.sh + +exit diff --git a/tools/test/stress2/misc/md.sh b/tools/test/stress2/misc/md.sh new file mode 100755 index 000000000000..47e491e2b841 --- /dev/null +++ b/tools/test/stress2/misc/md.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Caused panic: ffs_truncate3 +# The problem is caused by a full FS with Soft-updates disabled. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep "$mntpoint" | grep md${mdstart}$part > /dev/null && umount $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 2m -u $mdstart +bsdlabel -w md$mdstart auto +newfs md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +export RUNDIR=$mntpoint/stressX +export KBLOCKS=30000 # Exaggerate disk capacity +export INODES=8000 + +for i in `jot 20`; do + (cd ../testcases/rw;./rw -t 2m -i 20 > /dev/null 2>&1) +done + +while mount | grep -q $mntpoint; do + umount $([ $((`date '+%s'` % 2)) -eq 0 ] && + echo "-f" || echo "") $mntpoint > /dev/null 2>&1 +done + +mdconfig -d -u $mdstart +exit 0 diff --git a/tools/test/stress2/misc/md2.sh b/tools/test/stress2/misc/md2.sh new file mode 100755 index 000000000000..939d7e46db39 --- /dev/null +++ b/tools/test/stress2/misc/md2.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2011 Peter Holm +# All rights reserved. +# +# 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: ufs_dirbad: /mnt: bad dir ino 32899 at offset 16896: mangled entry + +# "panic: ffs_read: type 0" seen: +# https://people.freebsd.org/~pho/stress/log/kostik969.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep "on $mntpoint " | grep -q md$mdstart && umount $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t malloc -s 256m -u $mdstart + +export RUNDIR=$mntpoint/stressX +export runRUNTIME=10m +for i in 1 2; do + echo "newfs -O$i -i1024 /dev/md$mdstart" + newfs -O$i -i1024 /dev/md$mdstart > /dev/null 2>&1 + mount /dev/md$mdstart $mntpoint + + (cd ..; ./run.sh) + + while mount | grep -q "on $mntpoint "; do + umount $mntpoint + done +done +mdconfig -d -u $mdstart +exit 0 diff --git a/tools/test/stress2/misc/md3.sh b/tools/test/stress2/misc/md3.sh new file mode 100755 index 000000000000..626d578e54ae --- /dev/null +++ b/tools/test/stress2/misc/md3.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +# +# Copyright (c) 2009-2011 Peter Holm +# All rights reserved. +# +# 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 scenario for deadlock fixed in r200447 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep -q "$mntpoint" && umount $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1400m -u $mdstart +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +# Stop FS "out of inodes" problem by only using 70% +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$(($1 / 10 * 7)) +export INODES=$(($2 / 10 * 7)) + +export RUNDIR=$mntpoint/stressX +export runRUNTIME=10m + +(cd ..; ./run.sh marcus.cfg) + +umount $mntpoint +mount | grep -q "$mntpoint" && umount -f $mntpoint +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/md4.sh b/tools/test/stress2/misc/md4.sh new file mode 100755 index 000000000000..484e531e3f6c --- /dev/null +++ b/tools/test/stress2/misc/md4.sh @@ -0,0 +1,43 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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 data corruption on the swap-backed md. +# Test scenario by Nigel Williams . +# Fixed in r250966. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +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 diff --git a/tools/test/stress2/misc/md5.sh b/tools/test/stress2/misc/md5.sh new file mode 100755 index 000000000000..a6655db395b5 --- /dev/null +++ b/tools/test/stress2/misc/md5.sh @@ -0,0 +1,48 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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. +# + +# "dd: /dev/md5: Input/output error" seen. +# kib@: kern_physio() detects EOF due to incorrect calculation +# of bio bio_resid after the bio_length was clipped by the 'excess' code +# in g_io_check() +# Test scenario by Stefan Hegnauer +# Fixed in r259200 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +log=/tmp/md5.log +dd if=/dev/zero of=$diskimage bs=1k count=5k status=none +mdconfig -f $diskimage -u md$mdstart || exit 1 +newfs $newfs_flags /dev/md$mdstart > /dev/null +dd if=/dev/md$mdstart of=/dev/null > $log 2>&1 && s=0 || s=1 +[ $s -eq 1 ] && cat $log +mdconfig -d -u $mdstart +rm -f $diskimage $log +exit $s diff --git a/tools/test/stress2/misc/md6.sh b/tools/test/stress2/misc/md6.sh new file mode 100755 index 000000000000..f24f0d921e8b --- /dev/null +++ b/tools/test/stress2/misc/md6.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 mmap problem introduced by r271635 +# where mdconfig -l fails due to +# mmap(0,0x1000,PROT_READ,MAP_FILE,0x4,0) +# returning 0. +# Fixed by r271721. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 10m -u $mdstart || exit 1 +[ -c /dev/md$mdstart ] || echo "FAIL" +mdconfig -l -v > /dev/null || echo "FAIL of mdconfig -l" +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/md7.sh b/tools/test/stress2/misc/md7.sh new file mode 100755 index 000000000000..f15377607a97 --- /dev/null +++ b/tools/test/stress2/misc/md7.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Deadlock seen: The softdep code requesting workqueue cleanups while +# owning vnode locks: +# https://people.freebsd.org/~pho/stress/log/kostik812.txt +# Fixed by: r283600 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `swapinfo | wc -l` -eq 1 ] && exit 0 # Covered by md3.sh + +swapoff -a +./md3.sh +swapon -a diff --git a/tools/test/stress2/misc/md8.sh b/tools/test/stress2/misc/md8.sh new file mode 100755 index 000000000000..e073271dac15 --- /dev/null +++ b/tools/test/stress2/misc/md8.sh @@ -0,0 +1,121 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 of unmapped unaligned i/o over the vnode-backed md(4) volume. +# "panic: vm_fault: fault on nofault entry, addr: fffffe07f302c000" seen. +# https://people.freebsd.org/~pho/stress/log/md8.txt +# Fixed in r292128. + +# Test scenario by kib@ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -d /usr/src/sys ] || exit 0 + +. ../default.cfg + +rm -f $diskimage +dir=`dirname $diskimage` +free=`df -k $dir | tail -1 | awk '{print $4}'` +[ $((free / 1024)) -lt 50 ] && echo "Not enough disk space." && exit + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > md8.c +rm -f /tmp/md8 +mycc -o md8 -Wall -Wextra -g -O2 md8.c || exit 1 +rm -f md8.c + +cd $odir +trap "rm -f $diskimage" EXIT INT +dd if=/dev/zero of=$diskimage bs=1m count=50 status=none +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t vnode -f $diskimage -u $mdstart + +n=`sysctl -n hw.ncpu` +n=$((n + 1)) +(cd /usr/src; make -j $n buildkernel > /dev/null 2>&1) & +sleep 1 +/tmp/md8 /dev/md$mdstart +kill $! +wait + +mdconfig -d -u $mdstart +rm -rf /tmp/md8 +exit 0 +EOF +#include + +#include +#include +#include +#include +#include + +#define LOOPS 2000 + +void +test(char *path) +{ + int fd; + char data[MAXPHYS + 512] __aligned(PAGE_SIZE); + + if ((fd = open(path, O_RDONLY)) == -1) + err(1, "open(%s)", path); + if (read(fd, data + 512, MAXPHYS) != MAXPHYS) + err(1, "read"); + close(fd); + + if ((fd = open(path, O_WRONLY)) == -1) + err(1, "open(%s)", path); + if (write(fd, data + 512, MAXPHYS) != MAXPHYS) + err(1, "write"); + close(fd); + + if ((fd = open(path, O_RDONLY)) == -1) + err(1, "open(%s)", path); + if (read(fd, data + 512, MAXPHYS) != MAXPHYS) + err(1, "read"); + close(fd); +} + +int +main(int argc, char *argv[]) +{ + int i; + char *path; + + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + + path = argv[1]; + + for (i = 0; i < LOOPS; i++) + test(path); + + return (0); +} diff --git a/tools/test/stress2/misc/md9.sh b/tools/test/stress2/misc/md9.sh new file mode 100755 index 000000000000..a232ade6963f --- /dev/null +++ b/tools/test/stress2/misc/md9.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# memory disk with vnode on a tmpfs file system triggers: +# "g_handleattr(GEOM::ident): md10 bio_length 24 len 31 -> EFAULT" + +. ../default.cfg +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +set -e +mp2=${mntpoint}2 +mkdir -p $mp2 +mount | grep "on $mp2 " | grep -q /dev/md && umount -f $mp2 +mount -t tmpfs tmpfs $mp2 + +mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +diskimage=$mp2/diskimage +dd if=/dev/zero of=$diskimage bs=1m count=2k status=none +mdconfig -a -t vnode -f $diskimage -u $mdstart +bsdlabel -w md$mdstart auto +newfs -U /dev/md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +for i in `jot 10`; do + umount $mntpoint && break + sleep .5 +done +mount | grep "on $mntpoint " && { echo FATAL; exit 1; } +mdconfig -d -u $mdstart +umount $mp2 +tail -5 /var/log/messages | grep g_handleattr && s=1 || s=0 + +exit $s diff --git a/tools/test/stress2/misc/mdconfig.sh b/tools/test/stress2/misc/mdconfig.sh new file mode 100755 index 000000000000..ecfe188a102d --- /dev/null +++ b/tools/test/stress2/misc/mdconfig.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +. ../default.cfg + +# Regression test for: +# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=214721 +# https://people.freebsd.org/~pho/stress/log/mdconfig.txt +# Fixed by: r311964. + +mdconfig -at swap -S 65536 -s 20M -u $mdstart +mdconfig -d -u $mdstart + +exit 0 diff --git a/tools/test/stress2/misc/mdconfig2.sh b/tools/test/stress2/misc/mdconfig2.sh new file mode 100755 index 000000000000..13c13dc55111 --- /dev/null +++ b/tools/test/stress2/misc/mdconfig2.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# /dev/md* fails to be created. +# "kernel: g_dev_taste: make_dev_p() failed (gp->name=md10, error=17)" seen. +# The cause is that the device node is removed asynchronously. + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 + +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -l | grep -q md$mdstart && + { echo FAIL; ls -l /dev/md$mdstart; mdconfig -lv; exit 1; } + +s=0 +start=`date +%s` +workaround=${workaround:-0} +while [ $((`date +%s` - start)) -lt 60 ]; do + mdconfig -a -t swap -s 100m -u $mdstart || { s=2; break; } + [ -c /dev/md$mdstart ] || + { echo FAIL; ls -l /dev/md$mdstart; mdconfig -lv; exit 3; } + mdconfig -d -u $mdstart || { s=4; break; } + while [ $workaround -eq 1 -a -c /dev/md$mdstart ]; do + echo "Note: Waiting for removal of /dev/md$mdstart" + sleep .1 + done +done +exit $s diff --git a/tools/test/stress2/misc/mdconfig3.sh b/tools/test/stress2/misc/mdconfig3.sh new file mode 100755 index 000000000000..7fbdcbc1a5ff --- /dev/null +++ b/tools/test/stress2/misc/mdconfig3.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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(x) option force test. +# Fixed by r345758 + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 + +rm -df $diskimage +dd if=/dev/zero of=$diskimage bs=1m count=5 status=none +mdconfig -a -t vnode -f $diskimage -u $mdstart +dd if=/dev/random of=/dev/md$mdstart bs=1m count=5 status=none +md1=`md5 < /dev/md$mdstart` +mdconfig -d -u $mdstart -o force + +md2=`md5 < $diskimage` +rm -d $diskimage + +[ "$md1" != "$md2" ] && exit 1 || exit 0 diff --git a/tools/test/stress2/misc/memguard.sh b/tools/test/stress2/misc/memguard.sh new file mode 100755 index 000000000000..9b2a3a964d1b --- /dev/null +++ b/tools/test/stress2/misc/memguard.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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 + +# MEMGUARD(9) test scenario: Page fault seen in softdep_setup_inomapdep(). + +. ../default.cfg + +sysctl vm | grep -q memguard || { echo "MEMGUARD(9) not enabled"; exit 0; } + +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 20m -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=5m +export RUNDIR=$mntpoint/stressX +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$(($1 * 2)) +export INODES=$(($2 * 2)) + +sysctl vm.memguard.options=3 > /dev/null +sysctl vm.memguard.desc=inodedep + +su $testuser -c 'cd ..; ./run.sh disk.cfg' > /dev/null + +sysctl vm.memguard.desc="" > /dev/null +sysctl vm.memguard.options=1 > /dev/null + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/memguard2.sh b/tools/test/stress2/misc/memguard2.sh new file mode 100755 index 000000000000..4c4619ef89e3 --- /dev/null +++ b/tools/test/stress2/misc/memguard2.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# MEMGUARD(9) test scenario +# http://people.freebsd.org/~pho/stress/log/memguard4.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +sysctl vm | grep -q memguard || { echo "MEMGUARD(9) not enabled"; exit 1; } + +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=30s +export RUNDIR=$mntpoint/stressX +[ -d $RUNDIR ] || mkdir $RUNDIR +chmod 777 $RUNDIR + +sysctl vm.memguard.options=3 > /dev/null +{ vmstat -m; echo dummy; } | sed '1d;s/ [0-9].*//;s/^ *//' | \ + sed 's/ *$//' | tr '\n' ' ' | ../tools/shuffle | \ + tr ' ' '\n' | head -10 | while read type; do + sysctl vm.memguard.desc="$type" + su $testuser -c 'cd ..; ./run.sh disk.cfg' > /dev/null + find /tmp/stressX.control/* $mntpoint/stressX/* -delete 2>/dev/null +done +sysctl vm.memguard.desc="" > /dev/null +sysctl vm.memguard.options=1 > /dev/null + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/memguard3.sh b/tools/test/stress2/misc/memguard3.sh new file mode 100755 index 000000000000..8a7705c71537 --- /dev/null +++ b/tools/test/stress2/misc/memguard3.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# MEMGUARD(9) test scenario using "frequency". +# "panic: __rw_wlock_hard: recursing but non-recursive rw kmem vm object" +# seen. http://people.freebsd.org/~pho/stress/log/memguard5.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +sysctl vm | grep -q memguard || { echo "MEMGUARD(9) not enabled"; exit 1; } + +sysctl vm.memguard.options=3 +sysctl vm.memguard.frequency=1000 + +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 5g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=5m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +checkfs /dev/md${mdstart}$part; s=$? +mdconfig -d -u $mdstart + +sysctl vm.memguard.frequency=0 > /dev/null +sysctl vm.memguard.options=1 > /dev/null +exit $s diff --git a/tools/test/stress2/misc/memguard4.sh b/tools/test/stress2/misc/memguard4.sh new file mode 100755 index 000000000000..323183caf96d --- /dev/null +++ b/tools/test/stress2/misc/memguard4.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 without using memguard.options + +. ../default.cfg + +sysctl vm | grep -q memguard || { echo "MEMGUARD(9) not enabled"; exit 0; } + +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=5m +export RUNDIR=$mntpoint/stressX + +sysctl vm.memguard.desc=inodedep + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' > /dev/null 2>&1 + +sysctl vm.memguard.desc="" > /dev/null + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +exit 0 diff --git a/tools/test/stress2/misc/midi.sh b/tools/test/stress2/misc/midi.sh new file mode 100755 index 000000000000..47594734b4e0 --- /dev/null +++ b/tools/test/stress2/misc/midi.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 Mark Johnston +# +# 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: vm_fault_hold: fault on nofault entry, addr: 0x33522000' seen. +# Fixed by 351262 + +cat > /tmp/midi.c < +#include +#include +#include +#include +#include + +#define NTHREADS 16 + +static _Atomic(int) threads; +static int fd; + +static void * +t(void *data __unused) +{ + char buf[4096]; + ssize_t n; + off_t off; + + (void)atomic_fetch_add(&threads, 1); + while (atomic_load(&threads) != NTHREADS) + ; + + for (;;) { + arc4random_buf(&off, sizeof(off)); + if ((n = pread(fd, buf, sizeof(buf), off)) >= 0) + write(STDOUT_FILENO, buf, n); + } + + return (NULL); +} + +int +main(void) +{ + pthread_t tid[NTHREADS]; + int error, i; + + fd = open("/dev/midistat", O_RDONLY); + if (fd < 0) + err(1, "open"); + + for (i = 0; i < NTHREADS; i++) + if ((error = pthread_create(&tid[i], NULL, t, NULL)) != 0) + errc(1, error, "pthread_create"); + for (i = 0; i < NTHREADS; i++) + if ((error = pthread_join(tid[i], NULL)) != 0) + errc(1, error, "pthread_join"); + + return (0); +} +EOF +cc -o /tmp/midi -Wall -Wextra -O2 /tmp/midi.c -lpthread + +start=`date +%s` +while [ $((`date +%s` - start)) -lt 120 ]; do + timeout 10 /tmp/midi | strings | head -20 +done + +rm -f /tmp/midi /tmp/midi.c /tmp/midi.core +exit 0 diff --git a/tools/test/stress2/misc/midi2.sh b/tools/test/stress2/misc/midi2.sh new file mode 100755 index 000000000000..91f15aa3cc3b --- /dev/null +++ b/tools/test/stress2/misc/midi2.sh @@ -0,0 +1,114 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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 threaded access to /dev/midistat. + +# "panic: vm_fault_hold: fault on nofault entry, addr: 0x8b352000" seen. +# https://people.freebsd.org/~pho/stress/log/mark089.txt +# Fixed by 351262 + +. ../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/midi2.c +mycc -o midi2 -Wall -Wextra -O0 -g midi2.c -lpthread || exit 1 + +$dir/midi2 +s=$? +cat /dev/midistat > /dev/null || s=1 + +rm -rf midi2 midi2.c midi2.core +exit $s + +EOF +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int share; +static int fd; +static char buf[0xbc59], buf2[0x40eddf]; + +#define THREADS 4 +#define RUNTIME (1 * 60) +#define SYNC 0 + +static void * +t1(void *data __unused) +{ + + atomic_add_int(&share, 1); + while (share != THREADS) + ; + + pread(fd, buf, 0xbc59, 0x27dbb298LL); + pread(fd, buf, 0xbc59, 0x104e35c6d22eLL); + pread(fd, buf2, 0x40eddf, 0x405d1df88cbf41LL); + + return (NULL); +} + +int +main(void) +{ + pthread_t tid[THREADS]; + time_t start; + int i, rc; + + if ((fd = open("/dev/midistat", O_RDONLY)) == -1) + err(1, "open(/dev/midistat)"); + start = time(NULL); + while ((time(NULL) - start) < RUNTIME) { + share = 0; + for (i = 0; i < THREADS; i++) { + if ((rc = pthread_create(&tid[i], NULL, t1, NULL)) != + 0) + errc(1, rc, "pthread_create"); + } + + for (i = 0; i < THREADS; i++) { + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join"); + } + } + + return (0); +} diff --git a/tools/test/stress2/misc/mincore.sh b/tools/test/stress2/misc/mincore.sh new file mode 100755 index 000000000000..85c09cc0ceaf --- /dev/null +++ b/tools/test/stress2/misc/mincore.sh @@ -0,0 +1,157 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# Hunt for https://people.freebsd.org/~pho/stress/log/log0018.txt + +# Test scenario idea by kib@ +# Scenario should be the following (without paging load, so that pages stay +# resident): +# - create some large file, say 2G +# - map it and touch every page to ensure that they all allocated +# - unmap, and map again, so while the pages are resident, they are not +# installed into page table +# Do mincore(2) on the mapped region. +# + +# The problem was not reproduced. + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 +[ `sysctl -n vm.swap_total` -eq 0 ] && exit 0 +path=`dirname $diskimage` +[ `df -k $path | tail -1 | awk '{print int($4 / 1024 / 1024)}'` -lt 4 ] && exit 0 + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mincore.c +mycc -o mincore -Wall -Wextra -O0 -g mincore.c || exit 1 +rm -f mincore.c +cd $odir + +(cd ../testcases/swap; ./swap -t 10m -i 20 -l 100) & +for i in `jot 20`; do + [ `swapinfo | tail -1 | awk '{gsub("%", ""); print $5}'` -gt 0 ] && break + sleep 5 + pgrep -q swap || break +done +echo "`date +%T` Go" + +$dir/mincore $path; s=$? + +while pkill swap; do :; done +wait +rm -rf $dir/mincore +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 2 +#define RUNTIME 300 +#define SIZE (2LL * 1024 * 1024 * 1024) + +static void +test(char *dir) +{ + size_t i, len; + int fd; + char file[128], *p, *vec; + + len = SIZE; + snprintf(file, sizeof(file), "%s/mincore.%d.file", dir, getpid()); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, DEFFILEMODE)) + == -1) + err(1, "open(%s)", file); + if (unlink(file) == -1) + err(1, "unlink(%s)", file); + if (ftruncate(fd, len) == -1) + err(1, "ftruncete()"); + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == + MAP_FAILED) + err(1, "mmap()"); + for (i = 0; i < len; i += PAGE_SIZE) + p[i] = 1; + if (munmap(p, len) == -1) + err(1, "munmap()"); + if ((vec = malloc(len / PAGE_SIZE)) == NULL) + err(1, "malloc"); + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == + MAP_FAILED) + err(1, "mmap()"); + if (mincore(p, len, vec) == -1) + err(1, "mincore()"); + if (munmap(p, len) == -1) + err(1, "munmap()"); + close(fd); + + _exit(0); +} + +int +main(int argc __unused, char *argv[]) +{ + pid_t pids[PARALLEL]; + time_t start; + int i; + + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(argv[1]); + } + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], NULL, WNOHANG) == pids[i]) { + if ((pids[i] = fork()) == 0) + test(argv[1]); + } + } + } + + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], NULL, 0) != pids[i]) + err(1, "waitpid"); + } + + return (0); +} diff --git a/tools/test/stress2/misc/minherit.sh b/tools/test/stress2/misc/minherit.sh new file mode 100755 index 000000000000..facb018a0337 --- /dev/null +++ b/tools/test/stress2/misc/minherit.sh @@ -0,0 +1,176 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 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. +# + +# minherit() test scenario inspired by Jeff's collapse.sh test. +# No problems seen. + +. ../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/minherit.c +mycc -o minherit -Wall -Wextra -O0 -g minherit.c || exit 1 +rm -f minherit.c +cd $odir + +(cd $odir/../testcases/swap; ./swap -t 5m -i 10 -l 50) & +pid=$! +cd /tmp +$dir/minherit +s=$? +while pkill swap; do :; done +wait $oid +[ -f minherit.core -a $s -eq 0 ] && + { ls -l minherit.core; mv minherit.core $dir; s=1; } +cd $odir + +rm -rf $dir/minherit +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static _Atomic(int) *share; + +#define ADRSPACE (1024 * 1024) +#define CHILDREN 200 +#define PARALLEL 10 +#define RUNTIME (5 * 60) +#define SYNC 0 + +static void +test(void) +{ + pid_t pids[CHILDREN]; + off_t len; + void *p; + int i, ix, j, n, shared; + char *cp; + + (void)atomic_fetch_add(&share[SYNC], 1); + while (atomic_load(&share[SYNC]) != PARALLEL) + ; + + if ((p = mmap(NULL, ADRSPACE, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANON, -1, 0)) == MAP_FAILED) { + if (errno == ENOMEM) + return; + err(1, "mmap()"); + } + + /* Pick a random bit of address space to change inherit on. */ + for (i = 0; i < ADRSPACE; i += len) { + shared = arc4random() & 0x1; + len = roundup2(arc4random() % ((ADRSPACE - i) / 4), + PAGE_SIZE); + if (minherit(p + i, len, shared ? INHERIT_SHARE : + INHERIT_COPY) != 0) + err(1, "minherit"); + } + + n = arc4random() % CHILDREN + 1; + for (i = 0; i < n; i++) { + pids[i] = fork(); + if (pids[i] == -1) + err(1, "fork()"); + if (pids[i] == 0) { + usleep(arc4random() % 100); + for (j = 0; j < 10; j++) { + cp = p; + for (ix = 0; ix < ADRSPACE; ix += PAGE_SIZE) { + cp[ix] = 1; + if (arc4random() % 100 < 5) + usleep(arc4random() % 50); + } + } + _exit(0); + } + } + for (i = 0; i < n; i++) { + if (waitpid(pids[i], NULL, 0) == -1) + err(1, "waitpid(%d)", pids[i]); + } + + _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; + break; + } + } + } + + return (e); +} diff --git a/tools/test/stress2/misc/mkfifo.sh b/tools/test/stress2/misc/mkfifo.sh new file mode 100755 index 000000000000..a0f012da5baa --- /dev/null +++ b/tools/test/stress2/misc/mkfifo.sh @@ -0,0 +1,86 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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 + +# Hunt for "panic: ufsdirhash_newblk: bad offset" + +# but page fault seen in scheduler() due to a _thread_lock_flags() call on +# an inactive td. + +# Fault seen in "softdep_disk_io_initiation+0x41": +# https://people.freebsd.org/~pho/stress/log/mkfifo.txt + +# Run with mkfifo.cfg on a 2g swap backed MD + +. ../default.cfg + +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 || exit 1 +bsdlabel -w md$mdstart auto + +[ "$newfs_flags" = "-U" ] && opt="-j" +newfs $opt md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=20m +export RUNDIR=$mntpoint/stressX + +export TESTPROGS=" +testcases/creat/creat +testcases/fts/fts +testcases/link/link +testcases/lockf/lockf +testcases/mkdir/mkdir +testcases/mkfifo/mkfifo +testcases/openat/openat +testcases/rename/rename +testcases/rw/rw +testcases/swap/swap +" +export creatLOAD=100 +export ftsLOAD=100 +export linkLOAD=100 +export lockfLOAD=100 +export mkdirLOAD=100 +export mkfifoLOAD=100 +export openatLOAD=100 +export renameLOAD=100 +export rwLOAD=100 +export swapLOAD=100 + +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +exit 0 diff --git a/tools/test/stress2/misc/mkfifo2c.sh b/tools/test/stress2/misc/mkfifo2c.sh new file mode 100755 index 000000000000..6d83a5aca4a2 --- /dev/null +++ b/tools/test/stress2/misc/mkfifo2c.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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 + +# "bad offset" panic after up 10:57 on leopard3 + +# Run with mkfifo.cfg on a 2g swap backed MD +# Problem seen with and without +j + +# "panic: ufsdirhash_newblk: bad offset" seen: +# https://people.freebsd.org/~pho/stress/log/mkfifo2c.txt +# https://people.freebsd.org/~pho/stress/log/mkfifo2c-2.txt +# https://people.freebsd.org/~pho/stress/log/kostik932.txt +# Fixed by r305601. + +. ../default.cfg + +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 || exit 1 +bsdlabel -w md$mdstart auto + +[ $# -eq 1 ] && opt="$1" +[ $# -eq 0 ] && opt="-j" +newfs $opt md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=20m +export RUNDIR=$mntpoint/stressX + +export TESTPROGS=" +testcases/fts/fts +testcases/link/link +testcases/mkfifo/mkfifo +testcases/mkdir/mkdir +testcases/rename/rename +testcases/swap/swap +" + +export ftsLOAD=100 +export linkLOAD=100 +export mkdirLOAD=100 +export mkfifoLOAD=100 +export renameLOAD=100 +export swapLOAD=100 + +export renameINCARNATIONS=4 +export swapINCARNATIONS=4 +export linkINCARNATIONS=12 +export mkdirINCARNATIONS=20 +export mkfifoINCARNATIONS=22 +export ftsINCARNATIONS=2 + +export HOG=1 + +su $testuser -c 'cd ..; timeout 15m ./testcases/run/run $TESTPROGS' + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/mkfifo2d.sh b/tools/test/stress2/misc/mkfifo2d.sh new file mode 100755 index 000000000000..74d5875d090f --- /dev/null +++ b/tools/test/stress2/misc/mkfifo2d.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 + +# Copy of mkfifo2c.sh, but with a SU file system and async mount +# "panic: ufsdirhash_newblk: bad offset" seen from openat() +# https://people.freebsd.org/~pho/stress/log/mkfifo2d.txt +# Fixed by r305601. + +. ../default.cfg + +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null +mount -o async /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=5m +export RUNDIR=$mntpoint/stressX + +export TESTPROGS=" +testcases/fts/fts +testcases/link/link +testcases/mkfifo/mkfifo +testcases/mkdir/mkdir +testcases/rename/rename +testcases/swap/swap +" + +export ftsLOAD=100 +export linkLOAD=100 +export mkdirLOAD=100 +export mkfifoLOAD=100 +export renameLOAD=100 +export swapLOAD=100 + +export renameINCARNATIONS=4 +export swapINCARNATIONS=4 +export linkINCARNATIONS=12 +export mkdirINCARNATIONS=20 +export mkfifoINCARNATIONS=22 +export ftsINCARNATIONS=2 + +export HOG=1 + +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/mkfifo3.sh b/tools/test/stress2/misc/mkfifo3.sh new file mode 100755 index 000000000000..1f205dbfa98b --- /dev/null +++ b/tools/test/stress2/misc/mkfifo3.sh @@ -0,0 +1,139 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +. ../default.cfg + +# Regression test for +# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=203162 + +# FAIL +# 1001 82102 907 0 20 0 6484 2480 wait S+ 0 0:00,01 /bin/sh ./mkfifo3.sh +# 1001 82113 82102 0 52 0 3832 1604 fifoow I+ 0 0:03,91 /tmp/mkfifo3 + +# Fixed in r288044. + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mkfifo3.c +mycc -o mkfifo3 -Wall -Wextra -O0 -g mkfifo3.c || exit 1 +rm -f mkfifo3.c +cd $odir + +fifo=/tmp/mkfifo3.fifo +trap "rm -f $fifo /tmp/mkfifo3" EXIT INT + +/tmp/mkfifo3 & + +for i in `jot 12`; do + pgrep -q mkfifo3 || break + sleep 10 +done +s=0 +if pgrep -q mkfifo3; then + s=1 + pgrep mkfifo3 | xargs ps -lp + pkill mkfifo3 +fi +wait + +exit $s +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define ATIME 1 +#define LOOPS 100000 + +char file[] = "/tmp/mkfifo3.fifo"; + +static void +hand(int i __unused) { /* handler */ +} + +int +main(void) +{ + pid_t pid; + struct sigaction sa; + int fd, i, status; + + sa.sa_handler = hand; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGALRM, &sa, NULL) == -1) + err(1, "sigaction"); + + if (unlink(file) == -1) + if (errno != ENOENT) + err(1, "unlink(%s)", file); + if (mkfifo(file, 0640) == -1) + err(1, "mkfifo(%s)", file); + + for (i = 0; i < LOOPS; i++) { + if ((pid = fork()) == 0) { + ualarm(ATIME, 0); + do { + if((fd = open(file, O_RDONLY)) == -1) + if (errno != EINTR) + err(1, "open(%s, O_RDONLY @ %d)", + file, i); + } while (fd == -1); + if (close(fd) == -1) + err(1, "close() in child"); + alarm(0); + _exit(0); + } + ualarm(ATIME, 0); + do { + if ((fd = open(file, O_WRONLY)) == -1) + if (errno != EINTR) + err(1, "open(%s, O_WRONLY @ %d)", + file, i); + } while (fd == -1); + if (close(fd) == -1) + err(1, "close() in parent"); + alarm(0); + if (waitpid(pid, &status, 0) == -1) + err(1, "wait"); + } + + if (unlink(file) == -1) + err(1, "unlink(%s)", file); + + return (0); +} diff --git a/tools/test/stress2/misc/mkfifo4.sh b/tools/test/stress2/misc/mkfifo4.sh new file mode 100755 index 000000000000..0e560ffe7b4e --- /dev/null +++ b/tools/test/stress2/misc/mkfifo4.sh @@ -0,0 +1,186 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +. ../default.cfg + +# "Assertion vap->va_type == VDIR failed" seen on non HEAD. + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mkfifo4.c +mycc -o mkfifo4 -Wall -Wextra -O0 -g mkfifo4.c || exit 1 +rm -f mkfifo4.c +cd $odir + +fifo=/tmp/mkfifo4.fifo +trap "rm -f $fifo /tmp/mkfifo4" EXIT INT + +export runRUNTIME=5m +(cd ..; ./run.sh disk.cfg) > /dev/null 2>&1 & +sleep .2 + +while pgrep -fq run.sh; do + timeout 300 /tmp/mkfifo4 | grep -v Done + [ $? -eq 124 ] && + { echo "Timedout"; exit 1; } +done +wait + +exit $s +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define ATIME 1 +#define MXRETRY 100 +#define LOOPS 1000000 + +volatile int sigs; +char file[] = "/tmp/mkfifo4.fifo"; + +static void +hand(int i __unused) { /* handler */ + sigs++; +} + +int +main(void) +{ + pid_t pid, hpid; + struct sigaction sa; + int e, fd, fd2, i, status; + int failures, r, retries, w; + char c; + + sa.sa_handler = hand; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGALRM, &sa, NULL) == -1) + err(1, "sigaction"); + + sa.sa_handler = SIG_IGN; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGPIPE, &sa, NULL) == -1) + err(1, "sigaction"); + + unlink(file); + if (mkfifo(file, 0640) == -1) + err(1, "mkfifo(%s)", file); + if ((hpid = fork()) == 0) { + if ((fd2 = open(file, O_WRONLY | O_APPEND)) == -1) + err(1, "hold open of fifo"); + for (;;) + pause(); + _exit(0); + } + + if ((pid = fork()) == 0) { + setproctitle("child"); + r = 0; + for (i = 0; i < LOOPS; i++) { + failures = 0; +restart: + do { + if ((fd = open(file, O_RDONLY | + O_NONBLOCK)) == -1) + if (errno != EINTR) /* on OS X */ + err(1, "open(%s, O_RDONLY)", + file); + } while (fd == -1); + retries = 0; + do { + if ((e = read(fd, &c, 1)) == -1) { + if (errno != EINTR && + errno != EAGAIN) + err(1, "read(%d, ...)", fd); + } else if (retries++ > MXRETRY) { + close(fd); + usleep(1000); + fprintf(stderr, + "Re-open for read @ %d\n", i); + if (failures++ > 100) + errx(1, + "FAIL: Failure to read"); + goto restart; + } + } while (e <= 0); + r++; + ualarm(ATIME, 0); + if (close(fd) == -1) + err(1, "close() in child"); + alarm(0); + } + fprintf(stdout, "Done child. %d reads, %d signals.\n", r, + sigs); + fflush(stdout); + _exit(0); + } + setproctitle("parent"); + w = 0; + for (i = 0; i < LOOPS; i++) { + do { + if ((fd = open(file, O_WRONLY | O_APPEND | + O_NONBLOCK)) == -1) + if (errno != EINTR && errno != ENXIO) + err(1, "open(%s, O_WRONLY)", file); + } while (fd == -1); + do { + if ((e = write(fd, "a", 1)) != 1) + if (errno != EPIPE && errno != EAGAIN) + err(1, "write(%d, ...)", fd); + } while (e == -1); + w++; + ualarm(ATIME, 0); + if (close(fd) == -1) + err(1, "close() in parent"); + alarm(0); + } + fprintf(stdout, "Done parent. %d writes, %d signals.\n", w, sigs); + + if (waitpid(pid, &status, 0) == -1) + err(1, "wait"); + if (kill(hpid, SIGHUP) == -1) + err(1, "kill %d", hpid); + if (waitpid(hpid, NULL, 0) == -1) + err(1, "wait"); + if (unlink(file) == -1) + err(1, "unlink(%s)", file); + + return (WEXITSTATUS(status)); +} diff --git a/tools/test/stress2/misc/mkfifo5.sh b/tools/test/stress2/misc/mkfifo5.sh new file mode 100755 index 000000000000..c0355cef2db0 --- /dev/null +++ b/tools/test/stress2/misc/mkfifo5.sh @@ -0,0 +1,214 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# mkfifo(2), select(2) with tmpfs(5) scenario. + +. ../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/mkfifo5.c +mycc -o mkfifo5 -Wall -Wextra -O0 -g mkfifo5.c || exit 1 +rm -f mkfifo5.c +cd $odir + +mount | grep -q "on $mntpoint " && umount -f $mntpoint +mount -o size=1g -t tmpfs tmpfs $mntpoint + +fifo=$mntpoint/fifo.file +cd $mntpoint +/tmp/mkfifo5 $fifo +s=$? +cd $odir + +while mount | grep "on $mntpoint " | grep -q tmpfs; do + umount $mntpoint || sleep 1 +done +rm -rf /tmp/mkfifo5 +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static char *path; + +#define PARALLEL 1 + +static void +reader(void) +{ + fd_set rset; + struct timeval timeout; + int fd, n, r; + char ch; + + do { + if((fd = open(path, O_RDONLY)) == -1) + if (errno != EINTR) + err(1, "open(%s, O_RDONLY)", + path); + if (fd == -1) + warn("open(%s) ro", path); + } while (fd == -1); + + /* Read one character */ + FD_ZERO(&rset); + FD_SET(fd, &rset); + if ((n = select(fd + 1, &rset, NULL, NULL, NULL)) < 0) + if (errno != EINTR) + err(1, "select()"); + if (n == 1 && FD_ISSET(fd, &rset)) { + r = read(fd, &ch, 1); + if (r == -1) + err(1, "read"); + if (r == 0) + fprintf(stderr, "read(1): EOF\n"); + } + + /* timeout */ + ch = 'z'; + FD_ZERO(&rset); + FD_SET(fd, &rset); + timeout.tv_sec = 1; + timeout.tv_usec = 0; + if ((n = select(fd + 1, &rset, NULL, NULL, &timeout)) < 0) + if (errno != EINTR) + err(1, "select()"); + if (n != 1) + fprintf(stderr, "FAIL Expected n == 0, got %d\n", n); + if (n == 1 && FD_ISSET(fd, &rset)) { + r = read(fd, &ch, 1); + if (r == -1) + err(1, "read"); + if (r == 0) + fprintf(stderr, "read(2): EOF\n"); + } + + /* timeout */ + ch = 'z'; + FD_ZERO(&rset); + FD_SET(fd, &rset); + timeout.tv_sec = 1; + timeout.tv_usec = 0; + if ((n = select(fd + 1, &rset, NULL, NULL, &timeout)) < 0) + if (errno != EINTR) + err(1, "select()"); + if (n != 1) + fprintf(stderr, "FAIL Expected n == 0, got %d\n", n); + if (n == 1 && FD_ISSET(fd, &rset)) { + r = read(fd, &ch, 1); + if (r == -1) + err(1, "read"); + if (r != 0) + fprintf(stderr, "read(3): %c\n", ch); + } + + if (close(fd) == -1) + err(1, "close() in child"); + _exit(n == 1 ? 0 : 1); +} + +static void +writer(void) +{ + int fd; + + do { + if ((fd = open(path, O_WRONLY)) == -1) + if (errno != EINTR) + err(1, "open(%s, O_WRONLY)", + path); + if (fd == -1) + warn("open(%s) wr", path); + } while (fd == -1); + if (write(fd, "a", 1) != 1) + err(1, "write one"); + if (write(fd, "b", 1) != 1) + err(1, "write one"); + if (close(fd) == -1) + warn("close() in parent"); +} + +static void +test(void) +{ + pid_t pid; + int status; + + if ((pid = fork()) == 0) + reader(); + writer(); + + if (waitpid(pid, &status, 0) != pid) + err(1, "waitpid(%d)", pid); + + _exit(status != 0); +} + +int +main(int argc __unused, char *argv[]) +{ + int e, i, pids[PARALLEL], status; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + path = argv[1]; + e = 0; + + unlink(path); + if (mkfifo(path, 0640) == -1) + err(1, "mkfifo(%s)", path); + + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], &status, 0) == -1) + err(1, "waitpid(%d)", pids[i]); + e += status == 0 ? 0 : 1; + } + + return (e); +} diff --git a/tools/test/stress2/misc/mkfifo6.sh b/tools/test/stress2/misc/mkfifo6.sh new file mode 100755 index 000000000000..5647bf9493d6 --- /dev/null +++ b/tools/test/stress2/misc/mkfifo6.sh @@ -0,0 +1,183 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# mkfifo(2), select(2) with tmpfs(5) scenario. + +. ../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/mkfifo6.c +mycc -o mkfifo6 -Wall -Wextra -O0 -g mkfifo6.c || exit 1 +rm -f mkfifo6.c +cd $odir + +mount | grep -q "on $mntpoint " && umount -f $mntpoint +mount -o size=1g -t tmpfs tmpfs $mntpoint + +fifo=$mntpoint/fifo.file +cd $mntpoint +/tmp/mkfifo6 $fifo +s=$? +cd $odir + +while mount | grep "on $mntpoint " | grep -q tmpfs; do + umount $mntpoint || sleep 1 +done +rm -rf /tmp/mkfifo6 +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static char *path; + +#define PARALLEL 1 + +static void +reader(void) +{ + fd_set rset; + struct timeval timeout; + int fd, n, r; + char ch; + + do { + if((fd = open(path, O_RDONLY)) == -1) + if (errno != EINTR) + err(1, "open(%s, O_RDONLY)", + path); + if (fd == -1) + warn("open(%s) ro", path); + } while (fd == -1); + + /* timeout */ + ch = 'z'; + FD_ZERO(&rset); + FD_SET(fd, &rset); + timeout.tv_sec = 0; + timeout.tv_usec = 100000; + if ((n = select(fd + 1, &rset, NULL, NULL, &timeout)) < 0) + if (errno != EINTR) + err(1, "select()"); + if (n != 0) + fprintf(stderr, "FAIL Expected n == 0, got %d\n", n); + if (n == 1 && FD_ISSET(fd, &rset)) { + r = read(fd, &ch, 1); + if (r == -1) + err(1, "read"); + if (r != 0) + fprintf(stderr, "read(2): %c\n", ch); + else + fprintf(stderr, "read(2): EOF\n"); + } + + sleep(3); + if (close(fd) == -1) + err(1, "close() in child"); + _exit(n); +} + +static void +writer(void) +{ + int fd; + + do { + if ((fd = open(path, O_WRONLY)) == -1) + if (errno != EINTR) + err(1, "open(%s, O_WRONLY)", + path); + if (fd == -1) + warn("open(%s) wr", path); + } while (fd == -1); + sleep(2); + if (write(fd, "a", 1) != 1) + err(1, "write one"); + if (close(fd) == -1) + warn("close() in parent"); +} + +static void +test(void) +{ + pid_t pid; + int status; + + if ((pid = fork()) == 0) + reader(); + writer(); + + if (waitpid(pid, &status, 0) != pid) + err(1, "waitpid(%d)", pid); + + _exit(status != 0); +} + +int +main(int argc __unused, char *argv[]) +{ + int e, i, pids[PARALLEL], status; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + path = argv[1]; + e = 0; + + unlink(path); + if (mkfifo(path, 0640) == -1) + err(1, "mkfifo(%s)", path); + + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], &status, 0) == -1) + err(1, "waitpid(%d)", pids[i]); + e += status == 0 ? 0 : 1; + } + + return (e); +} diff --git a/tools/test/stress2/misc/mkfifo7.sh b/tools/test/stress2/misc/mkfifo7.sh new file mode 100755 index 000000000000..b17e84536bed --- /dev/null +++ b/tools/test/stress2/misc/mkfifo7.sh @@ -0,0 +1,203 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# mkfifo(2), poll(2) with tmpfs(5) scenario. + +. ../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/mkfifo7.c +mycc -o mkfifo7 -Wall -Wextra -O0 -g mkfifo7.c || exit 1 +rm -f mkfifo7.c +cd $odir + +mount | grep -q "on $mntpoint " && umount -f $mntpoint +mount -o size=1g -t tmpfs tmpfs $mntpoint + +fifo=$mntpoint/fifo.file +cd $mntpoint +/tmp/mkfifo7 $fifo +s=$? +cd $odir + +while mount | grep "on $mntpoint " | grep -q tmpfs; do + umount $mntpoint || sleep 1 +done +rm -rf /tmp/mkfifo7 +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char *path; + +#define PARALLEL 1 + +static void +reader(void) +{ + struct pollfd pfd; + int fd, n, r; + char ch; + + do { + if((fd = open(path, O_RDONLY)) == -1) + if (errno != EINTR) + err(1, "open(%s, O_RDONLY)", + path); + if (fd == -1) + warn("open(%s) ro", path); + } while (fd == -1); + + /* Read one character */ + pfd.fd = fd; + pfd.events = POLLIN; + if ((n = poll(&pfd, 1, 0)) == -1) + err(1, "poll()"); + if (n == 1) { + r = read(fd, &ch, 1); + if (r == -1) + err(1, "read"); + if (r != 0) + fprintf(stderr, "read(1): %c\n", ch); + else + fprintf(stderr, "read(1): EOF\n"); + } + + /* timeout */ + ch = 'z'; + if ((n = poll(&pfd, 1, 7000)) == -1) + err(1, "poll()"); + if (n != 1) + fprintf(stderr, "FAIL Expected n == 1, got %d\n", n); + if (n == 1) { + r = read(fd, &ch, 1); + if (r == -1) + err(1, "read"); + if (r == 0) + fprintf(stderr, "read(2): EOF\n"); + } + + /* timeout */ + ch = 'z'; + if ((n = poll(&pfd, 1, 7000)) == -1) + err(1, "poll()"); + if (n != 1) + fprintf(stderr, "FAIL Expected n == 1, got %d\n", n); + if (n == 1) { + r = read(fd, &ch, 1); + if (r == -1) + err(1, "read"); + if (r != 0) + fprintf(stderr, "read(3): %c\n", ch); + } + + if (close(fd) == -1) + err(1, "close() in child"); + _exit(n == 1 ? 0 : 1); +} + +static void +writer(void) +{ + int fd; + + do { + if ((fd = open(path, O_WRONLY)) == -1) + if (errno != EINTR) + err(1, "open(%s, O_WRONLY)", + path); + if (fd == -1) + warn("open(%s) wr", path); + } while (fd == -1); + if (write(fd, "a", 1) != 1) + err(1, "write one"); + if (close(fd) == -1) + warn("close() in parent"); +} + +static void +test(void) +{ + pid_t pid; + int status; + + if ((pid = fork()) == 0) + reader(); + writer(); + + if (waitpid(pid, &status, 0) != pid) + err(1, "waitpid(%d)", pid); + + _exit(status != 0); +} + +int +main(int argc __unused, char *argv[]) +{ + int e, i, pids[PARALLEL], status; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + path = argv[1]; + e = 0; + + unlink(path); + if (mkfifo(path, 0640) == -1) + err(1, "mkfifo(%s)", path); + + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], &status, 0) == -1) + err(1, "waitpid(%d)", pids[i]); + e += status == 0 ? 0 : 1; + } + + return (e); +} diff --git a/tools/test/stress2/misc/mkfifo8.sh b/tools/test/stress2/misc/mkfifo8.sh new file mode 100755 index 000000000000..6227070f016e --- /dev/null +++ b/tools/test/stress2/misc/mkfifo8.sh @@ -0,0 +1,200 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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 https://reviews.freebsd.org/D20784 +# "Fix mutual exclusion in pipe_direct_write()" +# https://people.freebsd.org/~pho/stress/log/mkfifo8.txt + +# Reported by syzbot+21811cc0a89b2a87a9e7@syzkaller.appspotmail.com +# Test scenario suggestion by markj@ +# Fixed by r349546 + +. ../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/mkfifo8.c +mycc -o mkfifo8 -Wall -Wextra -O0 -g mkfifo8.c || exit 1 +rm -f mkfifo8.c +cd $odir + +set -e +mount | grep -q "on $mntpoint " && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart +newfs $newfs_flags /dev/md$mdstart > /dev/null +mount /dev/md$mdstart $mntpoint +set +e + +cd $mntpoint +$dir/mkfifo8; s=$? +cd $odir + +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -rf /tmp/mkfifo8 +exit $s + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ACT 1 +#define NPROCS 64 +#define PARALLEL 4 +#define RUNTIME 60 +#define SIZ 8192 +#define SYNC 0 + +static volatile u_int *share; +static int fd; +static char cp[SIZ]; + +static void +tw(void) +{ + int r; + + atomic_add_int(&share[ACT], 1); + r = write(fd, cp, SIZ); + if (r == -1) + warn("write"); + + _exit(0); +} + +static void +tr(void) +{ + int i, r; + char cp[SIZ]; + + while (share[ACT] < NPROCS / 2) + usleep(10); + for (i = 0; i < NPROCS; i++) { + r = read(fd, cp, SIZ); + if (r == -1) + warn("read"); + } + + _exit(0); +} + +static void +test(void) +{ + pid_t pid[NPROCS + 1]; + int i; + char file[80]; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + snprintf(file, sizeof(file), "fifo.%d", getpid()); + if (mkfifo(file, DEFFILEMODE) == -1) + err(1, "mkfifo(%s)", file); + if ((fd = open(file, O_RDWR)) == -1) + err(1, "open(%s)", file); + + for (i = 0; i < NPROCS; i++) { + if ((pid[i] = fork()) == 0) + tw(); + } + if ((pid[NPROCS] = fork()) == 0) + tr(); + + for (i = 0; i < NPROCS + 1; i++) { + if (waitpid(pid[i], NULL, 0) != pid[i]) + err(1, "waitpid"); + } + close(fd); + unlink(file); + + _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"); + + for (i = 0; i < SIZ; i += PAGE_SIZE) + cp[i] = 1; + start = time(NULL); + while ((time(NULL) - start) < RUNTIME && e == 0) { + share[SYNC] = 0; + share[ACT] = 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); +} diff --git a/tools/test/stress2/misc/mknod.sh b/tools/test/stress2/misc/mknod.sh new file mode 100755 index 000000000000..d2b9aa617577 --- /dev/null +++ b/tools/test/stress2/misc/mknod.sh @@ -0,0 +1,163 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# mknod(2) regression test +# "panic: ffs_write: type 0xca2b02d0 8 (0,3)" seen. +# Reported by: Dmitry Vyukov +# Fixed by r324853 + +. ../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/mknod.c +mycc -o mknod -Wall -Wextra -O0 -g mknod.c || exit 1 +rm -f mknod.c +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +set +e + +cd $mntpoint +$dir/mknod $mntpoint +s=$? +[ -f mknod.core -a $s -eq 0 ] && + { ls -l mknod.core; mv mknod.core /tmp; s=1; } +cd $odir + +for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && exit 1 +mdconfig -d -u $mdstart +rm -rf $dir/mknod +exit $s + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; +static char *mp; + +#define PARALLEL 4 +#define RUNTIME (1 * 60) +#define SYNC 0 + +static void +test(void) +{ + dev_t dev; + mode_t mode; + time_t start; + int fd, n, r; + char path[128]; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + n = 0; + snprintf(path, sizeof(path), "%s/node.%06d.%d", mp, getpid(), n); + start = time(NULL); + while ((time(NULL) - start) < RUNTIME) { + dev = makedev(arc4random(), arc4random()); + mode = arc4random() % 0x10000; + r = mknod(path, mode, dev); + if (r == 0) { + if ((fd = open(path, O_RDWR)) != -1) { + write(fd, "x", 1); + close(fd); + } + unlink(path); + n++; + snprintf(path, sizeof(path), "%s/node.%06d.%d", mp, + getpid(), n); + } + } + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + pid_t pids[PARALLEL]; + size_t len; + int e, i, status; + + if (argc != 2) + return (1); + mp = argv[1]; + 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"); + + 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); +} diff --git a/tools/test/stress2/misc/mlockall.sh b/tools/test/stress2/misc/mlockall.sh new file mode 100755 index 000000000000..6171725d8b3d --- /dev/null +++ b/tools/test/stress2/misc/mlockall.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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: swap_reserved < decr" seen. Fixed in r195329 + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > mlockall.c +mycc -o mlockall -Wall mlockall.c +rm -f mlockall.c + +for i in `jot 10`; do + /tmp/mlockall & + sleep 1 + ps -x | grep /tmp/mlockall | grep -v grep | awk '{print $1}' | \ + while read pid; do + kill -2 $pid + kill -9 $pid + done +done + +rm -f /tmp/mlockall +exit +EOF +#include +#include +#include +#include +#include +#include + +void +child(void) +{ + if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) + err(1, "mlockall(MCL_CURRENT | MCL_FUTURE)"); + fork(); + sleep(60); +} + +int +main(int argc, char **argv) +{ + int status; + + if (fork() == 0) + child(); + wait(&status); + + return (0); +} diff --git a/tools/test/stress2/misc/mlockall2.sh b/tools/test/stress2/misc/mlockall2.sh new file mode 100755 index 000000000000..dbeaf729342b --- /dev/null +++ b/tools/test/stress2/misc/mlockall2.sh @@ -0,0 +1,165 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 + +# core dumps seen in watchdogd after mlockall() was added. +# This scenario demonstrates the problem. Fixed in r242012. + +# "panic: freeing mapped page 0xfffff8181b38a5e8" seen: +# https://people.freebsd.org/~pho/stress/log/mark030.txt + +mem=`sysctl -n hw.usermem` +[ `sysctl -n vm.swap_total` -eq 0 ] && mem=$((mem / 100 * 60)) + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mlockall2.c +mycc -o mlockall2 -Wall -Wextra -O2 -g mlockall2.c || exit 1 +rm -f mlockall2.c +cd $here + +rm -f mlockall2.core +/tmp/mlockall2 $mem & +while kill -0 $! 2>/dev/null; do + [ -r mlockall2.core ] && kill $! && break + sleep 10 +done +[ -r mlockall2.core ] && s=1 || s=0 +pkill mlockall2 +wait +rm -f /tmp/mlockall2 mlockall2.core +exit $s +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define LOAD 40 +#define N 90000 +#define PARALLEL 5 +#define RUNTIME 600 + +static long size; + +static void +swap(void) +{ + long i; + int page; + volatile char *c; + + setproctitle("swap"); + c = malloc(size); + while (c == NULL) { + size -= 1024 * 1024; + c = malloc(size); + } + page = getpagesize(); + for (;;) { + i = 0; + while (i < size) { + c[i] = 0; + i += page; + } + } +} + +static void +test(void) +{ + pid_t p; + int i, status; + + setproctitle("test"); + for (i = 0; i < N; i++) { + if ((p = fork()) == 0) { + _exit(0); + } + if (p > 0) + waitpid(p, &status, 0); + if (status != 0) + break; + } + _exit(0); +} + +int +main(int argc __unused, char **argv) +{ + time_t start; + struct rtprio rtp; + pid_t pids[LOAD], pids2[PARALLEL]; + int i; + + size = atol(argv[1]) / LOAD * 1.5; + for (i = 0; i < LOAD; i++) + if ((pids[i] = fork()) == 0) + swap(); + sleep(10); + + rtp.type = RTP_PRIO_REALTIME; + rtp.prio = 0; + if (rtprio(RTP_SET, 0, &rtp) == -1) + err(1, "rtprio"); + + if (madvise(0, 0, MADV_PROTECT) != 0) + err(1, "madvise failed"); + if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) + err(1, "mlockall failed"); + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + for (i = 0; i < PARALLEL; i++) { + if ((pids2[i] = fork()) == 0) + test(); + } + + for (i = 0; i < PARALLEL; i++) + if (waitpid(pids2[i], NULL, 0) != pids2[i]) + err(1, "waitpid(%d) (2)", pids2[i]); + if (access("mlockall2.core", R_OK) == 0) + break; + } + for (i = 0; i < LOAD; i++) + kill(pids[i], SIGKILL); + for (i = 0; i < LOAD; i++) + if (waitpid(pids[i], NULL, 0) != pids[i]) + err(1, "waitpid(%d)", pids[i]); + + return (0); +} diff --git a/tools/test/stress2/misc/mlockall3.sh b/tools/test/stress2/misc/mlockall3.sh new file mode 100755 index 000000000000..0ff1e24eaa7f --- /dev/null +++ b/tools/test/stress2/misc/mlockall3.sh @@ -0,0 +1,167 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# mlockall(2) test scenario. +# "panic: vm_page_unwire: page xxx's wire count is zero" seen. +# http://people.freebsd.org/~pho/stress/log/mlockall.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mlockall3.c +mycc -o mlockall3 -Wall -Wextra mlockall3.c -lpthread || exit 1 +rm -f mlockall3.c +cd $odir + +/tmp/mlockall3 + +killall mlockall3 > /dev/null 2>&1 +rm -f /tmp/mlockall3 +exit + +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +u_int32_t r[N]; + +static void +hand(int i __unused) { /* handler */ + _exit(1); +} + +unsigned long +makearg(void) +{ + unsigned int i; + unsigned long val; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return(val); +} + +void * +calls(void *arg __unused) +{ + int i; + unsigned long arg1, arg2, arg3; + + usleep(1000); + for (i = 0; i < 500; i++) { + arg1 = makearg(); + arg2 = makearg(); + arg3 = makearg(); + + alarm(1); + syscall(SYS_mlockall, arg1, arg2, arg3); + } + + return (0); +} + +int +main(void) +{ + struct passwd *pw; + pid_t pid; + pthread_t cp[50]; + int e, i, j; + + if ((pw = getpwnam("nobody")) == NULL) + err(1, "no such user: nobody"); + + 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(); + + signal(SIGALRM, hand); + signal(SIGILL, hand); + signal(SIGFPE, hand); + signal(SIGSEGV, hand); + signal(SIGBUS, hand); + signal(SIGURG, hand); + signal(SIGSYS, hand); + signal(SIGTRAP, hand); + + alarm(180); + for (i = 0; i < 8000; i++) { + if ((pid = fork()) == 0) { + for (j = 0; j < N; j++) + r[j] = arc4random(); + for (j = 0; j < 50; j++) + if ((e = pthread_create(&cp[j], NULL, calls, NULL)) != 0) + errc(1, e, "pthread_create"); + + for (j = 0; j < 50; j++) + pthread_join(cp[j], NULL); + _exit(0); + } + if (pid == -1) + err(1, "fork()"); + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mlockall4.sh b/tools/test/stress2/misc/mlockall4.sh new file mode 100755 index 000000000000..778256fa8976 --- /dev/null +++ b/tools/test/stress2/misc/mlockall4.sh @@ -0,0 +1,66 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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. +# + +# mlockall(2) / nullfs(5) scenario causes: +# http://people.freebsd.org/~pho/stress/log/kostik619.txt +# kern/182661, fixed in r256211. + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > mlockall4.c +mycc -o mlockall4 -Wall -Wextra mlockall4.c || exit 1 +rm -f mlockall4.c + +mount | grep -q "on $mntpoint " && umount -f $mntpoint +mount -t nullfs /tmp $mntpoint +$mntpoint/mlockall4 & +sleep 2 +umount -f $mntpoint + +wait +rm -f /tmp/mlockall4 +exit +EOF +#include +#include +#include +#include + +int +main(void) +{ + if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) + err(1, "mlockall(MCL_CURRENT | MCL_FUTURE)"); + sleep(5); + + return (0); +} diff --git a/tools/test/stress2/misc/mlockall5.sh b/tools/test/stress2/misc/mlockall5.sh new file mode 100755 index 000000000000..847909b478c2 --- /dev/null +++ b/tools/test/stress2/misc/mlockall5.sh @@ -0,0 +1,162 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 r287591: + +# From the commit log: +# Remove a check which caused spurious SIGSEGV on usermode access to the +# mapped address without valid pte installed, when parallel wiring of +# the entry happen. The entry must be copy on write. If entry is COW +# but was already copied, and parallel wiring set +# MAP_ENTRY_IN_TRANSITION, vm_fault() would sleep waiting for the +# MAP_ENTRY_IN_TRANSITION flag to clear. After that, the fault handler +# is restarted and vm_map_lookup() or vm_map_lookup_locked() trip over +# the check. Note that this is race, if the address is accessed after +# the wiring is done, the entry does not fault at all. + +# Test scenario by kib@. + +. ../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/mlockall5.c +mycc -o mlockall5 -Wall -Wextra -O0 -g mlockall5.c -lpthread || exit 1 +rm -f mlockall5.c +cd $odir + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags -n md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint || exit 1 + +(cd $mntpoint; /tmp/mlockall5 || echo FAIL) + +n=0 +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 + n=$((n + 1)) + [ $n -gt 10 ] && { echo FAIL; exit 1; } +done +mdconfig -d -u $mdstart +rm -rf /tmp/mlockall5 +exit + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +size_t clen; +volatile u_int share; +int ps; +char *c; + +void * +touch(void *arg __unused) +{ + + int i; + + while (share == 0) + ; + for (i = 0; i < (int)clen; i += ps) + c[i] = 1; + + return (NULL); +} + +void * +ml(void *arg __unused) +{ + while (share == 0) + ; + if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) + err(1, "mlock"); + + return (NULL); +} + +int +test(void) +{ + pthread_t tid[2]; + int i, rc, status; + + if (fork() == 0) { + alarm(60); + rc = pthread_create(&tid[0], NULL, touch, NULL); + if (rc != 0) + errc(1, rc, "pthread_create()"); + rc = pthread_create(&tid[1], NULL, ml, NULL); + if (rc != 0) + errc(1, rc, "pthread_create()"); + share = 1; + for (i = 0; i < (int)nitems(tid); i++) { + rc = pthread_join(tid[i], NULL); + if (rc != 0) + errc(1, rc, "pthread_join(%d)", i); + } + _exit(0); + } + + if (wait(&status) == -1) + err(1, "wait"); + + return (WTERMSIG(status)); +} + +int +main(void) +{ + int s; + + ps = getpagesize(); + clen = 32 * 1024; + if ((c = mmap(NULL, clen, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, + -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + s = test(); + + return (s); +} diff --git a/tools/test/stress2/misc/mlockall6.sh b/tools/test/stress2/misc/mlockall6.sh new file mode 100755 index 000000000000..a755350f673d --- /dev/null +++ b/tools/test/stress2/misc/mlockall6.sh @@ -0,0 +1,203 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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: Lock (rw) vm object not locked @ vm/vm_page.c:1013" seen: +# https://people.freebsd.org/~pho/stress/log/mlockall6-2.txt + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `swapinfo | wc -l` -eq 1 ] && exit 0 + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mlockall6.c +mycc -o mlockall6 -Wall -Wextra -O0 -g mlockall6.c || exit 1 +rm -f mlockall6.c +cd $odir + +mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 512m -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags -n md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint || exit 1 + +daemon sh -c "(cd $odir/../testcases/swap; ./swap -t 20m -i 20 -l 100)" \ + > /dev/null 2>&1 +sleep 2 + +(cd $mntpoint; /tmp/mlockall6 || echo FAIL) + +while pgrep -q swap; do + pkill -9 swap +done + +n=0 +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 + n=$((n + 1)) + [ $n -gt 10 ] && { echo FAIL; exit 1; } +done +mdconfig -d -u $mdstart +rm -rf /tmp/mlockall6 +exit 0 + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 2 +#define PARALLEL 8 +#define R0 0 +#define R1 1 +#define R2 2 +#define RUNTIME (10 * 60) + +static volatile u_int *share; +static int ps; +static char c[32 * 1024 * 1024]; + +static void +touch(void) +{ + int i; + + for (i = 0; i < (int)sizeof(c); i += ps) + c[i] = 1; +} + +static void +test2(void) +{ + pid_t pid; + volatile u_int *share2; + size_t len; + int i, status; + + len = ps; + if ((share2 = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + touch(); + usleep(arc4random() % 100000); + alarm(600); + if ((pid = fork()) == 0) { + alarm(600); + while (share2[R1] == 0) /* Wait for parent */ + ; + atomic_add_int(&share2[R1], 1); + if (arc4random() % 100 < 50) + usleep(arc4random() % 1000); + if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) + err(1, "mlock"); + touch(); + atomic_add_int(&share2[R2], 1); + _exit(0); + } + atomic_add_int(&share2[R1], 1); + while (share2[R1] != 2) /* Wait for child */ + ; + + for (i = 0; i < 100000 && share2[R2] == 0; i++) + touch(); /* while child is running */ + + if (waitpid(pid, &status, 0) == -1) + err(1, "wait"); + + if (status != 0) + fprintf(stderr, "Got signal %d\n", WTERMSIG(status)); + _exit(WTERMSIG(status)); +} + +static void +test(void) +{ + pid_t pid; + int i, s, status; + + while (share[R0] == 0) + ; + s = 0; + for (i = 0; i < LOOPS; i++) { + if ((pid = fork()) == 0) + test2(); + waitpid(pid, &status, 0); + s = (s == 0) ? status : s; + } + _exit(s); +} + +int +main(void) +{ + pid_t pid; + size_t len; + time_t start; + int i, s, status; + + ps = getpagesize(); + len = ps; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + start = time(NULL); + s = 0; + while (s == 0 && (time(NULL) - start) < RUNTIME) { + for (i = 0; i < PARALLEL; i++) { + if ((pid = fork()) == 0) + test(); + } + atomic_add_int(&share[R0], 1); /* Start test() runs */ + for (i = 0; i < PARALLEL; i++) { + waitpid(pid, &status, 0); + if (status != 0) { + fprintf(stderr, "FAIL: status = %d\n", + status); + } + s = (s == 0) ? status : s; + } + atomic_add_int(&share[R0], -1); + } + + return (s); +} diff --git a/tools/test/stress2/misc/mlockall7.sh b/tools/test/stress2/misc/mlockall7.sh new file mode 100755 index 000000000000..987e312f19e7 --- /dev/null +++ b/tools/test/stress2/misc/mlockall7.sh @@ -0,0 +1,262 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 mmap18.sh. +# "panic: vm_page_unwire: page 0xfffff81038d721f0's wire count is zero" seen: +# https://people.freebsd.org/~pho/stress/log/mlockall7.txt +# Fixed by r328880 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mlockall7.c +mycc -o mlockall7 -Wall -Wextra -O2 mlockall7.c -lpthread || exit 1 +rm -f mlockall7.c + +/tmp/mlockall7 `[ $# -eq 0 ] && echo 1 || echo $1` || s=1 + +sleep 2 +rm -f /tmp/mlockall7 /tmp/mlockall7.core +exit $s +EOF +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define N 4096 +#define PARALLEL 50 +#define RUNTIME 180 + +static u_int32_t r[N]; +static void *p; + +static unsigned long +makearg(void) +{ + unsigned long val; + unsigned int i; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return (val); +} + +static void * +tmmap(void *arg __unused) +{ + size_t len; + time_t start; + + pthread_set_name_np(pthread_self(), __func__); + len = 128LL * 1024 * 1024; + + start = time(NULL); + while (time(NULL) - start < 60) { + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, + -1, 0)) != MAP_FAILED) { + usleep(100); + munmap(p, len); + } + } + + return (NULL); +} + +static void * +tmlockall(void *arg __unused) +{ + time_t start; + int flags; + + pthread_set_name_np(pthread_self(), __func__); + start = time(NULL); + while (time(NULL) - start < 60) { + flags = makearg() & 0xff; + mlockall(flags); + usleep(100); + munlockall(); + usleep(1000); + } + + return (NULL); +} + +static void +test(void) +{ + pthread_t tid[2]; + time_t start; + int i, rc; + + if ((rc = pthread_create(&tid[0], NULL, tmmap, NULL)) != 0) + errc(1, rc, "tmmap()"); + if ((rc = pthread_create(&tid[1], NULL, tmlockall, NULL)) != 0) + errc(1, rc, "tmlock()"); + + start = time(NULL); + while (time(NULL) - start < 60) { + if (fork() == 0) { + usleep(10000); + _exit(0); + } + wait(NULL); + } + + for (i = 0; i < 2; i++) + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join"); + _exit(0); +} + +int +testing(unsigned long maxl) +{ + struct passwd *pw; + struct rlimit rl; + rlim_t maxlock; + time_t start; + int i; + + maxlock = maxl; + if ((pw = getpwnam("nobody")) == NULL) + err(1, "failed to resolve nobody"); + 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(); + + rl.rlim_max = rl.rlim_cur = 0; + if (setrlimit(RLIMIT_CORE, &rl) == -1) + warn("setrlimit"); + + if (getrlimit(RLIMIT_MEMLOCK, &rl) == -1) + warn("getrlimit"); + if (maxlock <= 0) + errx(1, "Argument is %jd", maxlock); + maxlock = (maxlock / 10 * 8) / PARALLEL * PAGE_SIZE; + if (maxlock < rl.rlim_cur) { + rl.rlim_max = rl.rlim_cur = maxlock; + if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) + warn("setrlimit"); + } + + for (i = 0; i < N; i++) + r[i] = arc4random(); + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + test(); + } + + for (i = 0; i < PARALLEL; i++) + wait(NULL); + } + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + pid_t pid; + size_t len; + int i, loops, s, status; + unsigned long max_wired; + unsigned int wire_count, wire_count_old; + + s = 0; + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + loops = atoi(argv[1]); + + len = sizeof(max_wired); + if (sysctlbyname("vm.max_user_wired", &max_wired, &len, NULL, 0) != 0) + err(1, "vm.max_user_wired"); + + len = sizeof(wire_count); + if (sysctlbyname("vm.stats.vm.v_user_wire_count", &wire_count, &len, + NULL, 0) != 0) + err(1, "vm.stats.vm.v_user_wire_count"); + + for (i = 0; i < loops; i++) { + wire_count_old = wire_count; + + if ((pid = fork()) == 0) + testing(max_wired); + if (waitpid(pid, &status, 0) != pid) + err(1, "waitpid(%d)", pid); + if (status != 0) + errx(1, "Exit status %d from pid %d\n", status, pid); + + len = sizeof(wire_count); + if (sysctlbyname("vm.stats.vm.v_user_wire_count", &wire_count, &len, + NULL, 0) != 0) + err(1, "vm.stats.vm.v_user_wire_count"); + fprintf(stderr, "vm.stats.vm.v_user_wire_count was %d, is %d. %d\n", + wire_count_old, wire_count, wire_count - wire_count_old); + } + + return (s); +} diff --git a/tools/test/stress2/misc/mmap.sh b/tools/test/stress2/misc/mmap.sh new file mode 100755 index 000000000000..95561365a53d --- /dev/null +++ b/tools/test/stress2/misc/mmap.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# Test scenario by Michiel Boland + +# panic: pmap_remove_all: page 0xc491f000 is fictitious + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > mmap.c +mycc -o mmap -Wall mmap.c +rm -f mmap.c + +./mmap +rm -f ./mmap +exit + +EOF +#include +#include +#include +#include +#include + +static const off_t map_address = 0xa0000; +static const size_t map_size = 0x1000; + +static int testit(int fd) +{ + void *p; + int rv; + + p = mmap(NULL, 2 * map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, + map_address); + if (p == MAP_FAILED) { + perror("mmap"); + return -1; + } + rv = *(char *) p; + if (munmap(p, map_size) == -1) { + perror("munmap"); + return -1; + } + return rv; +} + +int main(void) +{ + int fd, rv; + + fd = open("/dev/mem", O_RDWR); + if (fd == -1) { + perror("open"); + return 1; + } + rv = testit(fd); + close(fd); + return rv; +} + diff --git a/tools/test/stress2/misc/mmap10.sh b/tools/test/stress2/misc/mmap10.sh new file mode 100755 index 000000000000..a29768c36691 --- /dev/null +++ b/tools/test/stress2/misc/mmap10.sh @@ -0,0 +1,273 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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: vm_page_dirty: page is invalid!" seen. +# http://people.freebsd.org/~pho/stress/log/mmap10.txt +# No problems seen after r271681. + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +here=`pwd` +cd /tmp +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)" +sleep `jot -r 1 0 9` +for i in `jot 2`; do + /tmp/mmap10 & +done +sleep 300 +while pgrep -q mmap10; do + pkill -9 mmap10 + sleep 2 +done +wait +killall -q swap + +rm -f /tmp/mmap10 /tmp/mmap10.core +exit 0 +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 2 +#define MMSIZE (192 * 1024 * 1024) +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +#define PARALLEL 50 + +void *p; +u_int32_t r[N]; + +unsigned long +makearg(void) +{ + unsigned long val; + unsigned int i; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return(val); +} + +void * +makeptr(void) +{ + unsigned long val; + + if (p != MAP_FAILED && p != NULL) + val = (unsigned long)p + arc4random(); + else + val = makearg(); + val = trunc_page(val); + + return ((void *)val); +} + +void * +tmmap(void *arg __unused) +{ + size_t len; + int i, j, fd; + + pthread_set_name_np(pthread_self(), __func__); + len = MMSIZE; + + for (i = 0, j = 0; i < 100; i++) { + if ((fd = open("/dev/zero", O_RDWR)) == -1) + err(1,"open()"); + + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, + fd, 0)) != MAP_FAILED) { + usleep(100); + munmap(p, len); + j++; + } + + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, + -1, 0)) != MAP_FAILED) { + usleep(100); + munmap(p, len); + j++; + } + close(fd); + } + if (j == 0) + fprintf(stderr, "FAIL: all mmap(2) calls failed.\n"); + + return (NULL); +} + +void * +tmlock(void *arg __unused) +{ + size_t len; + int i, n; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + len = trunc_page(makearg()); + if (mlock(makeptr(), len) == 0) + n++; + len = trunc_page(makearg()); + if (arc4random() % 100 < 50) + if (munlock(makeptr(), len) == 0) + n++; + } + if (n < 10) + fprintf(stderr, "Note: tmlock() only succeeded %d times.\n", + n); + + return (NULL); +} + +void * +tmprotect(void *arg __unused) +{ + size_t len; + void *addr; + int i, n, prot; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + addr = makeptr(); + len = trunc_page(makearg()); + prot = makearg(); + if (mprotect(addr, len, prot) == 0) + n++; + usleep(1000); + } + if (n < 10) + fprintf(stderr, "Note: tmprotect() only succeeded %d times.\n", + n); + + return (NULL); +} + +void * +tmlockall(void *arg __unused) +{ + int flags, i, n; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + flags = makearg(); + if (mlockall(flags) == 0) + n++; + usleep(100); + munlockall(); + usleep(1000); + } + if (n < 10) + fprintf(stderr, "Note: tmlockall() only succeeded %d times.\n", + n); + + return (NULL); +} + +void +test(void) +{ + pthread_t tid[4]; + int i, rc; + + if ((rc = pthread_create(&tid[0], NULL, tmmap, NULL)) != 0) + errc(1, rc, "tmmap()"); + if ((rc = pthread_create(&tid[1], NULL, tmlock, NULL)) != 0) + errc(1, rc, "tmlock()"); + if ((rc = pthread_create(&tid[2], NULL, tmprotect, NULL)) != 0) + errc(1, rc, "tmprotect()"); + if ((rc = pthread_create(&tid[3], NULL, tmlockall, NULL)) != 0) + errc(1, rc, "tmlockall()"); + + for (i = 0; i < 100; i++) { + if (fork() == 0) { + usleep(10000); + _exit(0); + } + wait(NULL); + } + + for (i = 0; i < 4; i++) + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + _exit(0); +} + +int +main(void) +{ + int i, j; + + for (i = 0; i < N; i++) + r[i] = arc4random(); + + for (i = 0; i < LOOPS; i++) { + for (j = 0; j < PARALLEL; j++) { + if (fork() == 0) + test(); + } + + for (j = 0; j < PARALLEL; j++) + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mmap11.sh b/tools/test/stress2/misc/mmap11.sh new file mode 100755 index 000000000000..5d2fba6d98b7 --- /dev/null +++ b/tools/test/stress2/misc/mmap11.sh @@ -0,0 +1,301 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Copy of mmap10.sh with msync() added. +# "panic: vm_map_protect: inaccessible wired map entry" seen: +# http://people.freebsd.org/~pho/stress/log/mmap11.txt +# No problems seen after r271681. + +# http://people.freebsd.org/~pho/stress/log/kostik730.txt, Fixed in r273784 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mmap11.c +mycc -o mmap11 -Wall -Wextra -O2 -g mmap11.c -lpthread || exit 1 +rm -f mmap11.c + +daemon sh -c "(cd $here/../testcases/swap; ./swap -t 2m -i 20 -k)" +sleep `jot -r 1 0 9` +for i in `jot 2`; do + /tmp/mmap11 & +done +sleep 300 +while pgrep -q mmap11; do + pkill -9 mmap11 + sleep 2 +done +wait +killall -q swap + +rm -f /tmp/mmap11 /tmp/mmap11.core +exit 0 +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 2 +#define MMSIZE (192 * 1024 * 1024) +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +#define PARALLEL 50 + +void *p; +u_int32_t r[N]; + +unsigned long +makearg(void) +{ + unsigned long val; + unsigned int i; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return(val); +} + +void * +makeptr(void) +{ + unsigned long val; + + if (p != MAP_FAILED && p != NULL) + val = (unsigned long)p + arc4random(); + else + val = makearg(); + val = trunc_page(val); + + return ((void *)val); +} + +void * +tmmap(void *arg __unused) +{ + size_t len; + int i, j, fd; + + pthread_set_name_np(pthread_self(), __func__); + len = MMSIZE; + + for (i = 0, j = 0; i < 100; i++) { + if ((fd = open("/dev/zero", O_RDWR)) == -1) + err(1,"open()"); + + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, + fd, 0)) != MAP_FAILED) { + usleep(100); + munmap(p, len); + j++; + } + + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, + -1, 0)) != MAP_FAILED) { + usleep(100); + munmap(p, len); + j++; + } + close(fd); + } + if (j == 0) + fprintf(stderr, "FAIL: all mmap(2) calls failed.\n"); + + return (NULL); +} + +void * +tmlock(void *arg __unused) +{ + size_t len; + int i, n; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + len = trunc_page(makearg()); + if (mlock(makeptr(), len) == 0) + n++; + len = trunc_page(makearg()); + if (arc4random() % 100 < 50) + if (munlock(makeptr(), len) == 0) + n++; + } + if (n < 10) + fprintf(stderr, "Note: tmlock() only succeeded %d times.\n", + n); + + return (NULL); +} + +void * +tmprotect(void *arg __unused) +{ + size_t len; + void *addr; + int i, n, prot; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + addr = makeptr(); + len = trunc_page(makearg()); + prot = makearg(); + if (mprotect(addr, len, prot) == 0) + n++; + usleep(1000); + } + if (n < 10) + fprintf(stderr, "Note: tmprotect() only succeeded %d times.\n", + n); + return (NULL); +} + +void * +tmlockall(void *arg __unused) +{ + int flags, i, n; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + flags = makearg(); + if (mlockall(flags) == 0) + n++; + usleep(100); + munlockall(); + usleep(1000); + } + if (n < 10) + fprintf(stderr, "Note: tmlockall() only succeeded %d times.\n", + n); + + return (NULL); +} + +void * +tmsync(void *arg __unused) +{ + size_t len; + void *addr; + int flags, i, n; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + addr = makeptr(); + len = trunc_page(makearg()); + flags = makearg(); + if (msync(addr, len, flags) == 0) + n++; + usleep(2000); + } + if (n < 10) + fprintf(stderr, "Note: tmsync() only succeeded %d times.\n", + n); + + return (NULL); +} + +void +test(void) +{ + pthread_t tid[5]; + int i, rc; + + if ((rc = pthread_create(&tid[0], NULL, tmmap, NULL)) != 0) + errc(1, rc, "tmmap()"); + if ((rc = pthread_create(&tid[1], NULL, tmlock, NULL)) != 0) + errc(1, rc, "tmlock()"); + if ((rc = pthread_create(&tid[2], NULL, tmprotect, NULL)) != 0) + errc(1, rc, "tmprotect()"); + if ((rc = pthread_create(&tid[3], NULL, tmlockall, NULL)) != 0) + errc(1, rc, "tmlockall()"); + if ((rc = pthread_create(&tid[4], NULL, tmsync, NULL)) != 0) + errc(1, rc, "tmlockall()"); + + for (i = 0; i < 100; i++) { + if (fork() == 0) { + usleep(10000); + _exit(0); + } + wait(NULL); + } + + for (i = 0; i < 5; i++) + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + _exit(0); +} + +int +main(void) +{ + int i, j; + + for (i = 0; i < N; i++) + r[i] = arc4random(); + + for (i = 0; i < LOOPS; i++) { + for (j = 0; j < PARALLEL; j++) { + if (fork() == 0) + test(); + } + + for (j = 0; j < PARALLEL; j++) + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mmap12.sh b/tools/test/stress2/misc/mmap12.sh new file mode 100755 index 000000000000..917c23a6df8b --- /dev/null +++ b/tools/test/stress2/misc/mmap12.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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: vm_map_protect: inaccessible wired map entry" seen: +# http://people.freebsd.org/~pho/stress/log/mmap11.txt +# Fixed in r266780. + +# Test scenario by: Mark Johnston markj@ + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap12.c +mycc -o mmap12 -O2 -Wall -Wextra mmap12.c || exit 1 +rm -f mmap12.c +cd $odir + +/tmp/mmap12 + +rm -f /tmp/mmap12 +exit + +EOF +#include + +#include +#include +#include + +int +main(void) +{ + void *addr; + size_t sz = 1; + +/* + * This is the minimum amount of C code ot takes to panic the kernel. + * This is as submitted and thus not a complete and correct test program. + */ + addr = mmap(NULL, sz, PROT_READ, MAP_ANON, -1, 0); + if (addr == NULL) + err(1, "mmap"); + + if (mlock(addr, sz) != 0) + err(1, "mlock"); + if (mprotect(addr, sz, PROT_NONE) != 0) + err(1, "mprotect 1"); + if (mprotect(addr, sz, PROT_WRITE) != 0) + err(1, "mprotect 2"); + if (munmap(addr, sz) != 0) + err(1, "munmap"); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap13.sh b/tools/test/stress2/misc/mmap13.sh new file mode 100755 index 000000000000..993e1bc2185c --- /dev/null +++ b/tools/test/stress2/misc/mmap13.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Leak of "vm.stats.vm.v_user_wire_count" seen. +# This test must run in single user mode for accurate leak reporting. +# Test scenario by: Mark Johnston markj@ +# Fixed in r269134. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap13.c +mycc -o mmap13 -O2 -Wall -Wextra mmap13.c || exit 1 +rm -f mmap13.c +cd $odir + +# Both the 5000 and 500 are empirical values. +# Combined they demonstrate the leak in a consistent way. + +v1=`sysctl -n vm.stats.vm.v_user_wire_count` +for i in `jot 5000`; do + /tmp/mmap13 +done 2>&1 | tail -5 +v2=`sysctl -n vm.stats.vm.v_user_wire_count` +[ $v2 -gt $((v1 + 500)) ] && + echo "vm.stats.vm.v_user_wire_count changed from $v1 to $v2." + +rm -f /tmp/mmap13 +exit 0 + +EOF +#include + +#include +#include +#include + +int +main(void) +{ + void *addr; + size_t sz; + + sz = getpagesize(); + addr = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + if (addr == NULL) + err(1, "mmap"); + if (mlock(addr, sz) != 0) + err(1, "mlock"); + if (mprotect(addr, sz, PROT_NONE) != 0) + err(1, "mprotect"); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap14.sh b/tools/test/stress2/misc/mmap14.sh new file mode 100755 index 000000000000..e5a59890189b --- /dev/null +++ b/tools/test/stress2/misc/mmap14.sh @@ -0,0 +1,252 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Simplified version of mmap10.sh with focus on core dumps +# Deadlock seen: +# http://people.freebsd.org/~pho/stress/log/kostik673.txt +# No issues seen with r272060. + +# panic: vm_reserv_populate: reserv 0xfffff807cbd46300 is already promoted +# http://people.freebsd.org/~pho/stress/log/kostik764.txt +# Fixed by r280238 + +# panic: vm_reserv_break: reserv 0xfffff807cbe9af00 is full +# https://people.freebsd.org/~pho/stress/log/alan006.txt + +# panic: vm_page_dirty: page is invalid! +# https://people.freebsd.org/~pho/stress/log/kostik818.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mmap14.c +mycc -o mmap14 -Wall -Wextra -O2 -g mmap14.c -lpthread || exit 1 +rm -f mmap14.c + +daemon sh -c "(cd $here/../testcases/swap; ./swap -t 2m -i 20 -k -h)" +sleep `jot -r 1 1 10` +wire=$((`sysctl -n vm.max_user_wired` - \ + `sysctl -n vm.stats.vm.v_user_wire_count`)) +for i in `jot 2`; do + /tmp/mmap14 $wire +done +while pgrep -q swap; do + pkill -9 swap +done + +rm -f /tmp/mmap14 /tmp/mmap14.core +exit 0 +EOF +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 2 +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +#define PARALLEL 50 + +static void *p; +static u_int32_t r[N]; + +static unsigned long +makearg(void) +{ + unsigned long val; + unsigned int i; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return(val); +} + +static void * +makeptr(void) +{ + unsigned long val; + + if (p != MAP_FAILED && p != NULL) + val = (unsigned long)p + arc4random(); + else + val = makearg(); + val = trunc_page(val); + + return ((void *)val); +} + +static void * +tmmap(void *arg __unused) +{ + size_t len; + int i, fd; + + pthread_set_name_np(pthread_self(), __func__); + len = 1LL * 1024 * 1024 * 1024; + + for (i = 0; i < 100; i++) { + if ((fd = open("/dev/zero", O_RDWR)) == -1) + err(1,"open()"); + + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, + 0)) != MAP_FAILED) { + usleep(100); + munmap(p, len); + } + + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0)) != + MAP_FAILED) { + usleep(100); + munmap(p, len); + } + close(fd); + } + + return (NULL); +} + +static void * +tmlock(void *arg __unused) +{ + size_t len; + int i, n; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + len = trunc_page(makearg()); + if (mlock(makeptr(), len) == 0) + n++; + len = trunc_page(makearg()); + if (arc4random() % 100 < 50) + if (munlock(makeptr(), len) == 0) + n++; + } + if (n < 10) + fprintf(stderr, "Note: tmlock() only succeeded %d times.\n", + n); + + return (NULL); +} + +static void +test(void) +{ + pthread_t tid[4]; + int i, rc; + + if ((rc = pthread_create(&tid[0], NULL, tmmap, NULL)) != 0) + errc(1, rc, "tmmap()"); + if ((rc = pthread_create(&tid[1], NULL, tmlock, NULL)) != 0) + errc(1, rc, "tmlock()"); + + for (i = 0; i < 100; i++) { + if (fork() == 0) { + usleep(10000); + _exit(0); + } + wait(NULL); + } + + raise(SIGSEGV); + + for (i = 0; i < 2; i++) + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + struct rlimit rl; + rlim_t maxlock; + int i, j; + + if (argc != 2) { + fprintf(stderr, "Usage:%s \n", argv[0]); + exit(1); + } + if (getrlimit(RLIMIT_MEMLOCK, &rl) == -1) + warn("getrlimit"); + maxlock = atol(argv[1]); + if (maxlock == 0) + errx(1, "Argument is zero"); + maxlock = (maxlock / 10 * 8) / PARALLEL * PAGE_SIZE; + if (maxlock < rl.rlim_cur) { + rl.rlim_max = rl.rlim_cur = maxlock; + if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) + warn("setrlimit"); + } + + for (i = 0; i < N; i++) + r[i] = arc4random(); + + for (i = 0; i < LOOPS; i++) { + for (j = 0; j < PARALLEL; j++) { + if (fork() == 0) + test(); + } + + for (j = 0; j < PARALLEL; j++) + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mmap15.sh b/tools/test/stress2/misc/mmap15.sh new file mode 100755 index 000000000000..a34e8436255b --- /dev/null +++ b/tools/test/stress2/misc/mmap15.sh @@ -0,0 +1,223 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Missing wakeup in the bufobj_wwait(). + +# Snapshot of WiP work. +# http://people.freebsd.org/~pho/stress/log/mmap15.txt +# Not fixed + +# panic: invalid size +# http://people.freebsd.org/~pho/stress/log/kostik738.txt +# Fixed in r274878 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mmap15.c +mycc -o mmap15 -Wall -Wextra -O2 -g mmap15.c -lpthread || exit 1 +rm -f mmap15.c + +for i in `jot 2`; do + su $testuser -c /tmp/mmap15 & +done +sleep 300 +while pgrep -q mmap15; do + pkill -9 mmap15 + sleep 2 +done +wait + +rm -f /tmp/mmap15 /tmp/mmap15.core +exit 0 +EOF +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 2 +#define MMSIZE (256 * 1024) +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +#define PARALLEL 50 + +void *p; +u_int32_t r[N]; + +unsigned long +makearg(void) +{ + unsigned long val; + unsigned int i; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return(val); +} + +void * +makeptr(void) +{ + unsigned long val; + + if (p != MAP_FAILED && p != NULL) + val = (unsigned long)p + arc4random(); + else + val = makearg(); + val = trunc_page(val); + + return ((void *)val); +} + +void * +tmmap(void *arg __unused) +{ + size_t len; + int i, j, fd; + + pthread_set_name_np(pthread_self(), __func__); + len = MMSIZE; + + if ((fd = open("/dev/zero", O_RDWR)) == -1) + err(1,"open()"); + for (i = 0, j = 0; i < 100; i++) { + p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (p != MAP_FAILED) + j++; + p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + if (p != MAP_FAILED) + j++; + } + if (j == 0) + fprintf(stderr, "FAIL: all mmap(2) calls failed.\n"); + close(fd); + + return (NULL); +} + +void * +tmlock(void *arg __unused) +{ + size_t len; + int i, n; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + len = trunc_page(makearg()); + if (mlock(makeptr(), len) == 0) + n++; + len = trunc_page(makearg()); + if (arc4random() % 100 < 50) + if (munlock(makeptr(), len) == 0) + n++; + } + if (n < 10) + fprintf(stderr, "Note: tmlock() only succeeded %d times.\n", + n); + + return (NULL); +} + +void +test(void) +{ + pthread_t tid[2]; + int i, rc; + + if ((rc = pthread_create(&tid[0], NULL, tmmap, NULL)) != 0) + errc(1, rc, "tmmap()"); + if ((rc = pthread_create(&tid[1], NULL, tmlock, NULL)) != 0) + errc(1, rc, "tmlock()"); + + for (i = 0; i < 100; i++) { + if (fork() == 0) { + usleep(10000); + _exit(0); + } + wait(NULL); + } + + raise(SIGSEGV); + + for (i = 0; i < 2; i++) + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + _exit(0); +} + +int +main(void) +{ + int i, j; + + for (i = 0; i < N; i++) + r[i] = arc4random(); + + for (i = 0; i < LOOPS; i++) { + for (j = 0; j < PARALLEL; j++) { + if (fork() == 0) + test(); + } + + for (j = 0; j < PARALLEL; j++) + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mmap16.sh b/tools/test/stress2/misc/mmap16.sh new file mode 100755 index 000000000000..15a310505edd --- /dev/null +++ b/tools/test/stress2/misc/mmap16.sh @@ -0,0 +1,145 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 scenario by kib@ + +[ `uname -m` = "i386" ] || exit 0 + +. ../default.cfg + +grep -q MAP_GUARD /usr/include/sys/mman.h 2>/dev/null || exit 0 +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mmap16.c +mycc -o mmap16 -Wall -Wextra -O2 -g mmap16.c -lpthread || exit 1 +rm -f mmap16.c /tmp/mmap16.core + +echo "Expect: + mmap16: mprotect: Permission denied" +/tmp/mmap16 > /dev/null +s=$? + +rm -f /tmp/mmap16 /tmp/mmap16.core +exit $s +EOF +/* $Id: map_hole.c,v 1.6 2014/06/16 05:52:03 kostik Exp kostik $ */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static void +sighandler(int signo, siginfo_t *info, void *uap1) +{ + static char scratch; + ucontext_t *uap; + + uap = uap1; + printf("SIG%s(%d) at %p (%%eax %p)\n", + signo < sys_nsig ? sys_signame[signo] : "SOME", signo, + info->si_addr, (void *)(uintptr_t)uap->uc_mcontext.mc_eax); + uap->uc_mcontext.mc_eax = (uintptr_t)&scratch; +} + +static void +access_addr(char *addr) +{ + char r; + + r = '1'; + printf("accessing %p\n", addr); + __asm __volatile("movb %0,(%%eax)" : : "i"(r), "a"(addr) : "memory"); + printf("done\n"); +} + +static int pagesz; + +static void +test_access(char *addr) +{ + struct rusage ru; + long majflt, minflt; + + if (getrusage(RUSAGE_THREAD, &ru) == -1) + err(1, "getrusage"); + majflt = ru.ru_majflt; + minflt = ru.ru_minflt; + access_addr(addr); + if (mprotect(addr, pagesz, PROT_READ | PROT_WRITE) == -1) + warn("mprotect"); + access_addr(addr); + if (getrusage(RUSAGE_THREAD, &ru) == -1) + err(1, "getrusage"); + majflt = ru.ru_majflt - majflt; + minflt = ru.ru_minflt - minflt; + printf("majflt %ld minflt %ld\n", majflt, minflt); +} + +int +main(void) +{ + struct sigaction sa; + char *addr; + char cmd[128]; + + bzero(&sa, sizeof(sa)); + sa.sa_sigaction = sighandler; + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGSEGV, &sa, NULL) == -1) + err(1, "sigaction"); + pagesz = getpagesize(); + + printf("MAP_GUARD\n"); + addr = mmap(NULL, pagesz, PROT_NONE, MAP_GUARD, -1, 0); + if (addr == (char *)MAP_FAILED) + err(1, "FAIL: mmap(MAP_GUARD)"); + test_access(addr); + + printf("PROT_NONE wire\n"); + addr = mmap(NULL, pagesz, PROT_NONE, MAP_ANON, -1, 0); + if (addr == (char *)MAP_FAILED) + err(1, "mmap(PROT_NONE)"); + if (mlock(addr, pagesz) == -1) + if (errno != ENOMEM) + err(1, "mlock"); + test_access(addr); + + snprintf(cmd, sizeof(cmd), "procstat -v %d", getpid()); + system(cmd); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap17.sh b/tools/test/stress2/misc/mmap17.sh new file mode 100755 index 000000000000..bc67bb2e5a9e --- /dev/null +++ b/tools/test/stress2/misc/mmap17.sh @@ -0,0 +1,86 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 scenario by kib@ + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mmap17.c +mycc -o mmap17 -Wall -Wextra -O2 -g mmap17.c -lpthread || exit 1 +rm -f mmap17.c /tmp/mmap17.core +rm -f /tmp/mmap17.core + +{ /tmp/mmap17 > /dev/null; } 2>&1 | grep -v worked + +rm -f /tmp/mmap17 /tmp/mmap17.core +exit 0 +EOF +/* $Id: map_excl.c,v 1.2 2014/06/16 06:02:52 kostik Exp kostik $ */ + +#include +#include +#include +#include +#include + +#ifndef MAP_EXCL +#define MAP_EXCL 0x00004000 /* for MAP_FIXED, fail if address is used */ +#endif + +int +main(void) +{ + char *addr, *addr1; + int pagesz; + char cmd[128]; + + pagesz = getpagesize(); + addr = mmap(NULL, pagesz, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + if (addr == (char *)MAP_FAILED) + err(1, "mmap 1"); + printf("addr %p\n", addr); + + addr -= pagesz; + addr1 = mmap(addr, 3 * pagesz, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_FIXED | MAP_EXCL, -1, 0); + if (addr1 == MAP_FAILED) + warn("EXCL worked"); + else + fprintf(stderr, "EXCL failed\n"); + + addr1 = mmap(addr, 3 * pagesz, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_FIXED, -1, 0); + printf("addr1 %p\n", addr); + + snprintf(cmd, sizeof(cmd), "procstat -v %d", getpid()); + system(cmd); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap18.sh b/tools/test/stress2/misc/mmap18.sh new file mode 100755 index 000000000000..065b5bb7df6c --- /dev/null +++ b/tools/test/stress2/misc/mmap18.sh @@ -0,0 +1,308 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Copy of mmap10.sh with core dump disabled. +# http://people.freebsd.org/~pho/stress/log/kostik711.txt + +# panic: vm_fault_copy_entry: main object missing page +# http://people.freebsd.org/~pho/stress/log/mmap18.txt +# Fixed by: r316689 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mmap18.c +mycc -o mmap18 -Wall -Wextra -O2 mmap18.c -lpthread || exit 1 +rm -f mmap18.c + +s=0 +wire=$((`sysctl -n vm.max_user_wired` - \ + `sysctl -n vm.stats.vm.v_user_wire_count`)) +/tmp/mmap18 $wire & +start=`date +%s` +while true; do + e=$((`date +%s` - start)) + pgrep -q mmap18 || break + if [ $e -gt 900 ]; then + pgrep mmap18 | xargs ps -lHp + pkill mmap18 + break; + fi + sleep 10 +done +wait $!; s=$? + +rm -f /tmp/mmap18 /tmp/mmap18.core +exit $s +EOF +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 50 +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +#define PARALLEL 50 + +static u_int32_t r[N]; +static void *p; + +static unsigned long +makearg(void) +{ + unsigned long val; + unsigned int i; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return (val); +} + +static void * +makeptr(void) +{ + unsigned long val; + + if (p != MAP_FAILED && p != NULL) + val = (unsigned long)p + arc4random(); + else + val = makearg(); + val = trunc_page(val); + + return ((void *)val); +} + +static void * +tmmap(void *arg __unused) +{ + size_t len; + int i, fd; + + pthread_set_name_np(pthread_self(), __func__); + len = 1LL * 1024 * 1024 * 1024; + + for (i = 0; i < 100; i++) { + if ((fd = open("/dev/zero", O_RDWR)) == -1) + err(1,"open()"); + + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, + fd, 0)) != MAP_FAILED) { + usleep(100); + munmap(p, len); + } + + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, + -1, 0)) != MAP_FAILED) { + usleep(100); + munmap(p, len); + } + close(fd); + } + + return (NULL); +} + +static void * +tmlock(void *arg __unused) +{ + int i, n; + size_t len; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + len = trunc_page(makearg()); + if (mlock(makeptr(), len) == 0) + n++; + len = trunc_page(makearg()); + if (arc4random() % 100 < 50) + if (munlock(makeptr(), len) == 0) + n++; + } +#if defined(DEBUG) + if (n < 10) + fprintf(stderr, "Note: tmlock() only succeeded %d " + "times.\n", n); +#endif + + return (NULL); +} + +static void * +tmprotect(void *arg __unused) +{ + void *addr; + size_t len; + int i, n, prot; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + addr = makeptr(); + len = trunc_page(makearg()); + prot = makearg(); + if (mprotect(addr, len, prot) == 0) + n++; + usleep(1000); + } +#if defined(DEBUG) + if (n < 10) + fprintf(stderr, "Note: tmprotect() only succeeded %d " + "times.\n", n); +#endif + + return (NULL); +} + +static void * +tmlockall(void *arg __unused) +{ + int flags, i, n; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + flags = makearg(); + if (mlockall(flags) == 0) + n++; + usleep(100); + munlockall(); + usleep(1000); + } +#if defined(DEBUG) + if (n < 10) + fprintf(stderr, "Note: tmlockall() only succeeded %d " + "times.\n", n); +#endif + + return (NULL); +} + +static void +test(void) +{ + pthread_t tid[4]; + int i, rc; + + if ((rc = pthread_create(&tid[0], NULL, tmmap, NULL)) != 0) + errc(1, rc, "tmmap()"); + if ((rc = pthread_create(&tid[1], NULL, tmlock, NULL)) != 0) + errc(1, rc, "tmlock()"); + if ((rc = pthread_create(&tid[2], NULL, tmprotect, NULL)) != 0) + errc(1, rc, "tmprotect()"); + if ((rc = pthread_create(&tid[3], NULL, tmlockall, NULL)) != 0) + errc(1, rc, "tmlockall()"); + + for (i = 0; i < 100; i++) { + if (fork() == 0) { + usleep(10000); + _exit(0); + } + wait(NULL); + } + + for (i = 0; i < 4; i++) + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + struct rlimit rl; + rlim_t maxlock; + int i, j; + + if (argc != 2) { + fprintf(stderr, "Usage:%s \n", argv[0]); + exit(1); + } + rl.rlim_max = rl.rlim_cur = 0; + if (setrlimit(RLIMIT_CORE, &rl) == -1) + warn("setrlimit"); + + if (getrlimit(RLIMIT_MEMLOCK, &rl) == -1) + warn("getrlimit"); + maxlock = atol(argv[1]); + if (maxlock <= 0) + errx(1, "Bad argument %jd", maxlock); + maxlock = (maxlock / 10 * 8) / PARALLEL * PAGE_SIZE; + if (maxlock < rl.rlim_cur) { + rl.rlim_max = rl.rlim_cur = maxlock; + if (setrlimit(RLIMIT_MEMLOCK, &rl) == -1) + warn("setrlimit"); + } + + for (i = 0; i < N; i++) + r[i] = arc4random(); + + for (i = 0; i < LOOPS; i++) { + for (j = 0; j < PARALLEL; j++) { + if (fork() == 0) + test(); + } + + for (j = 0; j < PARALLEL; j++) + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mmap19.sh b/tools/test/stress2/misc/mmap19.sh new file mode 100755 index 000000000000..6a646563499a --- /dev/null +++ b/tools/test/stress2/misc/mmap19.sh @@ -0,0 +1,241 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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: pmap active 0xfffff801d22cdae8" seen. +# Variation of mmap18.sh. +# http://people.freebsd.org/~pho/stress/log/kostik712.txt +# Fixed by r271000. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mmap19.c +mycc -o mmap19 -Wall -Wextra -O2 mmap19.c -lpthread || exit 1 +rm -f mmap19.c + +daemon sh -c "(cd $here/../testcases/swap; ./swap -t 2m -i 20 -k)" +rnd=`od -An -N1 -t u1 /dev/random | sed 's/ //g'` +sleep $((rnd % 10)) +s=0 +for i in `jot 2`; do + /tmp/mmap19 || s=$? +done +while pgrep -q swap; do + pkill -9 swap +done + +rm -f /tmp/mmap19 /tmp/mmap19.core +exit $s +EOF +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 50 +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +#define PARALLEL 50 + +u_int32_t r[N]; +void *p; + +unsigned long +makearg(void) +{ + unsigned long val; + unsigned int i; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return(val); +} + +void * +makeptr(void) +{ + unsigned long val; + + if (p != MAP_FAILED && p != NULL) + val = (unsigned long)p + arc4random(); + else + val = makearg(); + val = trunc_page(val); + + return ((void *)val); +} + +void * +tmmap(void *arg __unused) +{ + size_t len; + int i, fd; + + pthread_set_name_np(pthread_self(), __func__); + len = 1LL * 1024 * 1024 * 1024; + + for (i = 0; i < 100; i++) { + if ((fd = open("/dev/zero", O_RDWR)) == -1) + err(1,"open()"); + + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, + fd, 0)) != MAP_FAILED) { + usleep(100); + munmap(p, len); + } + + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, + 0)) != MAP_FAILED) { + usleep(100); + munmap(p, len); + } + close(fd); + } + + return (NULL); +} + +void * +tmprotect(void *arg __unused) +{ + void *addr; + size_t len; + int i, n, prot; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + addr = makeptr(); + len = trunc_page(makearg()); + prot = makearg(); + if (mprotect(addr, len, prot) == 0) + n++; + usleep(1000); + } + if (n < 10) + fprintf(stderr, "Note: tmprotect() only succeeded %d times.\n", + n); + + return (NULL); +} + +void +test(void) +{ + pthread_t tid[2]; + int i, rc; + + if ((rc = pthread_create(&tid[0], NULL, tmmap, NULL)) != 0) + errc(1, rc, "tmmap()"); + if ((rc = pthread_create(&tid[1], NULL, tmprotect, NULL)) != 0) + errc(1, rc, "tmprotect()"); + + for (i = 0; i < 100; i++) { + if (fork() == 0) { + usleep(10000); + _exit(0); + } + wait(NULL); + } + + alarm(120); + for (i = 0; i < 2; i++) + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + time_t start; + struct rlimit rl; + int e, i, j, status; + + rl.rlim_max = rl.rlim_cur = 0; + if (setrlimit(RLIMIT_CORE, &rl) == -1) + warn("setrlimit"); + + for (i = 0; i < N; i++) + r[i] = arc4random(); + + e = 0; + start = time(NULL); + for (i = 0; i < LOOPS && e == 0; i++) { + for (j = 0; j < PARALLEL; j++) { + if ((pids[j] = fork()) == 0) + test(); + } + + for (j = 0; j < PARALLEL; j++) { + if (waitpid(pids[j], &status, 0) != pids[j]) + err(1, "waitpid(%d)", pids[j]); + if (status != 0 && e == 0 && status != SIGSEGV && status != EFAULT) + e = status; + } + if (time(NULL) - start > 1200) { + fprintf(stderr, "Timed out."); + break; + } + } + + return (e); +} diff --git a/tools/test/stress2/misc/mmap2.sh b/tools/test/stress2/misc/mmap2.sh new file mode 100755 index 000000000000..1595f7afacce --- /dev/null +++ b/tools/test/stress2/misc/mmap2.sh @@ -0,0 +1,177 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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. +# + +# Stress mmap by having at most 100 threads mapping random areas within +# a 100 Mb range. + +# Test scenario by kib@ + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > mmap2.c +mycc -o mmap2 -Wall -g mmap2.c -lpthread +rm -f mmap2.c + +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 600 ]; do + ./mmap2 +done +rm -f ./mmap2* +exit + +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define THREADS 100 +#define STARTADDR 0x50000000U +#define ADRSPACE 0x06400000U /* 100 Mb */ + +static void +work(int nr) +{ + int fd, m; + void *p; + size_t left, len; + char path[128]; + + p = (void *)STARTADDR + trunc_page(arc4random() % ADRSPACE); + left = ADRSPACE - (size_t)p + STARTADDR; + len = trunc_page(arc4random() % left) + PAGE_SIZE; + fd = -1; + + if (arc4random() % 100 < 90) + sprintf(path, "/tmp/mmap.%06d.%04d", getpid(), nr); + else + sprintf(path, "/dev/zero"); + if (arc4random() % 2 == 0) { + if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == -1) + err(1,"open()"); + if (ftruncate(fd, len) == -1) + err(1, "ftruncate"); + if (arc4random() % 2 == 0) { + if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == + MAP_FAILED) { + if (errno == ENOMEM) + return; + err(1, "mmap()"); + } + } else { + if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0)) == + MAP_FAILED) { + if (errno == ENOMEM) + return; + err(1, "mmap()"); + } + } + if (fd > 0 && strcmp(path, "/dev/zero")) + if (unlink(path) == -1) + err(1, "unlink(%s)", path); + } else { + if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0)) == MAP_FAILED) { + if (errno == ENOMEM) + return; + err(1, "mmap()"); + } + strcpy(path, "anon"); + } +#if 0 + printf("nr = %d, %-14s, start = %p, end = %p, len = 0x%08x, (%5d pages)\n", + nr, path, p, p + len, len, len>>PAGE_SHIFT); +#endif + + *(int *)p = 1; + + if (arc4random() % 2 == 0) { + m = arc4random() % 10; + if (madvise(p, len, m) == -1) + warn("madvise(%p, %zd, %d)", p, len, m); + } + if (arc4random() %2 == 0) + if (mprotect(p, trunc_page(arc4random() % len), PROT_READ) == -1 ) + err(1, "mprotect failed with error:"); + if (arc4random() % 2 == 0) { + if (arc4random() %2 == 0) { + if (msync(p, 0, MS_SYNC) == -1) + err(1, "msync(%p)", p); + } else { + if (msync(p, 0, MS_INVALIDATE) == -1) + err(1, "msync(%p)", p); + } + } + if (munmap(p, len) == -1) + err(1, "munmap(%p)", p); + close(fd); +} + +void * +thr(void *arg) +{ + int i; + + for (i = 0; i < 512; i++) { + work(*(int *)arg); + } + return (0); +} + +int +main(int argc, char **argv) +{ + pthread_t threads[THREADS]; + int nr[THREADS]; + int i, n, r; + +// printf("Address start 0x%x, address end 0x%x, pages %d\n", +// STARTADDR, STARTADDR + ADRSPACE, ADRSPACE>>PAGE_SHIFT); + n = arc4random() % THREADS + 1; + for (i = 0; i < n; i++) { + nr[i] = i; + if ((r = pthread_create(&threads[i], NULL, thr, (void *)&nr[i])) != 0) + errc(1, r, "pthread_create()"); + } + + for (i = 0; i < n; i++) { + if ((r = pthread_join(threads[i], NULL)) != 0) + errc(1, r, "pthread_join(%d)", i); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mmap20.sh b/tools/test/stress2/misc/mmap20.sh new file mode 100755 index 000000000000..da1a55e4b2b0 --- /dev/null +++ b/tools/test/stress2/misc/mmap20.sh @@ -0,0 +1,83 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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: pmap_unwire: pte 0x672d405 is missing PG_W" seen. +# http://people.freebsd.org/~pho/stress/log/mmap20.txt + +# Test scenario by: Mark Johnston markj@ + +# Fixed by r272036 + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap20.c +mycc -o mmap20 -O2 -Wall -Wextra mmap20.c || exit 1 +rm -f mmap20.c +cd $odir + +/tmp/mmap20 +s=$? + +rm -f /tmp/mmap20 +exit $s + +EOF +#include +#include + +#include +#include + +int +main(void) +{ + char *ptr; + size_t sz; + + sz = 4096; + ptr = mmap(NULL, sz, PROT_READ, MAP_ANON, -1, 0); + if (ptr == NULL) + err(1, "mmap"); + + if (mlock(ptr, sz) != 0) + err(1, "mlock"); + + if (mprotect(ptr, sz, PROT_EXEC) != 0) + err(1, "mprotect"); + + if (madvise(ptr, sz, MADV_WILLNEED) != 0) + err(1, "madvise"); + + if (munlock(ptr, sz) != 0) + err(1, "munlock"); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap21.sh b/tools/test/stress2/misc/mmap21.sh new file mode 100755 index 000000000000..4b5079160fce --- /dev/null +++ b/tools/test/stress2/misc/mmap21.sh @@ -0,0 +1,165 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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: vm_reserv_populate: reserv 0xfffff807cbd3c400 is already promoted +# http://people.freebsd.org/~pho/stress/log/mmap21.txt +# Fixed by r280238 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mmap21.c +mycc -o mmap21 -Wall -Wextra -O2 -g mmap21.c -lpthread || exit 1 +rm -f mmap21.c + +su $testuser -c /tmp/mmap21 + +rm -f /tmp/mmap21 /tmp/mmap21.core +exit 0 +EOF +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 1 +#define NMAPS 50 +#define PARALLEL 2 + +void *p; + +static void * +tmmap(void *arg __unused) +{ + size_t len; + int i; + + pthread_set_name_np(pthread_self(), __func__); + len = 1LL * 128 * 1024 * 1024; + + for (i = 0; i < NMAPS; i++) + p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + + return (NULL); +} + +static void * +tmlock(void *arg __unused) +{ + size_t len; + int i, n; + + pthread_set_name_np(pthread_self(), __func__); + n = 0; + for (i = 0; i < 200; i++) { + len = trunc_page(arc4random()); + if (mlock(p, len) == 0) + n++; + len = trunc_page(arc4random()); + if (arc4random() % 100 < 50) + if (munlock(p, len) == 0) + n++; + } + if (n < 10) + fprintf(stderr, "Note: tmlock() only succeeded %d times.\n", + n); + + return (NULL); +} + +static void +test(void) +{ + pid_t pid; + pthread_t tid[2]; + int i, rc; + + if ((rc = pthread_create(&tid[0], NULL, tmmap, NULL)) != 0) + errc(1, rc, "tmmap()"); + if ((rc = pthread_create(&tid[1], NULL, tmlock, NULL)) != 0) + errc(1, rc, "tmlock()"); + + for (i = 0; i < 100; i++) { + if ((pid = fork()) == 0) { + usleep(10000); + _exit(0); + } + if (waitpid(pid, NULL, 0) != pid) + err(1, "waitpid(%d)", pid); + } + + raise(SIGSEGV); + + for (i = 0; i < 2; i++) + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + _exit(0); +} + +int +main(void) +{ + + pid_t pids[PARALLEL]; + time_t start; + int e, i, j, status; + + start = time(NULL); + for (i = 0; i < LOOPS; i++) { + for (j = 0; j < PARALLEL; j++) { + if ((pids[j] = fork()) == 0) + test(); + } + + e = 0; + for (j = 0; j < PARALLEL; j++) { + if (waitpid(pids[j], &status, 0) == -1) + err(1, "waitpid(%d)", pids[j]); + e += status == 0 ? 0 : 1; + } + if (time(NULL) - start > 1200) { + fprintf(stderr, "Timed out."); + break; + } + } + + return (e); +} diff --git a/tools/test/stress2/misc/mmap22.sh b/tools/test/stress2/misc/mmap22.sh new file mode 100755 index 000000000000..4b730100d7dc --- /dev/null +++ b/tools/test/stress2/misc/mmap22.sh @@ -0,0 +1,130 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Core dump wedge +# Trimmed down version of mmap15.sh +# http://people.freebsd.org/~pho/stress/log/mmap15-2.txt +# Fixed in r272534 + r272535. + +# Page fault seen: http://people.freebsd.org/~pho/stress/log/kostik733.txt +# Fixed in r274474. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mmap22.c +mycc -o mmap22 -Wall -Wextra -O2 -g mmap22.c -lpthread || exit 1 +rm -f mmap22.c + +su $testuser -c /tmp/mmap22 & + +sleep 300 +while pgrep -q mmap22; do + pkill -9 mmap22 + sleep 2 +done +wait + +rm -f /tmp/mmap22 /tmp/mmap22.core +exit 0 +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define MMAPS 25 +#define PARALLEL 4 +#define SIZ (64 * 1024 * 1024) + +void * +tmmap(void *arg __unused) +{ + size_t len; + void *p; + int i; + + len = SIZ; + for (i = 0; i < MMAPS; i++) + p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + fsync(fileno(stdout)); + + return (NULL); +} + +void +test(void) +{ + pthread_t tid; + int i, rc; + + if ((rc = pthread_create(&tid, NULL, tmmap, NULL)) != 0) + errc(1, rc, "test()"); + + for (i = 0; i < 100; i++) { + if (fork() == 0) { + usleep(10000); + _exit(0); + } + wait(NULL); + } + + raise(SIGSEGV); + + if ((rc = pthread_join(tid, NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + _exit(0); +} + +int +main(void) +{ + int i; + + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + test(); + } + + for (i = 0; i < PARALLEL; i++) + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap23.sh b/tools/test/stress2/misc/mmap23.sh new file mode 100755 index 000000000000..6a4a04eecab1 --- /dev/null +++ b/tools/test/stress2/misc/mmap23.sh @@ -0,0 +1,108 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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: vm_object_unwire: missing page" seen. +# https://people.freebsd.org/~pho/stress/log/mmap23.txt +# Test scenario by kib@. +# Fixed by r285878. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap23.c +mycc -o mmap23 -Wall -Wextra mmap23.c || exit 1 +rm -f mmap23.c +cd $odir + +cp /tmp/mmap23 /tmp/mmap23.inputfile +daemon sh -c '(cd ../testcases/swap; ./swap -t 1m -i 2)' > \ + /dev/null 2>&1 + +/tmp/mmap23 /tmp/mmap23.inputfile & +sleep .2 +dd if=/dev/zero of=/tmp/mmap23.inputfile bs=1k count=1 status=none + +while pgrep -q swap; do + pkill -9 swap +done + +rm -f /tmp/mmap23 /tmp/mmap23.inputfile +exit + +EOF +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +const char *file; + +void +test(void) +{ + struct stat st; + char *p; + size_t len; + int error, fd; + + 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"); + p[arc4random() % len] = 1; + if ((error = mlock(p, len)) == -1) + err(1, "mlock"); + sleep(2); + if (munmap(p, len) == -1) + err(1, "unmap()"); + close(fd); +} + +int +main(int argc, char *argv[]) +{ + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + file = argv[1]; + + test(); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap24.sh b/tools/test/stress2/misc/mmap24.sh new file mode 100755 index 000000000000..4a25a0e3520f --- /dev/null +++ b/tools/test/stress2/misc/mmap24.sh @@ -0,0 +1,99 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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: vm_page_unwire: page 0xc36cafbc's wire count is zero" seen. +# https://people.freebsd.org/~pho/stress/log/mmap24.txt +# Test scenario by trasz@. +# Fixed by r285878. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap24.c +mycc -o mmap24 -Wall -Wextra mmap24.c || exit 1 +rm -f mmap24.c +cd $odir + +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +cp /tmp/mmap24 $mntpoint +(cd $mntpoint; ./mmap24) & +sleep .2 +umount -f $mntpoint + +kill $! +wait + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart + +rm -f /tmp/mmap24 +exit + +EOF +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +int +main(void) +{ + int error; + + error = mlockall(MCL_CURRENT | MCL_FUTURE); + if (error != 0) + err(1, "mlockall"); + + for (;;) { + sleep(1); + } +} diff --git a/tools/test/stress2/misc/mmap25.sh b/tools/test/stress2/misc/mmap25.sh new file mode 100755 index 000000000000..caad84d9b549 --- /dev/null +++ b/tools/test/stress2/misc/mmap25.sh @@ -0,0 +1,120 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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: vm_page_unwire: page 0xc36cce48's wire count is zero" seen. +# Fixed by r285878. + +# Test scenario by kib@: +# 1. We mapped and mlocked the file. +# 2. The file is truncated +# 3. The file is extended again to cover the whole mapped area. +# 4. The program accesses the mapping past the point of truncation. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap25.c +mycc -o mmap25 -Wall -Wextra mmap25.c || exit 1 +rm -f mmap25.c +cd $odir + +cp /tmp/mmap25 /tmp/mmap25.inputfile +daemon sh -c '(cd ../testcases/swap; ./swap -t 1m -i 2)' > \ + /dev/null 2>&1 +sleep 1 + +/tmp/mmap25 /tmp/mmap25.inputfile + +while pgrep -q swap; do + pkill -9 swap +done +rm -f /tmp/mmap25 /tmp/mmap25.inputfile mmap25.core +exit + +EOF +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +const char *file; +volatile char c; + +void +test(void) +{ + struct stat st; + char *p; + size_t len; + off_t pos; + int error, fd; + + 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); + pos = len - getpagesize(); + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) + == MAP_FAILED) + err(1, "mmap"); + if ((error = mlock(p, len)) == -1) + err(1, "mlock"); + + if (ftruncate(fd, pos) == -1) + err(1, "ftruncate 1"); + if (ftruncate(fd, len) == -1) + err(1, "ftruncate 2"); + + c = p[pos]; /* Program received signal SIGSEGV, Segmentation fault. */ + + if (munmap(p, len) == -1) + err(1, "unmap()"); + close(fd); +} + +int +main(int argc, char *argv[]) +{ + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + file = argv[1]; + + test(); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap26.sh b/tools/test/stress2/misc/mmap26.sh new file mode 100755 index 000000000000..19479b92461f --- /dev/null +++ b/tools/test/stress2/misc/mmap26.sh @@ -0,0 +1,123 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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: vm_page_unwire: page 0xc36cce48's wire count is zero" seen. +# https://people.freebsd.org/~pho/stress/log/kostik820.txt +# Fixed by r285878. + +# Variation of mmap25.sh: +# Access one byte past the end of the file, which is not wrong, but +# out of specified behaviour. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap26.c +mycc -o mmap26 -Wall -Wextra mmap26.c || exit 1 +rm -f mmap26.c +cd $odir + +cp /tmp/mmap26 /tmp/mmap26.inputfile +daemon sh -c '(cd ../testcases/swap; ./swap -t 1m -i 2)' > \ + /dev/null 2>&1 +sleep 1 + +(cd /tmp; /tmp/mmap26 /tmp/mmap26.inputfile) + +while pkill -9 swap; do :; done +rm -f /tmp/mmap26 /tmp/mmap26.inputfile /tmp/mmap26.core +exit 0 + +EOF +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +const char *file; +volatile char c; + +void +test(void) +{ + struct stat st; + char *p; + size_t len; + int error, fd; + + 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"); + if ((error = mlock(p, len)) == -1) + err(1, "mlock"); + + if (ftruncate(fd, (off_t)0) == -1) + err(1, "ftruncate 1"); + if (ftruncate(fd, len) == -1) + err(1, "ftruncate 2"); + + p[len - 1] = 1; + + /* one byte past EOF */ + if (round_page((unsigned long)&p[len]) == + round_page((unsigned long)&p[len - 1])) { + fprintf(stderr, "Expect: Segmentation fault (core dumped)\n"); + c = p[len]; + } + + if (munmap(p, len) == -1) + err(1, "unmap()"); + close(fd); +} + +int +main(int argc, char *argv[]) +{ + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + file = argv[1]; + + test(); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap27.sh b/tools/test/stress2/misc/mmap27.sh new file mode 100755 index 000000000000..7f8d4e94583a --- /dev/null +++ b/tools/test/stress2/misc/mmap27.sh @@ -0,0 +1,126 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# 'WARNING: A device driver has set "memattr" inconsistently.' seen on +# console. +# https://people.freebsd.org/~pho/stress/log/mmap27.txt +# Fixed by r298891. + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > mmap27.c +mycc -o mmap27 -Wall -Wextra -g -O0 mmap27.c || exit 1 +rm -f mmap27.c +cd $odir + +daemon sh -c '(cd ../testcases/swap; ./swap -t 2m -i 20 -l 100)' > /dev/null 2>&1 +sleep 2 +/tmp/mmap27 +while pgrep -q swap; do + pkill -9 swap +done +rm -f ./mmap27 /tmp/mmap27.0* /tmp/mmap27 +exit 0 + +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +int fd; + +#define ADRSPACE (256 * 1024 * 1024 ) +#define PARALLEL 64 +#define RUNTIME 120 +#define STARTADDR 0x50000000U + +static void +work(void) +{ + size_t left, len; + int i; + char *p; + volatile char val; + + if ((fd = open("/dev/mem", O_RDWR)) == -1) + err(1,"open()"); + + p = (void *)STARTADDR + trunc_page(arc4random() % ADRSPACE); + left = ADRSPACE - (size_t)p + STARTADDR; + len = trunc_page(arc4random() % left) + PAGE_SIZE; + + if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == + MAP_FAILED) { + if (errno == ENOMEM) + return; + err(1, "mmap()"); + } + + for (i = 0; i < 100; i++) + val = p[arc4random() % len]; + + if (munmap(p, len) == -1) + err(1, "munmap(%p)", p); + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + time_t start; + int i, n; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + n = arc4random() % PARALLEL + 1; + for (i = 0; i < n; i++) { + if ((pids[i] = fork()) == 0) + work(); + } + + for (i = 0; i < n; i++) + if (waitpid(pids[i], NULL, 0) != pids[i]) + err(1, "waitpid(%d)", pids[i]); + } + close(fd); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap28.sh b/tools/test/stress2/misc/mmap28.sh new file mode 100755 index 000000000000..fd64202e3814 --- /dev/null +++ b/tools/test/stress2/misc/mmap28.sh @@ -0,0 +1,131 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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: vnode_pager_generic_getpages: page 0xc3350b0c offset beyond vp +# 0xcc187000 size' seen. +# https://people.freebsd.org/~pho/stress/log/mmap28.txt +# This was introduced by r292373. +# +# A page fault is seen on a non INVARIANTS kernel w/ r292373, +# whereas this test runs as expected on r292372. +# https://people.freebsd.org/~pho/stress/log/mmap28-2.txt +# https://people.freebsd.org/~pho/stress/log/mmap28-3.txt +# To repeat, run this test with "sysctl vfs.ffs.use_buf_pager=0". +# Fixed by r307626 + +# Test scenario refinement by kib@ + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > mmap28.c +mycc -o mmap28 -Wall -Wextra -g -O0 mmap28.c || exit 1 +rm -f mmap28.c +cd $odir + +(cd /tmp; ./mmap28) + +rm -f /tmp/mmap28 /tmp/mmap28.0* /tmp/mmap28.core +exit 0 + +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define ADRSPACE (256 * 1024 * 1024 ) +#define STARTADDR 0x50000000U + +static void +work(void) +{ + size_t indx, left, len; + int fd, rfd; + int i; + char *p; + char path[128]; + volatile char val; + + if ((rfd = open("/dev/random", O_RDONLY)) == -1) + err(1, "open(/dev/random)"); + + snprintf(path, sizeof(path), "/tmp/mmap28.%06d", 0); + if ((fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) + err(1,"open(%s)", path); + + p = (void *)STARTADDR + trunc_page(arc4random() % ADRSPACE); + left = ADRSPACE - (size_t)p + STARTADDR; + len = trunc_page(arc4random() % left) + PAGE_SIZE; + + if (ftruncate(fd, len) == -1) + err(1, "ftruncate"); + + if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == + MAP_FAILED) { + if (errno == ENOMEM) + return; + err(1, "mmap()"); + } + + /* + Truncating the mapped file triggers a panic when accessed beyond + EOF. + */ + if (ftruncate(fd, len / 2) == -1) + err(1, "ftruncate(%s)", path); + + for (i = 0; i < 1000; i++) { + if (read(rfd, &indx, sizeof(indx)) != sizeof(indx)) + err(1, "read(random)"); + val = p[indx % len]; + } + close(rfd); + + if (munmap(p, len) == -1) + err(1, "munmap(%p)", p); + close(fd); + unlink(path); +} + +int +main(void) +{ + + work(); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap29.sh b/tools/test/stress2/misc/mmap29.sh new file mode 100755 index 000000000000..e6aacc15e48e --- /dev/null +++ b/tools/test/stress2/misc/mmap29.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +# Test scenario by: David Cross + +# "panic: softdep_deallocate_dependencies: dangling deps" seen. +# https://people.freebsd.org/~pho/stress/log/mmap29.txt +# Fixed by: r302567. + +. ../default.cfg +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +[ -z "`which timeout`" ] && exit 0 +mount | grep "on $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 || exit 1 +bsdlabel -w md$mdstart auto +newfs -U md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +mkdir $mntpoint/mmap29 +cd /tmp +cat > mmap29.c < +#include +#include + +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int fd; + unsigned char *memrange; + + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + unlink(argv[1]); + if ((fd = open(argv[1], O_RDWR | O_CREAT, DEFFILEMODE)) == -1) + err(1, "open(%s)", argv[1]); + lseek(fd, 0xbfff, SEEK_SET); + write(fd, "\0", 1); + if ((memrange = mmap(0, 0x2b6000, PROT_READ | PROT_WRITE, MAP_SHARED | + MAP_HASSEMAPHORE | MAP_NOSYNC, fd, 0)) == MAP_FAILED) + err(1, "mmap"); + memrange[0] = 5; + munmap(memrange, 0x2b6000); + close(fd); + + return (0); +} +EOFHERE + +cc -o mmap29 -Wall -Wextra -O0 -g mmap29.c || exit 1 +rm mmap29.c +./mmap29 $mntpoint/mmap29/mmap291 +old=`sysctl -n kern.maxvnodes` +trap "sysctl kern.maxvnodes=$old" EXIT INT +sysctl kern.maxvnodes=2000 +timeout 60 find / -xdev -print >/dev/null +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm mmap29 +exit 0 diff --git a/tools/test/stress2/misc/mmap3.sh b/tools/test/stress2/misc/mmap3.sh new file mode 100755 index 000000000000..bc5905dd920e --- /dev/null +++ b/tools/test/stress2/misc/mmap3.sh @@ -0,0 +1,167 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 mmap2.sh with focus on random arguments for mprotect() +# https://people.freebsd.org/~pho/stress/log/kostik209.txt + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > mmap3.c +mycc -o mmap3 -Wall mmap3.c -lpthread || exit 1 +rm -f mmap3.c + +start=`date '+%s'` +while [ `date '+%s'` -lt $((start + 5 * 60)) ]; do + ./mmap3 +done +echo "Expect Segmentation faults" +start=`date '+%s'` +while [ `date '+%s'` -lt $((start + 5 * 60)) ]; do + ./mmap3 random +done +rm -f mmap3 mmap3.core /tmp/mmap.0* +exit + +EOF +/* + Stress mmap by having max 100 threads mapping random areas within + a 100 Mb range. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define THREADS 100 +#define STARTADDR 0x50000000U +#define ADRSPACE 0x06400000U /* 100 Mb */ + +static int ra; + +void +trash(void *p) +{ + unsigned long v; + + mprotect(p, 0x570e3d38, 0x2c8fd54f); + if (ra) { + v = arc4random(); +#if defined(__LP64__) + v = v << 32 | arc4random(); +#endif + madvise((void *)v, arc4random(), arc4random()); + mprotect((void *)v, arc4random(), arc4random()); + msync((void *)v, arc4random(), arc4random()); + } + +} + +void +work(int nr) +{ + int fd, m; + void *p; + size_t len; + char path[128]; + + p = (void *)STARTADDR; + len = ADRSPACE; + + sprintf(path, "/tmp/mmap.%06d.%04d", getpid(), nr); + 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(p, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == + MAP_FAILED) { + if (errno == ENOMEM) + return; + err(1, "mmap()"); + } + if (unlink(path) == -1) + err(1, "unlink(%s)", path); + + trash(p); + + m = arc4random() % 10; + if (madvise(p, len, m) == -1) + warn("madvise(%p, %zd, %d)", p, len, m); + if (mprotect(p, trunc_page(arc4random() % len), PROT_READ) == -1 ) + err(1, "mprotect failed with error:"); + if (msync(p, 0, MS_SYNC) == -1) + err(1, "msync(%p)", p); + if (munmap(p, len) == -1) + err(1, "munmap(%p)", p); + close(fd); +} + +void * +thr(void *arg) +{ + int i; + + for (i = 0; i < 512; i++) { + work(*(int *)arg); + } + return (0); +} + +int +main(int argc, char **argv) +{ + pthread_t threads[THREADS]; + int nr[THREADS]; + int i, n, r; + + n = arc4random() % 14 + 5; + ra = argc != 1; +// printf("Address start 0x%x, address end 0x%x, pages %d, n %d\n", +// STARTADDR, STARTADDR + ADRSPACE, ADRSPACE>>PAGE_SHIFT, n); + for (i = 0; i < n; i++) { + nr[i] = i; + if ((r = pthread_create(&threads[i], NULL, thr, (void *)&nr[i])) != 0) + errc(1, r, "pthread_create()"); + } + + for (i = 0; i < n; i++) { + if ((r = pthread_join(threads[i], NULL)) != 0) + errc(1, r, "pthread_join(%d)", i); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mmap30.sh b/tools/test/stress2/misc/mmap30.sh new file mode 100755 index 000000000000..3f1b8cccbc54 --- /dev/null +++ b/tools/test/stress2/misc/mmap30.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# r320344: allow mprotect(2) over the guards to succeed regardless of +# the requested protection. + +. ../default.cfg + +grep -q MAP_GUARD /usr/include/sys/mman.h 2>/dev/null || exit 0 +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mmap30.c +mycc -o mmap30 -Wall -Wextra -O2 -g mmap30.c || exit 1 +rm -f mmap30.c /tmp/mmap30.core + +/tmp/mmap30 > /dev/null +s=$? + +rm -f /tmp/mmap30 /tmp/mmap30.core +exit $s +EOF +#include +#include + +#include +#include +#include +#include +#include + +int +main(void) +{ + int pagesz; + void *addr; + + pagesz = getpagesize(); + addr = mmap(NULL, pagesz, PROT_NONE, MAP_GUARD, -1, 0); + if (addr == (char *)MAP_FAILED) + err(1, "FAIL: mmap(MAP_GUARD)"); + + if (mprotect(addr, pagesz, PROT_READ | PROT_WRITE) == -1) + err(1, "mprotect(RW)"); + + if (mprotect(addr, pagesz, PROT_NONE) == -1) + err(1, "mprotect(RW)"); + + if (munmap(addr, pagesz) == -1) + err(1, "munmap"); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap31.sh b/tools/test/stress2/misc/mmap31.sh new file mode 100755 index 000000000000..8dd239579fb2 --- /dev/null +++ b/tools/test/stress2/misc/mmap31.sh @@ -0,0 +1,174 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 scenario for 2MB page promotions. +# No problems seen. + +. ../default.cfg +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ "`uname -p`" = "amd64" ] || exit 0 + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap31.c +mycc -o mmap31 -Wall -Wextra -O0 -g mmap31.c || exit 1 +rm -f mmap31.c +cd $odir + +(cd ../testcases/swap; ./swap -t 10m -i 20) > /dev/null & + +/tmp/mmap31 +s=$? +kill $! 2>/dev/null +while pkill -9 swap; do :; done +wait + +rm -rf /tmp/mmap31 +exit $s + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define SEGS 512 +static size_t l[SEGS]; +static char *c[SEGS]; +static volatile char r; +static volatile u_int *share; + +#define PARALLEL 8 +#define RUNTIME (2 * 60) +#define SYNC 0 + +static void +handler(int s __unused) +{ + _exit(0); +} + +static void +touch(void) +{ + time_t t; + int idx; + char *c1; + + t = time(NULL); + while (time(NULL) - t < 5) { + idx = arc4random() % SEGS; + c1 = c[idx]; + idx = arc4random() % l[idx]; + r += c1[idx]; + c1[idx] += 1; + } +} + +static void +test(void) +{ + pid_t pid; + int i, mode, status; + + r = 0; + for (i = 0; i < SEGS; i++) { + l[i] = (arc4random() % 512 + 1) * PAGE_SIZE; + mode = PROT_READ | PROT_WRITE; + if ((c[i] = (char *)mmap(NULL, l[i], mode, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + } + + if ((pid = fork()) == 0) { + signal(SIGHUP, handler); + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + touch(); + pause(); + _exit(0); + } + + while (share[SYNC] != PARALLEL) + ; + touch(); + + kill(pid, SIGHUP); + if (waitpid(pid, &status, 0) != pid) + err(1, "waitpid"); + if (status != 0) + errx(1, "child status = %d", status); + + _exit(status); +} + +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]); + e += status == 0 ? 0 : 1; + } + } + + return (e); +} diff --git a/tools/test/stress2/misc/mmap32.sh b/tools/test/stress2/misc/mmap32.sh new file mode 100755 index 000000000000..a775b756084e --- /dev/null +++ b/tools/test/stress2/misc/mmap32.sh @@ -0,0 +1,202 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Bug 223732 - mmap(2) causes unkillable denial of service with specific +# flags +# Test scenario inspired by: Arto Pekkanen + +# Fixed by r326098. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap32.c +mycc -o mmap32 -Wall -Wextra -O0 -g mmap32.c || exit 1 +rm -f mmap32.c + +$dir/mmap32 +s=$? +[ -f mmap32.core -a $s -eq 0 ] && + { ls -l mmap32.core; mv mmap32.core /tmp; s=1; } + +rm -rf $dir/mmap32 +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define N 4096 +static uint32_t r[N]; + +static unsigned long +makearg(void) +{ + unsigned int i; + unsigned long val; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return(val); +} + +static void +fuzz(int arg, void *addr, size_t len, int prot, int flags, int fd, + off_t offset) +{ + time_t start; + void *vp; + int n; + + setproctitle("arg%d", arg); + n = 0; + start = time(NULL); + while (time(NULL) - start < 10) { + switch (arg) { + case 1: + addr = (void *)makearg(); + break; + case 2: + len = makearg(); + break; + case 3: + prot = makearg(); + break; + case 4: + flags = makearg(); + break; + case 5: + fd = makearg(); + break; + case 6: + offset = makearg() & 0xffff; + break; + case 34: + prot = makearg(); + flags = makearg(); + break; + default: + errx(1, "Bad argument %d to %s", arg, __func__); + } + vp = mmap(addr, len, prot, flags, fd, offset); + if (vp != MAP_FAILED) { + munmap(vp, len); + n++; + } + } +#if defined(DEBUG) + if (n == 0 && arg != 5) + fprintf(stderr, "%s(%d) failed\n", __func__, arg); +#endif + exit(0); +} + +int +main(void) +{ + off_t offset; + pid_t pid; + size_t len; + struct rlimit rl; + time_t start; + void *addr, *vp; + int e, flags, fd, i, prot, status; + + e = 0; + + rl.rlim_max = rl.rlim_cur = 0; + if (setrlimit(RLIMIT_CORE, &rl) == -1) + warn("setrlimit"); + addr = 0; + len = PAGE_SIZE; + prot = PROT_READ | PROT_WRITE; + flags = MAP_ANON | MAP_SHARED; + fd = -1; + offset = 0; + vp = mmap(addr, len, prot, flags, fd, offset); + if (vp == MAP_FAILED) + err(1, "initail mmap"); + munmap(vp, len); + + start = time(NULL); + while (time(NULL) - start < 120) { + for (i = 0; i < N; i++) + r[i] = arc4random(); + for (i = 0; i < 6; i++) { + if ((pid = fork()) == 0) + fuzz(i + 1, addr, len, prot, flags, fd, + offset); + if (waitpid(pid, &status, 0) != pid) + err(1, "waitpid %d", pid); + if (status != 0) { + if (WIFSIGNALED(status)) + fprintf(stderr, + "pid %d exit signal %d\n", + pid, WTERMSIG(status)); + } + e += status == 0 ? 0 : 1; + } + if ((pid = fork()) == 0) + fuzz(34, addr, len, prot, flags, fd, offset); + if (waitpid(pid, &status, 0) != pid) + err(1, "waitpid %d", pid); + if (status != 0) { + if (WIFSIGNALED(status)) + fprintf(stderr, + "pid %d exit signal %d\n", + pid, WTERMSIG(status)); + } + e += status == 0 ? 0 : 1; + } + + return (e); +} diff --git a/tools/test/stress2/misc/mmap33.sh b/tools/test/stress2/misc/mmap33.sh new file mode 100755 index 000000000000..70ac054a9934 --- /dev/null +++ b/tools/test/stress2/misc/mmap33.sh @@ -0,0 +1,121 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# +# ftruncate+mmap+fsync fails for small maps +# https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=225586 + +# Original test scenario by tris_vern@hotmail.com + +# Fixed in r328773: +# On pageout, in vnode generic pager, for partially dirty page, only +# clear dirty bits for completely invalid blocks. + +. ../default.cfg + +cat > /tmp/mmap33.c < + +#include +#include +#include +#include +#include +#include + +int +main (int argc, char *argv[]) +{ + size_t i, size1, size2; + int fd; + char *data; + char *filename; + char pattern = 0x01; + + if (argc != 4) { + fprintf(stderr, "Usage: %s filename size1 size2\n", argv[0]); + exit(1); + } + + filename = argv[1]; + size1 = atoi(argv[2]); + size2 = atoi(argv[3]); + + fd = open(filename, O_RDWR | O_TRUNC | O_CREAT, 0644); + for (i = 0; i < size1; i++) + write(fd, &pattern, 1); + close(fd); + + fd = open(filename, O_RDWR, 0644); + if (fd == -1) + err(1, "open(%s)", filename); + if (ftruncate(fd, size2) == -1) + err(1, "ftruncate()"); + data = mmap(NULL, size2, PROT_READ|PROT_WRITE,MAP_SHARED, fd, 0); + if (data == MAP_FAILED) + err(1, "mmap()"); + memset(data, 0xFF, size2); + + if (munmap(data, size2) == -1) + err(1, "munmap"); + close(fd); + + return (0); +} +EOF +cc -o /tmp/mmap33 -Wall -Wextra -O2 -g /tmp/mmap33.c || exit 1 +rm /tmp/mmap33.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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags -n md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +set +e + +file=file +odir=`pwd` +cd $mntpoint +/tmp/mmap33 $file 1024 511 +s=$? +sum1=`md5 < $mntpoint/$file` +[ -f mmap33.core -a $s -eq 0 ] && + { ls -l mmap33.core; mv mmap33.core /tmp; s=1; } +cd $odir +umount $mntpoint +mount /dev/md${mdstart}$part $mntpoint +# This fails for truncate size < 512 +sum2=`md5 < $mntpoint/$file` +[ $sum1 = $sum2 ] || + { s=2; echo "md5 fingerprint differs."; } +umount $mntpoint + +mdconfig -d -u $mdstart +rm /tmp/mmap33 +exit $s diff --git a/tools/test/stress2/misc/mmap34.sh b/tools/test/stress2/misc/mmap34.sh new file mode 100755 index 000000000000..028d23b4f71f --- /dev/null +++ b/tools/test/stress2/misc/mmap34.sh @@ -0,0 +1,230 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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: caller failed to provide space -546873344 at address 0x20a00000" +# seen. +# https://people.freebsd.org/~pho/stress/log/indir_trunc.txt +# Fixed by r348968 + +# Test scenario inspired by: +# syzbot+6532e9aab8911f58beeb@syzkaller.appspotmail.com + +. ../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/mmap34.c +mycc -o mmap34 -Wall -Wextra -O0 -g mmap34.c -lpthread || 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 4g -u $mdstart +newfs $newfs_flags -n md$mdstart > /dev/null +mount /dev/md$mdstart $mntpoint +set +e + +(cd ../testcases/swap; ./swap -t 5m -i 20) & +cd $mntpoint +$dir/mmap34 +s=$? +while pkill swap; do :; done +wait +[ -f mmap34.core ] && + { ls -l mmap34.core; mv mmap34.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 +rm -f $dir/mmap34 +[ $s -eq 0 ] && rm -f mmap34.c +exit $s + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; + +#if defined(__LP64__) +#define MASK 0x7ffffffffffffULL +#else +#define MASK 0xffffffffULL +#endif +#define PARALLEL 64 +#define RUNTIME (5 * 60) +#define SYNC 0 + +static int fd; + +static void * +t1(void *data __unused) +{ + off_t offset; + time_t start; + + start = time(NULL); + while (time(NULL) - start < 30) { + offset = arc4random(); + offset = (offset << 32) | arc4random(); + offset &= MASK; + if (lseek(fd, offset, SEEK_SET) == -1) + err(1, "lseek(%jd)", offset); + if (write(fd, "a", 1) != 1) + err(1, "write"); + if (fsync(fd) == -1) + err(1, "fsync"); + usleep(100); + } + return (NULL); +} +static void * +t2(void *data __unused) +{ + off_t offset, old; + time_t start; + void *p; + char *c; + + old = 0; + start = time(NULL); + while (time(NULL) - start < 30) { + if (old != 0) + munmap(p, old); + offset = arc4random(); + offset = (offset << 32) | arc4random(); + offset &= MASK; + if (ftruncate(fd, offset) == -1) + err(1, "ftruncate(%jd)", offset); + write(fd, "b", 1); + p = mmap(NULL, offset, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, 0); + if (p == MAP_FAILED) + old = 0; + else { + old = offset; + c = p; + c[offset / 2] = 1; + if (offset > 0) + c[offset - 1] = 2; + } + usleep(20000); + } + return (NULL); +} + +static void +test(void) +{ + pthread_t tid[2]; + int r; + char file[80]; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + snprintf(file, sizeof(file), "file.%d", getpid()); + if ((fd = open(file, O_RDWR | O_CREAT, DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + + 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"); + close(fd); + unlink(file); + + _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); +} diff --git a/tools/test/stress2/misc/mmap35.sh b/tools/test/stress2/misc/mmap35.sh new file mode 100755 index 000000000000..6e76434e77ec --- /dev/null +++ b/tools/test/stress2/misc/mmap35.sh @@ -0,0 +1,112 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# mmap(2) should fail with "Invalid argument" on i386 +# Fixed by r348843 + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 +[ "`uname -p`" = "i386" ] || exit 0 + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap35.c +mycc -o mmap35 -Wall -Wextra -O0 -g mmap35.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 4g -u $mdstart +newfs $newfs_flags -n md$mdstart > /dev/null +mount /dev/md$mdstart $mntpoint +set +e + +cd $mntpoint +echo "Expect: mmap35: mmap: Cannot allocate memory" +$dir/mmap35 +s=$? +[ -f mmap35.core ] && + { ls -l mmap35.core; mv mmap35.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 +rm -f $dir/mmap35 +[ $s -eq 0 ] && rm -f mmap35.c +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define SIZ 0xfffff0fcULL + +int +main(void) +{ + off_t offset; + int fd; + char *c, file[80]; + + snprintf(file, sizeof(file), "file.%d", getpid()); + if ((fd = open(file, O_RDWR | O_CREAT, DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + + offset = SIZ; + if (ftruncate(fd, offset) == -1) + err(1, "ftruncate(%jd)", offset); + write(fd, "b", 1); + + c = mmap(NULL, offset, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, 0); + if (c == MAP_FAILED) + warn("mmap"); + else + c[offset / 2] = 1; + + unlink(file); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap36.sh b/tools/test/stress2/misc/mmap36.sh new file mode 100755 index 000000000000..2c38fd26890b --- /dev/null +++ b/tools/test/stress2/misc/mmap36.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# mmap(2) should fail with "Invalid argument" and not core dump +# Fixed by + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap36.c +mycc -o mmap36 -Wall -Wextra -O0 -g mmap36.c || exit 1 + +echo "Expect: mmap36: mmap: Cannot allocate memory" +$dir/mmap36 +s=$? +[ -f mmap36.core ] && + { ls -l mmap36.core; mv mmap36.core $dir; s=1; } +cd $odir +[ $s -eq 0 ] && rm -f mmap36.c mmap36 +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +int +main(void) +{ + off_t offset; + char *c; + + offset = SIZE_MAX - 5; + + c = mmap(NULL, offset, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, + -1, 0); + if (c == MAP_FAILED) + warn("mmap"); + else + c[offset / 2] = 1; + + return (0); +} diff --git a/tools/test/stress2/misc/mmap37.sh b/tools/test/stress2/misc/mmap37.sh new file mode 100755 index 000000000000..f5e25a282927 --- /dev/null +++ b/tools/test/stress2/misc/mmap37.sh @@ -0,0 +1,153 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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 https://reviews.freebsd.org/D20800 +# "Use a consistent snapshot of the fd's rights in fget_mmap()" +# https://people.freebsd.org/~pho/stress/log/mmap37.txt + +# Reported by syzbot+ae359438769fda1840f8@syzkaller.appspotmail.com +# Test scenario suggestion by markj@ +# Fixed by r349547 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > mmap37.c +mycc -o mmap37 -Wall -Wextra -O0 mmap37.c -lpthread || exit 1 +rm -f mmap37.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 + +cd $mntpoint +/tmp/mmap37 +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 +rm -f /tmp/mmap37 +exit + +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define THREADS 2 +#define SIZ 0x06400000U /* 100 Mb */ + +static volatile int go; +static char path[128]; + +void * +thr(void *arg) +{ + size_t len; + void *p; + int fd; + + fd = 0; + len = SIZ; + if (*(int *)arg == 0) { + while (go == 1) { + if ((fd = open(path, 2)) == -1) + err(1,"open()"); + p = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_SHARED, fd, 0); + munmap(p, len); + close(fd); + usleep(10); + } + } else { + while (go == 1) { + close(fd); + usleep(10); + } + } + + return (0); +} + +int +main(void) +{ + pthread_t threads[THREADS]; + size_t len; + int nr[THREADS]; + int i, fd, r; + + sprintf(path, "mmap37.%06d", getpid()); + if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == -1) + err(1,"open()"); + len = SIZ; + if (ftruncate(fd, len) == -1) + err(1, "ftruncate"); + close(fd); + + go = 1; + 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()"); + } + + sleep(30); + go = 0; + + for (i = 0; i < THREADS; i++) { + if ((r = pthread_join(threads[i], NULL)) != 0) + errc(1, r, "pthread_join(%d)", i); + } + if (unlink(path) == -1) + err(1, "unlink(%s)", path); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap38.sh b/tools/test/stress2/misc/mmap38.sh new file mode 100755 index 000000000000..b4cf60afe25b --- /dev/null +++ b/tools/test/stress2/misc/mmap38.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +# mmap(2) fuzz test. +# No problems seen. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +num=`awk '/SYS_mmap/ {print $NF}' < /usr/include/sys/syscall.h` +[ -z "$num" ] && exit 0 +start=`date +%s` + +cd ../misc +while [ $((`date +%s` - start)) -lt 300 ]; do + ./syscall4.sh $num +done +exit 0 diff --git a/tools/test/stress2/misc/mmap39.sh b/tools/test/stress2/misc/mmap39.sh new file mode 100755 index 000000000000..15aa8ec718a3 --- /dev/null +++ b/tools/test/stress2/misc/mmap39.sh @@ -0,0 +1,131 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +# Attempt to reproduce +# "panic: pmap_release: pmap 0xfffffe012fb61b08 resident count 1 != 0" +# No problems seen. + +# Test scenario suggestion by kib@ + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 +[ `uname -p` != "amd64" ] && exit 0 + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap39.c +mycc -o mmap39 -Wall -Wextra -O0 -g mmap39.c -static || exit 1 +rm -f mmap39.c +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 + +for i in `jot 128`; do + $dir/mmap39 & + pids="$pids $!" +done +s=0 +for pid in $pids; do + wait $pid + r=$? + [ $s -ne 0 ] && s=$r +done + +[ -f mmap39.core -a $s -eq 0 ] && + { ls -l mmap39.core; mv mmap39.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 +rm -rf $dir/mmap39 +exit $s + +EOF +#include +#include +#include + +#include +#include +#include +#include + +void +test(void) +{ + size_t i, len; + void *p; + + p = (void *)0x8000000000; /* 512G */ + len = 0x200000; /* 2M */ + if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0)) == + MAP_FAILED) + err(1, "mmap"); + + if (p != (void *)0x8000000000) + errx(1, "mmap address fail"); + + for (i = 0; i < len; i += PAGE_SIZE) + *(char *)(p + i) = 1; + + if (munmap(p, len) == -1) + err(1, "munmap()"); + + _exit(0); +} + +int +main(void) +{ + time_t start; + pid_t pid; + + sleep(5); + start = time(NULL); + while (time(NULL) - start < 120) { + if ((pid = fork()) == 0) + test(); + if (waitpid(pid, NULL, 0) != pid) + err(1, "waitpid"); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mmap4.sh b/tools/test/stress2/misc/mmap4.sh new file mode 100755 index 000000000000..8c84401fb960 --- /dev/null +++ b/tools/test/stress2/misc/mmap4.sh @@ -0,0 +1,116 @@ +#!/bin/sh + +# +# Copyright (c) 2010 Peter Holm +# All rights reserved. +# +# 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 overcommit of the file system capacity +# Causes panic: 1 vncache entries remaining +# Fixed in r202529 + +# Scenario by kib@ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mmap4.c +mycc -o mmap4 -Wall -O2 mmap4.c +rm -f mmap4.c + +mount | grep -q "$mntpoint" && umount $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 40m -u $mdstart +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +/tmp/mmap4 /$mntpoint/file + +cd $here +rm -f /tmp/mmap4 + +while mount | grep -q $mntpoint; do + sync;sync;sync + sleep 1 + umount $mntpoint +done + +mdconfig -d -u $mdstart +exit 0 +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STARTADDR 0x0U +#define ADRSPACE 0x06400000U /* 100 Mb */ + +int +main(int argc, char **argv) +{ + int fd, ps; + void *p; + size_t len; + volatile char *c; + char *path; + + p = (void *)STARTADDR; + len = ADRSPACE; + + 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(p, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == + MAP_FAILED) { + if (errno == ENOMEM) + return (1); + err(1, "mmap(1)"); + } + + c = p; + ps = getpagesize(); + for (c = p; (void *)c < p + len; c += ps) { + *c = 1; + } + + close(fd); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap40.sh b/tools/test/stress2/misc/mmap40.sh new file mode 100755 index 000000000000..4bf60fc8f44d --- /dev/null +++ b/tools/test/stress2/misc/mmap40.sh @@ -0,0 +1,159 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +# Attempt to reproduce "vm_page_assert_xbusied: page XXXX not exclusive busy" +# No problems seen. + +# Test scenario idea by markj@ + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 +[ `sysctl -n vm.swap_total` -eq 0 ] && exit 0 + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap40.c +mycc -o mmap40 -Wall -Wextra -O0 -g mmap40.c || exit 1 +rm -f mmap40.c +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 + +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 + sleep 1 +done + +$dir/mmap40 +s=0 +while pkill swap; do :; done +wait +[ -f mmap40.core -a $s -eq 0 ] && + { ls -l mmap40.core; mv mmap40.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 +rm -rf $dir/mmap40 +exit $s + +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define PARALLEL 512 +#define RUNTIME 300 + +void +test(void) +{ + pid_t pid; + size_t i, len; + time_t start; + void *p; + char *vec; + + len = 1024 * 1024; + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0)) == + MAP_FAILED) + err(1, "mmap"); + memset(p, 0, len); /* dirty the memory */ + if ((vec = malloc(len / PAGE_SIZE)) == NULL) + err(1, "malloc"); + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + usleep(arc4random() % 1000); + if (mincore(p, len, vec) == -1) + err(1, "mincore"); + for (i = 0; i < len / PAGE_SIZE; i++) { + if ((vec[i] & MINCORE_MODIFIED) == 0) { + _exit(0); + } + } + if ((pid = fork()) == 0) { + _exit(0); + } + if (waitpid(pid, NULL, 0) != pid) + err(1, "waitpid)"); + } + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + time_t start; + int i; + + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], NULL, WNOHANG) == pids[i]) { + if ((pids[i] = fork()) == 0) + test(); + } + } + } + + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], NULL, 0) != pids[i]) + err(1, "waitpid"); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mmap5.sh b/tools/test/stress2/misc/mmap5.sh new file mode 100755 index 000000000000..e6dee6d551de --- /dev/null +++ b/tools/test/stress2/misc/mmap5.sh @@ -0,0 +1,129 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 scenario inspired by alc@ +# "panic: vm_page_dirty: page is invalid!" seen. +# Fixed in r255396. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap5.c +mycc -o mmap5 -Wall -Wextra mmap5.c || exit 1 +rm -f mmap5.c +cd $odir + +cp /tmp/mmap5 /tmp/mmap5.inputfile +(cd ../testcases/swap; ./swap -t 1m -i 2) & +cp /tmp/mmap5 /tmp/mmap5.inputfile +/tmp/mmap5 /tmp/mmap5.inputfile +while killall -9 swap; do + sleep .1 +done > /dev/null 2>&1 +wait +rm -f /tmp/mmap5 /tmp/mmap5.inputfile +exit + +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char *file; + +void +test2(void) +{ + struct stat st; + char *p; + size_t len; + int error, fd; + + 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"); + p[arc4random() % len] = 1; + if (arc4random() % 100 < 50) + if ((error = mlock(p, len)) == -1) + err(1, "mlock"); + p[arc4random() % len] = 1; + if (arc4random() % 100 < 50) + if ((error = msync(p, len, MS_SYNC | MS_INVALIDATE)) == -1) + if (errno != EBUSY) + err(1, "msync"); + if (munmap(p, len) == -1) + err(1, "unmap()"); + close(fd); + _exit(0); + +} + +void +test(void) +{ + int i; + + for (i = 0; i < 3; i++) + if (fork() == 0) + test2(); + for (i = 0; i < 3; i++) + wait(NULL); + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + int i; + + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + file = argv[1]; + + for (i = 0; i < 30000; i++) { + if (fork() == 0) + test(); + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mmap6.sh b/tools/test/stress2/misc/mmap6.sh new file mode 100755 index 000000000000..e9efbbea5f8a --- /dev/null +++ b/tools/test/stress2/misc/mmap6.sh @@ -0,0 +1,179 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 scenario inspired by alc@ +# "panic: vm_page_dirty: page is invalid!" seen. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/wire_no_page.c +mycc -o mmap6 -Wall -Wextra wire_no_page.c || exit 1 +rm -f wire_no_page.c +cd $odir + +cp /tmp/mmap6 /tmp/mmap6.inputfile +(cd ../testcases/swap; ./swap -t 5m -i 2) & +cp /tmp/mmap6 /tmp/mmap6.inputfile +/tmp/mmap6 /tmp/mmap6.inputfile +while killall -9 swap; do + sleep .1 +done > /dev/null 2>&1 +wait +rm -f /tmp/mmap6 /tmp/mmap6.inputfile +exit 0 + +EOF +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define RUNTIME 300 + +const char *file; +char c; + +void +rd(void) +{ + struct stat st; + char *p1, *p2; + size_t len; + int error, fd; + + if ((fd = open(file, O_RDONLY)) == -1) + err(1, "open %s", file); + if ((error = fstat(fd, &st)) == -1) + err(1, "stat(%s)", file); + len = round_page(st.st_size); + if ((p1 = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) + err(1, "mmap"); + if ((p2 = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED) + err(1, "mmap"); + c = p1[arc4random() % len]; + c = p2[arc4random() % len]; + if (arc4random() % 100 < 50) + if ((error = mlock(p1, len)) == -1) + err(1, "mlock"); + c = p1[arc4random() % len]; + if (munmap(p2, len) == -1) + err(1, "unmap()"); + if (munmap(p1, len) == -1) + err(1, "unmap()"); + close(fd); + +} +void +wr(void) +{ + struct stat st; + char *p1, *p2; + size_t len; + int error, fd; + + 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 ((p1 = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == + MAP_FAILED) + err(1, "mmap"); + if ((p2 = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == + MAP_FAILED) + err(1, "mmap"); + p1[arc4random() % len] = 1; + p2[arc4random() % len] = 1; + if (arc4random() % 100 < 50) + if ((error = mlock(p1, len)) == -1) + err(1, "mlock"); + p1[arc4random() % len] = 1; + if (arc4random() % 100 < 50) + if ((error = msync(p1, len, MS_SYNC | MS_INVALIDATE)) == -1) + if (errno != EBUSY) + err(1, "msync"); + if (munmap(p2, len) == -1) + err(1, "unmap()"); + if (munmap(p1, len) == -1) + err(1, "unmap()"); + close(fd); + +} + +void +test2(void) +{ + if (arc4random() % 100 < 30) + rd(); + else + wr(); + _exit(0); +} + +void +test(void) +{ + int i; + + for (i = 0; i < 3; i++) + if (fork() == 0) + test2(); + for (i = 0; i < 3; i++) + wait(NULL); + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + time_t start; + + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + file = argv[1]; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if (fork() == 0) + test(); + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mmap7.sh b/tools/test/stress2/misc/mmap7.sh new file mode 100755 index 000000000000..7d467c715203 --- /dev/null +++ b/tools/test/stress2/misc/mmap7.sh @@ -0,0 +1,147 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 scenario inspired by alc@ +# Threaded version in order to "use the same pmap", as pointed out by kib@ + +# https://people.freebsd.org/~pho/stress/log/kostik601.txt +# Fixed by r255396 + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/wire_no_page.c +mycc -o mmap7 -Wall -Wextra wire_no_page.c -lpthread || exit 1 +rm -f wire_no_page.c +cd $odir + +(cd ../testcases/swap; ./swap -t 1m -i 2) & +sleep 1 +cp /tmp/mmap7 /tmp/mmap7.inputfile +/tmp/mmap7 /tmp/mmap7.inputfile +while pkill -9 swap; do :; done +wait +rm -f /tmp/mmap7 /tmp/mmap7.inputfile +exit + +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char *p1, *p2, *p3; +char c; +const char *file; +int fd; +size_t len; +struct stat st; + +void * +test2(void *arg __unused) +{ + int error, i; + + p1[arc4random() % len] = 1; + p2[arc4random() % len] = 1; + + if (arc4random() % 100 < 30) + i = p3[arc4random() % len]; + + if (arc4random() % 100 < 50) + if ((error = mlock(p1, len)) == -1) + err(1, "mlock"); + if (arc4random() % 100 < 50) + if ((error = msync(p1, len, MS_SYNC | MS_INVALIDATE)) == -1) + if (errno != EBUSY) + err(1, "msync"); + return (0); +} + +void +test(void) +{ + pthread_t cp[3]; + int e, error, i; + + 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 ((p1 = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) + err(1, "mmap"); + if ((p2 = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == MAP_FAILED) + err(1, "mmap"); + if ((p3 = mmap(NULL, len, PROT_READ , MAP_SHARED, fd, 0)) == MAP_FAILED) + err(1, "mmap"); + + for (i = 0; i < 3; i++) + if ((e = pthread_create(&cp[i], NULL, test2, NULL)) != 0) + errc(1, e, "pthread_create"); + for (i = 0; i < 3; i++) + pthread_join(cp[i], NULL); + + if (munmap(p3, len) == -1) + err(1, "unmap()"); + if (munmap(p2, len) == -1) + err(1, "unmap()"); + if (munmap(p1, len) == -1) + err(1, "unmap()"); + close(fd); + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + int i; + + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + file = argv[1]; + + for (i = 0; i < 30000; i++) { + if (fork() == 0) + test(); + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/mmap8.sh b/tools/test/stress2/misc/mmap8.sh new file mode 100755 index 000000000000..e8fd631ed1e6 --- /dev/null +++ b/tools/test/stress2/misc/mmap8.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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: vm_fault_copy_wired: page missing" seen: +# http://people.freebsd.org/~pho/stress/log/mmap8.txt +# Fixed in r265002. + +# Test scenario by: Mark Johnston markj@ + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap8.c +# At one point during the fix development, only the thread version would panic +mycc -o mmap8 -Wall -Wextra mmap8.c || exit 1 +mycc -o mmap8p -Wall -Wextra mmap8.c -pthread || exit 1 +rm -f mmap8.c +cd $odir + +/tmp/mmap8p +/tmp/mmap8 + +rm -f /tmp/mmap8 /tmp/mmap8p +exit + +EOF +#include +#include + +#include +#include +#include + +int +main(void) +{ + size_t sz = 1; + char *addr; + +/* + * This is the minimum amount of C code it takes to panic the kernel. + * This is as submitted and thus not a complete and correct test program. + */ + addr = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON, -1, 0); + if (addr == NULL) + err(1, "mmap"); + memset(addr, 0, sz); + + if (fork() != 0) { + if (mprotect(addr, sz, PROT_READ)) + err(1, "mprotect"); + if (mlock(addr, sz)) + err(1, "mlock"); + if (mprotect(addr, sz, PROT_WRITE | PROT_READ)) + err(1, "mprotect"); + if (munmap(addr, sz)) + err(1, "munmap"); + } else + sleep(1); + + return (0); +} diff --git a/tools/test/stress2/misc/mmap9.sh b/tools/test/stress2/misc/mmap9.sh new file mode 100755 index 000000000000..8608df01cb0c --- /dev/null +++ b/tools/test/stress2/misc/mmap9.sh @@ -0,0 +1,95 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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: vm_map_protect: object 0xca6869c0 overcharged" seen: +# http://people.freebsd.org/~pho/stress/log/mmap9.txt +# Fixed in r265843 + +# Test scenario by: Mark Johnston markj@ + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/mmap9.c +# At one point during the fix development, only the thread version would panic +mycc -o mmap9 -O2 -Wall -Wextra mmap9.c || exit 1 +mycc -o mmap9p -O2 -Wall -Wextra mmap9.c -lpthread || exit 1 +rm -f mmap9.c +cd $odir + +/tmp/mmap9 +/tmp/mmap9p + +rm -f /tmp/mmap9 /tmp/mmap9p +exit + +EOF +#include +#include + +#include +#include +#include + +int +main(void) +{ + size_t sz = 1; + char *addr; + +/* + * This is the minimum amount of C code it takes to panic the kernel. + * This is as submitted and thus not a complete and correct test program. + */ + addr = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_ANON, + -1, 0); + if (addr == NULL) + err(1, "mmap"); + memset(addr, 0, sz); + + if (fork() != 0) { + if (mlock(addr, sz)) + err(1, "mlock"); + if (mprotect(addr, sz, PROT_READ)) + err(1, "mprotect"); + if (mprotect(addr, sz, PROT_READ | PROT_WRITE)) + err(1, "mprotect"); + if (mprotect(addr, sz, PROT_READ)) + err(1, "mprotect"); + if (mprotect(addr, sz, PROT_READ | PROT_WRITE)) + err(1, "mprotect"); + } else + /* + * Ensure that shadow objects aren't collapsed by process exit. + */ + sleep(1); + + return (0); +} diff --git a/tools/test/stress2/misc/mount.sh b/tools/test/stress2/misc/mount.sh new file mode 100755 index 000000000000..4b020ca919bd --- /dev/null +++ b/tools/test/stress2/misc/mount.sh @@ -0,0 +1,82 @@ +#!/bin/sh +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Mount regression test + +# panic: vm_fault: fault on nofault entry, addr: deadc000 +# cpuid = 1 +# KDB: enter: panic +# [thread pid 69453 tid 100388 ] +# Stopped at kdb_enter+0x2b: nop +# db> where +# Tracing pid 69453 tid 100388 td 0xc4b5c1b0 +# kdb_enter(c091d9db) at kdb_enter+0x2b +# panic(c0938fa0,deadc000,e6b44834,c06c650e,c0a57d20,...) at panic+0x14b +# vm_fault(c1869000,deadc000,1,0) at vm_fault+0x1e0 +# trap_pfault(e6b4499c,0,deadc112) at trap_pfault+0x137 +# trap(8,c0910028,28,deadc0de,deadc0de,...) at trap+0x3f5 +# calltrap() at calltrap+0x5 +# --- trap 0xc, eip = 0xc0667def, esp = 0xe6b449dc, ebp = 0xe6b44a00 --- +# g_io_request(c66d6bdc,c4a1d840,d7c99940,d7c99940,e6b44a34,...) at g_io_request+0x5f +# g_vfs_strategy(c40624c4,d7c99940,d7c99940,0,c4e16dec,...) at g_vfs_strategy+0x49 +# ffs_geom_strategy(c40624c4,d7c99940,4ba0,0,c09dad00,...) at ffs_geom_strategy+0x141 +# ufs_strategy(e6b44a7c) at ufs_strategy+0xb5 +# VOP_STRATEGY_APV(c09da7c0,e6b44a7c) at VOP_STRATEGY_APV+0x95 +# bufstrategy(c50d2be0,d7c99940) at bufstrategy+0x55 +# breadn(c50d2b2c,0,0,1000,0,...) at breadn+0xf7 +# bread(c50d2b2c,0,0,1000,0,...) at bread+0x20 +# ffs_read(e6b44bb0) at ffs_read+0x23f +# VOP_READ_APV(c09da7c0,e6b44bb0) at VOP_READ_APV+0x7e +# ufs_readdir(e6b44c38) at ufs_readdir+0xd1 +# VOP_READDIR_APV(c09da7c0,e6b44c38) at VOP_READDIR_APV+0x7e +# getdirentries(c4b5c1b0,e6b44d04) at getdirentries+0x13f +# syscall(3b,3b,3b,8240160,1,...) at syscall+0x256 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep -q "$mntpoint" && umount $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null + +# The test: + +echo "Expect: mount: /dev/md5a: Device busy" +mount -r /dev/md${mdstart}$part $mntpoint +mount -r /dev/md${mdstart}$part $mntpoint +umount $mntpoint + +ls -lR $mntpoint > /dev/null # panic + +# End of test +mount | grep -q "$mntpoint" && umount $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/mount2.sh b/tools/test/stress2/misc/mount2.sh new file mode 100755 index 000000000000..d4b30bafe711 --- /dev/null +++ b/tools/test/stress2/misc/mount2.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Stress test by performing parallel calls to mount and umount. Alternate +# between forced and non-forced unmounts. + +# "kernel: g_dev_taste: make_dev_p() failed (gp->name=md10, error=17)" seen. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mounts=15 # Number of parallel scripts +D=$diskimage + +for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + [ ! -d ${mntpoint}$m ] && mkdir ${mntpoint}$m + mount | grep "$mntpoint" | grep -q md$m && + umount ${mntpoint}$m + mdconfig -l | grep -q md$m && mdconfig -d -u $m + + dd if=/dev/zero of=$D$m bs=1m count=1 status=none + mdconfig -a -t vnode -f $D$m -u $m || { rm -f $D$m; exit 1; } + bsdlabel -w md$m auto + newfs md${m}$part > /dev/null +done + +# start the parallel tests +for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + start=`date +%s` + while [ $((`date +%s` - start)) -lt 300 ]; do + opt=`[ $(( m % 2 )) -eq 0 ] && echo -f` + mount /dev/md${m}$part ${mntpoint}$m + while mount | grep -q ${mntpoint}$m; do + umount $opt ${mntpoint}$m > /dev/null 2>&1 + done + done & +done +wait + +for i in `jot $mounts`; do + m=$((i + mdstart - 1)) + mdconfig -d -u $m + rm -f $D$m +done +exit 0 diff --git a/tools/test/stress2/misc/mountro.sh b/tools/test/stress2/misc/mountro.sh new file mode 100755 index 000000000000..38f6c6e5bd10 --- /dev/null +++ b/tools/test/stress2/misc/mountro.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2011 Peter Holm +# All rights reserved. +# +# 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. +# + +# Page fault seen: https://people.freebsd.org/~pho/stress/log/mountro.txt +# Fixed by r346031 + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +D=$diskimage +dd if=/dev/zero of=$D bs=1m count=128 status=none || exit 1 + +mount | grep "$mntpoint " | grep -q /md && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart || { rm -f $D; exit 1; } + +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null 2>&1 +mount /dev/md${mdstart}$part $mntpoint + +mkdir $mntpoint/stressX +chmod 777 $mntpoint/stressX + +export RUNDIR=$mntpoint/stressX +export runRUNTIME=4m +(cd ..; ./run.sh disk.cfg > /dev/null 2>&1) & +sleep 10 + +for i in `jot 10`; do + mount -u -o ro $mntpoint + sleep 3 + mount -u -o rw $mntpoint + sleep 3 +done > /dev/null 2>&1 + +umount -f $mntpoint +mdconfig -d -u $mdstart +rm -f $D +pkill run.sh +wait diff --git a/tools/test/stress2/misc/mountro2.sh b/tools/test/stress2/misc/mountro2.sh new file mode 100755 index 000000000000..a57c6776fb03 --- /dev/null +++ b/tools/test/stress2/misc/mountro2.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 scenario by Matthew D. Fuller + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +D=$diskimage +dd if=/dev/zero of=$D bs=1m count=20 status=none || exit + +mount | grep "$mntpoint" | grep -q /md && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart || { rm -f $D; exit 1; } + +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null 2>&1 +mount /dev/md${mdstart}$part $mntpoint + +mtree -deU -f /etc/mtree/BSD.usr.dist -p $mntpoint/ >> /dev/null +sync ; sync ; sync + +rm -rf $mntpoint/* +mount -u -o ro $mntpoint + +umount -f $mntpoint > /dev/null 2>&1 +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/mountro3.sh b/tools/test/stress2/misc/mountro3.sh new file mode 100755 index 000000000000..e1749dfdc391 --- /dev/null +++ b/tools/test/stress2/misc/mountro3.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 scenario by barbara +# kern/121809: unable to umount + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +D=$diskimage +dd if=/dev/zero of=$D bs=1m count=64 status=none || exit 1 + +mount | grep "$mntpoint" | grep md${mdstart}$part > /dev/null && umount $mntpoint +mdconfig -l | grep md$mdstart > /dev/null && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart || { rm -f $D; exit 1; } +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null 2>&1 + +mount /dev/md${mdstart}$part $mntpoint +touch $mntpoint/file +umount $mntpoint + +mount /dev/md${mdstart}$part $mntpoint +rm $mntpoint/file +mount -u -o ro $mntpoint # Should fail with "Device busy" + +umount $mntpoint +mdconfig -d -u $mdstart +rm -f $D diff --git a/tools/test/stress2/misc/mountro4.sh b/tools/test/stress2/misc/mountro4.sh new file mode 100755 index 000000000000..b6ff922d5ff9 --- /dev/null +++ b/tools/test/stress2/misc/mountro4.sh @@ -0,0 +1,100 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# Check that the time stamps are not updated for a RO mount. + +. ../default.cfg + +f1=$mntpoint/f1 +f2=$mntpoint/f2 +s=0 + +# ufs +mount | grep -q "on $mntpoint " && umount $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart +newfs $newfs_flags /dev/md$mdstart > /dev/null +mount /dev/md$mdstart $mntpoint || exit 1 +touch $f1 +mount -u -o ro $mntpoint +touch $f2 2>/dev/null && { echo "ufs: ro failed"; s=1; } +d1=`stat -f '%a %m %c' $f1` +sleep 1 +cat $f1 > /dev/null +d2=`stat -f '%a %m %c' $f1` +if [ "$d1" != "$d2" ]; then + echo "ufs: Access time was updated. $d1 != $d2" + s=1 +fi +mount -u -o rw $mntpoint +touch $f2 2>/dev/null || { echo "ufs: rw failed"; s=1; } +umount $mntpoint +mdconfig -d -u $mdstart + +# tmpfs +mount -o size=100m -t tmpfs null $mntpoint || exit 1 +touch $f1 +mount -u -o ro $mntpoint +touch $f2 2>/dev/null && { echo "tmpfs: ro failed"; s=1; } +d1=`stat -f '%a %m %c' $f1` +sleep 1 +cat $f1 > /dev/null +d2=`stat -f '%a %m %c' $f1` +if [ "$d1" != "$d2" ]; then + echo "tmpfs: Access time was updated. $d1 != $d2" + s=1 +fi +mount -u -o rw $mntpoint +touch $f2 2>/dev/null || { echo "tmpfs: rw failed"; s=1; } +umount $mntpoint + +# msdosfs +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs_msdos /dev/md${mdstart}$part > /dev/null +mount -t msdosfs /dev/md${mdstart}$part $mntpoint || exit 1 + +touch $f1 +mount -u -o ro $mntpoint +touch $f2 2>/dev/null && { echo "msdosfs: ro failed"; s=1; } +d1=`stat -f '%a %m %c' $f1` +sleep 1 +cat $f1 > /dev/null +d2=`stat -f '%a %m %c' $f1` +if [ "$d1" != "$d2" ]; then + echo "msdosfs: Access time was updated. $d1 != $d2" + s=1 +fi +mount -u -o rw $mntpoint +touch $f2 2>/dev/null || { echo "msdosfs: rw failed"; s=1; } +umount $mntpoint +mdconfig -d -u $mdstart + +exit $s diff --git a/tools/test/stress2/misc/mountro5.sh b/tools/test/stress2/misc/mountro5.sh new file mode 100755 index 000000000000..67663df54145 --- /dev/null +++ b/tools/test/stress2/misc/mountro5.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# Toggle a tmpfs file system rw / ro. +# No problems seen. + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +mount | grep "on $mntpoint " | grep -q /md && umount -f $mntpoint +mount -t tmpfs null $mntpoint + +mkdir $mntpoint/stressX +chmod 777 $mntpoint/stressX + +export RUNDIR=$mntpoint/stressX +export CTRLDIR=$mntpoint/stressX.control +export runRUNTIME=4m +export TESTPROGS="testcases/swap/swap testcases/creat/creat \ + testcases/mkdir/mkdir testcases/rw/rw" +(cd ..; ./testcases/run/run $TESTPROGS > /dev/null 2>&1) & +sleep 10 + +start=`date +%s` +while [ $((`date +%s` - start)) -lt 60 ]; do + mount -fu -o ro $mntpoint + sleep .5 + mount -u -o rw $mntpoint + sleep .5 +done + +../tools/killall.sh +wait +while mount | grep -q "on $mntpoint "; do + umount $mntpoint +done diff --git a/tools/test/stress2/misc/mountro6.sh b/tools/test/stress2/misc/mountro6.sh new file mode 100755 index 000000000000..398cbeed4fea --- /dev/null +++ b/tools/test/stress2/misc/mountro6.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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 rw->ro remount when there is a text vnode mapping. +# Fixed by: r347968 + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && 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 + +cd $mntpoint +cp /bin/sleep . +./sleep 20 & +cd / +sleep .1 +mount -u -o ro $mntpoint || s=1 +wait +for i in `jot 5`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 5 +done +mount | grep -q "on $mntpoint " && { umount -f $mntpoint; s=2; } +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/mountu.sh b/tools/test/stress2/misc/mountu.sh new file mode 100755 index 000000000000..1c1b619463cd --- /dev/null +++ b/tools/test/stress2/misc/mountu.sh @@ -0,0 +1,284 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2012 Peter Holm +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# Change mount point from rw to ro with a file mapped rw +# Currently fails for NFS + +# Page fault seen: +# https://people.freebsd.org/~pho/stress/log/mountu.txt +# Fixed by: r285039. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > mountu.c +mycc -o mountu -Wall -Wextra -O2 mountu.c || exit 1 +rm -f mountu.c + +pstat() { + local pid + pid=`ps ax | grep -v grep | grep /tmp/mountu | awk '{print $1}'` + [ -n "$pid" ] && procstat -v $pid +} + +ck() { + if mount | grep $mntpoint | grep -q "read-only"; then + if pstat $!| awk "\$2 == \"$map\"" | grep -q " rw-"; then + echo + echo "$1 difference" + mount | grep $mntpoint + printf "RW mount mapping and RO mount mapping:\n%s\n" "$r" + pstat $! | awk "\$2 == \"$map\"" + status=$((status + 1)) + fi + else + echo "$1 mount point RO did not succeed" + mount | grep $mntpoint + status=$((status + 1)) + fi +} + +status=0 +file=$mntpoint/mountu.sh.file +mapfile=/tmp/mountu.sh.map +mount | grep -q "$mntpoint " && umount $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 100m -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +# ufs +exec 5>$mapfile +/tmp/mountu UFS $file & +pid=$! +sleep 1 +map=`cat $mapfile`; rm $mapfile; exec 5>&- + +r=`pstat $! | awk "\\$2 == \"$map\""` +mount -u -o ro $mntpoint 2>/dev/null || mount -fu -o ro $mntpoint +ck UFS +mount -u -o rw $mntpoint +rm -f $file +wait $pid +s=$? +[ $s -ne 139 ] && { echo "UFS exit status is $s"; status=1; } +while mount | grep -q "$mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart + +# nfs +if ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1; then + mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export \ + $mntpoint + sleep .2 + rm -f $file + /tmp/mountu NFS $file & + pid=$! + sleep 1 + + r=`pstat $! | awk "\\$2 == \"$map\""` + mount -u -o ro $mntpoint 2>/dev/null || + mount -fu -o ro $mntpoint 2>/dev/null + ck NFS + wait $pid + s=$? + [ $s -ne 139 ] && { echo "NFS exit status is $s"; status=1; } + + mount -u -o rw $mntpoint 2>/dev/null + sleep .2 + [ -f $file ] && rm -f $file + umount $mntpoint || umount $mntpoint +fi + +# msdos +if [ -x /sbin/mount_msdosfs ]; then + mdconfig -a -t swap -s 100m -u $mdstart + bsdlabel -w md$mdstart auto + newfs_msdos -F 16 -b 8192 /dev/md${mdstart}$part > /dev/null 2>&1 + mount_msdosfs -m 777 /dev/md${mdstart}$part $mntpoint + /tmp/mountu MSDOS $file & + pid=$! + + sleep 1 + r=`pstat $! | awk "\\$2 == \"$map\""` + mount -u -o ro $mntpoint 2>/dev/null || mount -fu -o ro $mntpoint + ck MSDOS + wait $pid + s=$? + [ $s -ne 139 ] && { echo "MSDOS exit status is $s"; status=1; } + mount -u -o rw $mntpoint + rm -f $file + + while mount | grep -q "$mntpoint "; do + umount $mntpoint || sleep 1 + done + mdconfig -d -u $mdstart +fi + +# tmpfs +mount -t tmpfs null $mntpoint +chmod 777 $mntpoint + +/tmp/mountu TMPFS $file & +pid=$! + +sleep 1 +r=`pstat $! | awk "\\$2 == \"$map\""` +mount -u -o ro $mntpoint 2>/dev/null || mount -fu -o ro $mntpoint +ck TMPFS +sleep 1 +mount -u -o rw $mntpoint +rm -f $file +wait $pid +s=$? +[ $s -ne 139 ] && { echo "TMPFS exit status is $s"; status=1; } +while mount | grep -q "$mntpoint "; do + umount $mntpoint || sleep 1 +done + +rm -f /tmp/mountu +exit 0 +EOF +/* kib@ noted: + UFS/NFS/msdosfs reclaim vnode on rw->ro forced remount, and + change the type of the underying object to OBJT_DEAD, but leave + the pages on the object queue and installed in the page tables. + Applications can read/write already mapped pages, but cannot + page in new pages, cannot observe possible further modifications + to already mapped pages (if ro->rw remount happen later), and + their updates to pages are not flushed to file. + + It is impossible to mimic this behaviour for tmpfs. + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define STARTADDR 0x0U +#define ADRSPACE 0x0640000U + +static void +sighandler(int signo, siginfo_t *si, void *uc1) +{ + ucontext_t *uc; + + uc = uc1; + printf("SIG%s at %p, addr %p\n", sys_signame[signo], si->si_addr, +#if defined(__i386__) + (void *)uc->uc_mcontext.mc_eip); +#else + (void *)uc->uc_mcontext.mc_rip); +#endif + exit(1); +} + +int +main(int argc __unused, char **argv) +{ + struct passwd *pw; + struct sigaction sa; + void *p; + size_t len; + int fd; + char *name, *path; + volatile char *c; + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = sighandler; + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGSEGV, &sa, NULL) == -1) + err(1, "sigaction(SIGSEGV)"); + if (sigaction(SIGBUS, &sa, NULL) == -1) + err(1, "sigaction(SIGBUS)"); + + if ((pw = getpwnam("nobody")) == NULL) + err(1, "no such user: nobody"); + + 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(); + + p = (void *)STARTADDR; + len = ADRSPACE; + + name = argv[1]; + path = argv[2]; + if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0622)) == -1) + err(1,"open(%s)", path); + if (ftruncate(fd, len) == -1) + err(1, "ftruncate"); + if ((p = mmap(p, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == + MAP_FAILED) { + if (errno == ENOMEM) { + warn("mmap()"); + return (1); + } + err(1, "mmap(1)"); + } + dprintf(5, "%p\n", p); + + for (c = p; (void *)c < p + len; c += PAGE_SIZE) { + *c = 1; + } + + close(fd); + sleep(5); + fprintf(stderr, "%s: Late read start.\n", name); + for (c = p; (void *)c < p + len; c += PAGE_SIZE) { + *c; + } + fprintf(stderr, "%s: Late read complete.\n", name); + + fprintf(stderr, "%s: Late write start.\n", name); + for (c = p; (void *)c < p + len; c += PAGE_SIZE) { + *c = 1; + } + fprintf(stderr, "%s: Late write complete.\n", name); + + return (0); +} diff --git a/tools/test/stress2/misc/mprotect.sh b/tools/test/stress2/misc/mprotect.sh new file mode 100755 index 000000000000..9fde68de56ec --- /dev/null +++ b/tools/test/stress2/misc/mprotect.sh @@ -0,0 +1,75 @@ +#!/bin/sh +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 Mark Johnston +# +# 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: pmap_demote_pde: page table page for a wired mapping +# is missing" seen. + +# Fixed by r345382 + +. ../default.cfg + +cd /tmp +cat > mprotect.c < + +#include +#include + +int +main(void) +{ + char *addr, c; + size_t i, len; + + len = 2 * 1024 * 1024; + addr = mmap(NULL, 2 * 1024 * 1024, PROT_READ, + MAP_ANON | MAP_ALIGNED_SUPER, -1, 0); + if (addr == MAP_FAILED) + err(1, "mmap"); + if (mlock(addr, len) != 0) /* hopefully this gets a superpage */ + err(1, "mlock"); + if (mprotect(addr, len, PROT_NONE) != 0) + err(1, "mprotect"); + if (mprotect(addr, len, PROT_READ) != 0) + err(1, "mprotect"); + for (i = 0; i < len; i++) /* preemptive superpage mapping */ + c = *(volatile char *)(addr + i); + if (mprotect(addr, 4096, PROT_NONE) != 0) /* trigger demotion */ + err(1, "mprotect"); + if (munlock(addr, len) != 0) + err(1, "munlock"); + + return (0); +} +EOF +mycc -o mprotect -Wall -Wextra -O2 mprotect.c || exit 1 + +./mprotect; s=$? + +rm mprotect.c mprotect +exit $s diff --git a/tools/test/stress2/misc/mprotect2.sh b/tools/test/stress2/misc/mprotect2.sh new file mode 100755 index 000000000000..c5cdc44a0f39 --- /dev/null +++ b/tools/test/stress2/misc/mprotect2.sh @@ -0,0 +1,97 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# Test scenario suggestion by alc@ + +. ../default.cfg + +cd /tmp +cat > mprotect2.c < +#include + +#include +#include +#include +#include +#include +#include + +#define SIZ 0x40000000LL /* 1GB */ + +static void +test(void) +{ + size_t i, len; + char *cp; + + len = SIZ; + if ((cp = mmap(NULL, len, PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0)) + == MAP_FAILED) + err(1, "mmap"); + + for (i = 0; i < SIZ; i += PAGE_SIZE * 2) { + if (mprotect(cp + i, PAGE_SIZE, 0) != 0) + err(1, "mprotect(). %d", __LINE__); + } + if (mprotect(cp, SIZ, PROT_WRITE) != 0) + err(1, "mprotect(). %d", __LINE__); + + if (munmap(cp, SIZ) == -1) + err(1, "munmap()"); +} + +int +main(void) +{ + int i; + + /* Slow run with debug.vmmap_check=1 */ + alarm(120); + + for (i = 0; i < 64; i++) + test(); + + return (0); +} +EOF +mycc -o mprotect2 -Wall -Wextra -O2 mprotect2.c || exit 1 + +./mprotect2; s=$? + +rm mprotect2.c mprotect2 +exit $s diff --git a/tools/test/stress2/misc/msdos.sh b/tools/test/stress2/misc/msdos.sh new file mode 100755 index 000000000000..2324404bfd16 --- /dev/null +++ b/tools/test/stress2/misc/msdos.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2010 Peter Holm +# All rights reserved. +# +# 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 + +# LOR seen. Fixed by r204467. + +. ../default.cfg + +[ -x /sbin/mount_msdosfs ] || exit +log=/tmp/msdos.sh.log +mount | grep "$mntpoint" | grep -q md$mdstart && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs_msdos /dev/md${mdstart}$part > /dev/null +mount -t msdosfs /dev/md${mdstart}$part $mntpoint + +export RUNDIR=$mntpoint/stressX +export runRUNTIME=10m # Run tests for 10 minutes +(cd ..; ./run.sh disk.cfg) + +while mount | grep "$mntpoint" | grep -q md$mdstart; do + umount $mntpoint || sleep 1 +done +fsck -t msdosfs -y /dev/md${mdstart}$part > $log 2>&1 +s=0 +if egrep -q "BAD|INCONSISTENCY|MODIFIED" $log; then + cat $log + rm $log + s=1 +fi +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/msdos10.sh b/tools/test/stress2/misc/msdos10.sh new file mode 100755 index 000000000000..09613a859082 --- /dev/null +++ b/tools/test/stress2/misc/msdos10.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# fsx test of with msdosfs and a 1k block size +# "panic: Assertion ma[i]->dirty == VM_PAGE_BITS_ALL failed" seen. +# Fixed by r324794 + +# Original test scenario by fsu@freebsd.org + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 +[ -r /usr/src/tools/regression/fsx/fsx.c ] || exit 0 + +[ -x /sbin/mount_msdosfs ] || exit 0 +dir=/tmp +odir=`pwd` +cd $dir +cc -o fsx -Wall -Wextra -O2 -g /usr/src/tools/regression/fsx/fsx.c || exit 1 +rm -f fsx.c +cd $odir +log=/tmp/fsx.sh.log +mount | grep "$mntpoint" | grep -q md$mdstart && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +set -e +mdconfig -a -t swap -s 4g -u $mdstart +bsdlabel -w md$mdstart auto +newfs_msdos -b 1024 /dev/md${mdstart}$part > /dev/null +mount -t msdosfs /dev/md${mdstart}$part $mntpoint +set +e + +cp /tmp/fsx $mntpoint + +cd $mntpoint + +NUM_OPS=2000 +SEED=2016 +( +./fsx -S ${SEED} -N ${NUM_OPS} ./TEST_FILE0 & +./fsx -S ${SEED} -l 5234123 -o 5156343 -N ${NUM_OPS} ./TEST_FILE1 & +./fsx -S ${SEED} -l 2311244 -o 2311200 -N ${NUM_OPS} ./TEST_FILE2 & +./fsx -S ${SEED} -l 8773121 -o 863672 -N ${NUM_OPS} ./TEST_FILE3 & +./fsx -S ${SEED} -l 234521 -o 234521 -N ${NUM_OPS} ./TEST_FILE4 & +./fsx -S ${SEED} -l 454321 -o 33 -N ${NUM_OPS} ./TEST_FILE5 & +./fsx -S ${SEED} -l 7234125 -o 7876728 -N ${NUM_OPS} ./TEST_FILE6 & +wait +) > /dev/null +cd / + +while mount | grep "$mntpoint" | grep -q md$mdstart; do + umount $mntpoint || sleep 1 +done +fsck -t msdosfs -y /dev/md${mdstart}$part > $log 2>&1 +if egrep -q "BAD|INCONSISTENCY|MODIFIED" $log; then + cat $log + s=1 + + mount -t msdosfs /dev/md${mdstart}$part $mntpoint || exit 1 + ls -lR $mntpoint + umount $mntpoint +fi +mdconfig -d -u $mdstart +rm /tmp/fsx $log +exit $s diff --git a/tools/test/stress2/misc/msdos2.sh b/tools/test/stress2/misc/msdos2.sh new file mode 100755 index 000000000000..838585595ec3 --- /dev/null +++ b/tools/test/stress2/misc/msdos2.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# +# Copyright (c) 2010 Peter Holm +# All rights reserved. +# +# 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: __lockmgr_args: recursing on non recursive lockmgr devfs @ ../../../kern/vfs_subr.c:2204 +# Scenario by kib@ + +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -x /sbin/mount_msdosfs ] || exit +mount | grep "$mntpoint" | grep -q md$mdstart && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs_msdos /dev/md${mdstart}$part > /dev/null +mount -t msdosfs /dev/md${mdstart}$part $mntpoint + +u=$((mdstart + 1)) +mdconfig -l | grep -q $u && mdconfig -d -u $u +mdconfig -a -t swap -s 1g -u $u +bsdlabel -w md$u auto +newfs_msdos /dev/md${u}$part > /dev/null +mount -u /dev/md${u}$part $mntpoint > /dev/null 2>&1 # panic + +ls $mntpoint > /dev/null + +while mount | grep "$mntpoint" | grep -q md$mdstart; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +mdconfig -d -u $u diff --git a/tools/test/stress2/misc/msdos3.sh b/tools/test/stress2/misc/msdos3.sh new file mode 100755 index 000000000000..e251f7bf7ee7 --- /dev/null +++ b/tools/test/stress2/misc/msdos3.sh @@ -0,0 +1,52 @@ +#!/bin/sh + +# +# Copyright (c) 2010 Peter Holm +# All rights reserved. +# +# 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. +# + +# Page fault seen +# Scenario by kib@ + +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -x /sbin/mount_msdosfs ] || exit +mount | grep "$mntpoint" | grep -q md$mdstart && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs_msdos /dev/md${mdstart}$part > /dev/null + +mount -t msdosfs /dev/md${mdstart}$part $mntpoint +mount -t msdosfs /dev/md${mdstart}$part $mntpoint || echo OK + +ls $mntpoint > /dev/null + +while mount | grep "$mntpoint" | grep -q md$mdstart; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/msdos4.sh b/tools/test/stress2/misc/msdos4.sh new file mode 100755 index 000000000000..807c3b5206eb --- /dev/null +++ b/tools/test/stress2/misc/msdos4.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +# +# Copyright (c) 2010 Peter Holm +# All rights reserved. +# +# 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 + +# "panic: leaf should be empty" seen + +# "panic: Assertion sq->sq_wchan != NULL" seen: +# https://people.freebsd.org/~pho/stress/log/msdos4.txt + +. ../default.cfg + +[ -x /sbin/mount_msdosfs ] || exit +log=/tmp/msdos4.sh.log +mount | grep "$mntpoint" | grep -q md$mdstart && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs_msdos /dev/md${mdstart}$part > /dev/null +mount -t msdosfs /dev/md${mdstart}$part $mntpoint || exit 1 + +export RUNDIR=$mntpoint/stressX +export runRUNTIME=10m +export TESTPROGS=' +testcases/lockf2/lockf2 +testcases/openat/openat +testcases/rw/rw +testcases/fts/fts +testcases/lockf/lockf +testcases/creat/creat +testcases/mkdir/mkdir +testcases/rename/rename +testcases/swap/swap +' + +(cd ..; ./testcases/run/run $TESTPROGS) + +while mount | grep "$mntpoint" | grep -q md$mdstart; do + umount $mntpoint || sleep 1 +done +fsck -t msdosfs -y /dev/md${mdstart}$part > $log 2>&1 +s=0 +if egrep -q "BAD|INCONSISTENCY|MODIFIED" $log; then + cat $log + rm $log + s=1 +fi +mdconfig -d -u $mdstart +s=0 # Ignore for now +exit $s diff --git a/tools/test/stress2/misc/msdos5.sh b/tools/test/stress2/misc/msdos5.sh new file mode 100755 index 000000000000..815eeca6fd4c --- /dev/null +++ b/tools/test/stress2/misc/msdos5.sh @@ -0,0 +1,59 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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: Freeing unused sector 79510 22 ff800000" seen. +# http://people.freebsd.org/~pho/stress/log/msdos5.txt +# FS corruption seen: http://people.freebsd.org/~pho/stress/log/msdos5-2.txt +# Fixed by r333693. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -x /sbin/mount_msdosfs ] || exit + +. ../default.cfg + +mycc -o /tmp/fstool -Wall -Wextra -O2 ../tools/fstool.c || exit 1 + +cd /tmp +mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 3g -u $mdstart +bsdlabel -w md$mdstart auto +newfs_msdos -F 32 -b 8192 /dev/md${mdstart}$part > /dev/null 2>&1 +mount_msdosfs -m 777 /dev/md${mdstart}$part $mntpoint + +for i in `jot 5`; do + (mkdir $mntpoint/test$i; cd $mntpoint/test$i; /tmp/fstool -l -f 400 -n 200 -s ${i}k) +done + +sleep 1 +rm -rf $mntpoint/* || echo FAIL + +while mount | grep -q "$mntpoint "; do + umount $mntpoint || sleep 1 +done +rm -f /tmp/fstool diff --git a/tools/test/stress2/misc/msdos6.sh b/tools/test/stress2/misc/msdos6.sh new file mode 100755 index 000000000000..475989b3fa1c --- /dev/null +++ b/tools/test/stress2/misc/msdos6.sh @@ -0,0 +1,93 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC Isilon +# All rights reserved. +# +# 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 of file systems + +# "panic: userret: Returning with 1 locks held" seen: +# https://people.freebsd.org/~pho/stress/log/mark165.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mounts=15 # Number of parallel scripts +cont=/tmp/msdos6.continue +mdstart=$mdstart # Use md unit numbers from this point + +if [ $# -eq 0 ]; then + touch $cont + mycc -o /tmp/fstool -Wall -Wextra -O2 ../tools/fstool.c || exit 1 + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + [ ! -d ${mntpoint}$m ] && mkdir ${mntpoint}$m + mount | grep "$mntpoint" | grep -q md$m && umount ${mntpoint}$m + mdconfig -l | grep -q md$m && mdconfig -d -u $m + + mdconfig -a -t swap -s 1g -u $m + bsdlabel -w md$m auto + newfs_msdos -F 32 -b 8192 /dev/md${m}$part > /dev/null 2>&1 + mount -t msdosfs /dev/md${m}$part ${mntpoint}$m + (mkdir ${mntpoint}$m/test$i; cd ${mntpoint}$m/test$i; /tmp/fstool -l -f 100 -n 100 -s ${i}k) + umount ${mntpoint}$m > /dev/null 2>&1 + done + + # start the parallel tests + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + ./$0 $m & + ./$0 find & + done + + wait + + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + mdconfig -d -u $m + done + rm -f /tmp/fstool + +else + if [ $1 = find ]; then + while [ -r $cont ]; do + find ${mntpoint}* -type f > /dev/null 2>&1 + done + else + + # The test: Parallel mount and unmounts + start=`date '+%s'` + while [ $((`date '+%s'` - start)) -lt 300 ]; do + m=$1 + mount -t msdosfs /dev/md${m}$part ${mntpoint}$m + while mount | grep -qw $mntpoint$m; do + opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && echo "-f") + umount $opt ${mntpoint}$m > /dev/null 2>&1 + done + done + rm -f $cont + fi +fi diff --git a/tools/test/stress2/misc/msdos7.sh b/tools/test/stress2/misc/msdos7.sh new file mode 100755 index 000000000000..7bebe3703848 --- /dev/null +++ b/tools/test/stress2/misc/msdos7.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Run misc/datamove.sh on a msdos fs. +# Thread waiting on "msdosfs". +# https://people.freebsd.org/~pho/stress/log/kostik958.txt +# Fixed by r308025. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep -q "on $mntpoint " && umount $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +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 +sed "1,/^EOF/d" < $here/datamove.sh > msdos7.c +mycc -o msdos7 -Wall msdos7.c +rm -f msdos7.c + +(cd $mntpoint; /tmp/msdos7) + +umount $mntpoint +mdconfig -d -u $mdstart +rm -f /tmp/msdos7 +exit 0 diff --git a/tools/test/stress2/misc/msdos8.sh b/tools/test/stress2/misc/msdos8.sh new file mode 100755 index 000000000000..58f0390e195d --- /dev/null +++ b/tools/test/stress2/misc/msdos8.sh @@ -0,0 +1,157 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# msdosfs rename scenario +# "Invalid long filename entry" seen from fsck + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 + +[ -x /sbin/mount_msdosfs ] || exit 0 +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/msdos8.c +cc -o msdos8 -Wall -Wextra -O0 -g msdos8.c || exit 1 +rm -f msdos8.c +cd $odir +log=/tmp/msdos8.sh.log +mount | grep "$mntpoint" | grep -q md$mdstart && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs_msdos /dev/md${mdstart}$part #> /dev/null +mount -t msdosfs /dev/md${mdstart}$part $mntpoint || exit 1 + +(cd $mntpoint; /tmp/msdos8) +s=$? + +while mount | grep "$mntpoint" | grep -q md$mdstart; do + umount $mntpoint || sleep 1 +done +fsck -t msdosfs -y /dev/md${mdstart}$part > $log 2>&1 +if egrep -q "BAD|INCONSISTENCY|MODIFIED" $log; then + cat $log + s=1 + + mount -t msdosfs /dev/md${mdstart}$part $mntpoint || exit 1 + ls -lR $mntpoint + umount $mntpoint +fi +mdconfig -d -u $mdstart +rm /tmp/msdos8 $log +s=0 # Ignore for now +exit $s +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +# define PARALLEL 10 + +static unsigned long size; + +static void +test(void) +{ + pid_t pid; + int fd, i, j; + char file1[128], file2[128]; + + pid = getpid(); + for (i = 0; i < (int)size; i++) { + sprintf(file1,"p%05d.%05d", pid, i); + if ((fd = open(file1, O_RDONLY|O_CREAT, 0660)) == -1) + err(1, "openat(%s), %s:%d", file1, __FILE__, + __LINE__); + close(fd); + } + for (j = 0; j < 100; j++) { + for (i = 0; i < (int)size; i++) { + sprintf(file1,"p%05d.%05d", pid, i); + sprintf(file2,"p%05d.%05d.togo", pid, i); + if (rename(file1, file2) == -1) + err(1, "rename(%s, %s). %s:%d", file1, + file2, __FILE__, __LINE__); + } + for (i = 0; i < (int)size; i++) { + sprintf(file1,"p%05d.%05d", pid, i); + sprintf(file2,"p%05d.%05d.togo", pid, i); + if (rename(file2, file1) == -1) + err(1, "rename(%s, %s). %s:%d", file2, + file1, __FILE__, __LINE__); + } + } + + for (i = 0; i < (int)size; i++) { + sprintf(file1,"p%05d.%05d", pid, i); + if (unlink(file1) == -1) + err(1, "unlink(%s), %s:%d", file1, __FILE__, + __LINE__); + } + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + time_t start; + int e, i, status; + + e = 0; + size = 5; + start = time(NULL); + while ((time(NULL) - start) < 60 && e == 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 (WIFSIGNALED(status)) + fprintf(stderr, "pid %d exit signal %d\n", + pids[i], WTERMSIG(status)); + e += status == 0 ? 0 : 1; + } + } + + return (e); +} diff --git a/tools/test/stress2/misc/msdos9.sh b/tools/test/stress2/misc/msdos9.sh new file mode 100755 index 000000000000..cafabc546aa9 --- /dev/null +++ b/tools/test/stress2/misc/msdos9.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# fsx test of with msdosfs and a 1k block size +# "panic: Assertion ma[i]->dirty == VM_PAGE_BITS_ALL failed" seen. +# Fixed by r324794 + +# Original test scenario by fsu@freebsd.org + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 +[ -r /usr/src/tools/regression/fsx/fsx.c ] || exit 0 + +[ -x /sbin/mount_msdosfs ] || exit 0 +dir=/tmp +odir=`pwd` +cd $dir +cc -o fsx -Wall -Wextra -O2 -g /usr/src/tools/regression/fsx/fsx.c || exit 1 +rm -f fsx.c +cd $odir +log=/tmp/fsx.sh.log +mount | grep "$mntpoint" | grep -q md$mdstart && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +set -e +mdconfig -a -t swap -s 4g -u $mdstart +bsdlabel -w md$mdstart auto +newfs_msdos -b 1024 /dev/md${mdstart}$part > /dev/null +mount -t msdosfs /dev/md${mdstart}$part $mntpoint +set +e + +cp /tmp/fsx $mntpoint + +cd $mntpoint +./fsx -S 2016 -N 2000 ./TEST_FILE > /dev/null +cd / + +while mount | grep "$mntpoint" | grep -q md$mdstart; do + umount $mntpoint || sleep 1 +done +fsck -t msdosfs -y /dev/md${mdstart}$part > $log 2>&1 +if egrep -q "BAD|INCONSISTENCY|MODIFIED" $log; then + cat $log + s=1 + + mount -t msdosfs /dev/md${mdstart}$part $mntpoint || exit 1 + ls -lR $mntpoint + umount $mntpoint +fi +mdconfig -d -u $mdstart +rm /tmp/fsx $log +exit $s diff --git a/tools/test/stress2/misc/msetdomain.sh b/tools/test/stress2/misc/msetdomain.sh new file mode 100755 index 000000000000..53e792be52e5 --- /dev/null +++ b/tools/test/stress2/misc/msetdomain.sh @@ -0,0 +1,144 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# msetdomain(2) fuzz test. +# No problems seen. + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 + +nm /usr/lib/libc.a | grep -q __sys_msetdomain || exit 0 +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/msetdomain.c +mycc -o msetdomain -Wall -Wextra -O0 -g msetdomain.c || exit 1 +rm -f msetdomain.c +cd $odir + +$dir/msetdomain +s=$? +[ -f msetdomain.core -a $s -eq 0 ] && + { ls -l msetdomain.core; mv msetdomain.core /tmp; s=1; } +rm -rf $dir/msetdomain +exit $s + +EOF +#include +#include +#include +#include +#include + +#include +#include +#include + +/* +struct msetdomain_args { + void *addr; + size_t size; + size_t domainsetsize; + domainset_t *mask; + int policy; + int flags; +*/ + +static long +random_long(long mi, long ma) +{ + return (arc4random() % (ma - mi + 1) + mi); +} + +void +flip(void *ap, size_t len) +{ + unsigned char *cp; + int byte; + unsigned char bit, buf, mask, old; + + 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; +} + +int +main(void) +{ + size_t len; + time_t start; + void *share; + domainset_t rootmask; + int flags, policy; + + 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 < 60) { + if (cpuset_getdomain(CPU_LEVEL_ROOT, CPU_WHICH_PID, -1, + sizeof(rootmask), &rootmask, &policy) != 0) + err(EXIT_FAILURE, "getdomain"); + + flags = 0; + flip(&flags, sizeof(flags)); + msetdomain(share, len, sizeof(rootmask), &rootmask, policy, + flags); + } + + start = time(NULL); + while (time(NULL) - start < 60) { + if (cpuset_getdomain(CPU_LEVEL_ROOT, CPU_WHICH_PID, -1, + sizeof(rootmask), &rootmask, &policy) != 0) + err(EXIT_FAILURE, "getdomain"); + + flip(&policy, sizeof(policy)); + msetdomain(share, len, sizeof(rootmask), &rootmask, policy, + flags); + } + + start = time(NULL); + while (time(NULL) - start < 60) { + if (cpuset_getdomain(CPU_LEVEL_ROOT, CPU_WHICH_PID, -1, + sizeof(rootmask), &rootmask, &policy) != 0) + err(EXIT_FAILURE, "getdomain"); + + flip(&rootmask, sizeof(rootmask)); + msetdomain(share, len, sizeof(rootmask), &rootmask, policy, + flags); + } + + return (0); +} diff --git a/tools/test/stress2/misc/msync.sh b/tools/test/stress2/misc/msync.sh new file mode 100755 index 000000000000..326c7e723774 --- /dev/null +++ b/tools/test/stress2/misc/msync.sh @@ -0,0 +1,201 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# msync(2) / mlockall(2) test scenario. +# "panic: vm_fault_copy_wired: page missing" seen. +# http://people.freebsd.org/~pho/stress/log/msync.txt +# Fixed in r253189. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/msync.c +mycc -o msync -Wall -Wextra msync.c -lpthread || exit 1 +rm -f msync.c +cd $odir + +/tmp/msync & +sleep 180 +while pkill -9 msync; do :; done +wait +rm -f /tmp/msync +exit + +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int syscallno = SYS_msync; +#define N (128 * 1024 / (int)sizeof(u_int32_t)) +u_int32_t r[N]; + +static void +hand(int i __unused) { /* handler */ + _exit(1); +} + +unsigned long +makearg(void) +{ + unsigned int i; + unsigned long val; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return(val); +} + +void * +calls(void *arg __unused) +{ + int i, num; + unsigned long arg1, arg2, arg3; + + usleep(1000); + num = syscallno; + for (i = 0; i < 500; i++) { + arg1 = makearg(); + arg2 = makearg(); +#if 0 + arg3 = makearg(); + arg3 = arg3 & ~MS_INVALIDATE; /* No problem seen */ +#else + arg3 = MS_INVALIDATE; /* panic */ +#endif + +#if 0 + fprintf(stderr, "%2d : syscall(%3d, 0x%lx, 0x%lx, 0x%lx)\n", + i, num, arg1, arg2, arg3); + usleep(50000); +#endif + alarm(1); + syscall(num, arg1, arg2, arg3); + num = 0; + } + + return (0); +} +void +wd(void) +{ + int i; + + if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) + err(1, "mlockall failed"); + + for (i = 0; i < 800; i++) { + if (fork() == 0) { + usleep(20000); + _exit(0); + } + wait(NULL); + usleep(100000); + } + + _exit(0); +} + +int +main(void) +{ + struct passwd *pw; + pthread_t cp[50]; + int e, i, j; + + if (fork() == 0) + wd(); + + if ((pw = getpwnam("nobody")) == NULL) + err(1, "no such user: nobody"); + + 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(); + + signal(SIGALRM, hand); + signal(SIGILL, hand); + signal(SIGFPE, hand); + signal(SIGSEGV, hand); + signal(SIGBUS, hand); + signal(SIGURG, hand); + signal(SIGSYS, hand); + signal(SIGTRAP, hand); + + alarm(180); + for (i = 0; i < 8000; i++) { + if (fork() == 0) { + for (j = 0; j < N; j++) + r[j] = arc4random(); + for (j = 0; j < 50; j++) + if ((e = pthread_create(&cp[j], NULL, calls, NULL)) != 0) + errc(1, e, "pthread_create"); + + for (j = 0; j < 50; j++) + pthread_join(cp[j], NULL); + _exit(0); + } + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/msync2.sh b/tools/test/stress2/misc/msync2.sh new file mode 100755 index 000000000000..c1a9e4f0e372 --- /dev/null +++ b/tools/test/stress2/misc/msync2.sh @@ -0,0 +1,131 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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: vm_pageout_flush: partially invalid page xx index 0/1" seen. +# Fixed in r255566. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/msync2.c +mycc -o msync2 -Wall -Wextra msync2.c || exit 1 +rm -f msync2.c +cd $odir + +dd if=/dev/zero bs=$((4096 + 1)) of=/tmp/msync2.inputfile count=1 \ + status=none +/tmp/msync2 /tmp/msync2.inputfile +rm -f /tmp/msync2 /tmp/msync2.inputfile +exit + +EOF +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define RUNTIME 400 + +const char *file; +char c; + +void +wr(void) +{ + struct stat st; + char *p1; + size_t len; + int error, fd; + + 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 ((p1 = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) == + MAP_FAILED) + err(1, "mmap"); +// p1[len - 1] = 1; /* No panic with this */ + p1[arc4random() % len] = 1; /* Need this for the panic */ + + if ((error = msync(p1, len, MS_SYNC | MS_INVALIDATE)) == -1) + if (errno != EBUSY) + err(1, "msync"); + + if (munmap(p1, len) == -1) + err(1, "unmap()"); + close(fd); + + _exit(0); +} + +void +test(void) +{ +#if 1 + int i; + + for (i = 0; i < 3; i++) + if (fork() == 0) + wr(); + for (i = 0; i < 3; i++) + wait(NULL); +#else + wr(); /* No problem here */ +#endif + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + time_t start; + + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + file = argv[1]; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if (fork() == 0) + test(); + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/multicast.sh b/tools/test/stress2/misc/multicast.sh new file mode 100755 index 000000000000..d95a55cef918 --- /dev/null +++ b/tools/test/stress2/misc/multicast.sh @@ -0,0 +1,118 @@ +#!/bin/sh + +# Multicast test example by Mark Claypool, claypool at cs.wpi.edu +# https://web.cs.wpi.edu/~claypool/courses/4514-B99/samples/multicast.c + +# Kernel page fault seen with WiP branch: +# https://people.freebsd.org/~pho/stress/log/kip036.txt + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/multicast.c +mycc -o multicast -Wall -Wextra -O0 -g multicast.c || exit 1 +rm -f multicast.c +cd $odir + +cd $dir +( + timeout -k 1s 20s ./multicast & + sleep 1 + timeout -k 1s 25s ./multicast 1 +) > /dev/null +wait + +rm -f $dir/multicast +exit $s +EOF +/* +multicast.c + +The following program sends or receives multicast packets. If invoked +with one argument, it sends a packet containing the current time to an +arbitrarily chosen multicast group and UDP port. If invoked with no +arguments, it receives and prints these packets. Start it as a sender on +just one host and as a receiver on all the other hosts + +*/ + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#define EXAMPLE_PORT 6000 +#define EXAMPLE_GROUP "239.0.0.1" + +int +main(int argc, char *argv[] __unused) +{ + struct ip_mreq mreq; + struct sockaddr_in addr; + socklen_t addrlen; + int cnt, sock; + char message[50]; + + /* set up socket */ + sock = socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + perror("socket"); + exit(1); + } + bzero((char *)&addr, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + addr.sin_port = htons(EXAMPLE_PORT); + addrlen = sizeof(addr); + + if (argc > 1) { + /* send */ + addr.sin_addr.s_addr = inet_addr(EXAMPLE_GROUP); + while (1) { + time_t t = time(0); + sprintf(message, "time is %-24.24s", ctime(&t)); + printf("sending: %s\n", message); + cnt = sendto(sock, message, sizeof(message), 0, + (struct sockaddr *) &addr, addrlen); + if (cnt < 0) { + perror("sendto"); + exit(1); + } + sleep(5); + } + } else { + + /* receive */ + if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + perror("bind"); + exit(1); + } + mreq.imr_multiaddr.s_addr = inet_addr(EXAMPLE_GROUP); + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, + &mreq, sizeof(mreq)) < 0) { + perror("setsockopt mreq"); + exit(1); + } + while (1) { + cnt = recvfrom(sock, message, sizeof(message), 0, + (struct sockaddr *) &addr, &addrlen); + if (cnt < 0) { + perror("recvfrom"); + exit(1); + } else if (cnt == 0) { + break; + } + printf("%s: message = \"%s\"\n", inet_ntoa(addr.sin_addr), message); + } + } +} diff --git a/tools/test/stress2/misc/multicast2.sh b/tools/test/stress2/misc/multicast2.sh new file mode 100755 index 000000000000..bd95cd0bd9e6 --- /dev/null +++ b/tools/test/stress2/misc/multicast2.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +# D19886 Fix numerous refcount bugs in multicast + +# Page fault in in6_pcbpurgeif0+0xc8 seen. +# https://people.freebsd.org/~pho/stress/log/mmacy035.txt +# Test scenario by mmacy + +# Fixed by r349507 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -x /usr/local/bin/mDNSResponderPosix ] || + { echo "mDNSResponder not installed"; exit 0; } + +(cd ../testcases/swap; ./swap -t 2m -i 50 -v -h -l 100) & +sleep 2 + +service mdnsd onestart +ifconfig vtnet0 delete 2>/dev/null +ifconfig epair create +ifconfig epair0a 0/24 up +ifconfig epair0a destroy +service mdnsd onestop + +while pkill swap; do :; done +wait diff --git a/tools/test/stress2/misc/namecache.sh b/tools/test/stress2/misc/namecache.sh new file mode 100755 index 000000000000..6ca790b297f8 --- /dev/null +++ b/tools/test/stress2/misc/namecache.sh @@ -0,0 +1,214 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 case for vfs.lookup_shared=1 that shows possible name cache +# inconsistency: + +# $ ls -l /tmp/file.05015? +# ls: /tmp/file.050150: No such file or directory +# $ fsdb -r /dev/ad4s1e +# ** /dev/ad4s1e (NO WRITE) +# Examining file system `/dev/ad4s1e' +# Last Mounted on /tmp +# current inode: directory +# I=2 MODE=41777 SIZE=5120 +# BTIME=May 7 05:54:47 2006 [0 nsec] +# MTIME=Apr 2 11:27:36 2009 [0 nsec] +# CTIME=Apr 2 11:27:36 2009 [0 nsec] +# ATIME=Apr 2 12:00:30 2009 [0 nsec] +# OWNER=root GRP=wheel LINKCNT=35 FLAGS=0 BLKCNT=c GEN=65f71df4 +# fsdb (inum: 2)> lookup file.050150 +# component `file.050150': current inode: regular file +# I=198 MODE=100600 SIZE=0 +# BTIME=Apr 2 11:24:33 2009 [0 nsec] +# MTIME=Apr 2 11:24:33 2009 [0 nsec] +# CTIME=Apr 2 11:24:33 2009 [0 nsec] +# ATIME=Apr 2 11:24:33 2009 [0 nsec] +# OWNER=pho GRP=wheel LINKCNT=1 FLAGS=0 BLKCNT=0 GEN=1deaab3a +# fsdb (inum: 198)> quit +# $ + +# Consistency is restored by a umount + mount of the FS + +# Observations: +# No problems seen with vfs.lookup_shared=0. +# Does not fail in a "private" subdirectory + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > namecache.c +mycc -o namecache -Wall namecache.c +rm -f namecache.c + +#dir=/tmp/namecache.dir # No problems seen +dir=/tmp +[ -d $dir ] || mkdir -p $dir +cd $dir + +start=`date '+%s'` +for i in `jot 30`; do + for j in `jot 10`; do + /tmp/namecache & + done + + for j in `jot 10`; do + wait + done + [ $((`date '+%s'` - start)) -gt 1200 ] && break +done + +if ls -l $dir/file.0* 2>&1 | egrep "file.0[0-9]" | grep -q "No such file"; then + echo FAIL + echo "ls -l $dir/file.0*" + ls -l $dir/file.0* +fi + +rm -f /tmp/namecache # /$dir/file.0* +exit +EOF +/* Test scenario for possible name cache problem */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char path[MAXPATHLEN+1]; +static char buf[64 * 1024]; + +void +pm(void) +{ + int fd, n; + int space = sizeof(buf); + struct stat statb; + off_t base; + struct dirent *dp; + char *bp = buf; + + if ((fd = open(".", O_RDONLY)) == -1) + err(1, "open(%s)", "."); + + do { + if ((n = getdirentries(fd, bp, space, &base)) == -1) + err(1, "getdirentries"); + space = space - n; + bp = bp + n; + } while (n != 0); + close(fd); + + bp = buf; + dp = (struct dirent *)bp; + for (;;) { + if (strcmp(path, dp->d_name) == 0) { + + if (stat(dp->d_name, &statb) == -1) { + warn("stat(%s)", dp->d_name); + printf("name: %-10s, inode %7ju, " + "type %2d, namelen %d, d_reclen %d\n", + dp->d_name, (uintmax_t)dp->d_fileno, dp->d_type, + dp->d_namlen, dp->d_reclen); + fflush(stdout); + } else { + printf("stat(%s) succeeded!\n", path); + fflush(stdout); + } + + } + bp = bp + dp->d_reclen; + dp = (struct dirent *)bp; + if (dp->d_reclen <= 0) + break; + } +} + +static void +reader(void) { + int fd; + + if ((fd = open(path, O_RDWR, 0600)) < 0) { + warn("open(%s). %s:%d", path, __FILE__, __LINE__); + pm(); + exit(1); + } + close(fd); + return; +} + +static void +writer(void) { + int fd; + + if ((fd = open(path, O_RDWR, 0600)) < 0) { + warn("open(%s). %s:%d", path, __FILE__, __LINE__); + pm(); + exit(1); + } + close(fd); + return; +} + +int +main(int argc, char **argv) +{ + pid_t pid; + int fd, i, status; + + for (i = 0; i < 10000; i++) { + if (sprintf(path, "file.0%d", getpid()) < 0) + err(1, "sprintf()"); + if ((fd = open(path, O_CREAT | O_RDWR, 0600)) == -1) + err(1, "open(%s)", path); + close(fd); + + if ((pid = fork()) == 0) { + writer(); + exit(EXIT_SUCCESS); + + } else if (pid > 0) { + reader(); + if (waitpid(pid, &status, 0) == -1) + warn("waitpid(%d)", pid); + } else + err(1, "fork(), %s:%d", __FILE__, __LINE__); + + if (unlink(path) == -1) + err(1, "unlink(%s). %s:%d", path, __FILE__, __LINE__); + } + return (0); +} diff --git a/tools/test/stress2/misc/namecache2.sh b/tools/test/stress2/misc/namecache2.sh new file mode 100755 index 000000000000..a5dd4319fc66 --- /dev/null +++ b/tools/test/stress2/misc/namecache2.sh @@ -0,0 +1,192 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# UFS cache inconsistancy for rename(2) demonstrated +# Fails with: +# ls -ali /mnt +# ls: tfa1022: No such file or directory +# Fixed by r248422 + +# Test scenario obtained from Rick Miller + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +# This threaded test is designed for MP. +[ `sysctl hw.ncpu | sed 's/.* //'` -eq 1 ] && exit 0 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > namecache2.c +rm -f /tmp/namecache2 +mycc -o namecache2 -Wall -Wextra -g -O2 namecache2.c -lpthread || exit 1 +rm -f namecache2.c +cd $odir + +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +(cd $mntpoint; /tmp/namecache2) + +f=`(cd $mntpoint; echo *)` +if [ "$f" != '*' ]; then + echo FAIL + echo "echo $mntpoint/*" + echo $mntpoint/* + echo "" + echo "ls -ali $mntpoint" + ls -ali $mntpoint + echo "" + echo "fsdb -r /dev/md${mdstart}$part" + fsdb -r /dev/md${mdstart}$part <<-EF + ls + quit + EF +fi + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/namecache2 +exit 0 +EOF +/* + * NOTE: This must be run with the current working directory on a local UFS + * disk partition, to demonstrate a FreeBSD namecache bug. I have never seen + * this bug happen with an NFS partition. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int stopping = false; +char *pFilename = 0; + +static void * +statThread(void *arg __unused) +{ + + struct stat statData; + int rc; + + for (;;) { + while (pFilename == 0) { + if (stopping) + return 0; + } + + rc = stat(pFilename, &statData); + if (rc < 0 && errno != ENOENT) { + printf(" statThread stat() on %s failed with errno %d\n", + pFilename, errno); + return 0; + } + } + + return 0; +} + +int +main(void) +{ + char filename1 [20], filename2[20], filename3[20]; + pthread_t threadId; + struct stat statData; + int result, fd; + unsigned int number; + struct timespec period; + time_t start; + + sprintf(filename1, "tfa0"); + fd = open(filename1, O_CREAT, S_IRWXU); + if (fd < 0) { + printf("open(O_CREAT) on %s failed with errno %d\n", filename1, errno); + return 0; + } + if (close(fd) < 0) { + printf("close() on %s failed with errno %d\n", filename1, errno); + return 0; + } + result = pthread_create(&threadId, NULL, statThread, NULL); + if (result < 0) + errc(1, result, "pthread_create()"); + + start = time(NULL); + for (number = 0; number < 0x001FFFFF; number += 2) { + sprintf(filename1, "tfa%u", number); + sprintf(filename2, "tfa%u", number + 1); + sprintf(filename3, "tfa%u", number + 2); + if (rename(filename1, filename2) < 0) { + printf(" rename1() from %s to %s failed with errno %d\n", + filename1, filename2, errno); + return 0; + } + pFilename = filename3; + + if (rename(filename2, filename3) < 0) { + printf(" rename2() from %s to %s failed with errno %d\n", + filename2, filename3, errno); + return 0; + } + pFilename = 0; + period.tv_sec = 0; + period.tv_nsec = 500; + nanosleep(&period, 0); + + if (stat(filename3, &statData) < 0) { + printf("stat(%s) failed with errno %d\n", filename3, errno); + stopping = true; + period.tv_sec = 0; + period.tv_nsec = 500; + nanosleep(&period, 0); + return 0; + } + if (time(NULL) - start > 1200) { + fprintf(stderr, "Test timed out.\n"); + break; + } + } + unlink(filename3); + + return 0; +} diff --git a/tools/test/stress2/misc/nanosleep.sh b/tools/test/stress2/misc/nanosleep.sh new file mode 100755 index 000000000000..79e2d505fb47 --- /dev/null +++ b/tools/test/stress2/misc/nanosleep.sh @@ -0,0 +1,87 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 simplistic regression test for r200510: + +[ `sysctl -n kern.hz` -lt 1000 ] && exit 0 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > nanosleep.c +mycc -o nanosleep -Wall -Wextra nanosleep.c || exit 1 +rm -f nanosleep.c + +/tmp/nanosleep && s=0 || s=$? + +rm -f /tmp/nanosleep +exit $s +EOF +#include +#include + +#include +#include +#include +#include + +#define N 20000 + +int +main(void) +{ + struct timespec rmt, rqt; + struct timespec finish, start, res; + long m; + int i; + + m = LONG_MAX; + for (i = 0; i < 100; i++) { + rqt.tv_sec = 0; + rqt.tv_nsec = N; + clock_gettime(CLOCK_REALTIME_PRECISE, &start); + if (nanosleep(&rqt, &rmt) == -1) + err(1, "nanosleep"); + clock_gettime(CLOCK_REALTIME_PRECISE, &finish); + timespecsub(&finish, &start, &res); + if (res.tv_nsec < N) + errx(1, "Short sleep: %ld", res.tv_nsec); +// fprintf(stderr, "asked for %f, got %f\n", (double)N / 1e9, +// (double)res.tv_nsec / 1e9); + if (m > res.tv_nsec) + m = res.tv_nsec; + } + if (m > 2 * N) { + fprintf(stderr, "nanosleep(%fs). Best value is %fs.\n", + (double)N / 1e9, (double)m / 1e9); + errx(1, "FAIL"); + } + + return (0); +} diff --git a/tools/test/stress2/misc/nbufkv.sh b/tools/test/stress2/misc/nbufkv.sh new file mode 100755 index 000000000000..db2c45feb496 --- /dev/null +++ b/tools/test/stress2/misc/nbufkv.sh @@ -0,0 +1,156 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 scenario with a 20G files on two UFS2 FSs with 64k/64k +# Test program will hang (deadlock) in "nbufkv" + +# Test scenario by John-Mark Gurney + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +dir=`dirname $diskimage` +d1=$dir/diskimage1 +d2=$dir/diskimage2 +rm -f $d1 $d2 + +size=20 # G +avail=$((`sysctl -n hw.physmem` / 1024 / 1024 / 1024)) +[ $((size * 2)) -gt $avail ] && size=$((avail / 2)) +[ `df -k $dir | tail -1 | awk '{print $4}'` -lt \ + $((size * 2 * 1024 * 1024)) ] && + echo "Not enough disk space on $dir." && exit 0 + +odir=`pwd` + +USE_TIMEOUT=1 +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > nbufkv.c +mycc -o nbufkv -Wall nbufkv.c +rm -f nbufkv.c +cd $odir + +u1=$mdstart +u2=$((u1 + 1)) +mp1=$mntpoint +mp2=${mntpoint}2 +[ -d $mp1 ] || mkdir $mp1 +[ -d $mp2 ] || mkdir $mp2 +dd if=/dev/zero of=$d1 bs=1m count=${size}k status=none || exit 1 +cp $d1 $d2 || exit 1 + +mount | grep -q /dev/md${u2}$part && umount -f /dev/md${u2}$part +mount | grep -q /dev/md${u1}$part && umount -f /dev/md${u1}$part +[ -c /dev/md$u2 ] && mdconfig -d -u $u2 +[ -c /dev/md$u1 ] && mdconfig -d -u $u1 + +mdconfig -a -t vnode -f $d1 -u $u1 || exit 1 +bsdlabel -w md$u1 auto +newfs -b 65536 -f 65536 -O2 md${u1}$part > /dev/null + +mdconfig -a -t vnode -f $d2 -u $u2 || exit 1 +bsdlabel -w md$u2 auto +newfs -b 65536 -f 65536 -O2 md${u2}$part > /dev/null + +mount /dev/md${u1}$part $mp1 +mount /dev/md${u2}$part $mp2 + +/tmp/nbufkv $mp1 & +/tmp/nbufkv $mp2 & +wait + +umount /dev/md${u2}$part +umount /dev/md${u1}$part + +mount | grep -q /dev/md${u2}$part && umount -f /dev/md${u2}$part +mount | grep -q /dev/md${u1}$part && umount -f /dev/md${u1}$part + +mdconfig -d -u $u2 +mdconfig -d -u $u1 + +rm -rf $d1 $d2 /tmp/nbufkv +exit +EOF +#include + +#include +#include +#include +#include +#include +#include + +void +handler(int i) { + fprintf(stderr, "FAIL. Timerout.\n"); + _exit(0); +} + +void +work(int fd, size_t n) +{ + int i; + + for (i = 0; i < 128 * 1024; i++) { + n = n - PAGE_SIZE; + if (lseek(fd, n , SEEK_SET) == -1) + err(1, "lseek()"); + if (write(fd, "1", 1) != 1) + err(1, "write()"); + } + +} + +int +main(int argc, char **argv) +{ + + int fd; + off_t len; + char path[128]; + + len = 20; + len = len * 1024 * 1024 * 1024; + + sprintf(path, "%s/nbufkv.%06d", argv[1], getpid()); + if ((fd = open(path, O_CREAT | O_TRUNC | O_RDWR, 0640)) == -1) + err(1,"open(%s)", path); + if (ftruncate(fd, len) == -1) + err(1, "ftruncate"); + + signal(SIGALRM, handler); + alarm(1200); + work(fd, len); + + close(fd); + if (unlink(path) == -1) + err(1, "unlink(%s)", path); + + return (0); +} diff --git a/tools/test/stress2/misc/newfs.sh b/tools/test/stress2/misc/newfs.sh new file mode 100755 index 000000000000..8ef7b9eae31e --- /dev/null +++ b/tools/test/stress2/misc/newfs.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2011 Peter Holm +# All rights reserved. +# +# 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 few UFS1 newfs combinations are known to cause fsck(8) to fail. +# Ignore these for now. Will be fixed: +# newfs -O1 -b 65536 -f 8192 +# newfs -O1 -b 65536 -f 16384 +# newfs -O1 -b 65536 -f 32768 +# newfs -O1 -b 65536 -f 65536 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep "$mntpoint" | grep md${mdstart}$part > /dev/null && + umount $mntpoint +mdconfig -l | grep md$mdstart > /dev/null && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto + +echo "Expect warnings from SU and SU+J." +log=/tmp/newfs.sh.log +s=0 +export RUNDIR=$mntpoint/stressX +export runRUNTIME=10s +export RUNTIME=$runRUNTIME +export CTRLDIR=$mntpoint/stressX.control +start=`date '+%s'` +for opt in -O1 -O2 -U -j; do + echo "Testing newfs with option $opt." + blocksize=4096 + while [ $blocksize -le 65536 ]; do + for i in 8 4 2 1; do + fragsize=$((blocksize / i)) + newfs $opt -b $blocksize -f $fragsize \ + md${mdstart}$part > /dev/null 2>&1 || continue + mount /dev/md${mdstart}$part $mntpoint + chmod 777 $mntpoint + rm -rf /tmp/stressX.control + su $testuser -c \ + "(cd ..; ./run.sh disk.cfg > /dev/null 2>&1)" & + sleep 10 + ../tools/killall.sh + wait + while mount | grep "$mntpoint" | \ + grep -q md${mdstart}$part; do + umount $mntpoint > /dev/null 2>&1 || sleep 1 + done + checkfs /dev/md${mdstart}$part > $log 2>&1 || { + cmd="newfs $opt -b $blocksize -f $fragsize" +# if ! grep -q -- "$cmd" $0; then + s=1 + echo "$cmd" + cat $log +# fi + } + done + blocksize=$((blocksize * 2)) + done + if [ $((`date '+%s'` - start)) -gt 1200 ]; then + echo "Timed out" + s=1 + break + fi +done +mdconfig -d -u $mdstart +rm -f $log +exit $s diff --git a/tools/test/stress2/misc/newfs2.sh b/tools/test/stress2/misc/newfs2.sh new file mode 100755 index 000000000000..ac891e7926fb --- /dev/null +++ b/tools/test/stress2/misc/newfs2.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2011 Peter Holm +# All rights reserved. +# +# 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. +# + +# phk has seen freezes with this newfs option: "-b 32768 -f 4096 -O2" + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +size=$((32 * 1024 * 1024)) + +mount | grep "$mntpoint" | grep -q md${mdstart}$part && umount $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +s=0 +start=`date '+%s'` +while [ $size -le $((900 * 1024 * 1024)) ]; do + mb=$((size / 1024 / 1024)) + rm -f $diskimage + dd if=/dev/zero of=$diskimage bs=1m count=$mb status=none + mdconfig -a -t vnode -f $diskimage -u $mdstart || + { rm $diskimage; exit 1; } + bsdlabel -w md$mdstart auto + newfs -b 32768 -f 4096 -O2 md${mdstart}$part > /dev/null 2>&1 + mount /dev/md${mdstart}$part $mntpoint + export RUNDIR=$mntpoint/stressX + export runRUNTIME=30s + export RUNTIME=$runRUNTIME + export CTRLDIR=$mntpoint/stressX.control + (cd ..; ./run.sh disk.cfg) > /dev/null + while mount | grep "$mntpoint" | grep -q md${mdstart}$part; do + umount $mntpoint > /dev/null 2>&1 + done + checkfs md${mdstart}$part || s=1 + mdconfig -d -u $mdstart + size=$((size + 32 * 1024 * 1024)) + if [ $((`date '+%s'` - start)) -gt 1200 ]; then + echo "Timed out" + s=1 + break + fi +done +rm -f $diskimage +exit $s diff --git a/tools/test/stress2/misc/newfs3.sh b/tools/test/stress2/misc/newfs3.sh new file mode 100755 index 000000000000..f6dd84e801bc --- /dev/null +++ b/tools/test/stress2/misc/newfs3.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2011 Peter Holm +# All rights reserved. +# +# 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. +# + +# phk has seen freezes with this newfs option: "-b 32768 -f 4096 -O2" +# +# Deadlocks seen with this test and: +# newfs -b 4096 -f 4096 -O2 md0c on a 128 Mb FS +# newfs -b 4096 -f 1024 -O2 md0c on a 64 Mb FS +# 20070505 newfs -b 4096 -f 4096 -O2 md0c on a 32 Mb FS: panic: lockmgr: locking against myself + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +size=$((32 * 1024 * 1024)) +opt="-O2" # newfs option. Eg. -U + +mount | grep "$mntpoint" | grep -q md${mdstart}$part && umount $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +s=0 +while [ $size -le $((128 * 1024 * 1024)) ]; do + mb=$((size / 1024 / 1024)) + rm -f $diskimage + dd if=/dev/zero of=$diskimage bs=1m count=$mb status=none + mdconfig -a -t vnode -f $diskimage -u $mdstart || + { rm -f $diskimage; exit 1; } + bsdlabel -w md$mdstart auto + blocksize=4096 + while [ $blocksize -le 65536 ]; do + for i in 1 2 4 8; do + fragsize=$((blocksize / i)) + newfs -b $blocksize -f $fragsize $opt md${mdstart}$part > \ + /dev/null 2>&1 + mount /dev/md${mdstart}$part $mntpoint + export RUNDIR=$mntpoint/stressX + export runRUNTIME=15s + export RUNTIME=$runRUNTIME + export CTRLDIR=$mntpoint/stressX.control + (cd ..; ./run.sh disk.cfg) > /dev/null 2>&1 & + sleep 15 + ../tools/killall.sh + wait + while mount | grep "$mntpoint" | \ + grep -q md${mdstart}$part; do + umount $mntpoint > /dev/null 2>&1 + done + checkfs /dev/md${mdstart}$part || s=1 + done + blocksize=$((blocksize * 2)) + done + mdconfig -d -u $mdstart + size=$((size + 32 * 1024 * 1024)) +done +rm -f $diskimage +exit $s diff --git a/tools/test/stress2/misc/newfs4.sh b/tools/test/stress2/misc/newfs4.sh new file mode 100755 index 000000000000..46d563a49460 --- /dev/null +++ b/tools/test/stress2/misc/newfs4.sh @@ -0,0 +1,128 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2013 Peter Holm +# All rights reserved. +# +# 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 + +# Deadlock problems. Test scenario by Lev Serebryakov +# newfs -O2 -U -b 65536 +# The io programs will get stuck in nbufkv wait state. + +# Threads stuck in newbuf: +# https://people.freebsd.org/~pho/stress/log/newfs4-2.txt + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > newfs4.c +mycc -o newfs4 -Wall -Wextra newfs4.c || exit 1 +rm -f newfs4.c +cd $odir + +mount | grep "$mntpoint" | grep -q md${mdstart}$part && umount $mntpoint +mdconfig -l | grep md$mdstart > /dev/null && mdconfig -d -u $mdstart + +size=9 # Gb +[ `df -k $(dirname $diskimage) | tail -1 | \ + awk '{print $4}'` -lt $((size * 1024 * 1024)) ] && \ + echo "Not enough disk space on `dirname $diskimage`." && exit 1 +trap "rm -f $diskimage" EXIT INT +dd if=/dev/zero of=$diskimage bs=1m count=$((size * 1024)) status=none || + exit 1 + +blocksize="-b 65536" +opt="-O2 -U" +mdconfig -a -t vnode -f $diskimage -u $mdstart +bsdlabel -w md$mdstart auto +newfs $blocksize $opt md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +cd $mntpoint +truncate -s 2g f1 +truncate -s 2g f2 +truncate -s 2g f3 +truncate -s 2g f4 +/tmp/newfs4 f1 & +/tmp/newfs4 f2 & +/tmp/newfs4 f3 & +/tmp/newfs4 f4 & +wait + +while mount | grep "$mntpoint" | grep -q md${mdstart}$part; do + umount -f $mntpoint || sleep 1 +done +checkfs /dev/md${mdstart}$part; s=$? + +mdconfig -d -u $mdstart +rm -f /tmp/newfs4 +exit $s + +EOF +#include +#include + +#include +#include +#include +#include +#include + +/* Perform random IO operations on a file */ + +int +main(int argc, char **argv) +{ + struct stat sb; + off_t bp, maxb; + long i; + int fd; + char buf[256]; + + if (argc != 2) { + fprintf(stderr, "Usage %s: file\n", argv[0]); + return (1); + } + if ((fd = open(argv[1], O_RDWR)) == -1) + err(1, "open(%s)", argv[1]); + if (fstat(fd, &sb) == -1) + err(1, "fstatf(stdin)"); + maxb = sb.st_size - sizeof(buf); + + for (i = 0; i < 10000; i++) { + bp = arc4random(); + bp = (bp << 31 | arc4random()) % maxb; + + if (lseek(fd, bp, 0) == -1) + err(1, "lseek()"); + if (write(fd, buf, sizeof(buf)) != sizeof(buf)) + err(1, "write()"); + } + close(fd); + + return (0); +} diff --git a/tools/test/stress2/misc/newfs5.sh b/tools/test/stress2/misc/newfs5.sh new file mode 100755 index 000000000000..f41da12e28dd --- /dev/null +++ b/tools/test/stress2/misc/newfs5.sh @@ -0,0 +1,116 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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 + +# Variation of newfs4.sh, using a swap backed MD disk + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > newfs5.c +mycc -o newfs5 -Wall -Wextra newfs5.c +rm -f newfs5.c +cd $odir + +mount | grep "$mntpoint" | grep md${mdstart}$part > /dev/null && umount $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +blocksize="-b 65536" +opt="-O2 -U" +size=9 # Gb +mdconfig -a -t swap -s ${size}g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $blocksize $opt md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +cd $mntpoint +truncate -s 2g f1 +truncate -s 2g f2 +truncate -s 2g f3 +truncate -s 2g f4 +/tmp/newfs5 f1 & +/tmp/newfs5 f2 & +/tmp/newfs5 f3 & +/tmp/newfs5 f4 & +wait + +while mount | grep "$mntpoint" | grep -q md${mdstart}$part; do + umount -f $mntpoint || sleep 1 +done +checkfs /dev/md${mdstart}$part; s=$? + +mdconfig -d -u $mdstart +rm -f $diskimage +rm -f /tmp/newfs5 +exit $s + +EOF +#include +#include +#include +#include +#include +#include +#include + +/* Perform random IO operations on a file */ + +int +main(int argc, char **argv) +{ + struct stat sb; + char buf[256]; + off_t bp, maxb; + int fd; + long i; + + if (argc != 2) { + fprintf(stderr, "Usage %s: file\n", argv[0]); + return (1); + } + if ((fd = open(argv[1], O_RDWR)) == -1) + err(1, "open(%s)", argv[1]); + if (fstat(fd, &sb) == -1) + err(1, "fstatf(stdin)"); + maxb = sb.st_size - sizeof(buf); + + for (i = 0; i < 10000; i++) { + bp = arc4random(); + bp = (bp << 31 | arc4random()) % maxb; + + if (lseek(fd, bp, 0) == -1) + err(1, "lseek()"); + if (write(fd, buf, sizeof(buf)) != sizeof(buf)) + err(1, "write()"); + } + close(fd); + + return (0); +} diff --git a/tools/test/stress2/misc/nfs.sh b/tools/test/stress2/misc/nfs.sh new file mode 100755 index 000000000000..a38745ce1cc3 --- /dev/null +++ b/tools/test/stress2/misc/nfs.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# No problems seen with this test + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +mount | grep "$mntpoint" | grep -q nfs && umount $mntpoint +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export $mntpoint + +export RUNDIR=$mntpoint/nfs.`jot -rc 8 a z | tr -d '\n'`/stressX +export runRUNTIME=10m + +mkdir -p $RUNDIR +chmod 777 $RUNDIR +su $testuser -c "(cd ..; ./run.sh disk.cfg)" 2>/dev/null +su $testuser -c "rm -rf $RUNDIR 2>/dev/null" +rm -rf $RUNDIR + +umount $mntpoint +while mount | grep "$mntpoint " | grep -q nfs; do + umount -f $mntpoint +done +exit 0 diff --git a/tools/test/stress2/misc/nfs10.sh b/tools/test/stress2/misc/nfs10.sh new file mode 100755 index 000000000000..15f449548f45 --- /dev/null +++ b/tools/test/stress2/misc/nfs10.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# nfsv4 test scenario +# Deadlock seen: http://people.freebsd.org/~pho/stress/log/nfs10.txt +# Lock violation: http://people.freebsd.org/~pho/stress/log/nfs10-2.txt +# Double fault: http://people.freebsd.org/~pho/stress/log/nfs10-3.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +grep -q $mntpoint /etc/exports || + { echo "$mntpoint missing from /etc/exports"; exit 0; } + +m2=${mntpoint}2 +[ -d $m2 ] || mkdir $m2 +mount | grep "on $m2 " | grep -q nfs && umount $m2 +mount | grep "on $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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +mount -t nfs -o nfsv4 -o rw,retrycnt=3 127.0.0.1:$mntpoint $m2 + +export RUNDIR=$m2/stressX +export runRUNTIME=10m # Run tests for 10 minutes + +su $testuser -c "(cd ..; ./run.sh marcus.cfg)" & +sleep 300 +umount $m2 2>/dev/null # Test umount of active FS while here +wait + +while mount | grep "on $m2 " | grep -q nfs; do + umount $m2 +done + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +exit 0 diff --git a/tools/test/stress2/misc/nfs11.sh b/tools/test/stress2/misc/nfs11.sh new file mode 100755 index 000000000000..e132ad9f894e --- /dev/null +++ b/tools/test/stress2/misc/nfs11.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# nfsv4 test scenario + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +grep -q $mntpoint /etc/exports || + { echo "$mntpoint missing from /etc/exports"; exit 0; } + +m2=${mntpoint}2 +[ -d $m2 ] || mkdir $m2 +mount | grep "on $m2 " | grep -q nfs && umount $m2 +mount | grep "on $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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +mount -t nfs -o nfsv4 -o rw,retrycnt=3 127.0.0.1:$mntpoint $m2 + +export RUNDIR=$m2/stressX +export runRUNTIME=10m # Run tests for 10 minutes + +su $testuser -c "(cd ..; ./run.sh marcus.cfg)" + +while mount | grep "on $m2 " | grep -q nfs; do + umount $m2 +done + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +exit 0 diff --git a/tools/test/stress2/misc/nfs12.sh b/tools/test/stress2/misc/nfs12.sh new file mode 100755 index 000000000000..e1b6e2c9279e --- /dev/null +++ b/tools/test/stress2/misc/nfs12.sh @@ -0,0 +1,160 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# "umount -f" test scenario (distill of nfs4.sh) +# "panic: vputx: missed vn_close" seen. +# Fixed in r248815 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > nfs12.c +mycc -o nfs12 -Wall -Wextra -O2 -g nfs12.c +rm -f nfs12.c +cd $here + +mount | grep "on $mntpoint " | grep nfs > /dev/null && umount $mntpoint +version="-o nfsv3" # The default +[ $# -eq 1 ] && [ "$1" -eq 4 ] && version="-o nfsv4" +for i in `jot 10`; do + mount -t nfs $version -o tcp -o retrycnt=3 -o intr,soft -o rw \ + $nfs_export $mntpoint + sleep 2 + + if [ $i -eq 10 ]; then + rm -f $mntpoint/nfs12.p* + else + (cd $mntpoint; /tmp/nfs12 > /dev/null 2>&1) & + sleep 2 + fi + + while mount | grep "on $mntpoint " | grep -q nfs; do + umount -f $mntpoint + done + kill -9 $! > /dev/null 2>/dev/null && kill $! + wait +done + +rm -f /tmp/nfs12 +exit +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define INPUTFILE "/bin/date" +#define PARALLEL 5 + +static int +tmmap(void) +{ + struct stat statbuf; + pid_t pid; + char *src, *dst; + int i; + int fdin, fdout; + char file[128]; + + pid = getpid(); + setproctitle("mmap"); + for (i = 0; i < 50000; i++) { + sprintf(file,"nfs12.p%05d.%05d", pid, i); + + if ((fdin = open(INPUTFILE, O_RDONLY)) < 0) + err(1, INPUTFILE); + + if ((fdout = open(file, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) + err(1, "%s", file); + + if (fstat(fdin, &statbuf) < 0) + err(1, "fstat error"); + + if (lseek(fdout, statbuf.st_size - 1, SEEK_SET) == -1) + err(1, "lseek error"); + + /* write a dummy byte at the last location */ + if (write(fdout, "", 1) != 1) + err(1, "write error"); + + if ((src = mmap(0, statbuf.st_size, PROT_READ, MAP_SHARED, fdin, 0)) == + (caddr_t) - 1) + err(1, "mmap error for input"); + + if ((dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE, + MAP_SHARED, fdout, 0)) == (caddr_t) - 1) + err(1, "mmap error for output"); + + memcpy(dst, src, statbuf.st_size); + + if (munmap(src, statbuf.st_size) == -1) + err(1, "munmap"); + close(fdin); + + if (munmap(dst, statbuf.st_size) == -1) + err(1, "munmap"); + close(fdout); + + if (unlink(file) == -1) + err(3, "unlink(%s)", file); + } + + _exit(0); +} + +int +main(void) +{ + int i; + + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + tmmap(); + } + + for (i = 0; i < PARALLEL; i++) { + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/nfs13.sh b/tools/test/stress2/misc/nfs13.sh new file mode 100755 index 000000000000..fb65b8a64044 --- /dev/null +++ b/tools/test/stress2/misc/nfs13.sh @@ -0,0 +1,66 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# nfs loopback mount of a tmpfs file system. +# "[tcp] 127.0.0.1:/mnt: Permission denied" seen. + +# " mount_nfs hangs in mntref" seen. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +grep -q $mntpoint /etc/exports 2>/dev/null || + { echo "$mntpoint missing from /etc/exports"; exit 0; } + +s=0 +m2=${mntpoint}2 +[ -d $m2 ] || mkdir $m2 +mount | grep "on $m2 " | grep -q nfs && umount $m2 +mount | grep "on $mntpoint " | grep -q tmpfs && umount -f $mntpoint + +mount -o size=1g -t tmpfs tmpfs $mntpoint || s=1 +chmod 777 $mntpoint + +[ $s -eq 0 ] && + mount -t nfs -o tcp -o rw,retrycnt=1 127.0.0.1:$mntpoint $m2 || s=2 + +export RUNDIR=$m2/stressX +export runRUNTIME=10m # Run tests for 10 minutes + +[ $s -eq 0 ] && + su $testuser -c "(cd ..; ./run.sh marcus.cfg)" + +while mount | grep "on $m2 " | grep -q nfs; do + umount $m2 +done + +while mount | grep "on $mntpoint " | grep -q tmpfs; do + umount $mntpoint || sleep 1 +done +exit $s diff --git a/tools/test/stress2/misc/nfs14.sh b/tools/test/stress2/misc/nfs14.sh new file mode 100755 index 000000000000..c3b4152c5af4 --- /dev/null +++ b/tools/test/stress2/misc/nfs14.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Bring the network down and up again during NFS tests. + +# "panic: re_txeof: freeing NULL mbufs!" seen: +# https://people.freebsd.org/~pho/stress/log/nfs14.txt + +# This is a very disruptive test, so be aware! +[ -z "$footshoot" ] && exit 0 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +if=`ifconfig -lu | awk '{print $1}'` +[ -z "$if" ] && exit 0 + +[ ! -d $mntpoint ] && mkdir $mntpoint +mount | grep "on $mntpoint " | grep -q nfs && umount $mntpoint +mount -t nfs -o tcp -o retrycnt=3 -o soft \ + -o rw $nfs_export $mntpoint + +sleep .5 +export RUNDIR=$mntpoint/nfs14.`jot -rc 8 a z | tr -d '\n'`/stressX +rm -rf $RUNDIR +mkdir -p $RUNDIR +chmod 777 $RUNDIR +export runRUNTIME=3m +rm -rf /tmp/stressX.control/* + +su $testuser -c '(cd ..; ./run.sh rw.cfg) > /dev/null 2>&1' & + +sleep `jot -r 1 5 15`.`jot -r 1 1 9` +downtime=`jot -r 1 100 150` +echo "Testing with $downtime seconds downtime." +ifconfig $if down; sleep $downtime; ifconfig $if up + +wait +rm -rf $RUNDIR +while mount | grep -q $mntpoint; do + umount -f $mntpoint > /dev/null 2>&1 +done +../tools/killall.sh +exit 0 diff --git a/tools/test/stress2/misc/nfs15.sh b/tools/test/stress2/misc/nfs15.sh new file mode 100755 index 000000000000..33546aba8d4b --- /dev/null +++ b/tools/test/stress2/misc/nfs15.sh @@ -0,0 +1,212 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 effort to reproduce reported: "observed a hang in a multi-threaded +# process that had hit an assertion failure and was attempting to dump core". +# Problem never seen. + +# Most interesting load are: +# - coredumping of the multithreaded program with the current dir on NFS, +# which also accesses NFS files; +# - advisory locking tests on NFS files, while e.g. sending SIGSTOP/SIGCONT +# to the test programs. + +# See also pthread9.sh + +# https://people.freebsd.org/~pho/stress/log/kostik897.txt +# Fixed in r302013. + +# "panic: mutex sleepq chain not owned at subr_sleepqueue.c:1009" seen: +# https://people.freebsd.org/~pho/stress/log/kostik914.txt +# Fixed in r302328. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +USE_TIMEOUT=1 +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > nfs15.c +mycc -o nfs15 -Wall -Wextra -O2 -g nfs15.c -lpthread || exit 1 +rm -f nfs15.c +cd $here + +mount | grep "on $mntpoint " | grep nfs > /dev/null && umount $mntpoint + +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw -o nolockd \ + $nfs_export $mntpoint || exit 1 +sleep 2 +wd=$mntpoint/nfs15.dir +rm -rf $wd +mkdir $wd + +(cd $wd; /tmp/nfs15) +rm -rf $wd + +while mount | grep "on $mntpoint " | grep -q nfs; do + umount $mntpoint || sleep 1 +done + +rm -f /tmp/nfs15 +exit 0 +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 4 +#define RUNTIME 300 +#define SYNC 0 + +volatile u_int *share; + +static void * +t1(void *data __unused) +{ + atomic_add_int(&share[SYNC], 1); + usleep(arc4random() % 8000); + raise(SIGABRT); + + return (NULL); +} + +static void * +t2(void *data __unused) +{ + int fd, i, r; + char file[80]; + + for (i = 0; i < 100; i++) { + atomic_add_int(&share[SYNC], 1); + snprintf(file, sizeof(file), "file.%06d", i); + if ((fd = open(file, O_WRONLY | O_CREAT | O_APPEND, + DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + do { + r = lockf(fd, F_LOCK, 0); + } while (r == -1 && errno == EDEADLK); + if (r == -1) + err(1, "lockf(%s, F_LOCK)", file); + write(fd, "x", 1); + if (lseek(fd, 0, SEEK_SET) == -1) + err(1, "lseek"); + if (lockf(fd, F_ULOCK, 0) == -1) + err(1, "lockf(%s, F_ULOCK)", file); + close(fd); + } + + return (NULL); +} + +int +test(void) +{ + pthread_t tid[3]; + int i, rc; + + for (i = 0; i < 10; i++) { + if ((rc = pthread_create(&tid[0], NULL, t2, NULL)) == -1) + errc(1, rc, "pthread_create"); + if ((rc = pthread_create(&tid[1], NULL, t2, NULL)) == -1) + errc(1, rc, "pthread_create"); + if ((rc = pthread_create(&tid[2], NULL, t1, NULL)) == -1) + errc(1, rc, "pthread_create"); + + if ((rc = pthread_join(tid[0], NULL)) == -1) + errc(1, rc, "pthread_join"); + if ((rc = pthread_join(tid[1], NULL)) == -1) + errc(1, rc, "pthread_join"); + if ((rc = pthread_join(tid[2], NULL)) == -1) + errc(1, rc, "pthread_join"); + } + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + size_t len; + time_t start; + int i, status; + + 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) { + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + + for(;;) { + if (share[SYNC] > 0) + atomic_add_int(&share[SYNC], -1); + for (i = 0; i < PARALLEL; i++) + kill(pids[i], SIGSTOP); + usleep(100 + arc4random() % 1000); + for (i = 0; i < PARALLEL; i++) + kill(pids[i], SIGCONT); + usleep(100 + arc4random() % 400); + if (share[SYNC] == 0) { /* If all procs are done */ + usleep(500); + if (share[SYNC] == 0) + break; + } + } + + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], &status, 0) != pids[i]) + err(1, "waitpid"); + } + } + + return (0); +} diff --git a/tools/test/stress2/misc/nfs15lockd.sh b/tools/test/stress2/misc/nfs15lockd.sh new file mode 100755 index 000000000000..8e744b967b18 --- /dev/null +++ b/tools/test/stress2/misc/nfs15lockd.sh @@ -0,0 +1,240 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC Isilon +# All rights reserved. +# +# 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 "wrong handling for suspend". +# https://www.mail-archive.com/freebsd-current@freebsd.org/msg166333.html + +# panic: Failed to register NFS lock locally - error=11 +# https://people.freebsd.org/~pho/stress/log/kostik897.txt +# Fixed in r302013. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +pgrep -q lockd || { echo "lockd not running."; exit 1; } + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > nfs15lockd.c +mycc -o nfs15lockd -Wall -Wextra -O2 -g nfs15lockd.c -lpthread || exit 1 +rm -f nfs15lockd.c +cd $here + +mount | grep "on $mntpoint " | grep nfs > /dev/null && umount $mntpoint + +[ $# -ne 0 ] && + # Problem only seen with lockd + { echo "Not using lockd"; debug="-o nolockd"; } +mount -t nfs -o tcp -o retrycnt=3 -o soft -o rw $debug \ + $nfs_export $mntpoint +sleep 2 + +s=0 +lockf -t 10 $mntpoint/$$.lock sleep 2 > /tmp/$$.log 2>&1 +if grep -q "No locks available" /tmp/$$.log; then + echo "Is lockd running on the remote host?" + rm /tmp/$$.log + s=1 +fi + +wd=$mntpoint/nfs15lockd-`jot -rc 8 a z | tr -d '\n'`.dir +rm -rf $wd +mkdir $wd + +echo "Expect: nfs15lockd exited on signal 6 (core dumped)" +(cd $wd; /tmp/nfs15lockd) & +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 600 ]; do + pgrep -q nfs15lockd || break + sleep 2 +done +if pgrep -q nfs15lockd; then + s=2 + echo "Thread suspension issue:" + ps -lx | grep -v grep | grep nfs15lockd | grep "T+" | \ + awk '{print $2}' | while read pid; do + ps -lp$pid + procstat -k $pid + kill -9 $pid + done + pkill nfs15lockd +fi +wait +rm -rf $wd + +n=0 +while mount | grep "on $mntpoint " | grep -q nfs; do + umount $mntpoint && break + n=$((n + 1)) + if [ $n -gt 60 ]; then + fstat -mf $mntpoint + s=3 + break + fi + sleep 2 +done 2>&1 | awk '!seen[$0]++' +mount | grep -q "on $mntpoint " && umount -f $mntpoint + +rm -f /tmp/nfs15lockd nfs15lockd.core +exit $s +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 4 +#define RUNTIME 300 +#define SYNC 0 + +volatile u_int *share; + +static void * +t1(void *data __unused) +{ + atomic_add_int(&share[SYNC], 1); + usleep(arc4random() % 8000); + raise(SIGABRT); + + return (NULL); +} + +static void * +t2(void *data __unused) +{ + int fd, i, r; + char file[80]; + + for (i = 0; i < 100; i++) { + atomic_add_int(&share[SYNC], 1); + snprintf(file, sizeof(file), "file.%06d", i); + if ((fd = open(file, O_WRONLY | O_CREAT | O_APPEND, + DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + do { + r = lockf(fd, F_LOCK, 0); + } while (r == -1 && (errno == EDEADLK || errno == EINTR)); + if (r == -1) + err(1, "lockf(%s, F_LOCK)", file); + write(fd, "x", 1); + usleep(arc4random() % 1000); + if (lseek(fd, 0, SEEK_SET) == -1) + err(1, "lseek"); + if (lockf(fd, F_ULOCK, 0) == -1) + err(1, "lockf(%s, F_ULOCK)", file); + close(fd); + } + + return (NULL); +} + +int +test(void) +{ + pthread_t tid[3]; + int i, rc; + + for (i = 0; i < 10; i++) { + if ((rc = pthread_create(&tid[0], NULL, t2, NULL)) == -1) + errc(1, rc, "pthread_create"); + if ((rc = pthread_create(&tid[1], NULL, t2, NULL)) == -1) + errc(1, rc, "pthread_create"); + if ((rc = pthread_create(&tid[2], NULL, t1, NULL)) == -1) + errc(1, rc, "pthread_create"); + + if ((rc = pthread_join(tid[0], NULL)) == -1) + errc(1, rc, "pthread_join"); + if ((rc = pthread_join(tid[1], NULL)) == -1) + errc(1, rc, "pthread_join"); + if ((rc = pthread_join(tid[2], NULL)) == -1) + errc(1, rc, "pthread_join"); + } + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + size_t len; + time_t start; + int i, status; + + 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) { + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + + for(;;) { + if (share[SYNC] > 0) + atomic_add_int(&share[SYNC], -1); + for (i = 0; i < PARALLEL; i++) + kill(pids[i], SIGSTOP); + usleep(1000); + for (i = 0; i < PARALLEL; i++) + kill(pids[i], SIGCONT); + usleep(100 + arc4random() % 400); + if (share[SYNC] == 0) { /* If all procs are done */ + usleep(500); + if (share[SYNC] == 0) + break; + } + } + + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], &status, 0) != pids[i]) + err(1, "waitpid"); + } + } + + return (0); +} diff --git a/tools/test/stress2/misc/nfs15lockd2.sh b/tools/test/stress2/misc/nfs15lockd2.sh new file mode 100755 index 000000000000..dcbef1946ce3 --- /dev/null +++ b/tools/test/stress2/misc/nfs15lockd2.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Page fault seen: +# https://people.freebsd.org/~pho/stress/log/kostik907.txt +# Fixed by: r302019 + r302020. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +./nfs15lockd.sh & +sleep 10 +mount | grep "on $mntpoint " | grep -q nfs && umount -f $mntpoint +wait +exit $? diff --git a/tools/test/stress2/misc/nfs15lockd3.sh b/tools/test/stress2/misc/nfs15lockd3.sh new file mode 100755 index 000000000000..fe43efa64a7c --- /dev/null +++ b/tools/test/stress2/misc/nfs15lockd3.sh @@ -0,0 +1,250 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC Isilon +# All rights reserved. +# +# 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 "wrong handling for suspend". +# https://www.mail-archive.com/freebsd-current@freebsd.org/msg166333.html + +# Variation of nfs15lockd.sh + +# Threads marked as stopped, but can not be killed. +# Fixed by r302215. + +# Also seen and not fixed: +# $ fstat -mf /mnt +# USER CMD PID FD MOUNT INUM MODE SZ|DV R/W +# $ umount /mnt +# umount: unmount of /mnt failed: Device busy +# $ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +pgrep -q lockd || { echo "lockd not running."; exit 1; } + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > nfs15lockd3.c +mycc -o nfs15lockd3 -Wall -Wextra -O2 -g nfs15lockd3.c -lpthread || exit 1 +rm -f nfs15lockd3.c +cd $here + +mount | grep "on $mntpoint " | grep nfs > /dev/null && umount $mntpoint + +[ $# -ne 0 ] && + # Problem only seen with lockd + { echo "Not using lockd"; debug="-o nolockd"; } +mount -t nfs -o tcp -o retrycnt=3 -o soft -o rw $debug \ + $nfs_export $mntpoint +sleep 2 + +s=0 +lockf -t 10 $mntpoint/$$.lock sleep 2 > /tmp/$$.log 2>&1 +if grep -q "No locks available" /tmp/$$.log; then + echo "Is lockd running on the remote host?" + rm /tmp/$$.log + s=1 +fi + +wd=$mntpoint/nfs15lockd3-`jot -rc 8 a z | tr -d '\n'`.dir +rm -rf $wd +mkdir $wd + +(cd $wd; /tmp/nfs15lockd3) & +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 600 ]; do + pgrep -q nfs15lockd || break + sleep 2 +done +if pgrep -q nfs15lockd; then + s=2 + echo "Thread suspension issue:" + ps -lx | grep -v grep | grep nfs15lockd | grep "T+" | \ + awk '{print $2}' | while read pid; do + ps -lp$pid + procstat -k $pid + kill -9 $pid + done + pkill nfs15lockd +fi +wait +rm -rf $wd + +n=0 +while mount | grep "on $mntpoint " | grep -q nfs; do + umount $mntpoint && break + n=$((n + 1)) + if [ $n -gt 60 ]; then + fstat -mf $mntpoint + s=3 + break + fi + sleep 2 +done + +rm -f /tmp/nfs15lockd3 nfs15lockd3.core file.0????? +exit $s +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 4 +#define RUNTIME 300 +#define SYNC 0 + +volatile u_int *share; + +static void * +t1(void *data __unused) +{ + atomic_add_int(&share[SYNC], 1); + usleep(arc4random() % 8000); + raise(SIGABRT); + + return (NULL); +} + +static void * +t2(void *data __unused) +{ + int fd, i, r; + char file[80]; + + for (i = 0; i < 10; i++) { + atomic_add_int(&share[SYNC], 1); + snprintf(file, sizeof(file), "file.%06d", i); + if ((fd = open(file, O_WRONLY | O_CREAT | O_APPEND, + DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + do { + r = lockf(fd, F_LOCK, 0); + } while (r == -1 && (errno == EDEADLK || errno == EINTR)); + if (r == -1) + err(1, "lockf(%s, F_LOCK)", file); + write(fd, "x", 1); + usleep(arc4random() % 1000); + if (lseek(fd, 0, SEEK_SET) == -1) + err(1, "lseek"); + if (lockf(fd, F_ULOCK, 0) == -1) + err(1, "lockf(%s, F_ULOCK)", file); + close(fd); + } + + return (NULL); +} + +int +test(void) +{ + pthread_t tid[3]; + int i, rc; + + for (i = 0; i < 5; i++) { + if ((rc = pthread_create(&tid[0], NULL, t2, NULL)) == -1) + errc(1, rc, "pthread_create"); + if ((rc = pthread_create(&tid[1], NULL, t2, NULL)) == -1) + errc(1, rc, "pthread_create"); + if ((rc = pthread_create(&tid[2], NULL, t1, NULL)) == -1) + errc(1, rc, "pthread_create"); + + if ((rc = pthread_join(tid[0], NULL)) == -1) + errc(1, rc, "pthread_join"); + if ((rc = pthread_join(tid[1], NULL)) == -1) + errc(1, rc, "pthread_join"); + if ((rc = pthread_join(tid[2], NULL)) == -1) + errc(1, rc, "pthread_join"); + } + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + size_t len; + time_t start; + int i, n, status; + + 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); + n = 0; + while (time(NULL) - start < RUNTIME) { + n++; + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + + for(;;) { + if (share[SYNC] > 0) + atomic_add_int(&share[SYNC], -1); + for (i = 0; i < PARALLEL; i++) + kill(pids[i], SIGSTOP); + usleep(1000); + for (i = 0; i < PARALLEL; i++) + kill(pids[i], SIGCONT); + usleep(100 + arc4random() % 400); + if (share[SYNC] == 0) { /* If all procs are done */ + usleep(500); + if (share[SYNC] == 0) + break; + } + } + + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], &status, 0) != pids[i]) + err(1, "waitpid"); + } + if (n > 2) + break; + } + + return (0); +} diff --git a/tools/test/stress2/misc/nfs16.sh b/tools/test/stress2/misc/nfs16.sh new file mode 100755 index 000000000000..b8bc0d1237cf --- /dev/null +++ b/tools/test/stress2/misc/nfs16.sh @@ -0,0 +1,196 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 nfs15.sh, using lockd(8). +# "panic: Failed to register NFS lock locally - error=11" seen: +# https://people.freebsd.org/~pho/stress/log/kostik897.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > nfs16.c +mycc -o nfs16 -Wall -Wextra -O2 -g nfs16.c -lpthread || exit 1 +rm -f nfs16.c +cd $here + +mount | grep "on $mntpoint " | grep nfs > /dev/null && umount $mntpoint + +mount -t nfs -o tcp -o retrycnt=3 -o soft -o rw \ + $nfs_export $mntpoint +sleep 2 +wd=$mntpoint/nfs16.dir +rm -rf $wd +mkdir $wd + +(cd $wd; /tmp/nfs16) +rm -rf $wd + +while mount | grep "on $mntpoint " | grep -q nfs; do + umount $mntpoint || sleep 1 +done + +rm -f /tmp/nfs16 +exit 0 +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 4 +#define RUNTIME 300 +#define SYNC 0 + +volatile u_int *share; + +static void * +t1(void *data __unused) +{ + atomic_add_int(&share[SYNC], 1); + usleep(arc4random() % 8000); + raise(SIGABRT); + + return (NULL); +} + +static void * +t2(void *data __unused) +{ + int fd, i, r; + char file[80]; + + for (i = 0; i < 100; i++) { + atomic_add_int(&share[SYNC], 1); + snprintf(file, sizeof(file), "file.%06d", i); + if ((fd = open(file, O_WRONLY | O_CREAT | O_APPEND, DEFFILEMODE)) == -1) + err(1, "open(%s)", file); + do { + r = lockf(fd, F_LOCK, 0); + } while (r == -1 && errno == EDEADLK); + if (r == -1) + err(1, "lockf(%s, F_LOCK)", file); + write(fd, "x", 1); + usleep(arc4random() % 1000); + if (lseek(fd, 0, SEEK_SET) == -1) + err(1, "lseek"); + if (lockf(fd, F_ULOCK, 0) == -1) + err(1, "lockf(%s, F_ULOCK)", file); + close(fd); + } + + return (NULL); +} + +int +test(void) +{ + pthread_t tid[3]; + int i, rc; + + for (i = 0; i < 10; i++) { + if ((rc = pthread_create(&tid[0], NULL, t2, NULL)) == -1) + errc(1, rc, "pthread_create"); + if ((rc = pthread_create(&tid[1], NULL, t2, NULL)) == -1) + errc(1, rc, "pthread_create"); + if ((rc = pthread_create(&tid[2], NULL, t1, NULL)) == -1) + errc(1, rc, "pthread_create"); + + if ((rc = pthread_join(tid[0], NULL)) == -1) + errc(1, rc, "pthread_join"); + if ((rc = pthread_join(tid[1], NULL)) == -1) + errc(1, rc, "pthread_join"); + if ((rc = pthread_join(tid[2], NULL)) == -1) + errc(1, rc, "pthread_join"); + } + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + size_t len; + time_t start; + int i, status; + + 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) { + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + + for(;;) { + if (share[SYNC] > 0) + atomic_add_int(&share[SYNC], -1); + for (i = 0; i < PARALLEL; i++) + kill(pids[i], SIGSTOP); + usleep(1000); + for (i = 0; i < PARALLEL; i++) + kill(pids[i], SIGCONT); + usleep(100 + arc4random() % 400); + if (share[SYNC] == 0) { /* If all procs are done */ + usleep(500); + if (share[SYNC] == 0) + break; + } + } + + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], &status, 0) != pids[i]) + err(1, "waitpid"); + } + } + + return (0); +} diff --git a/tools/test/stress2/misc/nfs17.sh b/tools/test/stress2/misc/nfs17.sh new file mode 100755 index 000000000000..2a012e476e55 --- /dev/null +++ b/tools/test/stress2/misc/nfs17.sh @@ -0,0 +1,76 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# Copy tests to a NFS FS and run from there. + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +mount | grep "on $mntpoint " | grep -q nfs && umount $mntpoint +mount -t nfs -o tcp -o retrycnt=3 -o soft -o rw $nfs_export $mntpoint +grep -q $mntpoint /etc/exports || + { echo "$mntpoint missing from /etc/exports"; exit 0; } + +chmod 777 $mntpoint + +rm -rf $mntpoint/nfs17; mkdir -p $mntpoint/nfs17 +chmod 0777 $mntpoint/nfs17 +cp -r ../../stress2 $mntpoint/nfs17 + +log=/tmp/nfs17.log +export CTRLDIR=$mntpoint/nfs17/stressX.control +export LOAD=80 +export MAXSWAPPCT=80 +export RUNDIR=$mntpoint/nfs17/stressX +export runRUNTIME=5m +export rwLOAD=80 +export TESTPROGS=`cd ..; find testcases/ -perm -1 -type f | \ + egrep -v "/run/|lockf|dirnprename"` + +here=`pwd` +cd $mntpoint/nfs17/stress2/misc || exit 1 +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' 2>&1 | tee $log +cd $here +rm -rf $mntpoint/nfs17/stress2 + +for i in `jot 3`; do + umount $mntpoint && break + sleep 10 +done +mount | grep -q "on $mntpoint " && { s=1; umount -f $mntpoint; } +sed < /tmp/nfs17.log | sed '/Loop/d;/run time/d' +s=0 +[ `sed < /tmp/nfs17.log | sed '/Loop/d;/run time/d' | wc -l` -ne 0 ] && + s=2 +[ $s -ne 0 ] && echo "Exit value is $s" +exit $s diff --git a/tools/test/stress2/misc/nfs2.sh b/tools/test/stress2/misc/nfs2.sh new file mode 100755 index 000000000000..9d470c18e8f0 --- /dev/null +++ b/tools/test/stress2/misc/nfs2.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2013 Peter Holm +# All rights reserved. +# +# 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 msdos over nfs. "panic: wrong diroffset" seen. +# This needs to be in /etc/exports: /mnt -maproot=root 127.0.0.1 + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +grep -q $mntpoint /etc/exports || + { echo "$mntpoint missing from /etc/exports"; exit 0; } +[ -x /sbin/mount_msdosfs ] || exit + +D=$diskimage +dd if=/dev/zero of=$D bs=1m count=128 status=none || exit + +mount | grep "${mntpoint}2" | grep nfs > /dev/null && umount -f ${mntpoint}2 +mount | grep "$mntpoint" | grep /md > /dev/null && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart + +bsdlabel -w md$mdstart auto +newfs_msdos -F 16 -b 8192 /dev/md${mdstart}$part > /dev/null +mount -t msdosfs -o rw /dev/md${mdstart}$part $mntpoint + +mkdir $mntpoint/stressX +chmod 777 $mntpoint/stressX + +[ ! -d ${mntpoint}2 ] && mkdir ${mntpoint}2 +chmod 777 ${mntpoint}2 + +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw \ + 127.0.0.1:$mntpoint ${mntpoint}2 + +export INODES=9999 # No inodes on a msdos fs +export RUNDIR=${mntpoint}2/stressX +export runRUNTIME=10m # Run tests for 10 minutes +(cd ..; ./run.sh disk.cfg) + +umount -f ${mntpoint}2 > /dev/null 2>&1 +umount -f $mntpoint > /dev/null 2>&1 +mdconfig -d -u $mdstart +rm -f $D diff --git a/tools/test/stress2/misc/nfs3.sh b/tools/test/stress2/misc/nfs3.sh new file mode 100755 index 000000000000..69ed0275b41d --- /dev/null +++ b/tools/test/stress2/misc/nfs3.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2013 Peter Holm +# All rights reserved. +# +# 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: neg mount point vnode list size + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +[ ! -d $mntpoint ] && mkdir $mntpoint +mount | grep "$mntpoint" | grep nfs > /dev/null && umount $mntpoint +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export $mntpoint +sleep 1 +rm -rf $mntpoint/stressX/* +rm -rf /tmp/stressX.control + +export RUNDIR=$mntpoint/nfs3.`jot -rc 8 a z | tr -d '\n'`/stressX +mkdir -p $RUNDIR +export runRUNTIME=1m +rm -rf /tmp/stressX.control/* + +su $testuser -c "(cd ..; ./run.sh io.cfg > /dev/null 2>&1)" & +sleep 50 + +while mount | grep -q "on $mntpoint "; do + umount -f $mntpoint || sleep 1 +done +kill -9 $! +../tools/killall.sh +wait +exit 0 diff --git a/tools/test/stress2/misc/nfs4.sh b/tools/test/stress2/misc/nfs4.sh new file mode 100755 index 000000000000..1d986c161154 --- /dev/null +++ b/tools/test/stress2/misc/nfs4.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2013 Peter Holm +# All rights reserved. +# +# 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: vm_fault: fault on nofault entry, from vfs_stdcheckexp+0x74 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +[ ! -d $mntpoint ] && mkdir $mntpoint +mount | grep "$mntpoint" | grep nfs > /dev/null && umount $mntpoint +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export $mntpoint +rm -rf $mntpoint/stressX/* +rm -rf /tmp/stressX.control + +export RUNDIR=$mntpoint/nfs4.`jot -rc 8 a z | tr -d '\n'`/stressX +mkdir -p $RUNDIR +chmod 777 $RUNDIR +export runRUNTIME=3m +rm -rf /tmp/stressX.control/* + +su $testuser -c '(cd ..; ./run.sh all.cfg) > /dev/null 2>&1' & +sleep 60 + +while mount | grep -q $mntpoint; do + umount -f $mntpoint > /dev/null 2>&1 + sleep 1 +done +kill -9 $! +../tools/killall.sh +wait + +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export $mntpoint +sleep .2 +su $testuser -c "find $RUNDIR -delete 2>/dev/null" +find $RUNDIR -delete +for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && exit 1 || exit 0 diff --git a/tools/test/stress2/misc/nfs5.sh b/tools/test/stress2/misc/nfs5.sh new file mode 100755 index 000000000000..1f311ef47baf --- /dev/null +++ b/tools/test/stress2/misc/nfs5.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2013 Peter Holm +# All rights reserved. +# +# 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. +# + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +D=$diskimage +dd if=dev=zero of=$D bs=1m count=128 status=none || exit + +mount | grep "${mntpoint}2" | grep nfs > /dev/null && umount -f ${mntpoint}2 +mount | grep "$mntpoint" | grep /md > /dev/null && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart + +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +mkdir $mntpoint/stressX +chmod 777 $mntpoint/stressX + +[ ! -d ${mntpoint}2 ] && mkdir ${mntpoint}2 +chmod 777 ${mntpoint}2 + +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw 127.0.0.1:$mntpoint \ + ${mntpoint}2 + +export RUNDIR=${mntpoint}2/stressX +export runRUNTIME=4m +su $testuser -c "(cd ..; ./run.sh disk.cfg > /dev/null 2>&1)" & +sleep 60 + +umount -f $mntpoint > /dev/null 2>&1 +umount -f ${mntpoint}2 > /dev/null 2>&1 + +mdconfig -d -u $mdstart +rm -f $D +kill $! +../tools/killall.sh +wait +exit 0 diff --git a/tools/test/stress2/misc/nfs6.sh b/tools/test/stress2/misc/nfs6.sh new file mode 100755 index 000000000000..98b2a9d40945 --- /dev/null +++ b/tools/test/stress2/misc/nfs6.sh @@ -0,0 +1,81 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2013 Peter Holm +# All rights reserved. +# +# 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: vn_finished_write: neg cnt +# http://people.freebsd.org/~pho/stress/log/kostik500.txt +# http://people.freebsd.org/~pho/stress/log/nfs6.txt + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +grep -q $mntpoint /etc/exports || + { echo "$mntpoint missing from /etc/exports"; exit 0; } + +D=$diskimage +dd if=/dev/zero of=$D bs=1m count=128 status=none || exit + +mount | grep "${mntpoint}2" | grep nfs > /dev/null && umount -f ${mntpoint}2 +mount | grep "$mntpoint" | grep /md > /dev/null && umount -f $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart + +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +mkdir $mntpoint/stressX +chmod 777 $mntpoint/stressX + +[ ! -d ${mntpoint}2 ] && mkdir ${mntpoint}2 +chmod 777 ${mntpoint}2 + +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw 127.0.0.1:$mntpoint \ + ${mntpoint}2 + +export RUNDIR=${mntpoint}2/stressX +export runRUNTIME=4m +su $testuser -c "(cd ..; ./run.sh disk.cfg > /dev/null 2>&1)" & +sleep 60 + +for i in `jot 10`; do + umount -f $mntpoint > /dev/null 2>&1 + sleep 1 + mount /dev/md${mdstart}$part $mntpoint + sleep 1 +done + +umount -f $mntpoint > /dev/null 2>&1 +umount -f ${mntpoint}2 > /dev/null 2>&1 + +mdconfig -d -u $mdstart +rm -f $D +kill $! +../tools/killall.sh +wait +exit 0 diff --git a/tools/test/stress2/misc/nfs7.sh b/tools/test/stress2/misc/nfs7.sh new file mode 100755 index 000000000000..8fad71000f73 --- /dev/null +++ b/tools/test/stress2/misc/nfs7.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# +# Copyright (c) 2009-2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# NFS test excluding lockd + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +[ ! -d $mntpoint ] && mkdir $mntpoint +mount | grep "$mntpoint" | grep nfs > /dev/null && umount $mntpoint +mount -t nfs -o nfsv3,tcp,nolockd -o retrycnt=3 -o intr,soft -o rw \ + $nfs_export $mntpoint +rm -rf /tmp/stressX.control + +export RUNDIR=$mntpoint/nfs7.`jot -rc 8 a z | tr -d '\n'`/stressX +USE_TIMEOUT=1 +rm -rf $RUNDIR +mkdir -p $RUNDIR +chmod 777 $RUNDIR +export runRUNTIME=10m +rm -rf /tmp/stressX.control/* + +su $testuser -c "(cd ..; ./run.sh marcus.cfg) > /dev/null 2>&1" + +umount $mntpoint +while mount | grep -q $mntpoint; do + umount -f $mntpoint > /dev/null 2>&1 +done + +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export $mntpoint +sleep .2 +su $testuser -c "find $RUNDIR -delete 2>/dev/null" +find $RUNDIR -delete +for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && exit 1 || exit 0 diff --git a/tools/test/stress2/misc/nfs8.sh b/tools/test/stress2/misc/nfs8.sh new file mode 100755 index 000000000000..010b3b1ae8e0 --- /dev/null +++ b/tools/test/stress2/misc/nfs8.sh @@ -0,0 +1,66 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 scenario for a lock cascade problem with sending SIGSTOP to processes +# accessing a NFS intr mount. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +[ ! -d $mntpoint ] && mkdir $mntpoint +mount | grep "$mntpoint" | grep nfs > /dev/null && umount $mntpoint +mount -t nfs -o nfsv3,tcp,nolockd -o retrycnt=3 -o intr,soft -o rw \ + $nfs_export $mntpoint +sleep .2 + +wdir=$mntpoint/nfs8.sh.dir +mkdir -p $wdir +jot 1000 | xargs -I% touch $wdir/% +for i in `jot 10`; do + find $mntpoint > /dev/null 2>&1 & + sleep 0.1 + kill -s STOP $! + pids="$pids $!" +done +rm -rf $wdir + +umount $mntpoint 2>&1 | grep -v "Device busy" +while mount | grep -q $mntpoint; do + umount -f $mntpoint > /dev/null 2>&1 +done + +kill -s CONT $pids +for pid in $pids; do + wait $pid +done +exit 0 diff --git a/tools/test/stress2/misc/nfs9.sh b/tools/test/stress2/misc/nfs9.sh new file mode 100755 index 000000000000..b970ab8e564c --- /dev/null +++ b/tools/test/stress2/misc/nfs9.sh @@ -0,0 +1,88 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# Copy of nfs4.sh, where it was discovered that a missing killall.sh script +# turned up quite a few new panics. For example: + +# vfs_mount_destroy: nonzero writeopcount +# Lock nfs not locked @ kern/vfs_default.c:462 +# Assertion x == LK_SHARERS_LOCK(1) failed at kern/kern_lock.c:236 + +# "panic: SACK scoreboard must not be empty" seen: +# https://people.freebsd.org/~pho/stress/log/nfs9-2.txt + +# Hang seen: +# $ ps -lp52442 +# UID PID PPID CPU PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND +# 0 52442 52120 0 20 0 11336 2868 nfsreq S 0 0:01.48 rm -rf /mnt/nfs9.dktfkpuf/stressX + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +[ ! -d $mntpoint ] && mkdir $mntpoint +export RUNDIR=$mntpoint/nfs9.`jot -rc 8 a z | tr -d '\n'`/stressX +USE_TIMEOUT=1 +s=0 +start=`date +%s` +for i in `jot 10`; do + mount | grep "on $mntpoint " | grep -q nfs && umount $mntpoint + mount -t nfs -o tcp -o retrycnt=3 -o intr -o soft \ + -o rw $nfs_export $mntpoint + sleep .5 + + rm -rf $RUNDIR 2> /dev/null + mkdir -p $RUNDIR || exit 1 + chmod -R 777 $RUNDIR 2> /dev/null + export runRUNTIME=3m + rm -rf /tmp/stressX.control/* + + if [ $i -eq 10 -o $((`date +%s` - start)) -ge 600 ]; then + ../tools/killall.sh + su $testuser -c "rm -rf $RUNDIR" 2> /dev/null + rm -rf `dirname $RUNDIR` || s=1 + done=1 + else + su $testuser -c '(cd ..; ./run.sh all.cfg) > /dev/null \ + 2>&1' & + sleep 60 + fi + + while mount | grep -q $mntpoint; do + umount -f $mntpoint > /dev/null 2>&1 + done + ../tools/killall.sh || break + kill -9 $! 2>/dev/null + wait + [ $done ] && break +done +exit $s diff --git a/tools/test/stress2/misc/nfs_halfpage.sh b/tools/test/stress2/misc/nfs_halfpage.sh new file mode 100755 index 000000000000..b665e84d7ddf --- /dev/null +++ b/tools/test/stress2/misc/nfs_halfpage.sh @@ -0,0 +1,99 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2017 Konstantin Belousov +# +# 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 + +# Regression test for: +# Mark pages after EOF as clean after pageout. +# https://reviews.freebsd.org/D11697 +# Committed as r321580 + r321581. + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/nfs_halfpage.c +mycc -o nfs_halfpage -Wall -Wextra -O0 -g nfs_halfpage.c || exit 1 +rm -f nfs_halfpage.c +cd $odir + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +mount | grep "$mntpoint" | grep -q nfs && umount $mntpoint +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export $mntpoint + +file=$mntpoint/nfs_halfpage.file +/tmp/nfs_halfpage $file + +echo "Reboot now to trigger syncing disks loop." +sleep 60 + +rm $file +for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && s=1 || s=0 +rm -f /tmp/nfs_halfpage + +exit $s +EOF +/* $Id: nfs_halfpage.c,v 1.2 2017/07/23 09:36:23 kostik Exp kostik $ */ + +#include +#include +#include +#include + +int +main(int argc __unused, char *argv[]) +{ + char *m; + int error, fd, pgsz, sz; + + pgsz = getpagesize(); + fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666); + if (fd == -1) + err(1, "open %s", argv[1]); + sz = pgsz / 4; + error = lseek(fd, sz, SEEK_SET); + if (error == -1) + err(1, "lseek"); + error = write(fd, "a", 1); + if (error == -1) + err(1, "write"); + else if (error != 1) + errx(1, "short write"); + m = mmap(NULL, sz + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (m == MAP_FAILED) + err(1, "mmap"); + m[0] = 'x'; +} diff --git a/tools/test/stress2/misc/nfs_halfpage2.sh b/tools/test/stress2/misc/nfs_halfpage2.sh new file mode 100755 index 000000000000..15895da2da21 --- /dev/null +++ b/tools/test/stress2/misc/nfs_halfpage2.sh @@ -0,0 +1,103 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2017 Konstantin Belousov +# +# 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 + +# Variation of nfs_halfpage.sh with a 2GB file. +# Mark pages after EOF as clean after pageout. +# https://reviews.freebsd.org/D11697 +# Committed as r321580 + r321581. + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/nfs_halfpage.c +mycc -o nfs_halfpage -Wall -Wextra -O0 -g nfs_halfpage.c || exit 1 +rm -f nfs_halfpage.c +cd $odir + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +mount | grep "$mntpoint" | grep -q nfs && umount $mntpoint +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export $mntpoint + +file=$mntpoint/nfs_halfpage.file +/tmp/nfs_halfpage $file + +ls -l $file +echo "Reboot now to trigger syncing disks loop." +sleep 60 + +rm $file +for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && exit 1 +rm -f /tmp/nfs_halfpage + +exit 0 +EOF +/* $Id: nfs_halfpage.c,v 1.2 2017/07/23 09:36:23 kostik Exp kostik $ */ + +#include +#include +#include +#include +#include + +int +main(int argc __unused, char *argv[]) +{ + off_t sz; + char *m; + int error, fd, pgsz; + + pgsz = getpagesize(); + fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666); + if (fd == -1) + err(1, "open %s", argv[1]); + sz = pgsz / 4; + sz += 2LL * 1024 * 1024 * 1024; + error = lseek(fd, sz, SEEK_SET); + if (error == -1) + err(1, "lseek"); + error = write(fd, "a", 1); + if (error == -1) + err(1, "write"); + else if (error != 1) + errx(1, "short write"); + m = mmap(NULL, sz + 1, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (m == MAP_FAILED) + err(1, "mmap"); + m[sz - 1] = 'x'; +} diff --git a/tools/test/stress2/misc/nfsdelegation.sh b/tools/test/stress2/misc/nfsdelegation.sh new file mode 100755 index 000000000000..b84b63e96658 --- /dev/null +++ b/tools/test/stress2/misc/nfsdelegation.sh @@ -0,0 +1,169 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 nfsv4 delegations. Scenario suggestion by kib. +# "(nfsdelegation), uid 0, was killed: text file modification" seen. +# Fixed by r316745 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > nfsdelegation.c +mycc -o nfsdelegation -Wall -Wextra -O0 nfsdelegation.c || exit 1 +rm -f nfsdelegation.c + +[ `sysctl -n sysctl vfs.timestamp_precision` -ne 3 ] && + echo "vfs.timestamp_precision must be set to 3" +[ "`sysctl -ni vfs.nfsd.issue_delegations`" != "1" ] && + { echo "vfs.nfsd.issue_delegations is not enabled"; exit 0; } +pgrep -q nfscbd || { echo "nfscbd is not running"; exit 0; } + +mount | grep "$mntpoint" | grep -q nfs && umount $mntpoint +opt="-o nocto" +opt="$opt -o nolockd -o nfsv4" +mount $opt $nfs_export $mntpoint || exit 1 +sleep .2 + +wdir=$mntpoint/nfsdelegation.`jot -rc 8 a z | tr -d '\n'`/nfsdelegation +mkdir -p $wdir || exit 1 + +delegs=0 +s=0 +(cd $wdir; /tmp/nfsdelegation) & +while kill -0 $! 2>/dev/null; do + r=`nfsstat -ec | grep -A1 Delegs | tail -1 | awk '{print $5}'` + [ $r -gt $delegs ] && { delegs=$r; break; } +done +wait +[ $delegs -eq 0 ] && { echo "No delegations detected"; s=2; } + +rm -rf $wdir +umount $mntpoint +while mount | grep "$mntpoint " | grep -q nfs; do + umount -f $mntpoint +done +tail -3 /var/log/messages | grep -m1 nfsdelegation: && s=2 +rm -f /tmp/nfsdelegation +exit $s +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 100 +#define INPUTFILE "/bin/sleep" +#define PARALLEL 3 + +static volatile u_int *share; + +static int +tmmap(int idx) +{ + struct stat statbuf; + pid_t epid, pid; + int i; + int fdout; + char *cmdline[3], *dst, file[128], help[80]; + + pid = getpid(); + cmdline[1] = ".01"; + cmdline[2] = 0; + for (i = 0; i < LOOPS; i++) { + sprintf(file,"nfsdelegation.p%05d.%05d", pid, i); + cmdline[0] = file; + + snprintf(help, sizeof(help), "cp %s %s; chmod 777 %s", INPUTFILE, file, file); + system(help); + share[idx] = 0; + if ((epid = fork()) == 0) { + alarm(60); + while (share[idx] == 0) + usleep(100); + if (execve(cmdline[0], cmdline, NULL) == -1) + err(1, "execve"); + } + + if ((fdout = open(file, O_RDWR)) < 0) + err(1, "open(%s)", file); + if (fstat(fdout, &statbuf) < 0) + err(1, "fstat error"); + + if ((dst = mmap(0, statbuf.st_size, PROT_READ | PROT_WRITE | + MAP_PRIVATE, MAP_SHARED, fdout, 0)) == (caddr_t) - 1) + err(1, "mmap error for output"); + + dst[statbuf.st_size] = 1; + + close(fdout); + if (munmap(dst, statbuf.st_size) == -1) + err(1, "munmap"); + share[idx] = 1; + if (waitpid(epid, NULL, 0) != epid) + err(1, "waitpid(%d)", epid); + } + + _exit(0); +} + +int +main(void) +{ + size_t len; + int i; + + len = PAGE_SIZE; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + tmmap(i); + } + + for (i = 0; i < PARALLEL; i++) { + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/nfsdepth.sh b/tools/test/stress2/misc/nfsdepth.sh new file mode 100755 index 000000000000..1abe56e24a80 --- /dev/null +++ b/tools/test/stress2/misc/nfsdepth.sh @@ -0,0 +1,239 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 + +# NFS test with deep directories. + +# Only issue seen is: +# nfsdepth: mkdir(d93) l35: Permission denied + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > nfsdepth.c +mycc -o nfsdepth -Wall -Wextra -g nfsdepth.c || exit 1 +rm -f nfsdepth.c +cd $odir + +mount | grep "$mntpoint" | grep nfs > /dev/null && umount $mntpoint +mount -t nfs -o tcp -o rw -o soft $nfs_export $mntpoint + +work=$mntpoint/nfsdepth.`jot -rc 8 a z | tr -d '\n'`.dir +mkdir -p $work +chmod 777 $work + +su $testuser -c "cd $work; /tmp/nfsdepth" +s=$? +if [ $s -eq 0 ]; then + su $testuser -c "rm -rf $work 2>/dev/null" + rm -rf $work +else + find $work -ls +fi + +umount $mntpoint > /dev/null 2>&1 +while mount | grep "$mntpoint" | grep -q nfs; do + umount $mntpoint > /dev/null 2>&1 +done + +rm -f /tmp/nfsdepth +exit $s + +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static unsigned long actual, size; +volatile int done_testing; +int fail; + +#define DEPTH 200 +#define PARALLEL 8 +#define RUNTIME 180 + +void +handler(int s __unused) +{ + done_testing = 1; +} + +void +mkDir(char *path, int level) { + int n, r; + char newPath[MAXPATHLEN + 1]; + + n = 0; + do { + r = mkdir(path, 0770); + if (r == -1 && errno == EACCES && n < 10) { + warn("mkdir(%s) l%d", path, __LINE__); + n++; + errno = EAGAIN; + usleep(10000); + } + if (r == -1 && errno == EINTR) + (void)rmdir(path); + } while (r == -1 && (errno == EINTR || errno == EAGAIN)); + + if (r == -1) { + warn("mkdir(%s), pid %d, l%d", path, getpid(), __LINE__); + fail++; + } else { + actual++; + do { + r = chdir (path); + if (r == -1 && errno == EACCES && n < 10) { + warn("chdir(%s) .%d", path, __LINE__); + n++; + errno = EAGAIN; + usleep(10000); + } + } while (r == -1 && (errno == EINTR || errno == EAGAIN)); + if (r == -1) + err(1, "chdir(%s), pid %d, l%d", path, getpid(), __LINE__); + } + + if (done_testing == 0 && fail == 0 && level < (int)size) { + sprintf(newPath,"d%d", level + 1); + mkDir(newPath, level + 1); + } +} + +void +rmDir(char *path, int level) { + int n, r; + char newPath[MAXPATHLEN + 1]; + + if (level == 0) + return; + + if (level < (int)actual) { + sprintf(newPath,"d%d", level+1); + rmDir(newPath, level+1); + } + n = 0; + do { + r = chdir (".."); + if (r == -1 && errno == EACCES && n < 10) { + warn("chdir(%s) l%d", path, __LINE__); + n++; + errno = EAGAIN; + usleep(10000); + } + } while (r == -1 && (errno == EINTR || errno == EAGAIN)); + if (r == -1) + err(1, "chdir(%s), pid %d, l%d", "..", getpid(), __LINE__); + n = 0; + do { + r = rmdir(path); + if (r == -1 && errno == EACCES && n < 10) { + warn("rmdir(%s) l%d", path, __LINE__); + n++; + errno = EAGAIN; + usleep(10000); + } + } while (r == -1 && (errno == EINTR || errno == EAGAIN)); + if (r == -1) + err(1, "rmdir(%s), pid %d, l%d", path, getpid(), __LINE__); +} + +int +test2(void) +{ + char path[MAXPATHLEN + 1]; + + fail = actual = 0; + umask(0); + sprintf(path,"p%05d.d%d", getpid(), 1); + mkDir(path, 1); + rmDir(path, 1); + + _exit (fail); +} + +int +test(void) +{ + pid_t pid; + time_t start; + int status; + + size = (arc4random() % DEPTH) + 1; + + signal(SIGHUP, handler); + start = time(NULL); + while (time(NULL) - start < RUNTIME && fail == 0) { + if ((pid = fork()) == 0) { + done_testing = 0; + test2(); + } + + status = 0; + while (wait4(pid, &status, WNOHANG, NULL) != pid) { + if (kill(pid, SIGHUP) == -1) + err(1, "kill(%d)", pid); + usleep(100000 + (arc4random() % 10000)); + } + if (status != 0) + fail++; + } + + _exit (status != 0); +} + +int +main(void) +{ + int e, i, pids[PARALLEL], status; + + e = 0; + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + for (i = 0; i < PARALLEL; i++) { + waitpid(pids[i], &status, 0); + e += status == 0 ? 0 : 1; + } + + return (e); +} diff --git a/tools/test/stress2/misc/nfsrename.sh b/tools/test/stress2/misc/nfsrename.sh new file mode 100755 index 000000000000..b6513fba1553 --- /dev/null +++ b/tools/test/stress2/misc/nfsrename.sh @@ -0,0 +1,224 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2013 Peter Holm +# All rights reserved. +# +# 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 + +# Test scenario by jhb@ + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > nfsrename.c +mycc -o nfsrename -Wall nfsrename.c +rm -f nfsrename.c +cd $odir + +mount | grep "$mntpoint" | grep nfs > /dev/null && umount $mntpoint +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export $mntpoint + +for i in `jot 10`; do + /tmp/nfsrename $mntpoint/nfsrename.$i > /dev/null 2>&1 & + pids="$pids $!" +done +s=0 +for i in $pids; do + wait $i + [ $? -ne 0 ] && s=1 +done +pkill nfsrename +rm -f $mntpoint/nfsrename.* + +umount $mntpoint > /dev/null 2>&1 +while mount | grep "$mntpoint" | grep -q nfs; do + umount -f $mntpoint > /dev/null 2>&1 +done + +rm -f /tmp/nfsrename +exit $s + +EOF +/* + * Try to expose races with doing renames over NFS that require silly + * renames. This results in 2 different RENAME RPCs leaving a race + * window where the file may not exist. It also appears that FreeBSD + * with shared lookups in NFS can get confused and possibly reference + * the sillyrenamed file in lookup but the file is deleted by the time + * open gets to it. + */ + +#include +#include +#include +#include +#include +#include +#include + +static char *filename; +static char *dir; + +#define RUNTIME 720 + +static void +usage(void) +{ + + fprintf(stderr, "nfsrename: [-n children] file\n"); + exit(1); +} + +static void +read_file(void) +{ + FILE *fp; + char buffer[4096]; + + fp = fopen(filename, "r"); + if (fp == NULL) { + return; + } + while (!feof(fp)) { + if (fread(buffer, sizeof(buffer), 1, fp) < sizeof(buffer)) + break; + } + if (ferror(fp)) + warnx("fread encountered an error"); + fclose(fp); +} + +static void +write_file(void) +{ + FILE *fp; + char path[1024]; + int fd; + + snprintf(path, sizeof(path), "%s/nfsrename.XXXXXX", dir); + fd = mkstemp(path); + if (fd < 0) { + warn("mkstemp"); + return; + } + + fp = fdopen(fd, "w"); + if (fp == NULL) { + warn("fdopen:writer"); + close(fd); + unlink(path); + } + + fprintf(fp, "blah blah blah garbage %ld\n", random()); + fclose(fp); + if (rename(path, filename) < 0) { + warn("rename"); + unlink(path); + } +} + +static void +random_sleep(int base, int slop) +{ + long val; + + val = random() % slop; + usleep(base + val); +} + +static void +child(void) +{ + time_t start; + + start = time(NULL); + for (;;) { + random_sleep(500, 50); + read_file(); + if (time(NULL) - start > RUNTIME) + errx(1, "Timed out"); + } + exit(0); +} + +int +main(int ac, char **av) +{ + time_t start; + long i, nchild; + char *cp; + int ch; + + nchild = 1; + while ((ch = getopt(ac, av, "n:")) != -1) { + switch (ch) { + case 'n': + nchild = strtol(optarg, &cp, 0); + if (*cp != '\0') + errx(1, "Invalid count %s", optarg); + break; + case '?': + default: + usage(); + } + } + ac -= optind; + av += optind; + + if (ac == 0) + errx(1, "Missing filename"); + else if (ac > 1) + errx(1, "Extra arguments"); + + filename = av[0]; + dir = dirname(filename); + srandomdev(); + write_file(); + + for (i = 0; i < nchild; i++) { + switch (fork()) { + case 0: + child(); + case -1: + err(1, "fork"); + } + } + + start = time(NULL); + for (i = 0; i < 10000; i++) { + random_sleep(1500, 1000); + write_file(); + if (time(NULL) - start > RUNTIME) + errx(1, "Timed out"); + } + + return (0); +} diff --git a/tools/test/stress2/misc/nfssillyrename.sh b/tools/test/stress2/misc/nfssillyrename.sh new file mode 100755 index 000000000000..8cb63c920533 --- /dev/null +++ b/tools/test/stress2/misc/nfssillyrename.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# "rm: src/: Directory not empty" seen. + +# See also nfsrename.sh + +# Test scenario by bdrewery@ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +mount | grep "$mntpoint" | grep -q nfs && umount $mntpoint +mount -t nfs -o tcp -o retrycnt=3 -o soft -o rw $nfs_export $mntpoint || + exit 1 + +mp=$mntpoint/sillyrename +rm -rf $mp +mkdir -p $mp + +status=0 +cd $mp +mkdir src dst +touch src/foo +ln src/foo dst/foo +tail -F dst/foo & +rm -rf src/ || status=1 + +cd / +kill $! +wait +rm -rf $mp +umount $mntpoint +while mount | grep "$mntpoint " | grep -q nfs; do + umount -f $mntpoint +done +exit $status diff --git a/tools/test/stress2/misc/nullfs.sh b/tools/test/stress2/misc/nullfs.sh new file mode 100755 index 000000000000..1424a90eed44 --- /dev/null +++ b/tools/test/stress2/misc/nullfs.sh @@ -0,0 +1,72 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Stress test by performing parallel calls to mount and umount. Alternate +# between forced and non-forced unmounts. + +# https://people.freebsd.org/~pho/stress/log/kostik169.txt +# https://people.freebsd.org/~pho/stress/log/kostik487.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mounts=15 # Number of parallel scripts +: ${nullfs_srcdir:=/tmp} +: ${nullfs_dstdir:=$mntpoint} + +if [ $# -eq 0 ]; then + for i in `jot $mounts`; do + [ ! -d ${nullfs_dstdir}$i ] && mkdir ${nullfs_dstdir}$i + mount | grep -q " ${nullfs_dstdir}$i " && + umount ${nullfs_dstdir}$i + done + + # start the parallel tests + for i in `jot $mounts`; do + ./$0 $i & + done + wait + + for i in `jot $mounts`; do + umount ${nullfs_dstdir}$i > /dev/null 2>&1 + done + exit 0 +else + # The test: Parallel mount and unmounts + start=`date '+%s'` + while [ `date '+%s'` -lt $((start + 300)) ]; do + m=$1 + mount_nullfs $nullfs_srcdir ${nullfs_dstdir}$m > \ + /dev/null 2>&1 + opt=`[ $(( m % 2 )) -eq 0 ] && echo -f` + while mount | grep -q ${nullfs_dstdir}$m; do + umount $opt ${nullfs_dstdir}$m > /dev/null 2>&1 + done + done +fi diff --git a/tools/test/stress2/misc/nullfs10.sh b/tools/test/stress2/misc/nullfs10.sh new file mode 100755 index 000000000000..4444bcca2913 --- /dev/null +++ b/tools/test/stress2/misc/nullfs10.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 + +# Regression test: + +# There is an issue, namely, when the lower file is already +# opened r/w, but its nullfs alias is executed. This situation obviously +# shall result in ETXTBUSY, but it currently does not. + +# Test scenario by kib@ + +. ../default.cfg + +mnt2=${mntpoint}2 +mount | grep -q $mnt2 && umount $mnt2 + +[ -d $mnt2 ] || mkdir $mnt2 +mount | grep $mnt2 | grep -q /dev/md && umount -f $mnt2 +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +mount -t nullfs $mntpoint $mnt2 + +cp /bin/ls $mntpoint +chmod +w $mntpoint/ls +sleep 2 >> $mntpoint/ls & +sleep .5 +# This line should cause a "/mnt2/ls: Text file busy" +$mnt2/ls -l /bin/ls $mntpoint $mnt2 && echo FAIL || echo OK +kill $! +wait + +while mount | grep -q "$mnt2 "; do + umount $mnt2 || sleep 1 +done + +while mount | grep -q "$mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/nullfs11.sh b/tools/test/stress2/misc/nullfs11.sh new file mode 100755 index 000000000000..9d02abd3b3ca --- /dev/null +++ b/tools/test/stress2/misc/nullfs11.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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. +# + +# nullfs cache / nocache benchmark + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +export LANG=C +CACHE=nullfs11-cache.log +NOCACHE=nullfs11-nocache.log +mp1=$mntpoint +mp2=${mntpoint}2 +[ -d $mp2 ] || mkdir $mp2 +rm -f $CACHE $NOCACHE + +mycc -o /tmp/fstool ../tools/fstool.c + +test() { + opt=$1 + mount | grep -wq $mp2 && umount $mp2 + mount | grep -wq $mp1 && umount $mp1 + mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + mdconfig -a -t swap -s 2g -u $mdstart || exit 1 + bsdlabel -w md$mdstart auto + newfs $newfs_flags md${mdstart}$part > /dev/null + mount /dev/md${mdstart}$part $mp1 + + mount -t nullfs $opt $mp1 $mp2 + + i=1 + (mkdir $mp2/test$i; cd $mp2/test$i; /tmp/fstool -l -f 50 -n 500 -s 4k) + rm -rf $mp2/test$i + sync + sleep 5 + + parallel=4 + for j in `jot 5`; do + s=`date '+%s'` + for i in `jot $parallel`; do + (mkdir $mp2/test$i; cd $mp2/test$i; \ + /tmp/fstool -l -f 50 -n 500 -s $((i * 4))k) & + done + for i in `jot $parallel`; do + wait + done + rm -rf $mp2/* + echo $((`date '+%s'` - $s)) + done + while mount | grep -wq $mp2; do + umount $mp2 || sleep 1 + done + while mount | grep $mp1 | grep -q /dev/md; do + umount $mp1 || sleep 1 + done + mdconfig -d -u $mdstart +} + +test "-o nocache" > $NOCACHE +test "-o cache" > $CACHE + +ministat -s -w 60 $NOCACHE $CACHE +rm -f /tmp/fstool $CACHE $NOCACHE diff --git a/tools/test/stress2/misc/nullfs12.sh b/tools/test/stress2/misc/nullfs12.sh new file mode 100755 index 000000000000..12671bb695c1 --- /dev/null +++ b/tools/test/stress2/misc/nullfs12.sh @@ -0,0 +1,64 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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 + +# "umount -f" test with files open for writing +# "panic: vputx: missed vn_close" seen. +# Scenario by kib@. Fixed in r245262. + +. ../default.cfg + +mnt2=${mntpoint}2 +mount | grep -q $mnt2 && umount $mnt2 + +[ -d $mnt2 ] || mkdir $mnt2 +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint +mount -t nullfs $mntpoint $mnt2 + +(sleep 5 > $mnt2/log) & +sleep 1 +umount -f $mnt2 + +kill $! +wait + +while mount | grep -q "$mnt2 "; do + umount $mnt2 || sleep 1 +done + +while mount | grep -q "$mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/nullfs13.sh b/tools/test/stress2/misc/nullfs13.sh new file mode 100755 index 000000000000..5c51621a8c94 --- /dev/null +++ b/tools/test/stress2/misc/nullfs13.sh @@ -0,0 +1,77 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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 + +# kern/178238 "nullfs don't release i-nodes on unlink" +# See also nullfs16.sh +# Fixed by: r292961. + +. ../default.cfg + +nullfsmp=${mntpoint}2 +mount | grep -q "$nullfsmp " && umount $nullfsmp + +[ -d $nullfsmp ] || mkdir $nullfsmp +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint +mount -t nullfs $mntpoint $nullfsmp + +(cd $nullfsmp; jot 20 | xargs touch) +rm $nullfsmp/* + +(cd $nullfsmp; jot 20 | xargs touch) +rm $mntpoint/* + +(cd $mntpoint; jot 20 | xargs touch) +rm $mntpoint/* + +(cd $mntpoint; jot 20 | xargs touch) +rm $nullfsmp/* + +ino=`df -i $nullfsmp | tail -1 | awk '{print $6}'` +if [ $ino -ne 2 ]; then + echo FAIL + df -i $mntpoint $nullfsmp + echo "ls -la $mntpoint $nullfsmp" + ls -la $mntpoint $nullfsmp +fi + +while mount | grep -q "$nullfsmp "; do + umount $nullfsmp || sleep 1 +done + +while mount | grep -q "$mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/nullfs14.sh b/tools/test/stress2/misc/nullfs14.sh new file mode 100755 index 000000000000..96bcb470dc40 --- /dev/null +++ b/tools/test/stress2/misc/nullfs14.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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 + +# Page fault seen in fifo_close() + +. ../default.cfg + +nullfsmp=${mntpoint}2 +mount | grep -q "$nullfsmp " && umount $nullfsmp + +[ -d $nullfsmp ] || mkdir $nullfsmp +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +#chmod 777 $mntpoint +mount -t nullfs $mntpoint $nullfsmp + +mkfifo $nullfsmp/fifo +rm $mntpoint/fifo # Triggers page fault + +while mount | grep -q "$nullfsmp "; do + umount $nullfsmp || sleep 1 +done + +while mount | grep -q "$mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/nullfs15.sh b/tools/test/stress2/misc/nullfs15.sh new file mode 100755 index 000000000000..fcaca4af8cb9 --- /dev/null +++ b/tools/test/stress2/misc/nullfs15.sh @@ -0,0 +1,64 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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 + +# panic: lockmgr still held. Fixed in r250852. +# Test scenario by antoine@ + +nullfsmp=${mntpoint}2 +mount | grep -q "$nullfsmp " && umount $nullfsmp + +[ -d $nullfsmp ] || mkdir $nullfsmp +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +mount -t nullfs $mntpoint $nullfsmp + +mkdir $mntpoint/.new_packages $nullfsmp/new_packages +mount -t nullfs $mntpoint/.new_packages $nullfsmp/new_packages +dd if=/dev/zero of=$nullfsmp/new_packages/bar count=20000 status=none +mv $mntpoint/.new_packages/bar /tmp/ +rm -rf $mntpoint/.new_packages +umount -f $nullfsmp/new_packages + +while mount | grep -q "$nullfsmp "; do + umount $nullfsmp || sleep 1 +done + +while mount | grep -q "$mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/bar +exit 0 diff --git a/tools/test/stress2/misc/nullfs16.sh b/tools/test/stress2/misc/nullfs16.sh new file mode 100755 index 000000000000..32f6d006bda6 --- /dev/null +++ b/tools/test/stress2/misc/nullfs16.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 + +# [Bug 178238] [nullfs] nullfs don't release i-nodes on unlink. +# Test scenaro by: noah.bergbauer@tum.de +# Fixed by: r292961 + +mount | grep -q "on $mntpoint " && umount -f $mntpoint +mount -o size=1g -t tmpfs tmpfs $mntpoint + +mp2=${mntpoint}2 +[ -d $mp2 ] || mkdir -p $mp2 +mount | grep -q "on $mp2 " && umount -f $mp2 +mount -t nullfs $mntpoint $mp2 + +# Expect second dd to fail +for i in `jot 2`; do + dd if=/dev/zero of=$mp2/file bs=1m count=1023 \ + status=none + rm -f $mp2/file +done +if [ `df -i $mp2 | tail -1 | awk '{print $5}'` = "100%" ]; then + echo FAIL + s=1 + ls -al $mntpoint $mp2 + df -i | egrep "${mntpoint}$|${mp2}$" +fi + +umount $mp2 +umount $mntpoint + +exit $s diff --git a/tools/test/stress2/misc/nullfs17.sh b/tools/test/stress2/misc/nullfs17.sh new file mode 100755 index 000000000000..121225f67c00 --- /dev/null +++ b/tools/test/stress2/misc/nullfs17.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 nullfs.sh + +# "panic: LK_RETRY set with incompatible flags (0x202400) or +# an error occured (11)" seen. +# https://people.freebsd.org/~pho/stress/log/matt001.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mounts=15 # Number of parallel scripts +: ${nullfs_srcdir:=/tmp} +: ${nullfs_dstdir:=$mntpoint} +CONT=/tmp/nullfs17.continue + +if [ $# -eq 0 ]; then + for i in `jot $mounts`; do + [ ! -d ${nullfs_dstdir}$i ] && mkdir ${nullfs_dstdir}$i + mount | grep -q " ${nullfs_dstdir}$i " && + umount ${nullfs_dstdir}$i + done + + # start the parallel tests + for i in `jot $mounts`; do + ./$0 $i & + ./$0 find $i & + done + wait + + for i in `jot $mounts`; do + umount ${nullfs_dstdir}$i > /dev/null 2>&1 + done + exit 0 +else + if [ $1 = find ]; then + while [ -f $CONT ]; do + find ${nullfs_dstdir}$2 -type f -maxdepth 2 -ls > \ + /dev/null 2>&1 + done + else + # The test: Parallel mount and unmounts + touch $CONT + start=`date '+%s'` + while [ `date '+%s'` -lt $((start + 300)) ]; do + m=$1 + mount_nullfs $nullfs_srcdir ${nullfs_dstdir}$m > \ + /dev/null 2>&1 + opt=`[ $(( m % 2 )) -eq 0 ] && echo -f` + while mount | grep -q ${nullfs_dstdir}$m; do + umount $opt ${nullfs_dstdir}$m > \ + /dev/null 2>&1 + done + done + rm -f $CONT + fi +fi diff --git a/tools/test/stress2/misc/nullfs18.sh b/tools/test/stress2/misc/nullfs18.sh new file mode 100755 index 000000000000..1f3320bff1e6 --- /dev/null +++ b/tools/test/stress2/misc/nullfs18.sh @@ -0,0 +1,133 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 + +# Demonstate nullfs(5) inode leak. +# Fixed by r295717. + +. ../default.cfg + +N=3 + +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs -n md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$(($1 / N)) +export INODES=$(($2 / N)) + +export runRUNTIME=2m +export LOAD=80 +export symlinkLOAD=80 +export rwLOAD=80 +export TESTPROGS=" +testcases/rw/rw +testcases/creat/creat +testcases/mkdir/mkdir +" + +for i in `jot $N 1`; do + eval mp$i=${mntpoint}$i +done + +for i in `jot $N 1`; do + eval mp=\$mp$i + [ -d $mp ] || mkdir -p $mp + mount | grep $mp | grep -q nullfs && umount -f $mp + msrc=$mntpoint/d$i + mkdir -p $msrc + chmod 777 $msrc + mount -t nullfs $msrc $mp + chmod 777 $mp + export RUNDIR=$mp/stressX + export CTRLDIR=$mp/stressX.control + mkdir $RUNDIR $CTRLDIR + chmod 777 $RUNDIR $CTRLDIR + su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > \ + /dev/null 2>&1 & + mps="$mps $mp" +done + +(cd ../testcases/swap; ./swap -t 10m -i 20 > /dev/null 2>&1) & +sleep 1 +while pgrep -q run; do + find $mps -ls > /dev/null 2>&1 +done +while pgrep -q swap; do + pkill -9 swap +done +wait + +(cd $mntpoint; find . -delete) +sync; sleep 1; sync; sleep 1; sync +inodes=`df -i $mntpoint | tail -1 | awk '{print $6}'` +if [ $inodes -ne 4 ]; then + echo "FAIL 1" + e=1 + mount | sed -n "1p;/${mntpoint#/}/p" + echo + df -ik | sed -n "1p;/${mntpoint#/}/p" + printf "\nfind ${mntpoint}* -ls\n" + find ${mntpoint}* -ls + + for i in `jot $N 1`; do + eval mp=\$mp$i + echo "umount $mp" + mount | grep $mp | grep -q nullfs && umount $mp + done + + echo + df -ik | sed -n "1p;/${mntpoint#/}/p" +else + for i in `jot $N 1`; do + eval mp=\$mp$i + mount | grep $mp | grep -q nullfs && umount $mp + done + inodes=`df -i $mntpoint | tail -1 | awk '{print $6}'` + if [ $inodes -ne 1 ]; then + echo "FAIL 2" + e=2 + mount | sed -n "1p;/${mntpoint#/}/p" + echo + df -ik | sed -n "1p;/${mntpoint#/}/p" + fi +fi + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +exit $e diff --git a/tools/test/stress2/misc/nullfs19.sh b/tools/test/stress2/misc/nullfs19.sh new file mode 100755 index 000000000000..fd5f16f4b780 --- /dev/null +++ b/tools/test/stress2/misc/nullfs19.sh @@ -0,0 +1,90 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 + +# Simplified version of nullfs18.sh + +. ../default.cfg + +N=3 + +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs -n $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$(($1 / N)) +export INODES=$(($2 / N)) + +export runRUNTIME=2m +export LOAD=80 +export TESTPROGS=" +testcases/creat/creat +testcases/link/link +testcases/mkdir/mkdir +testcases/fts/fts +" + +for i in `jot $N 1`; do + eval mp$i=${mntpoint}$i +done + +for i in `jot $N 1`; do + eval mp=\$mp$i + [ -d $mp ] || mkdir -p $mp + mount | grep $mp | grep -q nullfs && umount -f $mp + msrc=$mntpoint/d$i + mkdir -p $msrc + chmod 777 $msrc + mount -t nullfs $msrc $mp + chmod 777 $mp + export RUNDIR=$mp/stressX + export CTRLDIR=$mp/stressX.control + mkdir $RUNDIR $CTRLDIR + chmod 777 $RUNDIR $CTRLDIR + su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > \ + /dev/null 2>&1 & +done +wait + +for i in `jot $N 1`; do + eval mp=\$mp$i + mount | grep $mp | grep -q nullfs && umount $mp +done + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/nullfs2.sh b/tools/test/stress2/misc/nullfs2.sh new file mode 100755 index 000000000000..96cf57407f9c --- /dev/null +++ b/tools/test/stress2/misc/nullfs2.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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. +# + +# Simple nullfs test scenario. + +# Deadlock seen: +# https://people.freebsd.org/~pho/stress/log/nullfs2-2.txt +# suj34.sh seems to trigger the same problem. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +# NULLFS(5) and SUJ has known issues. +mount | grep "on `df $RUNDIR | sed '1d;s/.* //'` " | \ + grep -q "journaled soft-updates" && + { echo "Skipping test due to SUJ."; exit 0; } + +mount | grep -q "on $mntpoint " && umount -f $mntpoint + +mount -t nullfs $RUNDIR $mntpoint + +export RUNDIR=$mntpoint/stressX +export runRUNTIME=10m +(cd ..; ./run.sh marcus.cfg) + +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done diff --git a/tools/test/stress2/misc/nullfs20.sh b/tools/test/stress2/misc/nullfs20.sh new file mode 100755 index 000000000000..78c5295bae32 --- /dev/null +++ b/tools/test/stress2/misc/nullfs20.sh @@ -0,0 +1,74 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 + +# VOP_LOOKUP: 0xfffff8014d6fe000 is not locked but should be +# https://people.freebsd.org/~pho/stress/log/nullfs20.txt + +. ../default.cfg + +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs -n -b 4096 -f 512 -i 1024 md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +mp2=$mntpoint$((mdstart + 1)) +[ -d $mp2 ] || mkdir -p $mp2 +mount | grep -wq $mp2 && umount $mp2 +mount -t nullfs $mntpoint $mp2 + +export runRUNTIME=10m +export RUNDIR=$mp2/stressX + +export LOAD=100 +export ftsLOAD=100 +export TESTPROGS=" +testcases/fts/fts +testcases/swap/swap +testcases/link/link +" + +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' + +while mount | grep $mp2 | grep -q nullfs; do + umount $mp2 || sleep 1 +done +n=0 +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 + n=$((n + 1)) + [ $n -gt 30 ] && { echo FAIL; exit 1; } +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/nullfs21.sh b/tools/test/stress2/misc/nullfs21.sh new file mode 100755 index 000000000000..209ed65d1d3f --- /dev/null +++ b/tools/test/stress2/misc/nullfs21.sh @@ -0,0 +1,71 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 + +# mv removes the file. This is OK on FreeBSD. +# This is handled on Linux with "mount --bind". + +. ../default.cfg + +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 512m -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto + +newfs -n -b 4096 -f 512 -i 1024 md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint + +mp2=${mntpoint}2 +[ -d $mp2 ] || mkdir -p $mp2 +mount | grep -wq $mp2 && umount $mp2 +mount -t nullfs $mntpoint $mp2 + +touch $mntpoint/file + +# mv's rename(2) fails as this is a "cross mount" -> +# rm dst; cp src dst; rm src + +mv $mp2/file $mountpoint/file +[ -f $mntpoint/file ] || + { ls -ali $mntpoint $mp2; status=0; } +# { echo FAIL; ls -ali $mntpoint $mp2; status=1; } + +while mount | grep $mp2 | grep -q nullfs; do + umount $mp2 || sleep 1 +done +n=0 +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 + n=$((n + 1)) + [ $n -gt 30 ] && { echo FAIL; status=2; } +done +mdconfig -d -u $mdstart +exit $status diff --git a/tools/test/stress2/misc/nullfs22.sh b/tools/test/stress2/misc/nullfs22.sh new file mode 100755 index 000000000000..f7652d71bf40 --- /dev/null +++ b/tools/test/stress2/misc/nullfs22.sh @@ -0,0 +1,247 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# fcntl(2) locking scenario, using UFS and a nullfs mount. +# No problems seen. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > nullfs22.c +mycc -o nullfs22 -Wall -Wextra -O0 -g nullfs22.c || exit 1 +rm -f nullfs22.c + +mp2=${mntpoint}2 +[ -d $mp2 ] || mkdir -p $mp2 +mount | grep -q "on $mp2 " && umount $mp2 +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs -n md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +mount -t nullfs $mntpoint $mp2 + +/tmp/nullfs22 $mntpoint $mp2 +status=$? + +while mount | grep -q "on $mp2 "; do + umount $mp2 +done +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/nullfs22 +exit $status +EOF +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 1024 +#define N (512) +#define PARALLEL 4 + +#define DONE 1 +#define SYNC 0 + +int fd; +volatile u_int *share; +char name1[80], name2[80]; + +static void +ahandler(int s __unused) +{ + fprintf(stderr, "In alarm handler\n"); + unlink(name1); + _exit(1); +} + +void +add(int n, int increment) +{ + struct flock fl; + off_t pos; + long val, oval; + int r; + + pos = n * sizeof(val); + memset(&fl, 0, sizeof(fl)); + fl.l_start = pos; + fl.l_len = sizeof(val); + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + + while (fcntl(fd, F_SETLKW, &fl) < 0) { + if (errno != EAGAIN) + err(1, "F_SETLKW (child)"); + usleep(100); + } + + if (lseek(fd, pos, SEEK_SET) == -1) + err(1, "lseek"); + oval = 999999; + while ((r = read(fd, &val, sizeof(val)) != sizeof(val))) { + if (r == -1 && errno != EAGAIN) + err(1, "read"); + if (lseek(fd, pos, SEEK_SET) == -1) + err(1, "lseek"); + } + 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 (lseek(fd, pos, SEEK_SET) == -1) + err(1, "lseek"); + while ((r = write(fd, &val, sizeof(val)) != sizeof(val))) { + if (r == -1 && errno != EAGAIN) + err(1, "write"); + if (lseek(fd, pos, SEEK_SET) == -1) + err(1, "lseek"); + } + + fl.l_type = F_UNLCK; + if (fcntl(fd, F_SETLK, &fl) < 0) + err(1, "F_UNLCK"); + +} + +void +count(int val) +{ + int i, j; + char help[80], *name; + + if (val == 1) + name = name1; + else + name = name2; + snprintf(help, sizeof(help), "%s %d %s", __func__, val, name); + setproctitle("%s", help); + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != 2 * PARALLEL) + ; + + /* Need to re-open after a fork() */ + close(fd); + if ((fd = open(name, O_RDWR)) == -1) + err(1, "open(%s)", name); + + for (i = 0; i < LOOPS; i++) { + for (j = 0; j < N; j++) + add(j, val); + } + + atomic_add_int(&share[DONE], 1); + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + off_t len; + size_t mlen; + long val, sum; + int i, s, stat; + + if (argc != 3) { + fprintf(stderr, "Usage: %s \n", argv[0]); + exit(1); + } + + mlen = PAGE_SIZE; + if ((share = mmap(NULL, mlen, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + snprintf(name1, sizeof(name1), "%s/work", argv[1]); + snprintf(name2, sizeof(name2), "%s/work", argv[2]); + signal(SIGALRM, ahandler); + alarm(300); + if ((fd = open(name1, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) + err(1, "open(%s)", name1); + len = N * sizeof(val); + if (ftruncate(fd, len) == -1) + err(1, "ftruncate"); + + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + count(1); + } + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + count(-1); + } + + while (share[DONE] != 2 * PARALLEL) + usleep(10000); + + if (lseek(fd, 0, SEEK_SET) == -1) + err(1, "lseek"); + sum = 0; + for (i = 0; i < N; i++) { + if (read(fd, &val, sizeof(val)) != sizeof(val)) + err(1, "Final read"); + if (val != 0) + fprintf(stderr, "index %d: %ld\n", i, val); + sum += val; + } + if (sum != 0) + fprintf(stderr, "FAIL\n"); + unlink(name1); + + s = 0; + for (i = 0; i < PARALLEL; i++) { + wait(&stat); + s += WEXITSTATUS(stat); + wait(&stat); + s += WEXITSTATUS(stat); + } + + close(fd); + + return (sum != 0 || s != 0); +} diff --git a/tools/test/stress2/misc/nullfs23.sh b/tools/test/stress2/misc/nullfs23.sh new file mode 100755 index 000000000000..3e91c04d91b4 --- /dev/null +++ b/tools/test/stress2/misc/nullfs23.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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: Lock (lockmgr) nullfs not locked @ kern/kern_lock.c:620." seen: +# https://people.freebsd.org/~pho/stress/log/nullfs23.txt + +. ../default.cfg +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +mp2=/media +mount | grep "$mp2" | grep -q nfs && umount $mp2 +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export $mp2 + +export nullfs_srcdir=$mp2 +../misc/nullfs17.sh + +umount $mp2 +while mount | grep "$mp2 " | grep -q nfs; do + umount -f $mp2 +done +exit 0 diff --git a/tools/test/stress2/misc/nullfs24.sh b/tools/test/stress2/misc/nullfs24.sh new file mode 100755 index 000000000000..d7741c52a73a --- /dev/null +++ b/tools/test/stress2/misc/nullfs24.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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 nullfs.sh + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mounts=15 # Number of parallel scripts +: ${nullfs_srcdir:=/tmp} +: ${nullfs_dstdir:=$mntpoint} +runtime=300 + +for i in `jot $mounts`; do + [ ! -d ${nullfs_dstdir}$i ] && mkdir ${nullfs_dstdir}$i + mount | grep -q " ${nullfs_dstdir}$i " && + umount ${nullfs_dstdir}$i +done + +for i in `jot $mounts`; do + start=`date '+%s'` + while [ `date '+%s'` -lt $((start + $runtime)) ]; do + find ${nullfs_dstdir}* -type f -maxdepth 2 -ls > \ + /dev/null 2>&1 + done & +done + +(cd ../testcases/swap; ./swap -t ${runtime}s -i 20) & +for i in `jot $mounts`; do + # The test: Parallel mount and unmounts + start=`date '+%s'` + while [ `date '+%s'` -lt $((start + $runtime)) ]; 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 & +done +wait +exit 0 diff --git a/tools/test/stress2/misc/nullfs25.sh b/tools/test/stress2/misc/nullfs25.sh new file mode 100755 index 000000000000..5588567ead22 --- /dev/null +++ b/tools/test/stress2/misc/nullfs25.sh @@ -0,0 +1,90 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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 nullfs17.sh WiP + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +mounts=4 # Number of parallel scripts +: ${nullfs_srcdir:=$mntpoint} +: ${nullfs_dstdir:=$mntpoint} +CONT=/tmp/nullfs25.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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $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 + find ${nullfs_dstdir}$i -type f -maxdepth 2 -ls > \ + /dev/null 2>&1 + done & + # The test: Parallel mount and unmounts + 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 +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/nullfs26.sh b/tools/test/stress2/misc/nullfs26.sh new file mode 100755 index 000000000000..720021e9e199 --- /dev/null +++ b/tools/test/stress2/misc/nullfs26.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# +. ../default.cfg + +# nullfs + tmpfs scenario. No problems seen. + +mp1=${mntpoint}$mdstart +mp2=${mntpoint}$((mdstart + 1)) +mkdir -p $mp1 $mp2 +mount -o size=5g -t tmpfs null $mp1 || exit 1 +mount -t nullfs $mp1 $mp2 || exit 1 + +export runRUNTIME=10m +export RUNDIR=$mp2/stressX +mkdir -p $RUNDIR; chmod 0777 $RUNDIR + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' + +umount $mp2 +umount $mp1 +exit 0 diff --git a/tools/test/stress2/misc/nullfs27.sh b/tools/test/stress2/misc/nullfs27.sh new file mode 100755 index 000000000000..02894fba5efb --- /dev/null +++ b/tools/test/stress2/misc/nullfs27.sh @@ -0,0 +1,91 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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 + +# Run all the rename(2) test scenarios with nullfs. +# Used in connection with WiP work on nullfs. + +. ../default.cfg + +set -e +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +mp2=${mntpoint}2 +[ -d $mp2 ] || mkdir -p $mp2 +mount | grep -wq $mp2 && umount $mp2 +mount -t nullfs $mntpoint $mp2 +chmod 777 $mp2 +set +e + +export LOAD=80 +export MAXSWAPPCT=80 +export RUNDIR=$mp2/stressX +export runRUNTIME=10m +export rwLOAD=80 +export TESTPROGS=' +testcases/lockf2/lockf2 +testcases/symlink/symlink +testcases/openat/openat +testcases/socket/socket +testcases/rw/rw +testcases/mmap/mmap +testcases/fts/fts +testcases/link/link +testcases/lockf/lockf +testcases/creat/creat +testcases/mkdir/mkdir +testcases/rename/rename +testcases/swap/swap +testcases/mkfifo/mkfifo +testcases/dirnprename/dirnprename +testcases/dirrename/dirrename +' + +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' + +while mount | grep $mp2 | grep -q nullfs; do + umount $mp2 || sleep 1 +done +n=0 +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 + n=$((n + 1)) + [ $n -gt 30 ] && { echo FAIL; status=2; } +done +mdconfig -d -u $mdstart +exit $status diff --git a/tools/test/stress2/misc/nullfs3.sh b/tools/test/stress2/misc/nullfs3.sh new file mode 100755 index 000000000000..36a606ce7b7e --- /dev/null +++ b/tools/test/stress2/misc/nullfs3.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 scenario by "Paul B. Mahol" + +# Caused: lock violation + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +# NULLFS(5) and SUJ has known issues. +mount | grep "on `df $RUNDIR | sed '1d;s/.* //'` " | \ + grep -q "journaled soft-updates" && + { echo "Skipping test due to SUJ."; exit 0; } + +[ -d $RUNDIR/stressX ] || mkdir -p $RUNDIR/stressX + +mp=$mntpoint +mount | grep -q $mp && umount -f $mp + +mount -t nullfs `dirname $RUNDIR` $mp + +cd $mp/stressX +whereis something > /dev/null +cd / + +umount $mp + +mount | grep -q $mp && umount -f $mp +exit 0 diff --git a/tools/test/stress2/misc/nullfs4.sh b/tools/test/stress2/misc/nullfs4.sh new file mode 100755 index 000000000000..ac328196f56a --- /dev/null +++ b/tools/test/stress2/misc/nullfs4.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 scenario by Anatoli Klassen + +# kern/94269: [nullfs] procfs shows wrong data if executable is running from +# nullfs + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep -q /proc || mount -t procfs procfs /proc +mount -t nullfs /bin $mntpoint + +r1=`/bin/ls -l /proc/curproc/file` +r2=`$mntpoint/ls -l /proc/curproc/file | sed "s#$mntpoint#/bin#"` +if [ "$r1" != "$r2" ]; then + echo "/bin/ls -l /proc/curproc/file" + echo $r1 + echo "$mntpoint/ls -l /proc/curproc/file" + echo $r2 +fi + +umount $mntpoint diff --git a/tools/test/stress2/misc/nullfs5.sh b/tools/test/stress2/misc/nullfs5.sh new file mode 100755 index 000000000000..fa73b8179817 --- /dev/null +++ b/tools/test/stress2/misc/nullfs5.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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. +# + +# Composite test: nullfs2.sh + kinfo.sh + +# Kernel page fault with the following non-sleepable locks held from +# nullfs/null_vnops.c:531 + +# Fatal trap 12: page fault while in kernel mode +# https://people.freebsd.org/~pho/stress/log/jeff106.txt + +# panic: vholdl: inactive held vnode: +# https://people.freebsd.org/~pho/stress/log/kostik815.txt + +# umount busy seen: +# https://people.freebsd.org/~pho/stress/log/kostik893.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +# NULLFS(5) and SUJ has known issues. +mount | grep "on `df $RUNDIR | sed '1d;s/.* //'` " | \ + grep -q "journaled soft-updates" && + { echo "Skipping test due to SUJ."; exit 0; } + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d;s/60/600/' < $odir/kinfo.sh > kinfo.c +mycc -o kinfo -Wall -g kinfo.c -lutil +rm -f kinfo.c +cd $odir + +mount | grep -q procfs || mount -t procfs procfs /proc + +for j in `jot 5`; do + /tmp/kinfo & +done + +mount | grep -q $mntpoint && umount -f $mntpoint + +mount -t nullfs `dirname $RUNDIR` $mntpoint + +export RUNDIR=$mntpoint/stressX +export runRUNTIME=10m +#(cd ..; ./run.sh marcus.cfg) +(cd ..; timeout -k 15m 12m ./run.sh marcus.cfg) + +umount $mntpoint 2>&1 | grep -v busy + +mount | grep -q $mntpoint && umount -f $mntpoint + +wait +rm -f /tmp/kinfo diff --git a/tools/test/stress2/misc/nullfs6.sh b/tools/test/stress2/misc/nullfs6.sh new file mode 100755 index 000000000000..628e2fe2bfd7 --- /dev/null +++ b/tools/test/stress2/misc/nullfs6.sh @@ -0,0 +1,50 @@ +#!/bin/sh + +# +# Copyright (c) 2010 Peter Holm +# All rights reserved. +# +# 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. +# + +# Lock violation panic regression test +# Test scenario by Mikolaj Golub +# Fixed in r208773 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +nullfs_srcdir=${nullfs_srcdir:-/tmp} +mount | grep nullfs | grep -q $nullfs_srcdir/1 && umount $nullfs_srcdir/1 + +rm -rf $nullfs_srcdir/1 $nullfs_srcdir/2 +mkdir $nullfs_srcdir/1 $nullfs_srcdir/2 +touch $nullfs_srcdir/1/test.file + +mount -t nullfs $nullfs_srcdir/1 $nullfs_srcdir/2 + +cp $nullfs_srcdir/1/test.file $nullfs_srcdir/2/test.file # scenario by kib +mv $nullfs_srcdir/1/test.file $nullfs_srcdir/2/ # panics with lock violation + +umount $nullfs_srcdir/1 +rm -rf $nullfs_srcdir/1 $nullfs_srcdir/2 diff --git a/tools/test/stress2/misc/nullfs7.sh b/tools/test/stress2/misc/nullfs7.sh new file mode 100755 index 000000000000..329258f5af4d --- /dev/null +++ b/tools/test/stress2/misc/nullfs7.sh @@ -0,0 +1,63 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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: Lock ufs not locked @ ../../../kern/vfs_default.c:508" seen. +# Based on scenario by Subbsd +# Fixed in r226681 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +# NULLFS(5) and SUJ has known issues. +mount | grep "on `df $RUNDIR | sed '1d;s/.* //'` " | \ + grep -q "journaled soft-updates" && + { echo "Skipping test due to SUJ."; exit 0; } + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +[ -d $RUNDIR ] || mkdir -p $RUNDIR +for i in `jot 50`; do + DST="$mntpoint/$i" + [ -d "$DST" ] || mkdir $DST + mount -oro -t nullfs $RUNDIR $DST + mount -orw -t nullfs /bin $DST +done +mount | grep nullfs | awk '{print $3}' | xargs umount + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 + [ $((n += 1)) -gt 100 ] && exit 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/nullfs8.sh b/tools/test/stress2/misc/nullfs8.sh new file mode 100755 index 000000000000..c0c19fb48bdb --- /dev/null +++ b/tools/test/stress2/misc/nullfs8.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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. +# + +# Based on scenario by rea@, kern/164261. Different panic. +# insmntque: mp-safe fs and non-locked vp: 0xcb413984 is not exclusive +# locked but should be + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +nullfs_srcdir=${nullfs_srcdir:-/tmp} +opt="-o nfsv3,rw,udp,rdirplus,noauto,retrycnt=3" +grep -q $mntpoint /etc/exports || + { echo "$mntpoint missing from /etc/exports"; exit 0; } + +mount | grep -wq $mntpoint && umount $mntpoint +mount -t nullfs $nullfs_srcdir $mntpoint + +mntpoint2=${mntpoint}2 +mntpoint3=${mntpoint}3 +for m in $mntpoint2 $mntpoint3; do + [ -d $m ] || mkdir $m + mount | grep -wq $m && umount $m + mount -t nfs $opt 127.0.0.1:$mntpoint $m +done + +for i in `jot 50` ; do + su $testuser -c "cp -r /usr/include $mntpoint2/nullfs8-2 2>/dev/null" & + su $testuser -c "cp -r /usr/include $mntpoint3/nullfs8-2 2>/dev/null" & + wait + su $testuser -c "find $mntpoint2 > /dev/null 2>&1" & + su $testuser -c "find $mntpoint3 > /dev/null 2>&1" & + wait + rm -rf $nullfs_srcdir/nullfs8-2 +done + +for m in $mntpoint3 $mntpoint2 $mntpoint; do + while mount | grep -wq $m; do + umount $m || sleep 1 + done +done diff --git a/tools/test/stress2/misc/nullfs9.sh b/tools/test/stress2/misc/nullfs9.sh new file mode 100755 index 000000000000..e74cde947924 --- /dev/null +++ b/tools/test/stress2/misc/nullfs9.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 + +# nullfs + tmpfs regression test: +# ETXTBSY problem of executable +# Fails with "./nullfs9.sh: cannot create /mnt2/mp/true: Text file busy" + +. ../default.cfg + +mnt2=${mntpoint}2 +mount | grep -q $mnt2/mp && umount $mnt2/mp + +[ -d $mnt2 ] || mkdir $mnt2 +mount | grep $mnt2 | grep -q /dev/md && umount -f $mnt2 +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mnt2 +chmod 777 $mnt2 + +mount | grep $mntpoint | grep -q tmpfs && umount -f $mntpoint +mount -t tmpfs tmpfs $mntpoint +chmod 777 $mntpoint + +mkdir $mnt2/mp +mount -t nullfs $mntpoint $mnt2/mp + +# OK +cp /usr/bin/true $mnt2/mp/true +$mntpoint/true +if ! > $mntpoint/true ; then + echo FAIL 1 + mount | egrep "tmpfs|nullfs|$mntpoint |$mnt2 " +fi +rm -f $mntpoint/true + +# Fails +cp /usr/bin/true $mnt2/mp/true +$mnt2/mp/true +if ! > $mnt2/mp/true; then + echo FAIL 2 + mount | egrep "tmpfs|nullfs|$mntpoint |$mnt2 " +fi +rm -f $mnt2/mp/true + +umount $mnt2/mp +while mount | grep -q "$mnt2 "; do + umount $mnt2 || sleep 1 +done +mdconfig -d -u $mdstart + +while mount | grep -q "$mntpoint "; do + umount $mntpoint || sleep 1 +done diff --git a/tools/test/stress2/misc/numa.sh b/tools/test/stress2/misc/numa.sh new file mode 100755 index 000000000000..048eb1201714 --- /dev/null +++ b/tools/test/stress2/misc/numa.sh @@ -0,0 +1,46 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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 scenario: Last memory domain significantly smaller than the others. +# https://people.freebsd.org/~pho/stress/log/numa.txt +# Test scenario description by markj@ + +[ `sysctl -n vm.ndomains` -eq 1 ] && exit 0 + +doms=`sysctl -n vm.ndomains` +phys=`sysctl -n hw.physmem` # clamped size +real=`sysctl -n hw.realmem` # HW size + +goal=$((real - (real / doms) + 2 * 1024 * 1024 * 1024)) +mb=$((goal / 1024 / 1024)) +[ $phys -gt $goal ] && + { echo "hw.physmem must be set to ${mb}M for this test."; exit 0; } + +../misc/sort.sh +exit diff --git a/tools/test/stress2/misc/oom.sh b/tools/test/stress2/misc/oom.sh new file mode 100755 index 000000000000..d64ff9e88182 --- /dev/null +++ b/tools/test/stress2/misc/oom.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 OOM killing. + +# https://people.freebsd.org/~pho/stress/log/kostik847.txt +# Fixed by r290915 and r290917 + +# Expect: +# kernel: pid 5654 (sort), uid 0, was killed: out of swap space + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `sysctl -n hw.physmem` -gt $(( 1 * 1024 * 1024 * 1024)) ] && + echo "RAM should be capped to 1GB for this test." +[ `sysctl -n hw.physmem` -gt $(( 8 * 1024 * 1024 * 1024)) ] && exit 0 +[ `sysctl -n vm.swap_total` -gt 0 ] && { swapoff -a; off=1; } + +for i in `jot 4`; do + sort < /dev/zero & +done +wait +[ -n "$off" ] && swapon -a diff --git a/tools/test/stress2/misc/oom2.sh b/tools/test/stress2/misc/oom2.sh new file mode 100755 index 000000000000..a588c1d6cbde --- /dev/null +++ b/tools/test/stress2/misc/oom2.sh @@ -0,0 +1,49 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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 OOM killing. + +# sort stuck in "pfault" seen. +# https://people.freebsd.org/~pho/stress/log/oom2.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `sysctl -n vm.swap_total` -gt 0 ] && { swapoff -a; off=1; } + +[ `sysctl -n hw.physmem` -gt $((32 * 1024 * 1024 * 1024)) ] && + echo "RAM should be capped to no more than 32GB" +n=`sysctl -n hw.ncpu` +n=`jot $n` +start=`date +%s` +while [ $((`date +%s` - $start)) -lt 300 ]; do + for i in $n; do + sort < /dev/zero > /dev/null 2>&1 & + done + wait +done +[ $off ] && swapon -a +exit 0 diff --git a/tools/test/stress2/misc/oovm.sh b/tools/test/stress2/misc/oovm.sh new file mode 100755 index 000000000000..3eb4418c50d6 --- /dev/null +++ b/tools/test/stress2/misc/oovm.sh @@ -0,0 +1,134 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Out of VM deadlock seen. Introduced by r285808. +# https://people.freebsd.org/~pho/stress/log/oovm.txt +# https://people.freebsd.org/~pho/stress/log/oovm-2.txt + +# Fixed by r290047 and + +# Test scenario suggestion by alc@ + +. ../default.cfg + +[ `swapinfo | wc -l` -eq 1 ] && exit 0 +maxsize=$((2 * 1024)) # Limit size due to runtime reasons +size=$((`sysctl -n hw.physmem` / 1024 / 1024)) +[ $size -gt $((4 * 1024)) ] && + echo "RAM should be capped to 4GB for this test." +[ $size -gt $maxsize ] && size=$maxsize +need=$((size * 2)) +d1=$diskimage.1 +d2=$diskimage.2 +rm -f $d1 $d2 +[ `df -k $(dirname $diskimage) | tail -1 | awk '{print int($4 / 1024)}'` -lt \ + $need ] && printf "Need %d MB on %s.\n" $need `dirname $diskimage` && exit +dd if=/dev/zero of=$d1 bs=1m count=$size status=none +cp $d1 $d2 || exit +trap "rm -f $d1 $d2" EXIT INT + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/oovm.c +mycc -o oovm -Wall -Wextra -g oovm.c || exit 1 +rm -f oovm.c +cd $odir + +(cd /tmp; /tmp/oovm $d1) & +(cd /tmp; /tmp/oovm $d2) & +wait + +rm -f /tmp/oovm /tmp/oovm.core +exit + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +const char *file; + +#define RUNTIME 600 + +void +test(void) +{ + struct stat st; + size_t i, olen, len; + time_t start; + int error, fd, ps; + char *p; + + 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 = olen = round_page(st.st_size); + do { + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, 0)) == MAP_FAILED) { + if (errno == ENOMEM) + len -= ps; + else + err(1, "mmap"); + } + } while (p == MAP_FAILED); + + start = time(NULL); + /* Touch all pages of the file. */ + for (i = 0; i < len; i += ps) + p[i] = 1; + while (time(NULL) - start < RUNTIME) + p[arc4random() % len] = 1; + + if (munmap(p, len) == -1) + err(1, "unmap()"); + close(fd); +} + +int +main(int argc, char *argv[]) +{ + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + file = argv[1]; + + test(); + + return (0); +} diff --git a/tools/test/stress2/misc/oovm2.sh b/tools/test/stress2/misc/oovm2.sh new file mode 100755 index 000000000000..b65194ad792b --- /dev/null +++ b/tools/test/stress2/misc/oovm2.sh @@ -0,0 +1,136 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Out of VM deadlock seen. Introduced by r285808. Variation of oovm.sh +# https://people.freebsd.org/~pho/stress/log/oovm2.txt + +# Fixed by r290047 and + +# Test scenario suggestion by alc@ + +. ../default.cfg + +[ `swapinfo | wc -l` -eq 1 ] && exit 0 +maxsize=$((2 * 1024)) # Limit size due to runtime reasons +size=$((`sysctl -n hw.physmem` / 1024 / 1024)) +[ $size -gt $maxsize ] && size=$maxsize +d1=$diskimage.1 +d2=$diskimage.2 +d3=$diskimage.3 +d4=$diskimage.4 +rm -f $d1 $d2 $d3 $d4 +[ `df -k $(dirname $diskimage) | tail -1 | awk '{print int($4 / 1024)}'` -lt \ + $size ] && printf "Need %d MB on %s.\n" $size `dirname $diskimage` && exit +dd if=/dev/zero of=$d1 bs=1m count=$((size / 4)) status=none +cp $d1 $d2 || exit +cp $d1 $d3 || exit +cp $d1 $d4 || exit +trap "rm -f $d1 $d2 $d3 $d4" EXIT INT + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/oovm2.c +mycc -o oovm2 -Wall -Wextra -g oovm2.c || exit 1 +rm -f oovm2.c +cd $odir + +(cd /tmp; /tmp/oovm2 $d1) & +(cd /tmp; /tmp/oovm2 $d2) & +(cd /tmp; /tmp/oovm2 $d3) & +(cd /tmp; /tmp/oovm2 $d4) & +wait + +rm -f /tmp/oovm2 /tmp/oovm2.core +exit + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +const char *file; + +#define RUNTIME 600 + +void +test(void) +{ + struct stat st; + size_t i, olen, len; + time_t start; + int error, fd, ps; + char *p; + + 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 = olen = round_page(st.st_size); + do { + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, 0)) == MAP_FAILED) { + if (errno == ENOMEM) + len -= ps; + else + err(1, "mmap"); + } + } while (p == MAP_FAILED); + + start = time(NULL); + /* Touch all pages of the file. */ + for (i = 0; i < len; i += ps) + p[i] = 1; + while (time(NULL) - start < RUNTIME) + p[arc4random() % len] = 1; + + if (munmap(p, len) == -1) + err(1, "unmap()"); + close(fd); +} + +int +main(int argc, char *argv[]) +{ + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + file = argv[1]; + + test(); + + return (0); +} diff --git a/tools/test/stress2/misc/open.sh b/tools/test/stress2/misc/open.sh new file mode 100755 index 000000000000..e17df339842e --- /dev/null +++ b/tools/test/stress2/misc/open.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 202892 open with O_CREAT | O_DIRECTORY when path references a symlink. +# Fixed by r287599. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/open.c +mycc -o open -Wall -Wextra -O0 -g open.c || exit 1 +rm -f open.c + +wdir=/tmp/open.$$ +rm -rf $wdir +mkdir -p $wdir +cd $wdir +status=0 +/tmp/open || { echo FAIL; status=$?; } +[ -f broken -o -f broken2 ] && { ls -l; echo FAIL; status=1; } +cd $odir + +rm -rf /tmp/open $wdir +exit $status + +EOF +#include +#include +#include +#include +#include + +int +main(void) +{ + int fd; + + /* Setup. */ + if (unlink("broken") <= 0 && errno != ENOENT) + err(1, "unlink(broken)"); + if (unlink("target") <= 0 && errno != ENOENT) + err(1, "unlink(target)"); + if (symlink("target", "broken") < 0) + err(1, "symlink(target, broken)"); + + /* Test. */ + fd = open("broken", O_CREAT | O_DIRECTORY, 0600); + if (fd >= 0) + errx(1, "open(broken, O_CREAT | O_DIRECTORY) - no error"); + + fd = open("broken2", O_CREAT | O_DIRECTORY | O_EXCL, 0600); + if (fd != -1) + errx(1, "open() O_CREAT | O_DIRECTORY | O_EXCL"); + + return (0); +} diff --git a/tools/test/stress2/misc/openlock.sh b/tools/test/stress2/misc/openlock.sh new file mode 100755 index 000000000000..71263b79c02f --- /dev/null +++ b/tools/test/stress2/misc/openlock.sh @@ -0,0 +1,94 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Check O_EXLOCK behaviour on different file types +# Regression test for r313549. + +# Test scenario by kib@ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +kldstat -v | grep -q pty || { kldload pty || exit 0; } + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/openlock.c +mycc -o openlock -Wall -Wextra -O0 -g openlock.c || exit 1 +rm -f openlock.c + +e=0 +echo "expect: \"error 45 Operation not supported\"" +/tmp/openlock /dev/ptmx +s=$? +[ $s -eq 45 ] || { echo "Expected error 45, got $s."; e=1; } +/tmp/openlock /bin/ls +s=$? +[ $s -eq 0 ] || { echo "Expected error 0, got $s."; e=$((e + 2)); } +mkfifo openlock.fifo +s=$? +sleep 1 > openlock.fifo & +/tmp/openlock openlock.fifo +s=$? +[ $s -eq 45 ] || { echo "Expected error 45, got $s."; e=$((e + 4)); } +wait + +rm -f /tmp/openlock openlock.fifo +exit $e +EOF + +/* $Id: openlock.c,v 1.1 2017/02/10 14:07:24 kostik Exp kostik $ */ + +#include +#include +#include +#include +#include + +int +main(int argc, char *argv[]) +{ + int e, fd, i; + + for (i = 1; i < argc; i++) { + fd = open(argv[i], O_RDONLY | O_EXLOCK); + if (fd == -1) { + printf("%s error %d %s\n", argv[i], errno, + strerror(errno)); + e = errno; + } else { + printf("%s success\n", argv[i]); + close(fd); + e = 0; + } + } + return (e); +} + diff --git a/tools/test/stress2/misc/overcommit.sh b/tools/test/stress2/misc/overcommit.sh new file mode 100755 index 000000000000..40f60a32f4af --- /dev/null +++ b/tools/test/stress2/misc/overcommit.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 vm.overcommit + +# Setting bit 0 of the vm.overcommit sysctl causes the virtual memory +# system to return failure to the process when allocation of memory +# causes vm.swap_reserved to exceed vm.swap_total. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +old=`sysctl -n vm.overcommit` +[ $old -eq 1 ] && exit + +sysctl vm.overcommit=1 + +. ../default.cfg + +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX + +su $testuser -c 'cd ..; ./run.sh marcus.cfg' + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart + +sysctl vm.overcommit=$old diff --git a/tools/test/stress2/misc/overcommit2.sh b/tools/test/stress2/misc/overcommit2.sh new file mode 100755 index 000000000000..aed26689b933 --- /dev/null +++ b/tools/test/stress2/misc/overcommit2.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 vm.overcommit. Variation of overcommit.sh +# Use a swap backed MD disk with the size of 1.2 * hw.usermem. +# Deadlock seen: https://people.freebsd.org/~pho/stress/log/alan007.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `swapinfo | wc -l` -eq 1 ] && exit 0 + +. ../default.cfg + +old=`sysctl -n vm.overcommit` +[ $old -eq 1 ] && exit + +size=$((`sysctl -n hw.usermem` / 1024 / 1024)) # in MB +size=$((size + size / 100 * 20)) # 120% of hw.usermem +sysctl vm.overcommit=1 +trap "sysctl vm.overcommit=$old" EXIT INT + +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 ${size}m -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +echo "Expect: + /mnt: write failed, filesystem is full + dd: /mnt/big.1: No space left on device" + +for i in `jot 10`; do + dd if=/dev/zero of=$mntpoint/big.$i bs=1m status=none +done +wait + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/overflow3.sh b/tools/test/stress2/misc/overflow3.sh new file mode 100755 index 000000000000..a5a29721a30b --- /dev/null +++ b/tools/test/stress2/misc/overflow3.sh @@ -0,0 +1,96 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 Mark Johnston +# +# 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. +# +# Leaking fp references when truncating SCM_RIGHTS control messages +# Fixed in r343784 + +. ../default.cfg + +cd /tmp +cat > overflow3.c < +#include + +#include +#include +#include +#include + +int +main(void) +{ + struct iovec iov; + struct msghdr hdr, rhdr; + struct cmsghdr *chdr; + int nfds, sv[2]; + char ch; + + if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sv) != 0) + err(1, "socketpair"); + + nfds = 253; + + memset(&hdr, 0, sizeof(hdr)); + ch = 'a'; + iov.iov_base = &ch; + iov.iov_len = 1; + hdr.msg_iov = &iov; + hdr.msg_iovlen = 1; + hdr.msg_control = calloc(1, CMSG_SPACE(nfds * sizeof(int))); + hdr.msg_controllen = CMSG_SPACE(nfds * sizeof(int)); + + chdr = (struct cmsghdr *)hdr.msg_control; + chdr->cmsg_len = CMSG_LEN(nfds * sizeof(int)); + chdr->cmsg_level = SOL_SOCKET; + chdr->cmsg_type = SCM_RIGHTS; + + memset(&rhdr, 0, sizeof(rhdr)); + rhdr.msg_iov = &iov; + rhdr.msg_iovlen = 1; + rhdr.msg_control = calloc(1, CMSG_SPACE(0)); + rhdr.msg_controllen = CMSG_SPACE(0); + + for (;;) { + if (sendmsg(sv[0], &hdr, 0) != 1) + err(1, "sendmsg"); + if (recvmsg(sv[1], &rhdr, 0) != 1) + err(1, "recvmsg"); + if ((rhdr.msg_flags & MSG_CTRUNC) == 0) + errx(1, "MSG_CTRUNC not set"); + } + + return (0); +} +EOF +mycc -o overflow3 -Wall -Wextra -O2 overflow3.c || exit 1 +rm overflow3.c + +timeout 2m ./overflow3 + +rm overflow3 +exit diff --git a/tools/test/stress2/misc/overlap.sh b/tools/test/stress2/misc/overlap.sh new file mode 100755 index 000000000000..f7ac00116559 --- /dev/null +++ b/tools/test/stress2/misc/overlap.sh @@ -0,0 +1,160 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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 that fails on various non FreeBSD file systems. +# 3.13.0-74-generic #118-Ubuntu SMP: Mismatch @ count 214, 0 != 123 +# OK on OS X (Darwin Kernel Version 15.5.0) + +# Scanario by: Michael Ubell ubell mindspring com. + +. ../default.cfg + +mount | grep $mntpoint | grep -q /dev/md && umount -f $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +sed '1,/^EOF/d' < $0 > /tmp/overlap.c +mycc -o /tmp/overlap -Wall -Wextra -O2 /tmp/overlap.c -lpthread || exit 1 +rm -f /tmp/overlap.c + +size="1g" +mdconfig -a -t swap -s $size -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto + +newfs -U md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +(cd $mntpoint; /tmp/overlap) +s=$? + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/overlap +exit $s +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char file[128]; +int bsiz, siz; + +void +handler(int s __unused) +{ + _exit(0); +} + +void * +writer(void *arg __unused) { + int fdes, count; + ssize_t nwrite; + int *buf; + + if ((fdes = open(file, O_RDWR|O_CREAT, 0664)) == -1) + err(1, "open(%s)", file); + + count = 0; + buf = malloc(bsiz * sizeof(int)); + buf[0] = buf[bsiz - 1] = 0; + while ((nwrite = pwrite(fdes, buf, siz, 0)) != -1) { + if (nwrite < siz) + err(1, "pwrite @ count %d, nwrite %zd", count, nwrite); + buf[0] = ++buf[bsiz - 1]; + count++; + } + + err(1, "pwrite()"); +} + +void * +reader(void *arg __unused) { + int fdes, count; + ssize_t nread; + int *buf; + + if ((fdes = open(file, O_RDWR|O_CREAT, 0664)) == -1) + err(1, "open(%s)", file); + count = 0; + + buf = malloc(bsiz * sizeof(int)); + while ((nread = pread(fdes, buf, siz, 0)) == 0) + continue; + + do { + if (nread < siz) + err(1, "pread @ count %d, nread %zd", count, nread); + if (buf[0] != buf[bsiz - 1]) { + printf("Mismatch @ count %d, %d != %d\n", + count, buf[0], buf[bsiz - 1]); + abort(); + } + count++; + } while ((nread = pread(fdes, buf, siz, 0)) != -1); + + err(1, "pread()"); +} + +int +main(int argc, char **argv) { + pthread_t rp, wp; + int ret; + void *exitstatus; + + snprintf(file, sizeof(file), "test.%0d5", getpid()); + siz = 65536; + if (argc == 2) + siz = atoi(argv[1]); + + bsiz = siz / sizeof(int); + + signal(SIGALRM, handler); + alarm(300); + + if ((ret = pthread_create(&wp, NULL, writer, NULL)) != 0) + errc(1, ret, "pthread_create"); + if ((ret = pthread_create(&rp, NULL, reader, NULL)) != 0) + errc(1, ret, "pthread_create"); + + pthread_join(rp, &exitstatus); + pthread_join(wp, &exitstatus); + + unlink(file); + return (0); +} diff --git a/tools/test/stress2/misc/pageout.sh b/tools/test/stress2/misc/pageout.sh new file mode 100755 index 000000000000..5497a1135ff4 --- /dev/null +++ b/tools/test/stress2/misc/pageout.sh @@ -0,0 +1,144 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Trigger the two EDEADLK in vm/vm_pageout.c +# OOVM deadlock seen +# https://people.freebsd.org/~pho/stress/log/pageout.txt + +# "panic: handle_written_filepage: not started" seen: +# https://people.freebsd.org/~pho/stress/log/pageout-2.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/pageout.c +mycc -o pageout -Wall -Wextra -g pageout.c || exit 1 +rm -f pageout.c +cd $odir + +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +f1=$mntpoint/f1 +dd if=/dev/zero of=$f1 bs=1m count=1k status=none + +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 +done +while pgrep -q swap; do + pkill swap +done +wait + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/pageout /tmp/pageout.core +exit + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +const char *file; + +#define RUNTIME 600 + +void +test(void) +{ + struct stat st; + size_t i, len; + time_t start; + int error, fd, ps; + char *p; + + 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); + do { + if ((p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED, + fd, 0)) == MAP_FAILED) { + if (errno == ENOMEM) + len -= ps; + else + err(1, "mmap"); + } + } while (p == MAP_FAILED); + + start = time(NULL); + /* Touch all pages of the file. */ + for (i = 0; i < len; i += ps) + p[i] = 1; + while (time(NULL) - start < RUNTIME) + p[arc4random() % len] = 1; + + if (munmap(p, len) == -1) + err(1, "unmap()"); + close(fd); +} + +int +main(int argc, char *argv[]) +{ + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + file = argv[1]; + + test(); + + return (0); +} diff --git a/tools/test/stress2/misc/parallelmount.sh b/tools/test/stress2/misc/parallelmount.sh new file mode 100755 index 000000000000..5292efbed97a --- /dev/null +++ b/tools/test/stress2/misc/parallelmount.sh @@ -0,0 +1,68 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 unmount of the same mount point +# http://people.freebsd.org/~pho/stress/log/parallelumount3.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +parallel=40 + +if [ $# -eq 0 ]; then + [ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + mdconfig -a -t swap -s 10m -u $mdstart || exit 1 + bsdlabel -w md$mdstart auto + newfs $newfs_flags md${mdstart}$part > /dev/null + + # start the parallel tests + for i in `jot $parallel`; do + ./$0 $i & + done + + while kill -0 $! 2> /dev/null; do + for i in `jot 100`; do + find $mntpoint > /dev/null 2>&1 + done + done + wait + + while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 + done + mdconfig -d -u $mdstart + exit 0 +else + start=`date '+%s'` + while [ $((`date '+%s'` - start)) -lt 600 ]; do + mount /dev/md${mdstart}$part $mntpoint + umount $mntpoint + mount + done > /dev/null 2>&1 +fi diff --git a/tools/test/stress2/misc/parallelmount2.sh b/tools/test/stress2/misc/parallelmount2.sh new file mode 100755 index 000000000000..454a7b4b01ed --- /dev/null +++ b/tools/test/stress2/misc/parallelmount2.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC +# All rights reserved. +# +# 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. +# + +# Quota version of parallelmount.sh +# "umount busy seen: +# https://people.freebsd.org/~pho/stress/log/parallelmount2.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -z "$DEBUG" ] && exit 0 # Waiting for fix +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 + +. ../default.cfg + +parallel=40 + +if [ $# -eq 0 ]; then + [ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + mdconfig -a -t swap -s 10m -u $mdstart || exit 1 + bsdlabel -w md$mdstart auto + newfs $newfs_flags md${mdstart}$part > /dev/null + export PATH_FSTAB=/var/tmp/fstab.$$ + echo "/dev/md${mdstart}$part $mntpoint ufs rw,userquota 2 2" > $PATH_FSTAB + mount /dev/md${mdstart}$part $mntpoint + set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` + export QK=$(($1 / 10 * 8)) + export QI=$(($2 / 10 * 8)) + edquota -u -f $mntpoint -e $mntpoint:$((QK - 50)):$QK:$((QI - 50 )):$QI $testuser + quotaon $mntpoint + umount $mntpoint + + # start the parallel tests + for i in `jot $parallel`; do + ./$0 $i & + done + + while kill -0 $! 2> /dev/null; do + for i in `jot 100`; do + find $mntpoint > /dev/null 2>&1 + done + done + wait + rm -f $PATH_FSTAB + + for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 + done + [ $i -eq 6 ] && exit 1 + mdconfig -d -u $mdstart + exit 0 +else + start=`date '+%s'` + while [ $((`date '+%s'` - start)) -lt 600 ]; do + mount /dev/md${mdstart}$part $mntpoint + quotaon $mntpoint + umount $mntpoint + mount + done > /dev/null 2>&1 +fi diff --git a/tools/test/stress2/misc/pathconf.sh b/tools/test/stress2/misc/pathconf.sh new file mode 100755 index 000000000000..5de6b4e3728d --- /dev/null +++ b/tools/test/stress2/misc/pathconf.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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: _PC_ASYNC_IO should not get here" seen: +# https://people.freebsd.org/~pho/stress/log/pathconf.txt +# Fixed by r320900 + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 + +mp=${mntpoint}2 +[ -z "$nfs_export" ] && exit 0 +ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || + exit 0 + +syscall=`grep lpathconf /usr/include/sys/syscall.h 2>/dev/null` +[ -z "$syscall" ] && exit 0 +syscall=`echo $syscall | sed 's/.*[\t ]//'` + +mkdir -p $mp/nfs || exit 1 +mount -t nfs -o tcp -o retrycnt=3 -o intr,soft -o rw $nfs_export $mp/nfs +chmod a+rw $mp/nfs + +start=`date +%s` +while [ $((`date +%s` - start)) -lt 600 ]; do + ../misc/syscall4.sh $syscall +done + +umount $mp/nfs +rm -rf $mp +exit 0 diff --git a/tools/test/stress2/misc/pathconf2.sh b/tools/test/stress2/misc/pathconf2.sh new file mode 100755 index 000000000000..962f26e1aa53 --- /dev/null +++ b/tools/test/stress2/misc/pathconf2.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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: _PC_ASYNC_IO should not get here" seen: +# https://people.freebsd.org/~pho/stress/log/pathconf2.txt +# Fixed by r320900 + +# Test scenario by: Ngie Cooper + +getconf _POSIX_ASYNC_IO /usr/src/ > /dev/null + +exit diff --git a/tools/test/stress2/misc/pause.sh b/tools/test/stress2/misc/pause.sh new file mode 100755 index 000000000000..e786dd6cce0c --- /dev/null +++ b/tools/test/stress2/misc/pause.sh @@ -0,0 +1,159 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Hunt for lost wakeup problem. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/pause.c +mycc -o pause -Wall -Wextra -O0 -g pause.c || exit 1 +rm -f pause.c + +pkill pause +$dir/pause & +pid=$! +start=`date +%s` +while pgrep -q pause; do + sleep .5 + [ $((`date +%s` - $start)) -gt 1200 ] && + { echo "Timed out"; pgrep pause | xargs ps -lp; exit 1; } +done +wait $pid +s=$? + +cd $odir +rm -rf $dir/pause +exit $s + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; + +#define PARALLEL 400 +#define RUNTIME (5 * 60) +#define SYNC 0 + +void +hand(int i __unused) { +} + +static void +test(int idx) +{ + pid_t pid; + time_t start; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + usleep(1); + share[idx] = 0; + + if ((pid = fork()) == 0) { + share[idx] = 1; + for (;;) + pause(); + _exit(0); + } + while (share[idx] == 0) + usleep(10); + start = time(NULL); + while (time(NULL) - start < 60) { + usleep(arc4random() % 100); + if (kill(pid, SIGHUP) == -1) + err(1, "kill(%d)", pid); + } + kill(pid, SIGTERM); + if (waitpid(pid, NULL, 0) != pid) + err(1, "waitpid(%d)", pid); + + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + struct sigaction sa; + size_t len; + time_t start; + int e, i, status; + + sa.sa_handler = hand; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGHUP, &sa, NULL) == -1) + err(1, "sigaction"); + + 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(i + 1); + 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); +} diff --git a/tools/test/stress2/misc/pcatch.sh b/tools/test/stress2/misc/pcatch.sh new file mode 100755 index 000000000000..f1db7de253f2 --- /dev/null +++ b/tools/test/stress2/misc/pcatch.sh @@ -0,0 +1,154 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# The issue makes it possible for applications to get wrong EINTR +# or ERESTART (the later is not directly visible) when doing write +# to the file on suspended UFS volume. I.e. the thread is sleeping +# when fs is suspended, and process is signaled. + +# Test scenario mostly by kib. +# Fixed in r275744. + +# Deadlock seen: +# https://people.freebsd.org/~pho/stress/log/pcatch.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -z "$DEBUG" ] && exit 0 # Waiting for fix + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pcatch.c +mycc -o pcatch -Wall -Wextra -O0 -g pcatch.c || exit 1 +rm -f pcatch.c +cd $here + +mount | grep -q "$mntpoint" && umount $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint + +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 120 ]; do + /tmp/pcatch $mntpoint +done + +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/pcatch +exit 0 +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static void +hand_sigaction(int signo __unused, siginfo_t *si __unused, void *c __unused) +{ +} + +static void +suspend(char *path) +{ + struct statfs s; + int fd, error; + + if (fork() == 0) { + if ((error = statfs(path, &s)) != 0) + err(1, "statfs %s", path); + fd = open("/dev/ufssuspend", O_RDWR); + if ((error = ioctl(fd, UFSSUSPEND, &s.f_fsid)) != 0) + err(1, "UFSSUSPEND"); + sleep(1); + if ((error = ioctl(fd, UFSRESUME, &s.f_fsid)) != 0) + err(1, "UFSRESUME"); + _exit(0); + } +} + +static void +test(char *mp) +{ + pid_t pid; + struct sigaction sa; + int fd; + char buf[80], file[80]; + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = hand_sigaction; + if (sigaction(SIGUSR1, &sa, NULL) == -1) + err(1, "sigaction"); + + snprintf(file, sizeof(file), "%s/file", mp); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) + err(1, "open(%s). %s:%d", file, __FILE__, __LINE__); + + suspend(mp); + + if ((pid = fork()) == 0) { + if (write(fd, buf, sizeof(buf)) == -1) + warn("FAIL: write"); + _exit(0); + } + usleep(10000); + if (kill(pid, SIGUSR1) == -1) + err(1, "kill"); + wait(NULL); + wait(NULL); + close(fd); +} + +int +main(int argc, char *argv[]) +{ + + if (argc != 2) + errx(1, "Usage: %s ", argv[0]); + + test(argv[1]); + + return (0); +} diff --git a/tools/test/stress2/misc/pcatch2.sh b/tools/test/stress2/misc/pcatch2.sh new file mode 100755 index 000000000000..1c36406fec6f --- /dev/null +++ b/tools/test/stress2/misc/pcatch2.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# +# Copyright (c) 2016 Dell EMC +# All rights reserved. +# +# 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. +# + +# Process stuck in "suspfs": +# https://people.freebsd.org/~pho/stress/log/kostik944.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ -z "$DEBUG" ] && exit 0 # Waiting for fix + +for i in `jot 10`; do + ./pcatch.sh & + sleep `jot -r 1 1 5` + kill -INT $! + ./cleanup.sh + pgrep -q pcatch || break + wait +done +pgrep -q pcatch && s=1 || s=0 +exit $s diff --git a/tools/test/stress2/misc/pdfork.sh b/tools/test/stress2/misc/pdfork.sh new file mode 100755 index 000000000000..6c258a83521f --- /dev/null +++ b/tools/test/stress2/misc/pdfork.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# truss / pdfork regression test. +# Test scenario by: Ryan Stone rstone@, slightly mangled by pho@ + +# Interruptable hang seen: +# $ ps -lp992 +# UID PID PPID CPU PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND +# 1001 992 991 0 27 0 4168 1908 - TX+ 0 0:00.00 /tmp/pdfork -p +# $ + +cat > /tmp/pdfork.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + pid_t pid; + int fd; + + if (argc > 1 && strcmp(argv[1], "-p") == 0) { + pid = pdfork(&fd, 0); + } else { + pid = fork(); + } + + if (pid == 0) { + sleep(1); + exit(0); + } else if (pid < 0) { + err(1, "fork() failed"); + } else { + int status = 0; + if (argc > 1 && strcmp(argv[1], "-p") != 0) { + int error = wait4(pid, &status, WEXITED, NULL); + if (error < 0) + err(1, "wait4 failed"); + } + exit(status); + } +} +EOF +cc -o /tmp/pdfork -Wall -Wextra -O2 /tmp/pdfork.c || exit 1 + +timeout 20s truss -f /tmp/pdfork 2> /dev/null; s1=$? +timeout 20s truss -f /tmp/pdfork -p 2> /dev/null; s2=$? + +rm -f /tmp/pdfork /tmp/pdfork.c +return $((s1 + s2)) diff --git a/tools/test/stress2/misc/perf.sh b/tools/test/stress2/misc/perf.sh new file mode 100755 index 000000000000..89e9dd8d371c --- /dev/null +++ b/tools/test/stress2/misc/perf.sh @@ -0,0 +1,151 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# O_CREAT / unlink() timing test with different FFS options. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ `uname -m` = "i386" ] && exit 0 # very long runtime + +. ../default.cfg +[ $# -eq 0 ] && half=1 # SU and SUJ workaround +first=1 +export LANG=en_US.ISO8859-1 +odir=`pwd` +dir=$mntpoint + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > perf.c +mycc -o perf -Wall -Wextra perf.c || exit 1 +rm -f perf.c +cd $odir + +mount | grep -q "on $mntpoint " && umount $mntpoint +mdconfig -l | grep md$mdstart > /dev/null && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 2g -u $mdstart + +tst() { + local i j k s + + s=0 + cd $dir + inodes=`df -ik $mntpoint | tail -1 | \ + awk '{printf "%d\n", $7}'` +# SU and SUJ tests fail with ENOSPC + [ $half ] && + i=$((inodes / 4)) || + i=$(((inodes - 500) / 2)) + [ $first -eq 1 ] && + printf "Using %'\''d inodes out of a total of %'\''d.\n" \ + $((i * 2)) $inodes + first=0 + + for k in `jot 3`; do + pids="" + for j in `jot 2`; do + /tmp/perf $i & + pids="$pids $!" + done + for pid in $pids; do + wait $pid; r=$? + [ $r -ne 0 ] && s=$r + done + done + cd $odir + return $s +} + +s=0 +for i in "" "-U" "-j"; do + newfs $i /dev/md$mdstart > /dev/null 2>&1 + mount /dev/md$mdstart $mntpoint + + t1=`date +%s` + tst; r=$? + t2=$((`date +%s` - t1)) + + umount -f $mntpoint + t2=$((`date +%s` - t1)) + [ $t2 -eq 0 ] && t2=1 + [ -z "$base" ] && base=$t2 + pct=$(((t2 - base) * 100 / base)) + printf '%3d seconds elapsed for newfs option "%2s" (%+4d%%)\n' \ + $t2 "$i" $pct + [ $pct -gt 10 ] && s=111 + [ $s -eq 0 -a $r -ne 0 ] && s=$r +done +rm -f /tmp/perf +mdconfig -d -u $mdstart +exit $s +EOF +#include +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc __unused, char **argv) +{ + pid_t pid; + int64_t size; + int e, fd, i, j; + char file[128]; + + size = atol(argv[1]); + + e = 0; + pid = getpid(); + for (j = 0; j < size; j++) { + sprintf(file,"p%05d.%05d", pid, j); + if ((fd = open(file, O_RDWR | O_CREAT | O_TRUNC, + DEFFILEMODE)) == -1) { + e = errno; + if (errno != EINTR) { + warn("open(%s)", file); + printf("break out at %d, errno %d\n", j, + errno); + break; + } + } + close(fd); + } + + for (i = --j; i >= 0; i--) { + sprintf(file,"p%05d.%05d", pid, i); + if (unlink(file) == -1) + err(3, "unlink(%s)", file); + + } + + return (e); +} diff --git a/tools/test/stress2/misc/pfl.sh b/tools/test/stress2/misc/pfl.sh new file mode 100755 index 000000000000..6d590b5cf225 --- /dev/null +++ b/tools/test/stress2/misc/pfl.sh @@ -0,0 +1,188 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 scenario for the change of a global SU lock to a per filesystem lock. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pfl.c +mycc -o pfl -Wall -Wextra pfl.c || exit 1 +rm -f pfl.c +cd $here + +md1=$mdstart +md2=$((mdstart + 1)) +mp1=${mntpoint}$md1 +mp2=${mntpoint}$md2 +mkdir -p $mp1 $mp2 + +usermem=`sysctl -n hw.usermem` +[ `swapinfo | wc -l` -eq 1 ] && usermem=$((usermem/100*80)) +size=$((2 * 1024 * 1024 * 1024)) # Ideal disk size is 2G +[ $((size * 2)) -gt $usermem ] && size=$((usermem / 2)) +size=$((size / 1024 / 1024)) + +opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && echo "-j" || echo "-U") +[ "$newfs_flags" = "-U" ] || opt="" +mount | grep "on $mp1 " | grep -q /dev/md && umount -f $mp1 +[ -c /dev/md$md1 ] && mdconfig -d -u $md1 +mdconfig -a -t swap -s ${size}m -u $md1 +bsdlabel -w md$md1 auto +newfs $opt md${md1}$part > /dev/null +mount /dev/md${md1}$part $mp1 +chmod 777 $mp1 + +mount | grep "on $mp2 " | grep -q /dev/md && umount -f $mp2 +[ -c /dev/md$md2 ] && mdconfig -d -u $md2 +mdconfig -a -t swap -s ${size}m -u $md2 +bsdlabel -w md$md2 auto +newfs $opt md${md2}$part > /dev/null +mount /dev/md${md2}$part $mp2 +chmod 777 $mp2 + +su $testuser -c "cd $mp1; /tmp/pfl" & +pids=$! +su $testuser -c "cd $mp2; /tmp/pfl" & +pids="$pids $!" +sleep .5 +s=0 +start=`date '+%s'` +while pgrep -q pfl; do + if [ $((`date '+%s'`- start)) -gt 900 ]; then + s=1 + echo "$0 timed out." + pkill -9 pfl + fi + sleep 10 +done +for p in $pids; do + wait $p + [ $? -ne 0 ] && s=2 +done + +while mount | grep "$mp2 " | grep -q /dev/md; do + umount $mp2 || sleep 1 +done +mdconfig -d -u $md2 +while mount | grep "$mp1 " | grep -q /dev/md; do + umount $mp1 || sleep 1 +done +rm -f /tmp/pfl +mdconfig -d -u $md1 +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 10 + +static void +test(void) +{ + pid_t pid; + int fd, i, j; + char file[128]; + + pid = getpid(); + sprintf(file,"d%05d", pid); + if (mkdir(file, 0740) == -1) + err(1, "mkdir(%s)", file); + chdir(file); + for (j = 0; j < 10000; j++) { + sprintf(file,"p%05d.%05d", pid, j); + if ((fd = open(file, O_CREAT | O_TRUNC | O_WRONLY, 0644)) == + -1) { + if (errno != EINTR) { + warn("mkdir(%s). %s:%d", file, __FILE__, + __LINE__); + unlink("continue"); + break; + } + } + if (arc4random() % 100 < 10) + if (write(fd, "1", 1) != 1) + err(1, "write()"); + close(fd); + + } + sleep(3); + + for (i = --j; i >= 0; i--) { + sprintf(file,"p%05d.%05d", pid, i); + if (unlink(file) == -1) + err(3, "unlink(%s)", file); + + } + chdir(".."); + sprintf(file,"d%05d", pid); + if (rmdir(file) == -1) + err(3, "unlink(%s)", file); +} + +int +main(void) +{ + pid_t pids[PARALLEL]; + int e, fd, j, k, s; + + umask(0); + if ((fd = open("continue", O_CREAT, 0644)) == -1) + err(1, "open()"); + close(fd); + e = 0; + for (j = 0; j < PARALLEL; j++) { + if ((pids[j] = fork()) == 0) { + for (k = 0; k < 40; k++) + test(); + _exit(0); + } + } + + for (j = 0; j < PARALLEL; j++) { + if (waitpid(pids[j], &s, 0) == -1) + err(1, "waitpid(%d)", pids[j]); + e += s == 0 ? 0 : 1; + } + + return (e); +} diff --git a/tools/test/stress2/misc/pfl2.sh b/tools/test/stress2/misc/pfl2.sh new file mode 100755 index 000000000000..9b6497294242 --- /dev/null +++ b/tools/test/stress2/misc/pfl2.sh @@ -0,0 +1,104 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 scenario for the change of a global SU lock to a per filesystem lock. +# "panic: softdep_write_inodeblock: indirect pointer #0 mismatch ..." seen. +# http://people.freebsd.org/~pho/stress/log/kirk063.txt + +# https://people.freebsd.org/~pho/stress/log/kirk080.txt + +. ../default.cfg + +[ `swapinfo | wc -l` -eq 1 ] && exit 0 + +md1=$mdstart +md2=$((mdstart + 1)) +mp1=${mntpoint}$md1 +mp2=${mntpoint}$md2 +mkdir -p $mp1 $mp2 + +usermem=`sysctl -n hw.usermem` +size=$((2 * 1024 * 1024 * 1024)) # Ideal disk size is 2G +[ $((size * 2)) -gt $usermem ] && size=$((usermem / 2)) +size=$((size / 1024 / 1024)) + +opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && echo "-j" || echo "-U") +[ "$newfs_flags" = "-U" ] || opt="" +mount | grep "on $mp1 " | grep -q /dev/md && umount -f $mp1 +mdconfig -l | grep -q md$md1 && mdconfig -d -u $md1 +mdconfig -a -t swap -s ${size}m -u $md1 +bsdlabel -w md$md1 auto +newfs $opt md${md1}$part > /dev/null +mount /dev/md${md1}$part $mp1 +chmod 777 $mp1 + +mount | grep "on $mp2 " | grep -q /dev/md && umount -f $mp2 +mdconfig -l | grep -q md$md2 && mdconfig -d -u $md2 +mdconfig -a -t swap -s ${size}m -u $md2 +bsdlabel -w md$md2 auto +newfs $opt md${md2}$part > /dev/null +mount /dev/md${md2}$part $mp2 +chmod 777 $mp2 + +export runRUNTIME=10m +export RUNDIR=$mp1/stressX +export CTRLDIR=$mp1/stressX.control +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 +" +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > /dev/null 2>&1 & + +export TESTPROGS="$TESTPROGS testcases/swap/swap" +export RUNDIR=$mp2/stressX +export CTRLDIR=$mp2/stressX.control +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' > /dev/null 2>&1 & +wait + +while mount | grep "$mp2 " | grep -q /dev/md; do + umount $mp2 || sleep 1 +done +mdconfig -d -u $md2 +while mount | grep "$mp1 " | grep -q /dev/md; do + umount $mp1 || sleep 1 +done +mdconfig -d -u $md1 diff --git a/tools/test/stress2/misc/pfl3.sh b/tools/test/stress2/misc/pfl3.sh new file mode 100755 index 000000000000..8c2bb2396e9d --- /dev/null +++ b/tools/test/stress2/misc/pfl3.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 + +# Start pfl.sh and "umount -f" the two mount points in use. +# "panic: handle_written_inodeblock: live inodedep" seen. +# http://people.freebsd.org/~pho/stress/log/pfl3.txt + +# Not seen on FreeBSD 14.0-CURRENT #0 main-n244671-b3c6fe663bb + +. ../default.cfg + +./pfl.sh > /dev/null 2>&1 & +sleep `jot -r 1 10 60` +while mount | grep -q "$mntpoint"; do + umount -f ${mntpoint}$mdstart & pid=$! + umount -f ${mntpoint}$((mdstart + 1)) + wait $pid +done +wait +exit 0 diff --git a/tools/test/stress2/misc/pfl4.sh b/tools/test/stress2/misc/pfl4.sh new file mode 100755 index 000000000000..8128fa1f585c --- /dev/null +++ b/tools/test/stress2/misc/pfl4.sh @@ -0,0 +1,95 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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: invalid queue 255" seen: +# https://people.freebsd.org/~pho/stress/log/pfl4.txt + +. ../default.cfg +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ $((`sysctl -n hw.usermem` / 1024 / 1024 / 1024)) -le 8 ] && exit 0 + +mounts=4 +newfs_flags="" + +export runRUNTIME=10m +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 +" + +prefix=$mntpoint +start=$mdstart +for i in `jot $mounts $start`; do + mdstart=$i + mntpoint=${prefix}$i + [ -d $mntpoint ] || mkdir -p $mntpoint + + mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint + mdconfig -a -t swap -s 2g -u $mdstart + bsdlabel -w md$mdstart auto + newfs $newfs_flags md${mdstart}$part > /dev/null + mount /dev/md${mdstart}$part $mntpoint + chmod 777 $mntpoint + + export RUNDIR=$mntpoint/stressX + export CTRLDIR=$mntpoint/stressX.control + set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` + export KBLOCKS=$(($1 / 1)) + export INODES=$(($2 / 1)) + su $testuser -c 'sleep 2; cd ..; ./testcases/run/run $TESTPROGS' > \ + /dev/null 2>&1 & +done +su $testuser -c "sleep 2; cd ..; ./testcases/swap/swap -t 10m -i 20" & + +wait + +s=0 +for i in `jot $mounts $start`; do + mdstart=$i + mntpoint=${prefix}$i + n=0 + while mount | grep -q "on $mntpoint "; do + umount $mntpoint && mdconfig -d -u $mdstart || sleep 1 + n=$((n += 1)) + [ $n -gt 60 ] && exit 1 + done + checkfs /dev/md${mdstart}$part || s=$? +done +exit $s diff --git a/tools/test/stress2/misc/ping.sh b/tools/test/stress2/misc/ping.sh new file mode 100755 index 000000000000..2594c6d5e43c --- /dev/null +++ b/tools/test/stress2/misc/ping.sh @@ -0,0 +1,53 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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 r351461. Handle missing time stamp from SO_TIMESTAMP. +# Fixed by r352229 + +. ../default.cfg +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +[ -z "$nfs_export" ] && exit 0 +ip=`echo $nfs_export | sed 's/:.*//'` +ping -c 2 $ip > /dev/null 2>&1 || exit 0 + +log=/tmp/ping.log +tail -F -n 0 /var/log/messages > $log & +sleep .5 +pid=$! +for i in `jot 10`; do + ping -c 1 $ip & + pids="$pids $!" +done > /dev/null +for i in $pids; do wait $i; done +kill $pid +wait +grep "(ping)" $log && s=1 || s=0 +rm -f $log +exit $s diff --git a/tools/test/stress2/misc/pipe.sh b/tools/test/stress2/misc/pipe.sh new file mode 100755 index 000000000000..3a27a3dd7d88 --- /dev/null +++ b/tools/test/stress2/misc/pipe.sh @@ -0,0 +1,132 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Stress vm object collapse. + +# "panic: backing_object 0xfffff800a018f420 was somehow re-referenced during +# collapse!" seen with uma_zalloc_arg fail point enabled. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/pipe.c +mycc -o pipe -Wall -Wextra -O0 -g pipe.c || exit 1 +rm -f pipe.c +cd $odir + +daemon sh -c '(cd ../testcases/swap; ./swap -t 10m -i 20)' > /dev/null 2>&1 +sleep 1 +e=0 +export e +start=`date '+%s'` +while [ $((`date '+%s'` - start)) -lt 300 ]; do + for i in `jot $(sysctl -n hw.ncpu)`; do + /tmp/pipe & + pids="$pids $!" + done + for i in $pids; do + wait $i + [ $? -ne 0 ] && e=$((e + 1)) + done + pids="" + [ $e -ne 0 ] && break +done +while pgrep -q swap; do + pkill -9 swap +done +rm -rf /tmp/pipe pipe.core +exit $e + +EOF +#include + +#include +#include +#include +#include + +#define PIPES 64 +#define RUNTIME 300 + +int +test(void) +{ + int c, e, status; + int fds[PIPES][2]; + int i; + + for (i = 0; i < PIPES; i++) { + if (pipe(fds[i]) == -1) + err(1, "pipe"); + } + c = e = 0; + if (write(fds[0][1], &c, sizeof(c)) != sizeof(c)) + err(1, "pipe write"); + for (i = 0; i < PIPES; i++) { + if (fork() == 0) { + close(fds[i][1]); + if (read(fds[i][0], &c, sizeof(c)) != sizeof(c)) + err(1, "pipe read"); +#if defined(DEBUG) + fprintf(stderr, "pid %d: i = %d: read %d\n", getpid(), + i, c); +#endif + c++; + if (i != PIPES - 1) + if (write(fds[i + 1][1], &c, sizeof(c)) != + sizeof(c)) + err(1, "pipe write"); + + _exit(0); + } + close(fds[i][0]); + close(fds[i][1]); + } + for (i = 0; i < PIPES; i++) { + wait(&status); + e += status == 0 ? 0 : 1; + } + + return (e); +} + +int +main(void) +{ + time_t start; + int e; + + e = 0; + start = time(NULL); + while (time(NULL) - start < RUNTIME && e == 0) + e = test(); + + return (e); +} diff --git a/tools/test/stress2/misc/pipe2.sh b/tools/test/stress2/misc/pipe2.sh new file mode 100755 index 000000000000..b20318c45a98 --- /dev/null +++ b/tools/test/stress2/misc/pipe2.sh @@ -0,0 +1,163 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# pipe(2) test + +. ../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/pipe2.c +mycc -o pipe2 -Wall -Wextra -O0 -g pipe2.c || exit 1 +rm -f pipe2.c + +daemon sh -c "(cd $odir/../testcases/swap; ./swap -t 10m -i 20)" > \ + /dev/null 2>&1 +sleep 10 + +su $testuser -c /tmp/pipe2 +s=$? + +while pgrep -q swap; do + pkill -9 swap +done + +rm -rf /tmp/pipe2 +exit $s + +EOF +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +volatile u_int *share, *share2; + +#define R1 1 /* sync start */ +#define R2 2 /* forks */ + +#define PIPES 128 +#define PARALLEL 32 + +static void +hand(int i __unused) { /* handler */ + fprintf(stderr, "Timed out\n"); + _exit(1); +} + +void +test(void) +{ + size_t len; + int fds[2], r; + int token; + + len = PAGE_SIZE; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + if (pipe(fds) == -1) + err(1, "pipe"); + token = 0; + write(fds[1], &token, sizeof(token)); + for (;;) { + if (share[R2] >= PIPES) + break; + if ((r = fork()) == 0) { + atomic_add_int(&share[R2], 1); + if (read(fds[0], &token, sizeof(token)) != sizeof(token)) + err(1, "read"); + close(fds[0]); + if (pipe(fds) == -1) + err(1, "pipe"); + token++; + if (write(fds[1], &token, sizeof(token)) != sizeof(token)) + err(1, "write"); + } + if (r == -1) + err(1, "fork()"); + if (r != 0) + _exit(0); + } + + if (share[R2] == PIPES) { +#if defined(DEBUG) + if (read(fds[0], &token, sizeof(token)) != sizeof(token)) + err(1, "final read"); + fprintf(stderr, "FINAL read %d from %d\n", token, fds[0]); +#endif + atomic_add_int(&share2[R1], 1); + } + _exit(0); +} + +int +main(void) +{ + struct sigaction sa; + size_t len; + int i; + + len = PAGE_SIZE; + if ((share2 = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + sa.sa_handler = SIG_IGN; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGCHLD, &sa, 0) == -1) + err(1, "sigaction"); + + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + test(); + } + + signal(SIGALRM, hand); + alarm(300); + while (share2[R1] != PARALLEL) { + sleep(1); +#if defined(DEBUG) + fprintf(stderr, "share2 = %d\n", share2[R1]); +#endif + } + + return (0); +} diff --git a/tools/test/stress2/misc/pipe3.sh b/tools/test/stress2/misc/pipe3.sh new file mode 100755 index 000000000000..6208e1a52f90 --- /dev/null +++ b/tools/test/stress2/misc/pipe3.sh @@ -0,0 +1,148 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 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. +# + +# pipe(2) tests. +# "panic: vm_page_dequeue: queued unlocked page 0xfffffe0019a73518" seen. + +# Reported by syzkaller +# Fixed by r354400 + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/pipe3.c +mycc -o pipe3 -Wall -Wextra -O0 -g pipe3.c || exit 1 +rm -f pipe3.c +cd $odir + +(cd ../testcases/swap; ./swap -t 5m -i 20 -l 100) & +sleep 1 +for i in `jot 25`; do + /tmp/pipe3 & +done +while pkill -0 pipe3; do sleep 2; done +while pkill -9 swap; do sleep 1; done +wait +rm -rf /tmp/pipe3 +exit 0 + +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 64 +#define RUNTIME (5 * 60) + +static void +handler(int i __unused) { + _exit(0); +} + +void +test(void) +{ + int fds[2], r; + char c; + + if (pipe(fds) == -1) + err(1, "pipe"); + + if (fork() == 0) { + signal(SIGALRM, handler); + ualarm(1 + arc4random() % 10000, 0); + close(fds[1]); + if ((r = write(fds[0], &c, sizeof(c))) != sizeof(c)) + if (r == -1) + err(1, "pipe write"); + _exit(0); + } + signal(SIGALRM, handler); + ualarm(1 + arc4random() % 10000, 0); + close(fds[0]); + if ((r = read(fds[1], &c, sizeof(c))) != sizeof(c)) + if (r == -1) + err(1, "pipe read"); + wait(NULL); + _exit(0); +} + +int +main(void) +{ + pid_t pids[PARALLEL], rpid; + time_t start; + int i, running, status; + bool done; + + for (i = 0; i < PARALLEL; i++) + pids[i] = 0; + running = 0; + start = time(NULL); + for (;;) { + done = (time(NULL) - start) >= RUNTIME; + for (i = 0; i < PARALLEL; i++) { + if (pids[i] == 0 && !done) { + if ((pids[i] = fork()) == 0) + test(); + if (pids[i] == -1) + err(1, "fork()"); + running++; + } + } + for (i = 0; i < PARALLEL; i++) { + if (pids[i] != 0) { + if ((rpid = waitpid(pids[i], &status, + WNOHANG)) == -1) + err(1, "waitpid(%d)", pids[i]); + if (rpid == 0) + continue; + if (rpid != pids[i]) + err(1, "waitpid(%d)", pids[i]); + running --; + pids[i] = 0; + break; + } + } + if (running == 0 && done) + break; + usleep(100); + } + + return (0); +} diff --git a/tools/test/stress2/misc/pipe_enomem.sh b/tools/test/stress2/misc/pipe_enomem.sh new file mode 100755 index 000000000000..92558b164336 --- /dev/null +++ b/tools/test/stress2/misc/pipe_enomem.sh @@ -0,0 +1,102 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 Konstantin Belousov +# +# 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. +# + +# Pipe test scenario from https://reviews.freebsd.org/D23993 +# https://gist.github.com/kostikbel/b2844258b7fba6e8ce3ccd8ef9422e5a + +. ../default.cfg + +cd /tmp +cat > pipe_enomem.c < +#include +#include +#include +#include + +struct pipepair { + int pp[2]; +}; + +static struct pipepair *p; + +int +main(void) +{ + int error, pp[2]; + size_t i, k, nsz, sz; + char x; + + sz = 1024; + p = calloc(sz, sizeof(struct pipepair)); + if (p == NULL) { + fprintf(stderr, "calloc: %s\n", strerror(errno)); + exit(1); + } + + for (i = 0;; i++) { + if (pipe(pp) == -1) { + printf("created %zd pipes. syscall error %s\n", + i, strerror(errno)); + break; + } + if (i >= sz) { + nsz = sz * 2; + p = reallocf(p, nsz * sizeof(struct pipepair)); + if (p == NULL) { + fprintf(stderr, "reallocf: %s\n", + strerror(errno)); + exit(1); + } + memset(p + sz, 0, (nsz - sz) * sizeof(struct pipepair)); + sz = nsz; + } + p[i].pp[0]= pp[0]; + p[i].pp[1]= pp[1]; + } + + x = 'a'; + for (k = 0; k < i; k++) { + error = write(p[k].pp[1], &x, 1); + if (error == -1) + printf("pipe %zd fds %d %d error %s\n", + k, p[k].pp[0], p[k].pp[1], strerror(errno)); + else if (error == 0) + printf("pipe %zd fds %d %d EOF\n", + k, p[k].pp[0], p[k].pp[1]); + } +} +EOF + +mycc -o pipe_enomem -Wall -Wextra -O2 pipe_enomem.c || exit 1 +./pipe_enomem 2>&1 | head -5 +rm -f pipe_enomem.c pipe_enomem +exit 0 diff --git a/tools/test/stress2/misc/pkru.sh b/tools/test/stress2/misc/pkru.sh new file mode 100755 index 000000000000..9ac0a5000daf --- /dev/null +++ b/tools/test/stress2/misc/pkru.sh @@ -0,0 +1,512 @@ +#/bin/sh +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Konstantin Belousov +# +# 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 scenario for Intel userspace protection keys feature on Skylake Xeons + +grep -qw PKU /var/run/dmesg.boot || exit 0 +cd /tmp +cat > /tmp/pkru_exec.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef TEST_COMPILE +int x86_pkru_get_perm(unsigned int keyidx, int *access, int *modify); +int x86_pkru_set_perm(unsigned int keyidx, int access, int modify); +int x86_pkru_protect_range(void *addr, unsigned long len, unsigned int keyidx, + int flag); +int x86_pkru_unprotect_range(void *addr, unsigned long len); +uint32_t rdpkru(void); +void wrpkru(uint32_t); +#define AMD64_PKRU_PERSIST 0x0001 +#endif + +extern char **environ; + +#define OPKEY 1 + +int +main(void) +{ + char *args[3] = { + "/bin/date", + NULL + }; + struct rlimit rl; + + if (getrlimit(RLIMIT_STACK, &rl) != 0) + err(1, "getrlimit RLIMIT_STACK"); + if (x86_pkru_protect_range(0, 0x800000000000 - rl.rlim_max, OPKEY, + AMD64_PKRU_PERSIST) != 0) + err(1, "x86_pkru_protect_range"); + if (x86_pkru_set_perm(1, 1, 0) != 0) + err(1, "x86_pkru_set_perm"); + execve("/bin/date", args, environ); +} +EOF +cc -Wall -Wextra -g -O -o pkru_exec64 pkru_exec.c || exit 1 +cc -Wall -Wextra -g -O -o pkru_exec32 pkru_exec.c -m32 || exit 1 +rm pkru_exec.c +echo "Expect: Segmentation fault (core dumped)" +LD_BIND_NOW=1 ./pkru_exec64 +LD_BIND_NOW=1 ./pkru_exec32 +rm -f pkru_exec64 pkru_exec32 pkru_exec64.core pkru_exec32.core + +cat > /tmp/pkru_fork.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef TEST_COMPILE +int x86_pkru_get_perm(unsigned int keyidx, int *access, int *modify); +int x86_pkru_set_perm(unsigned int keyidx, int access, int modify); +int x86_pkru_protect_range(void *addr, unsigned long len, unsigned int keyidx, + int flag); +int x86_pkru_unprotect_range(void *addr, unsigned long len); +uint32_t rdpkru(void); +void wrpkru(uint32_t); +#endif + +static volatile char *mapping; + +#define OPKEY 1 + +int +main(void) +{ + int error; + pid_t child; + + mapping = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (mapping == MAP_FAILED) + err(1, "mmap"); + error = x86_pkru_protect_range((void *)mapping, getpagesize(), + OPKEY, 0); + if (error != 0) + err(1, "x86_pkru_protect_range"); + error = x86_pkru_set_perm(OPKEY, 0, 0); + if (error != 0) + err(1, "x86_pkru_set_perm"); + child = fork(); + if (child == -1) + err(1, "fork"); + if (child == 0) { + *mapping = 0; + printf("Still alive, pkru did not worked after fork"); + } + waitpid(child, NULL, 0); +} +EOF +cc -Wall -Wextra -g -O -o pkru_fork64 pkru_fork.c || exit 1 +cc -Wall -Wextra -g -O -o pkru_fork32 -m32 pkru_fork.c || exit 1 +rm pkru_fork.c +./pkru_fork64 +./pkru_fork32 +rm -f pkru_fork64 pkru_fork64.core pkru_fork32 pkru_fork32.core + +cat > /tmp/pkru_perm.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef TEST_COMPILE +int x86_pkru_get_perm(unsigned int keyidx, int *access, int *modify); +int x86_pkru_set_perm(unsigned int keyidx, int access, int modify); +int x86_pkru_protect_range(void *addr, unsigned long len, unsigned int keyidx, + int flag); +int x86_pkru_unprotect_range(void *addr, unsigned long len); +uint32_t rdpkru(void); +void wrpkru(uint32_t); +#define AMD64_PKRU_PERSIST 0x0001 +#endif + +static void +sighandler(int signo __unused, siginfo_t *si __unused, void *uc1 __unused) +{ + + exit(0); +} + +static volatile char *mapping; + +#define OPKEY 1 + +int +main(void) +{ + struct sigaction sa; + char *mapping1; + int error; + + error = x86_pkru_set_perm(OPKEY, 0, 0); + if (error != 0) + err(1, "x86_pkru_set_perm"); + mapping = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (mapping == MAP_FAILED) + err(1, "mmap"); + error = x86_pkru_protect_range((void *)mapping, getpagesize(), + OPKEY, 0); + if (error != 0) + err(1, "x86_pkru_protect_range"); + error = munmap((void *)mapping, getpagesize()); + if (error != 0) + err(1, "munmap"); + mapping1 = mmap((void *)mapping, getpagesize(), PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED | MAP_EXCL, -1, 0); + if (mapping1 == MAP_FAILED) + err(1, "mmap 2"); + *mapping = 0; + error = x86_pkru_protect_range((void *)mapping, getpagesize(), + OPKEY, AMD64_PKRU_PERSIST); + mapping1 = mmap((void *)mapping, getpagesize(), PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0); + if (mapping1 == MAP_FAILED) + err(1, "mmap 3"); + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = sighandler; + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGSEGV, &sa, NULL) == -1) + err(1, "sigaction"); + *mapping = 0; + printf("Still alive, pkru persist did not worked"); + exit(1); +} +EOF +cc -Wall -Wextra -g -O -o pkru_perm64 pkru_perm.c || exit 1 +cc -Wall -Wextra -g -O -o pkru_perm32 -m32 pkru_perm.c || exit 1 +rm pkru_perm.c +./pkru_perm64 +./pkru_perm32 +rm -f pkru_perm64 pkru_perm32 + +cat > /tmp/pkru.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef TEST_COMPILE +int x86_pkru_get_perm(unsigned int keyidx, int *access, int *modify); +int x86_pkru_set_perm(unsigned int keyidx, int access, int modify); +int x86_pkru_protect_range(void *addr, unsigned long len, unsigned int keyidx, + int flag); +int x86_pkru_unprotect_range(void *addr, unsigned long len); +uint32_t rdpkru(void); +void wrpkru(uint32_t); +#endif + +static char *mut_region; +static size_t mut_region_len; +static unsigned *mut_region_keys; +static pthread_t bga_thr; +static int signal_seen; +static siginfo_t si_seen; +static ucontext_t *uc_seen; +static u_int rpku_offset; + +static void +handler(int i __unused) { + _exit(0); +} + +static void +report_sig(int signo, siginfo_t *si, ucontext_t *uc) +{ + + printf("signal %d %s", signo, strsignal(signo)); + printf(" si_code %d si_status %d si_addr %p", si->si_code, + si->si_status, si->si_addr); + printf(" mc_err %#jx", (uintmax_t)uc->uc_mcontext.mc_err); + if (uc->uc_mcontext.mc_xfpustate != 0 && + (unsigned long)uc->uc_mcontext.mc_xfpustate_len >= + rpku_offset) { + printf(" pkru 0x%08x", *(uint32_t *)( + uc->uc_mcontext.mc_xfpustate + rpku_offset)); + } + printf("\n"); +} + +static void +sighandler(int signo, siginfo_t *si, void *u) +{ + ucontext_t *uc; + pthread_t thr; + size_t len; + uint32_t *pkrup; + + uc = u; + thr = pthread_self(); + if (thr == bga_thr) { + printf("Fault from background access thread\n"); + report_sig(signo, si, uc); + exit(1); + } + signal_seen = signo; + si_seen = *si; + + len = sizeof(ucontext_t); + if (uc->uc_mcontext.mc_xfpustate != 0) + len += uc->uc_mcontext.mc_xfpustate_len; + uc_seen = malloc(len); + if (uc_seen == NULL) + err(1, "malloc(%d)", (int)len); + memcpy(uc_seen, uc, sizeof(*uc)); +#if 0 +printf("signal %d xpfustate %p len %ld rpkuo %u\n", signo, (void *)uc->uc_mcontext.mc_xfpustate, uc->uc_mcontext.mc_xfpustate_len, rpku_offset); +#endif + if (uc->uc_mcontext.mc_xfpustate != 0) { + uc_seen->uc_mcontext.mc_xfpustate = (uintptr_t)uc_seen + + sizeof(*uc); + memcpy((void *)uc_seen->uc_mcontext.mc_xfpustate, + (void *)uc->uc_mcontext.mc_xfpustate, + uc->uc_mcontext.mc_xfpustate_len); + + if ((unsigned long)uc->uc_mcontext.mc_xfpustate_len >= + rpku_offset + sizeof(uint32_t)) { + pkrup = (uint32_t *)(rpku_offset + + (char *)uc->uc_mcontext.mc_xfpustate); +#if 0 +printf("signal %d *pkru %08x\n", signo, *pkrup); +#endif + *pkrup = 0; + } + } +} + +static void * +bg_access_thread_fn(void *arg __unused) +{ + char *c, x; + + pthread_set_name_np(pthread_self(), "bgaccess"); + for (x = 0, c = mut_region;;) { + *c = x; + if (++c >= mut_region + mut_region_len) { + c = mut_region; + x++; + } + } + return (NULL); +} + +static void +clear_signal_report(void) +{ + + signal_seen = 0; + free(uc_seen); + uc_seen = NULL; +} + +static void +check_signal(unsigned key, int check_access, int check_modify) +{ + + if (signal_seen == 0) { + printf("Did not get signal, key %d check_access %d " + "check_modify %d\n", key, check_access, check_modify); + printf("pkru 0x%08x\n", rdpkru()); + exit(1); + } +} + +static void +check_no_signal(void) +{ + + if (signal_seen != 0) { + printf("pkru 0x%08x\n", rdpkru()); + printf("Got signal\n"); + report_sig(signal_seen, &si_seen, uc_seen); + exit(1); + } +} + +static void +check(char *p, unsigned key, int check_access, int check_modify) +{ + int access, error, modify, orig_access, orig_modify; + + error = x86_pkru_get_perm(key, &orig_access, &orig_modify); + if (error != 0) + err(1, "x86_pkru_get_perm"); + access = check_access ? 0 : 1; + modify = check_modify ? 0 : 1; + error = x86_pkru_set_perm(key, access, modify); + if (error != 0) + err(1, "x86_pkru_set_perm access"); + clear_signal_report(); + if (check_modify) + *(volatile char *)p = 1; + else if (check_access) + *(volatile char *)p; + if (key == mut_region_keys[(p - mut_region) / getpagesize()]) + check_signal(key, check_access, check_modify); + else + check_no_signal(); + error = x86_pkru_set_perm(key, orig_access, orig_modify); + if (error != 0) + err(1, "x86_pkru_set_perm access restore"); + clear_signal_report(); + if (check_modify) + *(volatile char *)p = 1; + else if (check_access) + *(volatile char *)p; + check_no_signal(); +} + +static void +mutate_perms(void) +{ + unsigned key; + char *p; + + for (p = mut_region;;) { + for (key = 1; key < 0x10; key++) { + check(p, key, 1, 0); + check(p, key, 0, 1); + check(p, key, 1, 1); + } + p += getpagesize(); + if (p >= mut_region + mut_region_len) + p = mut_region; + } +} + +int +main(void) +{ + struct sigaction sa; + char *p; + unsigned i; + u_int regs[4]; + int error; + + cpuid_count(0xd, 0x9, regs); + rpku_offset = regs[1]; + if (rpku_offset != 0) +#if defined(__i386__) + rpku_offset -= sizeof(union savefpu); +#else + rpku_offset -= sizeof(struct savefpu); +#endif + + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = sighandler; + sa.sa_flags = SA_SIGINFO; + if (sigaction(SIGSEGV, &sa, NULL) == -1) + err(1, "sigaction SIGSEGV"); + if (sigaction(SIGBUS, &sa, NULL) == -1) + err(1, "sigaction SIGBUS"); + + mut_region_len = getpagesize() * 100; + mut_region_keys = calloc(mut_region_len, sizeof(unsigned)); + if (mut_region_keys == NULL) + err(1, "calloc keys"); + mut_region = mmap(NULL, mut_region_len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0); + if (mut_region == MAP_FAILED) + err(1, "mmap"); + for (i = 1, p = mut_region; p < mut_region + mut_region_len; + p += getpagesize()) { + error = x86_pkru_protect_range(p, getpagesize(), i, 0); + if (error != 0) + err(1, "x86_pkru_protect_range key %d", i); + mut_region_keys[(p - mut_region) / getpagesize()] = i; + if (++i > 0xf) + i = 1; + } + + signal(SIGALRM, handler); + alarm(5); + error = pthread_create(&bga_thr, NULL, bg_access_thread_fn, NULL); + if (error != 0) + errc(1, error, "pthread create background access thread"); + + mutate_perms(); +} +EOF +cc -Wall -Wextra -g -O -o pkru64 pkru.c -lpthread || exit 1 +cc -Wall -Wextra -g -O -o pkru32 -m32 pkru.c -lpthread || exit 1 +rm pkru.c +./pkru64 +./pkru32 +rm -f pkru64 pkru32 + +exit diff --git a/tools/test/stress2/misc/pkru2.sh b/tools/test/stress2/misc/pkru2.sh new file mode 100755 index 000000000000..cf9fac187793 --- /dev/null +++ b/tools/test/stress2/misc/pkru2.sh @@ -0,0 +1,108 @@ +#/bin/sh + +# Test scenario for Intel userspace protection keys feature on Skylake Xeons +# Based on tests by kib@ + +grep -qw PKU /var/run/dmesg.boot || exit 0 +cd /tmp + +cat > /tmp/pkru2a.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile char *mapping; + +#define OPKEY 1 + +int +main(void) +{ + time_t start; + int error; + + start = time(NULL); + while (time(NULL) - start < 60) { + mapping = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (mapping == MAP_FAILED) + err(1, "mmap"); + error = x86_pkru_protect_range((void *)mapping, + getpagesize(), OPKEY, 0); + error = x86_pkru_protect_range((void *)mapping, + getpagesize() * 64, OPKEY, 0); + if (error != 0) + err(1, "x86_pkru_protect_range"); + error = x86_pkru_set_perm(OPKEY, 0, 0); + if (error != 0) + err(1, "x86_pkru_set_perm"); + if (munmap((void *)mapping, getpagesize()) == -1) + err(1, "munmap()"); + } + return (0); +} +EOF +cc -Wall -Wextra -g -O -o pkru2a64 pkru2a.c || exit 1 +cc -Wall -Wextra -g -O -o pkru2a32 -m32 pkru2a.c || exit 1 +rm pkru2a.c +./pkru2a64 +./pkru2a32 +rm -f pkru2a64 pkru2a32 + +cat > /tmp/pkru2b.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile char *mapping; + +#define OPKEY 1 + +int +main(void) +{ + time_t start; + int error; + + start = time(NULL); + while (time(NULL) - start < 60) { + mapping = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (mapping == MAP_FAILED) + err(1, "mmap"); + error = x86_pkru_protect_range((void *)mapping, + getpagesize() * 64, OPKEY, 0); + if (error != 0) + err(1, "x86_pkru_protect_range"); + error = x86_pkru_set_perm(OPKEY, 0, 0); + if (error != 0) + err(1, "x86_pkru_set_perm"); + if (munmap((void *)mapping, getpagesize()) == -1) + err(1, "munmap()"); + } + return (0); +} +EOF + +cc -Wall -Wextra -g -O -o pkru2b64 pkru2b.c || exit 1 +cc -Wall -Wextra -g -O -o pkru2b32 -m32 pkru2b.c || exit 1 +rm pkru2b.c +./pkru2b64 +./pkru2b32 +rm -f pkru2b64 pkru2b32 + +exit diff --git a/tools/test/stress2/misc/pmc.sh b/tools/test/stress2/misc/pmc.sh new file mode 100755 index 000000000000..b36cfa89c779 --- /dev/null +++ b/tools/test/stress2/misc/pmc.sh @@ -0,0 +1,55 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2011 Peter Holm +# All rights reserved. +# +# 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. +# + +# Simple pmc test + +# "panic: [pmc,4950] pm=0x2ddfe880 runcount 0" seen. +# https://people.freebsd.org/~pho/stress/log/pmc.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +kldstat -v | grep -q hwpmc || { kldload hwpmc; loaded=1; } + +event=`pmcstat -L 2>/dev/null | tr -d '\t' | sort -R | head -1` +if [ -n "$event" ]; then + for i in `jot 2`; do + pmcstat -P $event -O /tmp/sample.out.$i find -x /var \ + -name not.there & + done + sleep 1 + + export runRUNTIME=5m + pgrep -q pmcstat && + (cd ..; ./run.sh vfs.cfg) + wait +fi +[ $loaded ] && kldunload hwpmc +rm -f /tmp/sample.out.* +exit 0 diff --git a/tools/test/stress2/misc/pmc2.sh b/tools/test/stress2/misc/pmc2.sh new file mode 100755 index 000000000000..1e773e1448f8 --- /dev/null +++ b/tools/test/stress2/misc/pmc2.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Page fault seen: +# https://people.freebsd.org/~pho/stress/log/pmc2.txt + +# https://people.freebsd.org/~pho/stress/log/mmacy004.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +kldstat -v | grep -q hwpmc || { kldload hwpmc; loaded=1; } + +event=`pmcstat -L 2>/dev/null | tr -d '\t' | sort -R | head -1` +if [ -n "$event" ]; then + ../misc/churn.sh & + pid=$! + while ! pgrep -q churn; do sleep .5; done + pmcstat -P $event -t churn -O /tmp/pmc2.log + wait $pid + rm /tmp/pmc2.log +fi +[ $loaded ] && kldunload hwpmc + +exit 0 diff --git a/tools/test/stress2/misc/pmc3.sh b/tools/test/stress2/misc/pmc3.sh new file mode 100755 index 000000000000..cdfee000d352 --- /dev/null +++ b/tools/test/stress2/misc/pmc3.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# syscall fuzz of hwpmc.ko + +# Page fault seen: +# https://people.freebsd.org/~pho/stress/log/hwpmc3-1.txt + +kldstat | grep -q hwpmc || { kldload hwpmc.ko; loaded=1; } + +num=`kldstat -d -m hwpmc | awk -F ',' '/hwpmc/ {print $2}'` +[ $num ] || exit 1 + +for i in `jot 2`; do + noswap=1 sleeptime=18 ../misc/syscall4.sh $num +done + +[ $loaded ] && kldunload hwpmc +exit 0 diff --git a/tools/test/stress2/misc/pmc4.sh b/tools/test/stress2/misc/pmc4.sh new file mode 100755 index 000000000000..949e97073750 --- /dev/null +++ b/tools/test/stress2/misc/pmc4.sh @@ -0,0 +1,124 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# pmc fuzz test + +. ../default.cfg + +kldstat -v | grep -q hwpmc || { kldload hwpmc; loaded=1; } +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/pmc4.c +mycc -o pmc4 -Wall -Wextra -O0 -g pmc4.c -lpmc -lpthread || exit 0 +rm -f pmc4.c + +for i in `jot 100`; do + ./pmc4 +done > /dev/null 2>&1 + +rm -rf pmc4 pmc4.core +[ $loaded ] && kldunload hwpmc +exit 0 + +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +static int fd1[2]; +static int kq; +#define THREADS 20 + +static void * +test(void *arg __unused) +{ + + void *rfd; + char *cmdline[] = { "/usr/bin/true", NULL }; + + if ((rfd = pmclog_open(kq)) == NULL) + err(1, "pmclog_open(%d)", kq); + if (pmc_configure_logfile(kq) < 0) + err(1, "ERROR: Cannot configure log file"); + sleep(1); + usleep(arc4random() % 20000); + if (execve(cmdline[0], cmdline, NULL) == -1) + err(1, "execve"); + + return (0); +} + +int +main(void) +{ + struct kevent ev[3]; + pthread_t tid[THREADS]; + int i, n, rc; + + if (pmc_init() == -1) + err(1, "pmc_init"); + + if (pipe(fd1) == -1) + err(1, "pipe()"); + + if ((kq = kqueue()) < 0) + err(1, "kqueue(). %s:%d", __FILE__, __LINE__); + + n = 0; + EV_SET(&ev[n], fd1[1], EVFILT_WRITE, + EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0); + n++; + + if (kevent(kq, ev, n, NULL, 0, NULL) < 0) + err(1, "kevent(). %s:%d", __FILE__, __LINE__); + n = 0; + EV_SET(&ev[n], fd1[1], EVFILT_WRITE, + EV_DELETE, 0, 0, 0); + n++; + if (kevent(kq, ev, n, NULL, 0, NULL) < 0) + warn("kevent(). %s:%d", __FILE__, __LINE__); + + for (i = 0; i < THREADS; i++) { + if ((rc = pthread_create(&tid[i], NULL, test, NULL)) != 0) + errc(1, rc, "test()"); + } + for (i = 0; i < THREADS; i++) { + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + } + + return (0); +} diff --git a/tools/test/stress2/misc/pmc5.sh b/tools/test/stress2/misc/pmc5.sh new file mode 100755 index 000000000000..c7305aa4d470 --- /dev/null +++ b/tools/test/stress2/misc/pmc5.sh @@ -0,0 +1,138 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# pmc fuzz test + +. ../default.cfg + +kldstat -v | grep -q hwpmc || { kldload hwpmc; loaded=1; } +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/pmc5.c +mycc -o pmc5 -Wall -Wextra -O0 -g pmc5.c -lpmc -lpthread || exit 1 +rm -f pmc5.c + +for i in `jot 100`; do + ./pmc5 +done > /dev/null 2>&1 + +rm -rf pmc5 pmc5.core +[ $loaded ] && kldunload hwpmc +exit 0 + +EOF +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; +static int fd1[2]; +static int kq; +#define THREADS 20 +#define SYNC 0 + +void * +test(void *arg __unused) +{ + + void *rfd; + char *cmdline[] = { "/usr/bin/true", NULL }; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != THREADS) + ; + if ((rfd = pmclog_open(kq)) == NULL) + err(1, "pmclog_open(%d)", kq); +// if (pmc_configure_logfile(fd1[1]) < 0) + if (pmc_configure_logfile(kq) < 0) + err(1, "ERROR: Cannot configure log file"); + sleep(1); + usleep(arc4random() % 20000); + if (execve(cmdline[0], cmdline, NULL) == -1) + err(1, "execve"); + + return (0); +} + +int +main(void) +{ + struct kevent ev[3]; + pthread_t tid[THREADS]; + size_t len; + int i, n, rc; + + len = PAGE_SIZE; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + if (pmc_init() == -1) + err(1, "pmc_init"); + + if (pipe(fd1) == -1) + err(1, "pipe()"); + + if ((kq = kqueue()) < 0) + err(1, "kqueue(). %s:%d", __FILE__, __LINE__); + + n = 0; + EV_SET(&ev[n], fd1[1], EVFILT_WRITE, + EV_ADD | EV_ENABLE | EV_CLEAR, 0, 0, 0); + n++; + + if (kevent(kq, ev, n, NULL, 0, NULL) < 0) + err(1, "kevent(). %s:%d", __FILE__, __LINE__); + n = 0; + EV_SET(&ev[n], fd1[1], EVFILT_WRITE, + EV_DELETE, 0, 0, 0); + n++; + if (kevent(kq, ev, n, NULL, 0, NULL) < 0) + warn("kevent(). %s:%d", __FILE__, __LINE__); + + for (i = 0; i < THREADS; i++) { + if ((rc = pthread_create(&tid[i], NULL, test, NULL)) != 0) + errc(1, rc, "test()"); + } + for (i = 0; i < THREADS; i++) { + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + } + + return (0); +} diff --git a/tools/test/stress2/misc/pmc6.sh b/tools/test/stress2/misc/pmc6.sh new file mode 100755 index 000000000000..4cbdf278125f --- /dev/null +++ b/tools/test/stress2/misc/pmc6.sh @@ -0,0 +1,41 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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 scenario from: +# [Bug 230985] pmcstat triggers assertion "pmcval outside of expected range" +# by markj@FreeBSD.org + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +kldstat -v | grep -q hwpmc || { kldload hwpmc; loaded=1; } + +event=inst_retired.any +pmcstat -L 2>/dev/null | grep -q $event || exit 0 +pmcstat -P $event -- find -x / -name foo > /dev/null 2>&1 + +[ $loaded ] && kldunload hwpmc diff --git a/tools/test/stress2/misc/pmc7.sh b/tools/test/stress2/misc/pmc7.sh new file mode 100755 index 000000000000..6a4726b24203 --- /dev/null +++ b/tools/test/stress2/misc/pmc7.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# From https://reviews.freebsd.org/D17011 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +cd /tmp +kldstat -v | grep -q hwpmc || { kldload hwpmc; loaded=1; } +pmcstat -S unhalted_core_cycles -O ppid.pmcstat sleep 10 +pmcstat -R ppid.pmcstat -z100 -G ppid.stacks +[ $loaded ] && kldunload hwpmc +rm -f ppid.pmcstat ppid.stacks diff --git a/tools/test/stress2/misc/poll.sh b/tools/test/stress2/misc/poll.sh new file mode 100755 index 000000000000..c345ffae9817 --- /dev/null +++ b/tools/test/stress2/misc/poll.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# A pipe_poll() regression test. +# Python test scenario by Alexander Motin +# https://reviews.freebsd.org/D21333 + +# Hang seen: +# $ procstat -k 19529 +# PID TID COMM KSTACK +# 19529 101381 python3.7 - ... _sleep kqueue_kevent kern_kevent_fp kern_kevent kern_kevent_generic sys_kevent amd64_syscall fast_syscall_common +# 19529 101630 python3.7 - ... _sleep pipe_read dofileread kern_readv sys_read amd64_syscall fast_syscall_common +# 19529 101631 python3.7 - ... _sleep umtxq_sleep do_sem2_wait __umtx_op_sem2_wait amd64_syscall fast_syscall_common +# $ + +# Fixed by r351348 + +[ -z "`type python3 2>/dev/null`" ] && exit 0 +cat > /tmp/poll.py < $log & +pid=$! +sleep 60 +s1=`wc -l < $log` +sleep 60 +s2=`wc -l < $log` +while pgrep -qf poll.py; do pkill -f poll.py; done +wait $pid +[ $s2 -gt $s1 ] && s=0 || s=1 + +rm -f /tmp/poll.py $log +exit $s + +dtrace -wn '*::pipe_poll:entry {@rw[execname,probefunc] = count(); }' diff --git a/tools/test/stress2/misc/poll2.sh b/tools/test/stress2/misc/poll2.sh new file mode 100755 index 000000000000..13db2d0d22d3 --- /dev/null +++ b/tools/test/stress2/misc/poll2.sh @@ -0,0 +1,212 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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 of pipe_poll() +# https://reviews.freebsd.org/D21333 + +# No problems seen. + +# markj@ write: +# A simplified reproducible might be tricky to come up with. I think this +# would do it: +# +# - Thread W writes 8KB (PIPE_MINDIRECT) of data to a pipe at a time. +# - Thread P poll()s the pipe for POLLIN. +# - Thread R reads 8KB of data from the pipe at a time. +# +# Thread P uses non-blocking poll() (timeout == 0). When thread P does +# not see POLLIN, it signals the reader and the writer and continues +# polling in a loop. When thread P sees POLLIN it signals the reader and +# sleeps until the reader returns and wakes it up. After threads R and W +# finish their respective system calls, they always wait for another +# signal from P before doing anything. +# +# Basically, if all three threads are executing their respective system +# calls, and the reader has drained the writer's data and awoken the +# writer, there is a window where poll() will return POLLIN even though +# all data has been read. If the reader then attempts to read() from the +# pipe again, it will block and the application appears to be hung. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +rm -f $dir/poll2.c || exit 1 +sed '1,/^EOF/d' < $odir/$0 > $dir/poll2.c +mycc -o poll2 -Wall -Wextra -O0 -g poll2.c -lpthread || exit 1 + +cpuset -l 0 $dir/poll2 +s=$? +pkill swap +wait + +rm -rf poll2 poll2.c poll2.core +exit $s + +EOF +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile int done, frd, fwr, fpl; +static int fds[2]; +static char b1[8192], b2[8192]; + +#define RUNTIME (2 * 60) +#define LOOP 400000 + +static void * +wr(void *data __unused) +{ + int i; + + for (i = 0; i < LOOP; i++) { + pthread_set_name_np(pthread_self(), "wr-idle"); + while (fwr == 0) + usleep(5); + pthread_set_name_np(pthread_self(), "wr-act"); + fpl = 1; + if (write(fds[1], b1, sizeof(b1)) != sizeof(b1)) + err(1, "write"); + fpl = 1; + fwr = 0; + } + + return (NULL); +} + +static void * +rd(void *data __unused) +{ + int i; + + for (i = 0; i < LOOP; i++) { + fpl = 1; + pthread_set_name_np(pthread_self(), "rd-idle"); + while (frd == 0) + usleep(5); + pthread_set_name_np(pthread_self(), "rd-act"); + if (read(fds[0], b2, sizeof(b2)) != sizeof(b2)) + err(1, "read"); + frd = 0; + fpl = 1; + } + done = 1; + + return (NULL); +} + +static void * +pl(void *data __unused) +{ + struct pollfd pfd; + int i, r; + + pfd.fd = fds[0]; + pfd.events = POLLIN; + for (i = 0; done == 0; i++) { + pfd.fd = fds[0]; + pfd.events = POLLIN; + pthread_set_name_np(pthread_self(), "pl-idle"); + pthread_set_name_np(pthread_self(), "pl-act"); + while (fpl == 0) + usleep(5); +again: + if ((r = poll(&pfd, 1, 0)) == -1) + err(1, "poll"); + if (done == 1) + return (NULL); + if (r == 0) { + frd = fwr = 1; + goto again; + } else { + fpl = 0; + frd = fwr = 1; + } + } + + return (NULL); +} + +void +test(void) +{ + pthread_t tid[3]; + int rc; + + if (pipe(fds) == -1) + err(1, "pipe"); + done = 0; + fpl = 0; + frd = 0; + fwr = 0; + if ((rc = pthread_create(&tid[0], NULL, rd, NULL)) != 0) + errc(1, rc, "pthread_create"); + if ((rc = pthread_create(&tid[1], NULL, wr, NULL)) != 0) + errc(1, rc, "pthread_create"); + if ((rc = pthread_create(&tid[2], NULL, pl, NULL)) != 0) + errc(1, rc, "pthread_create"); + + frd = 1; + fwr = 1; + + if ((rc = pthread_join(tid[0], NULL)) != 0) + errc(1, rc, "pthread_join"); + if ((rc = pthread_join(tid[1], NULL)) != 0) + errc(1, rc, "pthread_join"); + if ((rc = pthread_join(tid[2], NULL)) != 0) + errc(1, rc, "pthread_join"); + + close(fds[0]); + close(fds[1]); +} + +int +main(void) +{ + time_t start; + + alarm(600); + start = time(NULL); + while ((time(NULL) - start) < RUNTIME) { + test(); + } + + return (0); +} diff --git a/tools/test/stress2/misc/posix_fadvise.sh b/tools/test/stress2/misc/posix_fadvise.sh new file mode 100755 index 000000000000..df0995570783 --- /dev/null +++ b/tools/test/stress2/misc/posix_fadvise.sh @@ -0,0 +1,72 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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. +# + +# Memory leak. Fixed in r232702. + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > posix_fadvise.c +mycc -o posix_fadvise -Wall -Wextra -O2 -g posix_fadvise.c + +n1=`vmstat -m | grep fadvise | awk '{print $2 + 0}'` +/tmp/posix_fadvise +n2=`vmstat -m | grep fadvise | awk '{print $2 + 0}'` +if [ $((n2 - n1)) -gt 10 ]; then + echo FAIL + vmstat -m | sed -n '1p;/fadvise/p' +fi + +rm -f /tmp/posix_fadvise posix_fadvise.c +exit +EOF +#include +#include +#include +#include +#include + +int +main(void) +{ + off_t len, offset; + int advise, fd, i; + + for (i = 0; i < 500; i++) { + if ((fd = open("posix_fadvise.c", O_RDONLY)) == -1) + err(1, "open()"); + offset = arc4random(); + len = arc4random(); + advise = arc4random() % 6; + if (posix_fadvise(fd, offset, len, advise) == -1) + warn("posix_fadvise"); + close(fd); + } + return (0); +} diff --git a/tools/test/stress2/misc/posix_fadvise2.sh b/tools/test/stress2/misc/posix_fadvise2.sh new file mode 100755 index 000000000000..de9562e6c57b --- /dev/null +++ b/tools/test/stress2/misc/posix_fadvise2.sh @@ -0,0 +1,78 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Looping thread seen: +# https://people.freebsd.org/~pho/stress/log/kostik850.txt +# Fixed by r292326. + +. ../default.cfg +[ -f /usr/libexec/sendmail/sendmail ] || exit 0 + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > posix_fadvise2.c +mycc -o posix_fadvise2 -Wall -Wextra -O2 posix_fadvise2.c || exit 1 +rm -f posix_fadvise2.c + +/tmp/posix_fadvise2 + +rm -f /tmp/posix_fadvise2 /tmp/posix_fadvise2 +exit +EOF +#include + +#include +#include +#include +#include +#include + +char *file[2] = { + "/usr/libexec/sendmail/sendmail", + "/tmp/posix_fadvise2"}; + +int +main(void) +{ + int fd, i, r; + + for (i = 0; i < 2; i++) { + fprintf(stderr, "Testing with %s.\n", file[i]); + if ((fd = open(file[i], O_RDONLY)) == -1) + err(1, "open(%s)", file[i]); + +/* Arguments from syscall4.sh test as seen in kostik850.txt */ + if ((r = posix_fadvise(fd, 0x1e9cda7a9ada8319, + 0x1e9d1deee0401abd, POSIX_FADV_DONTNEED)) != 0) + errc(1, r, "posix_fadvise(%s)", file[i]); + + close(fd); + } + + return(0); +} diff --git a/tools/test/stress2/misc/posix_fadvise3.sh b/tools/test/stress2/misc/posix_fadvise3.sh new file mode 100755 index 000000000000..c9dc5895d8ea --- /dev/null +++ b/tools/test/stress2/misc/posix_fadvise3.sh @@ -0,0 +1,120 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Looping thread seen: +# https://people.freebsd.org/~pho/stress/log/kostik855.txt +# Fixed by r293197. + +# Again on i386: +# https://people.freebsd.org/~pho/stress/log/kostik867.txt +# Fixed by r295716. + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > posix_fadvise3.c +mycc -o posix_fadvise3 -Wall -Wextra -O2 -g posix_fadvise3.c + +data=/tmp/posix_fadvise3.data +dd if=/dev/zero of=$data bs=1m count=64 status=none +/tmp/posix_fadvise3 + +rm $data +truncate -s 64m $data +/tmp/posix_fadvise3 + +rm -f /tmp/posix_fadvise3 posix_fadvise3.c $data +exit +EOF +#include +#include +#include +#include +#include + +#define LOOPS 10000 +#define N (128 * 1024 / (int)sizeof(u_int32_t)) + +u_int32_t r[N]; + +unsigned long +makearg(void) +{ + unsigned int i; + unsigned long val; + + val = arc4random(); + i = arc4random() % 100; + if (i < 20) + val = val & 0xff; + if (i >= 20 && i < 40) + val = val & 0xffff; + if (i >= 40 && i < 60) + val = (unsigned long)(r) | (val & 0xffff); +#if defined(__LP64__) + if (i >= 60) { + val = (val << 32) | arc4random(); + if (i > 80) + val = val & 0x00007fffffffffffUL; + } +#endif + + return(val); +} + +int +main(void) +{ + off_t len, offset; + int advise, fd, i, j; + + if ((fd = open("/tmp/posix_fadvise3.data", O_RDONLY)) == -1) + err(1, "open()"); + offset = 0; + len = 0x7fffffffffffffff; + advise = 4; + if (posix_fadvise(fd, offset, len, advise) == -1) + warn("posix_fadvise"); + close(fd); + + for (i = 0; i < LOOPS; i++) { + for (j = 0; j < N; j++) + r[j] = arc4random(); + if ((fd = open("/tmp/posix_fadvise3.data", O_RDONLY)) == -1) + err(1, "open()"); + offset = makearg(); + len = makearg(); + advise = arc4random() % 6; + if (posix_fadvise(fd, offset, len, advise) == -1) + warn("posix_fadvise"); + close(fd); + } + + return (0); +} diff --git a/tools/test/stress2/misc/posix_openpt.sh b/tools/test/stress2/misc/posix_openpt.sh new file mode 100755 index 000000000000..8457b8c4fe55 --- /dev/null +++ b/tools/test/stress2/misc/posix_openpt.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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: Assertion ttyinq_getsize(&tp->t_inq) == 0 failed" seen. +# https://people.freebsd.org/~pho/stress/log/posix_openpt.txt +# Test scenario by brde@ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > posix_openpt.c +mycc -o posix_openpt -Wall -Wextra -O2 posix_openpt.c || exit 1 +rm -f posix_openpt.c + +for i in `jot 10`; do + /tmp/posix_openpt & +done + +me=`tty` +stty -f /dev/ptmx 300 2>/dev/null +for i in /dev/pts/*; do + [ $i = $me ] && continue + stty -f $i 300 2>/dev/null +done +wait +rm -f /tmp/posix_openpt + +exit +EOF +#include +#include +#include +#include + +int +main(void) +{ + int masterfd, slavefd; + char *slave; + + if ((masterfd = posix_openpt(O_RDWR | O_NOCTTY)) == -1) + err(1, "posix_openpt"); + if ((slave = ptsname (masterfd)) == NULL) + err(1, "ptsname"); + if ((slavefd = open(slave, O_RDWR|O_NOCTTY)) == -1) + err(1, "open(%s)", slave); + + sleep(arc4random() % 60 + 1); + + return (0); +} diff --git a/tools/test/stress2/misc/posix_openpt2.sh b/tools/test/stress2/misc/posix_openpt2.sh new file mode 100755 index 000000000000..2d3427c26ea1 --- /dev/null +++ b/tools/test/stress2/misc/posix_openpt2.sh @@ -0,0 +1,152 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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: Assertion !tty_gone(tp) failed at ttydevsw.h:153" seen. +# https://people.freebsd.org/~pho/stress/log/posix_openpt2.txt +# Fixed by r312077 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > posix_openpt2.c +mycc -o posix_openpt2 -Wall -Wextra -O2 posix_openpt2.c -lutil || exit 1 +rm -f posix_openpt2.c + +/tmp/posix_openpt2 & + +while kill -0 $! 2>/dev/null; do + $here/../testcases/swap/swap -t 2m -i 20 +done +wait + +rm -f /tmp/posix_openpt2 +exit 0 +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 10 +#define PARALLEL 2 +#define RUNTIME 300 + +void +churn(char *path) +{ + FTS *fts; + FTSENT *p; + time_t start; + int fd, ftsoptions; + char *args[2]; + + ftsoptions = FTS_PHYSICAL; + args[0] = path; + args[1] = 0; + + setproctitle("churn"); + start = time(NULL); + while (time(NULL) - start < RUNTIME / LOOPS) { + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) { + if (p->fts_info == FTS_D || + p->fts_info == FTS_DP) + continue; + if ((fd = open(p->fts_path, O_RDONLY)) > 0) + close(fd); + + } + + if (errno != 0 && errno != ENOENT) + err(1, "fts_read"); + if (fts_close(fts) == -1) + err(1, "fts_close()"); + } + + _exit(0); +} + +void +pty(void) +{ + time_t start; + int masterfd, slavefd; + char *slave; + + start = time(NULL); + while (time(NULL) - start < RUNTIME / LOOPS) { + if ((masterfd = posix_openpt(O_RDWR | O_NOCTTY)) == -1) + err(1, "posix_openpt"); + if ((slave = ptsname (masterfd)) == NULL) + err(1, "ptsname"); + if ((slavefd = open(slave, O_RDWR|O_NOCTTY)) == -1) + err(1, "open(%s)", slave); + usleep(arc4random() % 10000); + close(slavefd); + close(masterfd); + } + _exit(0); +} + +int +main(void) +{ + int i, j; + + for (j = 0; j < LOOPS; j++) { + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + pty(); + } + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + churn("/dev/pts"); + } + for (i = 0; i < 2 * PARALLEL; i++) + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/pread.sh b/tools/test/stress2/misc/pread.sh new file mode 100755 index 000000000000..fecdc18675c9 --- /dev/null +++ b/tools/test/stress2/misc/pread.sh @@ -0,0 +1,190 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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. +# + +# pread(2) fuzzing inspired by the iknowthis test suite +# by Tavis Ormandy + +# Fixed in r227527. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pread.c +mycc -o pread -Wall -Wextra pread.c +rm -f pread.c + +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 +cp -a /usr/include $mntpoint +echo "Testing tmpfs(5)" +/tmp/pread $mntpoint +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done + +echo "Testing fdescfs(5)" +mount -t fdescfs null /dev/fd +for i in `jot 100`; do + /tmp/pread /dev/fd +done + +while mount | grep -q "on /dev/fd "; do + umount /dev/fd || sleep 1 +done + +echo "Testing procfs(5)" +mount -t procfs procfs $mntpoint +/tmp/pread $mntpoint +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done + +mdconfig -a -t swap -s 1g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +cp -a /usr/include $mntpoint +echo "Testing FFS" +/tmp/pread $mntpoint +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart + +mount -t nullfs /bin $mntpoint +echo "Testing nullfs(5)" +/tmp/pread $mntpoint +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done + +echo "Testing procfs(5)" +mount -t procfs procfs $mntpoint +/tmp/pread $mntpoint +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done + +echo "Testing devfs(8)" +mount -t devfs devfs $mntpoint +/tmp/pread $mntpoint +while mount | grep -q "on $mntpoint "; do + umount $mntpoint || sleep 1 +done + +rm -f /tmp/pread +exit 0 +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void +hand(int i __unused) { /* handler */ + _exit(1); +} + +int +test(char *path) +{ + + FTS *fts; + FTSENT *p; + int ftsoptions; + char *args[2]; + int buf[64], fd; + + signal(SIGSEGV, hand); + signal(SIGABRT, hand); + ftsoptions = FTS_PHYSICAL; + args[0] = path; + args[1] = 0; + + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) { + if ((fd = open(p->fts_path, O_RDONLY)) == -1) { + if (errno != EACCES && errno != ENXIO) + warn("open(%s)", p->fts_path); + continue; + } + alarm(1); + pread(fd, (void *)0xdeadc0de, 0x7ffffff, 0xffffffff); + pread(fd, buf, 0x7ffffff, 0xffffffff); + pread(fd, buf, sizeof(buf), 0xffffffff); + pread(fd, buf, sizeof(buf), 0); + close(fd); + } + fts_close(fts); + + exit(0); +} + +int +main(int argc __unused, char **argv) +{ + int i; + struct passwd *pw; + + if ((pw = getpwnam("nobody")) == NULL) + err(1, "no such user: nobody"); + + 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(); + + if (daemon(0, 0) == -1) + err(1, "daemon()"); + + for (i = 0; i < 10; i++) { + if (fork() == 0) + test(argv[1]); + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/proccontrol.sh b/tools/test/stress2/misc/proccontrol.sh new file mode 100755 index 000000000000..52f7cc824372 --- /dev/null +++ b/tools/test/stress2/misc/proccontrol.sh @@ -0,0 +1,54 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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. +# + +# A brif test of proccontrol(1). No problems seen. + +[ -x /usr/bin/proccontrol ] || exit 0 + +sleep 60 & pid=$! +proccontrol -m aslr -s disable sleep 1 +proccontrol -m aslr -s enable sleep 1 +proccontrol -m aslr sleep 1 +proccontrol -m aslr -s disable -p $pid +proccontrol -m aslr -s enable -p $pid +proccontrol -m aslr -q -p $pid + +proccontrol -m trace -s disable sleep 1 +proccontrol -m trace -s enable sleep 1 +proccontrol -m trace sleep 1 +proccontrol -m trace -q -p $pid + +proccontrol -m trapcap -s disable sleep 1 +proccontrol -m trapcap -s enable sleep 1 +proccontrol -m trapcap sleep 1 +proccontrol -m trapcap -s disable -p $pid +proccontrol -m trapcap -s enable -p $pid +proccontrol -m trapcap -q -p $pid +kill $pid +wait diff --git a/tools/test/stress2/misc/procfs.sh b/tools/test/stress2/misc/procfs.sh new file mode 100755 index 000000000000..6b445b0d7e48 --- /dev/null +++ b/tools/test/stress2/misc/procfs.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 + +mounts=15 # Number of parallel scripts +mdstart=$mdstart # Use md unit numbers from this point + +if [ $# -eq 0 ]; then + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + [ ! -d ${mntpoint}$m ] && mkdir ${mntpoint}$m + mount | grep "$mntpoint" | grep -q md$m && umount ${mntpoint}$m + done + + # start the parallel tests + touch /tmp/$0 + for i in `jot $mounts`; do + m=$(( i + mdstart - 1 )) + ./$0 $m & + ./$0 find $m > /dev/null 2>&1 & + done + wait +else + if [ $1 = find ]; then + while [ -r /tmp/$0 ]; do + ls -lR ${mntpoint}* + done + else + + # The test: Parallel mount and unmounts + for i in `jot 128`; do + m=$1 + mount -t procfs proc ${mntpoint}$m + while mount | grep -qw $mntpoint$m; do + opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && echo "-f") + umount $opt ${mntpoint}$m > /dev/null 2>&1 + done + done + rm -f /tmp/$0 + fi +fi diff --git a/tools/test/stress2/misc/procfs2.sh b/tools/test/stress2/misc/procfs2.sh new file mode 100755 index 000000000000..dd0f1074f9b2 --- /dev/null +++ b/tools/test/stress2/misc/procfs2.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +# +# Copyright (c) 2010 Peter Holm +# All rights reserved. +# +# 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: not suspended thread 0xc674c870 +# Found by scrashme and fixed in r216120 + +mount | grep -q "/proc " || { mount -t procfs procfs /proc || exit 1; } +for i in `find /proc ! -type d`; do + dd if=$i of=/dev/null > /dev/null 2>&1 + dd if=/dev/random of=$i > /dev/null 2>&1 +done +exit 0 diff --git a/tools/test/stress2/misc/procfs3.sh b/tools/test/stress2/misc/procfs3.sh new file mode 100755 index 000000000000..c9c4820adbff --- /dev/null +++ b/tools/test/stress2/misc/procfs3.sh @@ -0,0 +1,154 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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. +# + +# procfs(5) test scenario. +# "panic: wchan 0xc10a4f68 has no wmesg" seen + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep -q "/proc " || { mount -t procfs procfs /proc || exit 1; } +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > procfs3.c +mycc -o procfs3 -Wall -Wextra -O2 procfs3.c || exit 1 +rm -f procfs3.c +cd $here + +su $testuser -c /tmp/procfs3 + +rm -f /tmp/procfs3 +exit 0 +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 10 + +void +handler(int i __unused) +{ +} + +int +test(void) +{ + + FTS *fts; + FTSENT *p; + int ftsoptions; + char *args[2]; + int fd, i; + char buf[1629]; + + ftsoptions = FTS_PHYSICAL; + args[0] = "/proc"; + args[1] = 0; + + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) { + switch (p->fts_info) { + case FTS_F: /* Ignore. */ + break; + case FTS_D: /* Ignore. */ + continue; + case FTS_DP: + continue; + case FTS_DC: /* Ignore. */ + continue; + case FTS_SL: /* Ignore. */ + continue; + case FTS_DNR: + continue; + case FTS_NS: + continue; + case FTS_ERR: + case FTS_DEFAULT: + warnx("%s: %s. fts_info = %d", p->fts_path, strerror(p->fts_errno), + p->fts_info); + continue; + default: + printf("%s: default, %d\n", getprogname(), p->fts_info); + break; + } + + if ((fd = open(p->fts_path, O_RDONLY)) == -1) + continue; + signal(SIGALRM, handler); + alarm(1); + + for (i = 0; i < 2; i++) { + read(fd, buf, 1629); + } + close(fd); + } + + if (errno != 0 && errno != ENOENT) + err(1, "fts_read"); + if (fts_close(fts) == -1) + err(1, "fts_close()"); + + return (0); +} + +int +main(void) +{ + int i, j; + + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) { + for (j = 0; j < 50; j++) { + test(); + } + _exit(0); + } + } + + for (i = 0; i < PARALLEL; i++) + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/procfs4.sh b/tools/test/stress2/misc/procfs4.sh new file mode 100755 index 000000000000..ffa812a7f73d --- /dev/null +++ b/tools/test/stress2/misc/procfs4.sh @@ -0,0 +1,156 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 scenario idea by kib@ + +# "panic: double fault" seen due to recursion + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep -q procfs || mount -t procfs procfs /proc +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > procfs4.c +mycc -o procfs4 -Wall -Wextra -O2 procfs4.c || exit 1 +rm -f procfs4.c +cd $here + +su $testuser -c /tmp/procfs4 +e=$? + +rm -f /tmp/procfs4 +exit $e +EOF +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 1000 +#define MAXRUN 1200 +#define PARALLEL 10 + +char *files[] = { + "cmdline", + "ctl", + "dbregs", + "etype", + "file", + "fpregs", + "map", + "mem", + "note", + "notepg", + "osrel", + "regs", + "rlimit", + "status" +}; + +void +test(void) +{ + pid_t p; + int fd, i, j, n, opens; + char path[128]; + + for (i = 0; i < 64; i++) { + if ((p = fork()) == 0) { + setproctitle("Sleeper"); + usleep(20000); + usleep(arc4random() % 200); + for (j = 0; j < 10000; j++) + getpid(); + _exit(0); + } + opens = 0; + setproctitle("load"); + for (j = 0; j < 14; j++) { + snprintf(path, sizeof(path), "/proc/%d/%s", p, files[j]); + if ((fd = open(path, O_RDWR)) == -1) + if ((fd = open(path, O_RDONLY)) == -1) + continue; + + ioctl(fd, FIONREAD, &n); + if (ioctl(fd, FIONBIO, &n) != -1) + opens++; + + close(fd); + } + kill(p, SIGHUP); +#if 0 + if (opens < 1) + fprintf(stderr, "Warn %d open(s) for pid %d\n", opens, getpid()); +#endif + } + + for (i = 0; i < 64; i++) + wait(NULL); + + _exit(0); +} + +int +main(void) +{ + time_t start; + int e, i, j; + + e = 0; + start = time(NULL); + for (i = 0; i < LOOPS; i++) { + for (j = 0; j < PARALLEL; j++) { + if (fork() == 0) + test(); + } + + for (j = 0; j < PARALLEL; j++) + wait(NULL); + usleep(10000); + if (time(NULL) - start > MAXRUN) { + fprintf(stderr, "FAIL Timeout\n"); + e = 1; + break; + } + } + + return (e); +} diff --git a/tools/test/stress2/misc/procfs5.sh b/tools/test/stress2/misc/procfs5.sh new file mode 100755 index 000000000000..70cd3214db02 --- /dev/null +++ b/tools/test/stress2/misc/procfs5.sh @@ -0,0 +1,84 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Issue involving signed overflow. +# Test scenario based on panic seen in +# http://people.freebsd.org/~pho/stress/log/kostik640.txt +# Fixed in r258365, r258397. + +# Scenario by kib@ + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep -q "/proc " || mount -t procfs procfs /proc + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > procfs_lr.c +mycc -o procfs_lr -Wall -Wextra -O2 procfs_lr.c || exit 1 +rm -f procfs_lr.c + +/tmp/procfs_lr 2>/dev/null + +rm -f /tmp/procfs_lr + +exit 0 +EOF +/* $Id: procfs_lr.c,v 1.1 2013/11/16 07:06:46 kostik Exp kostik $ */ + +#include +#include +#include +#include +#include +#include +#include + +int +main(void) +{ + static const char name[] = "/proc/curproc/map"; + const off_t uio_offset = 0x6f51f3a1185bced9; +#if defined(__LP64__) + const size_t uio_resid = 0x4c330b10965a61af; +#else + const size_t uio_resid = 0x965a61af; +#endif + char buf[1]; + int error, fd; + + fd = open(name, O_RDONLY); + if (fd == -1) + err(1, "open"); + error = pread(fd, buf, uio_resid, uio_offset); + if (error == -1) + fprintf(stderr, "pread: %s\n", strerror(errno)); + return (0); +} diff --git a/tools/test/stress2/misc/procfs6.sh b/tools/test/stress2/misc/procfs6.sh new file mode 100755 index 000000000000..b4cc4c1eb4c0 --- /dev/null +++ b/tools/test/stress2/misc/procfs6.sh @@ -0,0 +1,42 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 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 problem introduced by r351741 and fixed by 351815. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +if ! mount | grep -q /proc; then + mount -t procfs null /proc || exit 1 + mounted=1 +fi +[ `ls /proc | wc -l` -eq 0 ] && { ls -l /proc; exit 1; } +[ `ls /proc/$$ | wc -l` -eq 0 ] && { ls -l /proc; exit 1; } + +[ $mounted ] && umount /proc +exit 0 diff --git a/tools/test/stress2/misc/procstat.sh b/tools/test/stress2/misc/procstat.sh new file mode 100755 index 000000000000..91a846ba91ee --- /dev/null +++ b/tools/test/stress2/misc/procstat.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# procstat -k test scenario +# Page fault seen in stack_save_td() +# https://people.freebsd.org/~pho/stress/log/procstat.txt + +[ `uname -m` = "i386" ] || exit 0 # XXX Known issue on i386 XXX +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 +./fifo4.sh & +sleep .1 +while pgrep -fq fifo4.sh; do + pgrep fifo2 | xargs procstat -k > /dev/null 2>&1 +done +echo done +wait +exit 0 diff --git a/tools/test/stress2/misc/procstat2.sh b/tools/test/stress2/misc/procstat2.sh new file mode 100755 index 000000000000..712f53c11b3b --- /dev/null +++ b/tools/test/stress2/misc/procstat2.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +# This test scenario would trigger an NMI. +# https://people.freebsd.org/~pho/stress/log/mjguzik022.txt + +# Test scenario idea by Mark Johnston +# Fixed by r357334 + +../misc/marcus.sh > /dev/null 2>&1 & +start=`date +%s` +while [ $((`date +%s` - start)) -lt 300 ]; do + procstat -kka > /dev/null 2>&1 +done +../tools/killall.sh +wait + +exit 0 diff --git a/tools/test/stress2/misc/pthread.sh b/tools/test/stress2/misc/pthread.sh new file mode 100755 index 000000000000..9bb45a11465d --- /dev/null +++ b/tools/test/stress2/misc/pthread.sh @@ -0,0 +1,137 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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: spin lock held too long + +# Test program and scenario by Peter Wemm + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > pth.c +mycc -o pth -Wall pth.c -pthread +rm -f pth.c +cd $odir + +for i in `jot 2000`; do + /tmp/pth 2>/dev/null +done + +rm -f /tmp/pth +exit +EOF +#include + +#include +#include +#include +#include +#include + +static pthread_t worker1_thr; +static pthread_t worker2_thr; + +static pthread_mutex_t worker_mtx; +static pthread_cond_t worker_go; +static pthread_cond_t worker_done; + +struct workitem { + struct workitem *next; + int a, b; +}; + +struct workitem *head; + +static void * +worker(void *arg) +{ + struct workitem *w; + + pthread_detach(pthread_self()); + fprintf(stderr, "WORKER: started %p\n", arg); fflush(stderr); + + for (;;) { + pthread_mutex_lock(&worker_mtx); + while (head == NULL) { + pthread_cond_wait(&worker_go, &worker_mtx); + } + w = head; + head = w->next; + pthread_mutex_unlock(&worker_mtx); + + fprintf(stderr, "WORKER(%p): got work a=%d b=%d\n", arg, w->a, w->b); fflush(stderr); + free(w); + pthread_cond_signal(&worker_done); + } +} + +void +work_add(int a, int b) +{ + struct workitem *w; + int dowake = 0; + + w = calloc(sizeof(*w), 1); + w->a = a; + w->b = b; + pthread_mutex_lock(&worker_mtx); + if (head == 0) + dowake = 1; + w->next = head; + head = w; + pthread_mutex_unlock(&worker_mtx); + if (dowake) + pthread_cond_signal(&worker_go); +} + +int +main() +{ + pthread_mutex_init(&worker_mtx, NULL); + pthread_cond_init(&worker_go, NULL); + pthread_cond_init(&worker_done, NULL); + + fprintf(stderr, "pthread create\n"); fflush(stderr); + pthread_create(&worker1_thr, NULL, worker, (void *)1); + pthread_create(&worker2_thr, NULL, worker, (void *)2); + + work_add(10, 15); + work_add(11, 22); + work_add(314, 159); + + pthread_mutex_lock(&worker_mtx); + while (head != NULL) { + pthread_cond_wait(&worker_done, &worker_mtx); + } + pthread_mutex_unlock(&worker_mtx); + + fprintf(stderr, "job complete\n"); fflush(stderr); + exit(0); +} diff --git a/tools/test/stress2/misc/pthread2.sh b/tools/test/stress2/misc/pthread2.sh new file mode 100755 index 000000000000..08236647fcad --- /dev/null +++ b/tools/test/stress2/misc/pthread2.sh @@ -0,0 +1,296 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Threaded producer-consumer test. + +. ../default.cfg + +export LANG=C +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pthread2.c +mycc -o pthread2 -Wall -Wextra -O2 -g pthread2.c -lpthread || exit 1 +rm -f pthread2.c /tmp/pthread2.core + +log=/tmp/pthread2.`date '+%Y%m%d-%H%M'` +for i in `jot 5`; do + [ $i -eq 1 ] && echo "# `uname -v`" + time sh -c ' + for i in `jot 8`; do + /tmp/pthread2 & + done + wait + ' +done > $log 2>&1 +rm -f /tmp/pthread2 + +if [ -n "$bench" ]; then + pair=`ls /tmp/pthread2* | egrep "pthread2\.[0-9]{8}-" | sort | + tail -2 | tr '\n' ' '` + ministat -w 72 $pair +else + rm -f $log +fi + +# __thr_umutex_lock() may call abort(3) under VM pressure. +[ -r /tmp/pthread2.core ] && echo FAIL +exit 0 +EOF +/* + * Threaded producer-consumer test. + * Loosly based on work by + * Andrey Zonov (c) 2012 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#define __NP__ +#endif +#include +#include +#include +#include +#include +#include +#include + +#define LOCK(x) plock(&x.mtx) +#define UNLOCK(x) punlock(&x.mtx) +#define SIGNAL(x) psig(&x.wait) +#define WAIT(x) pwait(&x.wait, &x.mtx) + +long ncreate, nrename, nunlink; +int bench, max; +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; + +#define MAXQ 100000 /* Max create queue length */ +#define MESSAGES 10000000; + +static void +hand(int i __unused) { /* handler */ + fprintf(stderr, "max = %d, ncreate = %ld, nrename = %ld, nunlink = %ld\n", + max, ncreate, nrename, nunlink); +} + +static void +ahand(int i __unused) { /* handler */ + fprintf(stderr, "FAIL\n"); + hand(0); + _exit(0); +} + +void +plock(pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_mutex_lock(l)) != 0) + errc(1, rc, "pthread_mutex_lock"); +} + +void +punlock(pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_mutex_unlock(l)) != 0) + errc(1, rc, "pthread_mutex_unlock"); +} + +void +psig(pthread_cond_t *c) +{ + int rc; + + if ((rc = pthread_cond_signal(c)) != 0) + errc(1, rc, "pthread_cond_signal"); +} + +void +pwait(pthread_cond_t *c, pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_cond_wait(c, l)) != 0) + errc(1, rc, "pthread_cond_wait"); +} + +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); + LOCK(newfiles); + STAILQ_INSERT_TAIL(&newfiles.list, file, next); + ncreate++; + UNLOCK(newfiles); + SIGNAL(newfiles); + if (ncreate - nrename > MAXQ) + usleep(400); + } + return (NULL); +} + +void * +loop_rename(void *arg __unused) +{ + char *filename, *newname; + struct file *file; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + + while (nrename < max) { + LOCK(newfiles); + while (STAILQ_EMPTY(&newfiles.list)) { + WAIT(newfiles); + } + file = STAILQ_FIRST(&newfiles.list); + STAILQ_REMOVE_HEAD(&newfiles.list, next); + UNLOCK(newfiles); + filename = strrchr(file->name, '/'); + asprintf(&newname, "%s/%s", dirname2, filename); + nrename++; + free(file->name); + file->name = newname; + LOCK(renamedfiles); + STAILQ_INSERT_TAIL(&renamedfiles.list, file, next); + UNLOCK(renamedfiles); + SIGNAL(renamedfiles); + } + return (NULL); +} + +void * +loop_unlink(void *arg __unused) +{ + struct file *file; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + + while (nunlink < max) { + LOCK(renamedfiles); + while (STAILQ_EMPTY(&renamedfiles.list)) { + WAIT(renamedfiles); + } + file = STAILQ_FIRST(&renamedfiles.list); + STAILQ_REMOVE_HEAD(&renamedfiles.list, next); + nunlink++; + UNLOCK(renamedfiles); + free(file->name); + free(file); + } + return (NULL); +} + +int +main(void) +{ + int i; + int rc; + pthread_t tid[3]; + + bench = getenv("bench") != NULL; + asprintf(&dirname1, "%s.1", "f1"); + asprintf(&dirname2, "%s.2", "f2"); + max = MESSAGES; + + STAILQ_INIT(&newfiles.list); + STAILQ_INIT(&renamedfiles.list); + + if ((rc = pthread_mutex_init(&newfiles.mtx, NULL)) != 0) + errc(1, rc, "pthread_mutex_init()"); + if ((rc = pthread_cond_init(&newfiles.wait, NULL)) != 0) + errc(1, rc, "pthread_cond_init()"); + if ((rc = pthread_mutex_init(&renamedfiles.mtx, NULL)) != 0) + errc(1, rc, "pthread_mutex_init()"); + if ((rc = pthread_cond_init(&renamedfiles.wait, NULL)) != 0) + errc(1, rc, "pthread_cond_init()"); + + signal(SIGINFO, hand); + signal(SIGALRM, ahand); + alarm(300); + if ((rc = pthread_create(&tid[0], NULL, loop_create, NULL)) != 0) + errc(1, rc, "pthread_create()"); + if ((rc = pthread_create(&tid[1], NULL, loop_rename, NULL)) != 0) + errc(1, rc, "pthread_create()"); + if ((rc = pthread_create(&tid[2], NULL, loop_unlink, NULL)) != 0) + errc(1, rc, "pthread_create()"); + + for (i = 0; i < 3; i++) { + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + } + + if ((rc = pthread_mutex_destroy(&newfiles.mtx)) != 0) + errc(1, rc, "pthread_mutex_destroy(newfiles)"); + if ((rc = pthread_cond_destroy(&newfiles.wait)) != 0) + errc(1, rc, "pthread_cond_destroy(newfiles)"); + if ((rc = pthread_mutex_destroy(&renamedfiles.mtx)) != 0) + errc(1, rc, "pthread_mutex_destroy(renamedfiles)"); + if ((rc = pthread_cond_destroy(&renamedfiles.wait)) != 0) + errc(1, rc, "pthread_cond_destroy(renamedfiles)"); + free(dirname1); + free(dirname2); + + return (0); +} diff --git a/tools/test/stress2/misc/pthread3.sh b/tools/test/stress2/misc/pthread3.sh new file mode 100755 index 000000000000..71ec35141ef4 --- /dev/null +++ b/tools/test/stress2/misc/pthread3.sh @@ -0,0 +1,304 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# _exit(2) test scenario with focus on shared channel tear down. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pthread3.c +mycc -o pthread3 -Wall -Wextra -O2 -g -gdwarf-2 pthread3.c -lpthread || exit 1 +rm -f pthread3.c + +for i in `jot 8`; do + /tmp/pthread3 & + pids="$pids $!" +done +s=0 +for i in $pids; do + wait $i + e=$? + [ $e -ne 0 ] && s=$e +done + +rm -f /tmp/pthread3 + +exit $s +EOF +/* + * Threaded producer-consumer test. + * Loosly based on work by + * Andrey Zonov (c) 2012 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#define __NP__ +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOCK(x) plock(&x.mtx) +#define UNLOCK(x) punlock(&x.mtx) +#define SIGNAL(x) psig(&x.wait) +#define WAIT(x) pwait(&x.wait, &x.mtx) + +long ncreate, nrename, nunlink; +int max; +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; + +static void +hand(int i __unused) { /* handler */ + fprintf(stderr, "max = %d, ncreate = %ld, nrename = %ld, nunlink = %ld\n", + max, ncreate, nrename, nunlink); +} + +static void +ahand(int i __unused) { /* handler */ + fprintf(stderr, "FAIL\n"); + hand(0); + _exit(0); +} + +void +plock(pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_mutex_lock(l)) != 0) + errc(1, rc, "pthread_mutex_lock"); +} + +void +punlock(pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_mutex_unlock(l)) != 0) + errc(1, rc, "pthread_mutex_unlock"); +} + +void +psig(pthread_cond_t *c) +{ + int rc; + + if ((rc = pthread_cond_signal(c)) != 0) + errc(1, rc, "pthread_cond_signal"); +} + +void +pwait(pthread_cond_t *c, pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_cond_wait(c, l)) != 0) + errc(1, rc, "pthread_cond_wait"); +} + +void * +loop_create(void *arg __unused) +{ + int i, j; + 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); + LOCK(newfiles); + STAILQ_INSERT_TAIL(&newfiles.list, file, next); + ncreate++; + UNLOCK(newfiles); + SIGNAL(newfiles); + if ((i > 0) && (i % 100000 == 0)) + for (j = 0; j < 10 && ncreate != nrename; j++) + usleep(400); + } + return (NULL); +} + +void * +loop_rename(void *arg __unused) +{ + char *filename, *newname; + struct file *file; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + + while (nrename < max) { + LOCK(newfiles); + while (STAILQ_EMPTY(&newfiles.list)) { + WAIT(newfiles); + } + file = STAILQ_FIRST(&newfiles.list); + STAILQ_REMOVE_HEAD(&newfiles.list, next); + UNLOCK(newfiles); + filename = strrchr(file->name, '/'); + asprintf(&newname, "%s/%s", dirname2, filename); + nrename++; + free(file->name); + file->name = newname; + LOCK(renamedfiles); + STAILQ_INSERT_TAIL(&renamedfiles.list, file, next); + UNLOCK(renamedfiles); + SIGNAL(renamedfiles); + } + return (NULL); +} + +void * +loop_unlink(void *arg __unused) +{ + struct file *file; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + + while (nunlink < max) { + LOCK(renamedfiles); + while (STAILQ_EMPTY(&renamedfiles.list)) { + WAIT(renamedfiles); + } + file = STAILQ_FIRST(&renamedfiles.list); + STAILQ_REMOVE_HEAD(&renamedfiles.list, next); + nunlink++; + UNLOCK(renamedfiles); + free(file->name); + free(file); + if (arc4random() % 100 == 1) + if (arc4random() % 100 == 1) + if (arc4random() % 100 < 10) + _exit(0); + } + return (NULL); +} + +void +test(void) +{ + int i; + int rc; + pthread_t tid[3]; + + asprintf(&dirname1, "%s.1", "f1"); + asprintf(&dirname2, "%s.2", "f2"); +// max = 15000000; + max = 50000; + + STAILQ_INIT(&newfiles.list); + STAILQ_INIT(&renamedfiles.list); + + if ((rc = pthread_mutex_init(&newfiles.mtx, NULL)) != 0) + errc(1, rc, "pthread_mutex_init()"); + if ((rc = pthread_cond_init(&newfiles.wait, NULL)) != 0) + errc(1, rc, "pthread_cond_init()"); + if ((rc = pthread_mutex_init(&renamedfiles.mtx, NULL)) != 0) + errc(1, rc, "pthread_mutex_init()"); + if ((rc = pthread_cond_init(&renamedfiles.wait, NULL)) != 0) + errc(1, rc, "pthread_cond_init()"); + + signal(SIGINFO, hand); + signal(SIGALRM, ahand); + alarm(300); + if ((rc = pthread_create(&tid[0], NULL, loop_create, NULL)) != 0) + errc(1, rc, "pthread_create()"); + if ((rc = pthread_create(&tid[1], NULL, loop_rename, NULL)) != 0) + errc(1, rc, "pthread_create()"); + if ((rc = pthread_create(&tid[2], NULL, loop_unlink, NULL)) != 0) + errc(1, rc, "pthread_create()"); + + for (i = 0; i < 3; i++) { + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + } + + if ((rc = pthread_mutex_destroy(&newfiles.mtx)) != 0) + errc(1, rc, "pthread_mutex_destroy(newfiles)"); + if ((rc = pthread_cond_destroy(&newfiles.wait)) != 0) + errc(1, rc, "pthread_cond_destroy(newfiles)"); + if ((rc = pthread_mutex_destroy(&renamedfiles.mtx)) != 0) + errc(1, rc, "pthread_mutex_destroy(renamedfiles)"); + if ((rc = pthread_cond_destroy(&renamedfiles.wait)) != 0) + errc(1, rc, "pthread_cond_destroy(renamedfiles)"); + free(dirname1); + free(dirname2); + + _exit(0); +} + +int +main(void) +{ + int i; + + alarm(1200); + for (i = 0; i < 1000; i++) { + if (fork() == 0) + test(); + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/pthread4.sh b/tools/test/stress2/misc/pthread4.sh new file mode 100755 index 000000000000..8733ac6e2cf0 --- /dev/null +++ b/tools/test/stress2/misc/pthread4.sh @@ -0,0 +1,296 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP version of pthread2.sh + +. ../default.cfg + +export LANG=C +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pthread4.c +mycc -o pthread4 -Wall -Wextra -O2 -g -gdwarf-2 pthread4.c -lpthread || exit 1 +rm -f pthread4.c /tmp/pthread4.core + +log=/tmp/pthread4.`date '+%Y%m%d-%H%M'` +for i in `jot 5`; do + [ $i -eq 1 ] && echo "# `uname -v`" + time sh -c ' + for i in `jot 8`; do + /tmp/pthread4 & + done + wait + ' +done > $log 2>&1 +rm -f /tmp/pthread4 + +if [ -n "$bench" ]; then + pair=`ls /tmp/pthread4* | egrep "pthread4\.[0-9]{8}-" | sort | + tail -2 | tr '\n' ' '` + ministat -w 72 $pair +else + rm -f $log +fi + +exit 0 +EOF +/* + * Threaded producer-consumer test. + * Loosly based on work by + * Andrey Zonov (c) 2012 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#define __NP__ +#endif +#include +#include +#include +#include +#include +#include +#include + +#define LOCK(x) plock(&x.mtx) +#define UNLOCK(x) punlock(&x.mtx) +#define SIGNAL(x) psig(&x.wait) +#define WAIT(x) pwait(&x.wait, &x.mtx) + +long ncreate, nrename, nunlink; +int bench, max; +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; + +static void +hand(int i __unused) { /* handler */ + fprintf(stderr, "max = %d, ncreate = %ld, nrename = %ld, nunlink = %ld\n", + max, ncreate, nrename, nunlink); +} + +static void +ahand(int i __unused) { /* handler */ + fprintf(stderr, "FAIL\n"); + hand(0); + _exit(0); +} + +void +plock(pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_mutex_lock(l)) != 0) + errc(1, rc, "pthread_mutex_lock"); +} + +void +punlock(pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_mutex_unlock(l)) != 0) + errc(1, rc, "pthread_mutex_unlock"); +} + +void +psig(pthread_cond_t *c) +{ + int rc; + + if ((rc = pthread_cond_signal(c)) != 0) + errc(1, rc, "pthread_cond_signal"); +} + +void +pwait(pthread_cond_t *c, pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_cond_wait(c, l)) != 0) + errc(1, rc, "pthread_cond_wait"); +} + +void * +loop_create(void *arg __unused) +{ + int i, j; + 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); + LOCK(newfiles); + STAILQ_INSERT_TAIL(&newfiles.list, file, next); + ncreate++; + UNLOCK(newfiles); + SIGNAL(newfiles); + if ((bench == 0) && (i > 0) && (i % 100000 == 0)) + for (j = 0; j < 10 && ncreate != nrename; j++) + usleep(400); + } + return (NULL); +} + +void * +loop_rename(void *arg __unused) +{ + char *filename, *newname; + struct file *file; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + + while (nrename < max) { + LOCK(newfiles); + while (STAILQ_EMPTY(&newfiles.list)) { + WAIT(newfiles); + } + file = STAILQ_FIRST(&newfiles.list); + STAILQ_REMOVE_HEAD(&newfiles.list, next); + UNLOCK(newfiles); + filename = strrchr(file->name, '/'); + asprintf(&newname, "%s/%s", dirname2, filename); + nrename++; + free(file->name); + file->name = newname; + LOCK(renamedfiles); + STAILQ_INSERT_TAIL(&renamedfiles.list, file, next); + UNLOCK(renamedfiles); + SIGNAL(renamedfiles); + } + return (NULL); +} + +void * +loop_unlink(void *arg __unused) +{ + struct file *file; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + + while (nunlink < max) { + LOCK(renamedfiles); + while (STAILQ_EMPTY(&renamedfiles.list)) { + WAIT(renamedfiles); + } + file = STAILQ_FIRST(&renamedfiles.list); + STAILQ_REMOVE_HEAD(&renamedfiles.list, next); + nunlink++; + UNLOCK(renamedfiles); + free(file->name); + free(file); + } + return (NULL); +} + +int +main(void) +{ + int i; + int rc; + pthread_t tid[3]; + pthread_mutexattr_t attr, *pattr = NULL; + + bench = getenv("bench") != NULL; + asprintf(&dirname1, "%s.1", "f1"); + asprintf(&dirname2, "%s.2", "f2"); + max = 15000000; + + STAILQ_INIT(&newfiles.list); + STAILQ_INIT(&renamedfiles.list); + + pthread_mutexattr_init (&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + pattr = &attr; + if ((rc = pthread_mutex_init(&newfiles.mtx, pattr)) != 0) + errc(1, rc, "pthread_mutex_init()"); + if ((rc = pthread_cond_init(&newfiles.wait, NULL)) != 0) + errc(1, rc, "pthread_cond_init()"); + if ((rc = pthread_mutex_init(&renamedfiles.mtx, NULL)) != 0) + errc(1, rc, "pthread_mutex_init()"); + if ((rc = pthread_cond_init(&renamedfiles.wait, NULL)) != 0) + errc(1, rc, "pthread_cond_init()"); + + signal(SIGINFO, hand); + signal(SIGALRM, ahand); + alarm(300); + if ((rc = pthread_create(&tid[0], NULL, loop_create, NULL)) != 0) + errc(1, rc, "pthread_create()"); + if ((rc = pthread_create(&tid[1], NULL, loop_rename, NULL)) != 0) + errc(1, rc, "pthread_create()"); + if ((rc = pthread_create(&tid[2], NULL, loop_unlink, NULL)) != 0) + errc(1, rc, "pthread_create()"); + + for (i = 0; i < 3; i++) { + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + } + + if ((rc = pthread_mutex_destroy(&newfiles.mtx)) != 0) + errc(1, rc, "pthread_mutex_destroy(newfiles)"); + if ((rc = pthread_cond_destroy(&newfiles.wait)) != 0) + errc(1, rc, "pthread_cond_destroy(newfiles)"); + if ((rc = pthread_mutex_destroy(&renamedfiles.mtx)) != 0) + errc(1, rc, "pthread_mutex_destroy(renamedfiles)"); + if ((rc = pthread_cond_destroy(&renamedfiles.wait)) != 0) + errc(1, rc, "pthread_cond_destroy(renamedfiles)"); + free(dirname1); + free(dirname2); + + return (0); +} diff --git a/tools/test/stress2/misc/pthread5.sh b/tools/test/stress2/misc/pthread5.sh new file mode 100755 index 000000000000..02093ae48ed5 --- /dev/null +++ b/tools/test/stress2/misc/pthread5.sh @@ -0,0 +1,121 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Stress shchan allocations. + +. ../default.cfg +[ `swapinfo | wc -l` -eq 1 ] && exit 0 # kstack allocation failed + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pthread5.c +mycc -o pthread5 -Wall -Wextra -O2 pthread5.c -lpthread || exit 1 +rm -f pthread5.c + +/tmp/pthread5 + +rm -f /tmp/pthread5 +exit 0 +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ITER 2 +#define PARALLEL 1000 +#define THREADS 100 + +pthread_cond_t cond = PTHREAD_COND_INITIALIZER; +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +static void * +nicethreads(void *data __unused) +{ + struct timespec ts; + struct timeval tp; + + pthread_mutex_lock(&mutex); + gettimeofday(&tp, NULL); + + ts.tv_sec = tp.tv_sec; + ts.tv_nsec = tp.tv_usec * 1000; + ts.tv_sec += 30; + + pthread_cond_timedwait(&cond, &mutex, &ts); + pthread_mutex_unlock(&mutex); + + return (NULL); +} + +int +test(void) +{ + int num_thread = THREADS; + pthread_t tid[num_thread]; + int i, iter, rc; + + for (iter = 0; iter < ITER; iter++) { + for (i = 0; i < num_thread; i++) { + if ((rc = pthread_create(&tid[i], NULL, nicethreads, + NULL)) != 0) + errc(1, rc, "pthread_create"); + } + usleep(20000); + for (i = 0; i < num_thread; i++) { + rc = pthread_mutex_lock(&mutex); + rc = pthread_cond_signal(&cond); + rc = pthread_mutex_unlock(&mutex); + } + for (i = 0; i < num_thread; i++) + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join"); + } + + _exit(0); +} + +int +main(void) +{ + int i; + + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + test(); + for (i = 0; i < PARALLEL; i++) + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/pthread6.sh b/tools/test/stress2/misc/pthread6.sh new file mode 100755 index 000000000000..052dd2c5f678 --- /dev/null +++ b/tools/test/stress2/misc/pthread6.sh @@ -0,0 +1,308 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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: pmap active 0xfffff80128cd84b8" seen: +# http://people.freebsd.org/~pho/stress/log/attilio101.txt + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pthread6.c +mycc -o pthread6 -Wall -Wextra -O2 -g -gdwarf-2 pthread6.c -lpthread || exit 1 +rm -f pthread6.c /tmp/pthread6.core + +daemon sh -c "(cd $here/../testcases/swap; ./swap -t 2m -i 20 -k)" +sleep `jot -r 1 1 9` +echo "Expect SIGABRT" +for i in `jot 50`; do + /tmp/pthread6 +done +while pgrep -q swap; do + pkill swap + sleep 1 +done + +rm -f /tmp/pthread6 /tmp/pthread6.core +exit 0 +EOF +/* + * Threaded producer-consumer test. + * Loosly based on work by + * Andrey Zonov (c) 2012 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#define __NP__ +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOCK(x) plock(&x.mtx) +#define UNLOCK(x) punlock(&x.mtx) +#define SIGNAL(x) psig(&x.wait) +#define WAIT(x) pwait(&x.wait, &x.mtx) + +#define PARALLEL 4 +#define LOOPS 2 + +long ncreate, nrename, nunlink; +int bench, max; +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; + +static void +hand(int i __unused) { /* handler */ +} + +static void +ahand(int i __unused) { /* handler */ + abort(); +} + +void +plock(pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_mutex_lock(l)) != 0) + errc(1, rc, "pthread_mutex_lock"); +} + +void +punlock(pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_mutex_unlock(l)) != 0) + errc(1, rc, "pthread_mutex_unlock"); +} + +void +psig(pthread_cond_t *c) +{ + int rc; + + if ((rc = pthread_cond_signal(c)) != 0) + errc(1, rc, "pthread_cond_signal"); +} + +void +pwait(pthread_cond_t *c, pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_cond_wait(c, l)) != 0) + errc(1, rc, "pthread_cond_wait"); +} + +void * +loop_create(void *arg __unused) +{ + int i, j; + 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); + LOCK(newfiles); + STAILQ_INSERT_TAIL(&newfiles.list, file, next); + ncreate++; + UNLOCK(newfiles); + SIGNAL(newfiles); + if ((bench == 0) && (i > 0) && (i % 100000 == 0)) + for (j = 0; j < 10 && ncreate != nrename; j++) + usleep(400); + } + return (NULL); +} + +void * +loop_rename(void *arg __unused) +{ + char *filename, *newname; + struct file *file; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + + while (nrename < max) { + LOCK(newfiles); + while (STAILQ_EMPTY(&newfiles.list)) { + WAIT(newfiles); + } + file = STAILQ_FIRST(&newfiles.list); + STAILQ_REMOVE_HEAD(&newfiles.list, next); + UNLOCK(newfiles); + filename = strrchr(file->name, '/'); + asprintf(&newname, "%s/%s", dirname2, filename); + nrename++; + free(file->name); + file->name = newname; + LOCK(renamedfiles); + STAILQ_INSERT_TAIL(&renamedfiles.list, file, next); + UNLOCK(renamedfiles); + SIGNAL(renamedfiles); + } + return (NULL); +} + +void * +loop_unlink(void *arg __unused) +{ + struct file *file; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + + while (nunlink < max) { + LOCK(renamedfiles); + while (STAILQ_EMPTY(&renamedfiles.list)) { + WAIT(renamedfiles); + } + file = STAILQ_FIRST(&renamedfiles.list); + STAILQ_REMOVE_HEAD(&renamedfiles.list, next); + nunlink++; + UNLOCK(renamedfiles); + free(file->name); + free(file); + } + return (NULL); +} + +void +test(void) +{ + int i; + int rc; + pthread_t tid[3]; + pthread_mutexattr_t attr, *pattr = NULL; + + bench = getenv("bench") != NULL; + bench = 1; + asprintf(&dirname1, "%s.1", "f1"); + asprintf(&dirname2, "%s.2", "f2"); + max = 15000000; + + STAILQ_INIT(&newfiles.list); + STAILQ_INIT(&renamedfiles.list); + + pthread_mutexattr_init (&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ADAPTIVE_NP); + pattr = &attr; + if ((rc = pthread_mutex_init(&newfiles.mtx, pattr)) != 0) + errc(1, rc, "pthread_mutex_init()"); + if ((rc = pthread_cond_init(&newfiles.wait, NULL)) != 0) + errc(1, rc, "pthread_cond_init()"); + if ((rc = pthread_mutex_init(&renamedfiles.mtx, NULL)) != 0) + errc(1, rc, "pthread_mutex_init()"); + if ((rc = pthread_cond_init(&renamedfiles.wait, NULL)) != 0) + errc(1, rc, "pthread_cond_init()"); + + signal(SIGINFO, hand); + signal(SIGALRM, ahand); + if ((rc = pthread_create(&tid[0], NULL, loop_create, NULL)) != 0) + errc(1, rc, "pthread_create()"); + if ((rc = pthread_create(&tid[1], NULL, loop_rename, NULL)) != 0) + errc(1, rc, "pthread_create()"); + if ((rc = pthread_create(&tid[2], NULL, loop_unlink, NULL)) != 0) + errc(1, rc, "pthread_create()"); + + usleep(1000); + ualarm(arc4random() % 100000, 0); + for (i = 0; i < 3; i++) { + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + } + + if ((rc = pthread_mutex_destroy(&newfiles.mtx)) != 0) + errc(1, rc, "pthread_mutex_destroy(newfiles)"); + if ((rc = pthread_cond_destroy(&newfiles.wait)) != 0) + errc(1, rc, "pthread_cond_destroy(newfiles)"); + if ((rc = pthread_mutex_destroy(&renamedfiles.mtx)) != 0) + errc(1, rc, "pthread_mutex_destroy(renamedfiles)"); + if ((rc = pthread_cond_destroy(&renamedfiles.wait)) != 0) + errc(1, rc, "pthread_cond_destroy(renamedfiles)"); + free(dirname1); + free(dirname2); + + _exit(0); +} + +int +main(void) +{ + int i, j; + + for (i = 0; i < LOOPS; i++) { + for (j = 0; j < PARALLEL; j++) { + if (fork() == 0) + test(); + } + + for (j = 0; j < PARALLEL; j++) + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/pthread7.sh b/tools/test/stress2/misc/pthread7.sh new file mode 100755 index 000000000000..41190190bd22 --- /dev/null +++ b/tools/test/stress2/misc/pthread7.sh @@ -0,0 +1,285 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# PTHREAD_PRIO_INHERIT version of pthread2.sh + +. ../default.cfg + +export LANG=C +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pthread7.c +mycc -o pthread7 -Wall -Wextra -O2 -g pthread7.c -lpthread || exit 1 +rm -f pthread7.c + +for i in `jot 5`; do + for i in `jot 8`; do + /tmp/pthread7 & + done + wait +done +rm -f /tmp/pthread7 +exit 0 +EOF +/* + * Threaded producer-consumer test. + * Loosly based on work by + * Andrey Zonov (c) 2012 + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#define __NP__ +#endif +#include +#include +#include +#include +#include +#include +#include + +#define LOCK(x) plock(&x.mtx) +#define UNLOCK(x) punlock(&x.mtx) +#define SIGNAL(x) psig(&x.wait) +#define WAIT(x) pwait(&x.wait, &x.mtx) + +long ncreate, nrename, nunlink; +int max; +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; + +#define MAXQ 100000 /* Max create queue length */ +#define MESSAGES 10000000; + +static void +hand(int i __unused) { /* handler */ + fprintf(stderr, "max = %d, ncreate = %ld, nrename = %ld, nunlink = %ld\n", + max, ncreate, nrename, nunlink); +} + +static void +ahand(int i __unused) { /* handler */ + fprintf(stderr, "FAIL\n"); + hand(0); + _exit(0); +} + +void +plock(pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_mutex_lock(l)) != 0) + errc(1, rc, "pthread_mutex_lock"); +} + +void +punlock(pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_mutex_unlock(l)) != 0) + errc(1, rc, "pthread_mutex_unlock"); +} + +void +psig(pthread_cond_t *c) +{ + int rc; + + if ((rc = pthread_cond_signal(c)) != 0) + errc(1, rc, "pthread_cond_signal"); +} + +void +pwait(pthread_cond_t *c, pthread_mutex_t *l) +{ + int rc; + + if ((rc = pthread_cond_wait(c, l)) != 0) + errc(1, rc, "pthread_cond_wait"); +} + +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); + LOCK(newfiles); + STAILQ_INSERT_TAIL(&newfiles.list, file, next); + ncreate++; + UNLOCK(newfiles); + SIGNAL(newfiles); + if (ncreate - nrename > MAXQ) + usleep(400); + } + return (NULL); +} + +void * +loop_rename(void *arg __unused) +{ + char *filename, *newname; + struct file *file; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + + while (nrename < max) { + LOCK(newfiles); + while (STAILQ_EMPTY(&newfiles.list)) { + WAIT(newfiles); + } + file = STAILQ_FIRST(&newfiles.list); + STAILQ_REMOVE_HEAD(&newfiles.list, next); + UNLOCK(newfiles); + filename = strrchr(file->name, '/'); + asprintf(&newname, "%s/%s", dirname2, filename); + nrename++; + free(file->name); + file->name = newname; + LOCK(renamedfiles); + STAILQ_INSERT_TAIL(&renamedfiles.list, file, next); + UNLOCK(renamedfiles); + SIGNAL(renamedfiles); + } + return (NULL); +} + +void * +loop_unlink(void *arg __unused) +{ + struct file *file; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + + while (nunlink < max) { + LOCK(renamedfiles); + while (STAILQ_EMPTY(&renamedfiles.list)) { + WAIT(renamedfiles); + } + file = STAILQ_FIRST(&renamedfiles.list); + STAILQ_REMOVE_HEAD(&renamedfiles.list, next); + nunlink++; + UNLOCK(renamedfiles); + free(file->name); + free(file); + } + return (NULL); +} + +int +main(void) +{ + int i; + int rc; + pthread_t tid[3]; + pthread_mutexattr_t attr, *pattr = NULL; + + asprintf(&dirname1, "%s.1", "f1"); + asprintf(&dirname2, "%s.2", "f2"); + max = MESSAGES; + + STAILQ_INIT(&newfiles.list); + STAILQ_INIT(&renamedfiles.list); + + pthread_mutexattr_init (&attr); + if ((rc = pthread_mutexattr_setprotocol(&attr, PTHREAD_PRIO_INHERIT)) != 0) + errc(1, rc, "PTHREAD_PRIO_INHERIT"); + pattr = &attr; + if ((rc = pthread_mutex_init(&newfiles.mtx, pattr)) != 0) + errc(1, rc, "pthread_mutex_init()"); + if ((rc = pthread_cond_init(&newfiles.wait, NULL)) != 0) + errc(1, rc, "pthread_cond_init()"); + if ((rc = pthread_mutex_init(&renamedfiles.mtx, NULL)) != 0) + errc(1, rc, "pthread_mutex_init()"); + if ((rc = pthread_cond_init(&renamedfiles.wait, NULL)) != 0) + errc(1, rc, "pthread_cond_init()"); + + signal(SIGINFO, hand); + signal(SIGALRM, ahand); + alarm(300); + if ((rc = pthread_create(&tid[0], NULL, loop_create, NULL)) != 0) + errc(1, rc, "pthread_create()"); + if ((rc = pthread_create(&tid[1], NULL, loop_rename, NULL)) != 0) + errc(1, rc, "pthread_create()"); + if ((rc = pthread_create(&tid[2], NULL, loop_unlink, NULL)) != 0) + errc(1, rc, "pthread_create()"); + + for (i = 0; i < 3; i++) { + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join(%d)", i); + } + + if ((rc = pthread_mutex_destroy(&newfiles.mtx)) != 0) + errc(1, rc, "pthread_mutex_destroy(newfiles)"); + if ((rc = pthread_cond_destroy(&newfiles.wait)) != 0) + errc(1, rc, "pthread_cond_destroy(newfiles)"); + if ((rc = pthread_mutex_destroy(&renamedfiles.mtx)) != 0) + errc(1, rc, "pthread_mutex_destroy(renamedfiles)"); + if ((rc = pthread_cond_destroy(&renamedfiles.wait)) != 0) + errc(1, rc, "pthread_cond_destroy(renamedfiles)"); + free(dirname1); + free(dirname2); + + return (0); +} diff --git a/tools/test/stress2/misc/pthread8.sh b/tools/test/stress2/misc/pthread8.sh new file mode 100755 index 000000000000..d6461daa0f46 --- /dev/null +++ b/tools/test/stress2/misc/pthread8.sh @@ -0,0 +1,137 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# PTHREAD_PRIO_INHERIT test scenario + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pthread8.c +mycc -o pthread8 -Wall -Wextra -O0 -g pthread8.c -lpthread || exit 1 +rm -f pthread8.c /tmp/pthread8.core + +/tmp/pthread8 + +rm -f /tmp/pthread8 +exit 0 +EOF +/* $Id: pi.c,v 1.2 2015/01/31 11:36:07 kostik Exp kostik $ */ + +#include +#include +#include +#include +#include +#include +#include + +struct runner_arg { + pthread_mutex_t *locks; + u_int lock_cnt; +}; + +int stop; + +void * +runner(void *arg) +{ + struct runner_arg *ra; + pthread_mutex_t *l; + u_int i; + int error; + + ra = arg; + while (stop == 0) { + for (i = 0; i < ra->lock_cnt; i++) { + l = &ra->locks[i]; + error = pthread_mutex_lock(l); + if (error != 0) + errc(1, error, "pthread_mutex_lock"); + pthread_yield(); + } + for (i = 0; i < ra->lock_cnt; i++) { + l = &ra->locks[i]; + error = pthread_mutex_unlock(l); + if (error != 0) + errc(1, error, "pthread_mutex_lock"); + pthread_yield(); + } + } + return (NULL); +} + +int +main(void) +{ + struct runner_arg ra; + time_t start; + pthread_t *threads; + pthread_mutexattr_t mattr; + u_int i, ncpus; + int error; + size_t ncpus_len; + + ncpus_len = sizeof(ncpus); + error = sysctlbyname("hw.ncpu", &ncpus, &ncpus_len, NULL, 0); + if (error != 0) + err(1, "sysctl hw.ncpus"); + threads = calloc(ncpus, sizeof(pthread_t)); + if (threads == NULL) + err(1, "calloc threads"); + + ra.lock_cnt = 100; + ra.locks = calloc(ra.lock_cnt, sizeof(pthread_mutex_t)); + if (ra.locks == NULL) + err(1, "calloc locks"); + error = pthread_mutexattr_init(&mattr); + if (error != 0) + errc(1, error, "pthread_mutexattr_init"); + error = pthread_mutexattr_setprotocol(&mattr, PTHREAD_PRIO_INHERIT); + if (error != 0) + errc(1, error, "pthread_mutexattr_setprotocol PRIO_INHERIT"); + for (i = 0; i < ra.lock_cnt; i++) { + error = pthread_mutex_init(&ra.locks[i], &mattr); + if (error != 0) + errc(1, error, "pthread_mutex_init"); + } + + for (i = 0; i < ncpus; i++) { + error = pthread_create(&threads[i], NULL, runner, &ra); + if (error != 0) + errc(1, error, "pthread_create"); + } + start = time(NULL); + while (time(NULL) - start < 180) + sleep(1); + stop = 1; + for (i = 0; i < ncpus; i++) + pthread_join(threads[i], NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/pthread9.sh b/tools/test/stress2/misc/pthread9.sh new file mode 100755 index 000000000000..a5aaeeab9af0 --- /dev/null +++ b/tools/test/stress2/misc/pthread9.sh @@ -0,0 +1,185 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Thread suspend deadlock seen: +# https://people.freebsd.org/~pho/stress/log/pthread9.txt + +# Test scenario by Conrad Meyer. +# Fixed by r283320. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pthread9.c +mycc -o pthread9 -Wall -Wextra -O2 pthread9.c -lpthread || exit 1 +rm -f pthread9.c + +status=0 +if ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1; then + mount -t nfs -o nfsv3,tcp,nolockd,retrycnt=3,intr $nfs_export \ + $mntpoint || exit 1 + sleep .5 + echo "Expect core dumps" + (cd $mntpoint; /tmp/pthread9) & + sleep 200 + if pgrep -q pthread9; then + echo FAIL + procstat -k `pgrep pthread9 | grep -v $!` + status=1 + fi + rm -f $mntpoint/pthread9.core + umount -f $mntpoint + wait +fi + +rm -f /tmp/pthread9 /tmp/pthread9.core +exit $status +EOF +#include + +#include + +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#define __NP__ +#endif +#include +#include +#include +#include +#include + +#define LOOPS 50 +#define RUNTIME 180 + +volatile u_int go; +int fd; +char file[] = "pthread9.file"; + +static void * +t1(void *data __unused) +{ + int i; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + while (go == 0) + pthread_yield(); + + atomic_add_int(&go, 1); + for (i = 0; i < 100; i++) + if (ftruncate(fd, 0) == -1) + err(1, "truncate"); + + return (NULL); +} + +static void * +t2(void *data __unused) +{ + int i; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + while (go == 0) + pthread_yield(); + + atomic_add_int(&go, 1); + for (i = 0; i < 100; i++) + if (ftruncate(fd, 0) == -1) + err(1, "truncate"); + + return (NULL); +} + +static void * +t3(void *data __unused) +{ + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + while (go != 3) + pthread_yield(); + abort(); + + return (NULL); +} + +int +test(void) +{ + pthread_t tid[3]; + int i, rc; + + go = 0; + if ((rc = pthread_create(&tid[0], NULL, t1, NULL)) != 0) + errc(1, rc, "pthread_create"); + if ((rc = pthread_create(&tid[1], NULL, t2, NULL)) != 0) + errc(1, rc, "pthread_create"); + if ((rc = pthread_create(&tid[2], NULL, t3, NULL)) != 0) + errc(1, rc, "pthread_create"); + usleep(200); + atomic_add_int(&go, 1); + + for (i = 0; i < 3; i++) { + if ((rc = pthread_join(tid[i], NULL)) != 0) + errc(1, rc, "pthread_join"); + } + + _exit(0); +} + +int +main(void) +{ + time_t start; + + if ((fd = open(file, O_RDWR | O_CREAT, 0644)) == -1) + err(1, "open(%s)", file); + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if (fork() == 0) + test(); + wait(NULL); + } + close(fd); + unlink(file); + + return (0); +} diff --git a/tools/test/stress2/misc/ptrace.sh b/tools/test/stress2/misc/ptrace.sh new file mode 100755 index 000000000000..7e747378624e --- /dev/null +++ b/tools/test/stress2/misc/ptrace.sh @@ -0,0 +1,106 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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. +# + +# wait4(2) / ptrace(2) regression test. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > ptrace.c +mycc -o ptrace -Wall -Wextra -g ptrace.c || exit 1 +rm -f ptrace.c +cd $here + +/tmp/ptrace + +rm -f /tmp/ptrace +exit + +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +test(void) +{ + pid_t pid, rpid; + struct rusage ru; + int status; + + if ((pid = fork()) == 0) { + usleep(2000); + _exit(64); + } + if (pid == -1) + err(1, "fork()"); + if (ptrace(PT_ATTACH, pid, NULL, 0) == -1) + err(1, "ptrace(%d) attach", pid); + if (wait(NULL) == -1) + err(1, "wait"); + bzero(&ru, sizeof(ru)); + usleep(2000); + if ((rpid = wait4(-1, &status, WNOHANG, &ru)) == -1) { + if (errno == ECHILD) + warn("FAIL"); + else + err(1, "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); + + _exit(0); +} + +int +main(void) +{ + test(); + + return (0); +} diff --git a/tools/test/stress2/misc/ptrace10.sh b/tools/test/stress2/misc/ptrace10.sh new file mode 100755 index 000000000000..c2dec736a240 --- /dev/null +++ b/tools/test/stress2/misc/ptrace10.sh @@ -0,0 +1,161 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2021 Mark Johnston +# +# 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. +# + +# ptrace(2) test scenario by Mark Johnston +# https://people.freebsd.org/~markj/ptrace_stop_mt.c +# Fixed by r303423. + +# stopped on signal 17 after detach +# UID PID PPID CPU PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND +# 1001 47125 62778 0 52 0 6568 2456 wait S+ 2 0:00.01 /bin/sh ./ptrace10.sh +# 1001 47146 47125 0 23 0 6108 1928 nanslp S+ 2 0:00.00 ./ptrace10 +# 1001 47148 47146 0 24 0 6240 1932 - T+ 2 0:00.00 ./ptrace10 +# 1001 47148 47146 0 24 0 6240 1932 - T+ 2 0:00.00 ./ptrace10 + +. ../default.cfg + +cd /tmp +cat > ptrace10.c < +#include +#include + +#include +#include +#include +#include +#include +#include + +static void +sighup(int sig __unused) +{ +} + +static void +sleep_forever(void) +{ + + while (1) + sleep(1); +} + +static void * +thread(void *arg __unused) +{ + + sleep_forever(); + return (NULL); +} + +int +main(void) +{ + struct sigaction act; + sigset_t set; + pthread_t t; + pid_t pid, ret; + int e, try, limit, r, status; + + e = 0; + pid = fork(); + if (pid < 0) + err(1, "fork"); + if (pid == 0) { + act.sa_handler = sighup; + act.sa_flags = 0; + sigemptyset(&act.sa_mask); + if (sigaction(SIGHUP, &act, NULL) != 0) + err(1, "sigaction"); + + r = pthread_create(&t, NULL, thread, NULL); + if (r != 0) + errc(1, r, "pthread_create"); + + /* Force SIGHUP to be delivered to the new thread. */ + sigemptyset(&set); + sigaddset(&set, SIGHUP); + r = pthread_sigmask(SIG_BLOCK, &set, NULL); + if (r != 0) + errc(1, r, "pthread_sigmask"); + + sleep_forever(); + } else { + sleep(1); /* give the child a chance to set itself up */ + + limit = 100; + for (try = 1; try <= limit; try++) { + if (kill(pid, SIGHUP) != 0) + err(1, "kill(SIGHUP)"); + if (ptrace(PT_ATTACH, pid, NULL, 0) != 0) + err(1, "ptrace(PT_ATTACH)"); + if (waitpid(pid, &status, WUNTRACED) != pid) + err(1, "waitpid 1"); + if (!WIFSTOPPED(status)) + errx(1, "unexpected status %d after PT_ATTACH", + status); + if (ptrace(PT_DETACH, pid, NULL, 0) != 0) + err(1, "ptrace(PT_DETACH)"); + + sleep(1); + ret = waitpid(pid, &status, WUNTRACED | WNOHANG); + if (ret < 0) + err(1, "waitpid"); + if (ret == 0) + continue; + if (!WIFSTOPPED(status)) + errx(1, "unexpected status %d after PT_DETACH", + status); + printf("stopped on signal %d after detach\n", + WSTOPSIG(status)); + e = 1; + break; + } + } + kill(pid, SIGINT); + + return (e); +} +EOF + +mycc -o ptrace10 -Wall -Wextra -O2 -g ptrace10.c -lpthread || exit 1 +rm ptrace10.c + +./ptrace10 +s=$? +if [ $s -ne 0 ]; then + ps -lxH | grep -v grep | egrep "UID|ptrace10" + while pgrep -q ptrace10; do + pkill -9 ptrace10 + done +fi +wait + +rm -f ptrace10 +exit $s diff --git a/tools/test/stress2/misc/ptrace11.sh b/tools/test/stress2/misc/ptrace11.sh new file mode 100755 index 000000000000..9fbd44481624 --- /dev/null +++ b/tools/test/stress2/misc/ptrace11.sh @@ -0,0 +1,124 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# markj@ wrote: +# I found a kernel bug that caused init to consume 100% CPU if the +# following steps occurred: +# - process A forks and creates process B +# - process C ptrace attaches to process B +# - process A exits +# - process C detaches from process B +# - process B exits +# +# Process B gets reparented to init, and the bug causes wait() to return +# an error each time init attempts to reap process B. + +. ../default.cfg +cd /tmp +cat > ptrace11.c < +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; +#define SYNC 0 + +int +main(void) +{ + pid_t pida, pidb; + size_t len; + int status; + + setproctitle("A"); + len = PAGE_SIZE; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + pida = fork(); + if (pida < 0) + err(1, "fork"); + if (pida == 0) { + setproctitle("B"); + while (share[SYNC] != 2) + usleep(10); + _exit(0); + } else { + sleep(1); + pidb = fork(); + if (pidb < 0) + err(1, "fork"); + if (pidb == 0) { + setproctitle("C"); + if (ptrace(PT_ATTACH, pida, NULL, 0) != 0) + err(1, "ptrace(PT_ATTACH)"); + wait4(pida, &status, 0, NULL); + share[SYNC] = 1; /* A to exit */ + usleep(1000); + if (ptrace(PT_DETACH, pida, NULL, 0) != 0) + err(1, "ptrace(PT_DETACH)"); + share[SYNC] = 2; /* B to exit */ + _exit(0); + } else { + while (share[SYNC] != 1) + usleep(10); + _exit(0); + } + } + + return (0); +} +EOF + +mycc -o ptrace11 -Wall -Wextra -O2 -g ptrace11.c || exit 1 +rm ptrace11.c +old=`ps auxwwl | grep -v grep | grep "" | wc -l` + +./ptrace11 + +new=`ps auxwwl | grep -v grep | grep "" | wc -l` +if [ $old -ne $new ]; then + ps auxwwl | sed -n '1p;//p' + echo FAIL + s=1 +fi + +rm -f ptrace11 +exit $s diff --git a/tools/test/stress2/misc/ptrace2.sh b/tools/test/stress2/misc/ptrace2.sh new file mode 100755 index 000000000000..7e689f981fc8 --- /dev/null +++ b/tools/test/stress2/misc/ptrace2.sh @@ -0,0 +1,143 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 kern/142757, race condition in traced process signal +# handling. Fixed in r202692. + +# Test scenario by Tijl Coosemans, tijl@ + +. ../default.cfg + +cd /tmp + +cat > race1.c < +#include +#include +#include +#include +#include + +int +main(void) +{ + pid_t pid; + int i, status; + + alarm(120); + /* fork dummy child process */ + pid = fork(); + if (pid == 0) { + /* child does nothing */ + for (;;) { + sleep(1); + } + } else { + /* parent */ + sleep(1); + for (i = 0; i < 100000; i++) { + /* loop: attach, wait, detach */ + printf("attach "); + fflush(stdout); + ptrace(PT_ATTACH, pid, (caddr_t) 0, 0); + + printf("wait "); + fflush(stdout); + wait4(pid, &status, 0, NULL); + + printf("detach "); + fflush(stdout); + ptrace(PT_DETACH, pid, (caddr_t) 1, 0); + + printf("ok\n"); + fflush(stdout); + } + } + kill(pid, SIGINT); + + return (0); +} +EOF + +cat > race2.c < +#include +#include +#include +#include +#include + +int +main(void) +{ + pid_t pid; + int i, status; + + alarm(120); + /* fork dummy child process */ + pid = fork(); + if (pid == 0) { + /* child does nothing */ + for (;;) { + sleep(1); + } + } else { + /* parent */ + sleep(1); + ptrace(PT_ATTACH, pid, (caddr_t) 0, 0); + wait4(pid, &status, 0, NULL); + for (i = 0; i < 100000; i++) { + /* loop: continue, kill, wait */ + printf("continue "); + fflush(stdout); + ptrace(PT_CONTINUE, pid, (caddr_t) 1, 0); + + printf("kill "); + fflush(stdout); + kill(pid, SIGINT); + + printf("wait "); + fflush(stdout); + wait4(pid, &status, 0, NULL); + + printf("ok\n"); + fflush(stdout); + } + } + + return (0); +} +EOF + +mycc -o race1 -Wall -Wextra race1.c +mycc -o race2 -Wall -Wextra race2.c + +./race1 > /dev/null || echo "FAIL #1" +./race2 > /dev/null || echo "FAIL #2" + +rm -f race1.c race1 race2.c race2 diff --git a/tools/test/stress2/misc/ptrace3.sh b/tools/test/stress2/misc/ptrace3.sh new file mode 100755 index 000000000000..9b8cd4c39670 --- /dev/null +++ b/tools/test/stress2/misc/ptrace3.sh @@ -0,0 +1,130 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 regression test for a bug introduced in r269656. +# Page fault in proc_realparent+0x70 seen. +# Fixed in r270024. + +# Test scenario by Mark Johnston markj@ + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > ptrace3.c +mycc -o ptrace3 -Wall -Wextra -g ptrace3.c || exit 1 +rm -f ptrace3.c +cd $here + +/tmp/ptrace3 + +rm -f /tmp/ptrace3 +exit +EOF +#include +#include +#include + +#include +#include +#include + +/* + * A regression test for a bug introduced in r269656. The test process p creates + * child processes c1 and c2 which do nothing but sleep; a third child process + * (c3) uses ptrace(2) to reparent c1 and c2 from p to c3. Then c3 detaches from + * c1 and c2, causing a crash when c1 and c2 are removed from p's now-corrupt + * orphan list. + */ + +pid_t +sleeper() +{ + pid_t p; + + p = fork(); + if (p == -1) + err(1, "fork"); + else if (p == 0) + while (1) + sleep(1000000); + return (p); +} + +void +attach(pid_t p) +{ + int status; + + if (ptrace(PT_ATTACH, p, 0, 0) == -1) + err(1, "ptrace"); + + if (waitpid(p, &status, 0) == -1) + err(1, "waitpid"); + else if (!WIFSTOPPED(status)) + errx(1, "failed to stop child"); +} + +void +detach(pid_t p) +{ + + if (ptrace(PT_DETACH, p, 0, 0) == -1) + err(1, "ptrace"); +} + +int +main(void) +{ + int status; + pid_t c1, c2, p; + + c1 = sleeper(); + c2 = sleeper(); + + p = fork(); + if (p == -1) { + err(1, "fork"); + } else if (p == 0) { + attach(c1); + attach(c2); + detach(c1); + detach(c2); + } else { + if (waitpid(p, &status, 0) == -1) + err(1, "waitpid"); + if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) + errx(1, "child exited abnormally"); + } + + /* Clean up. */ + (void)kill(c1, SIGKILL); + (void)kill(c2, SIGKILL); + + return (0); +} diff --git a/tools/test/stress2/misc/ptrace4.sh b/tools/test/stress2/misc/ptrace4.sh new file mode 100755 index 000000000000..88d9893c165a --- /dev/null +++ b/tools/test/stress2/misc/ptrace4.sh @@ -0,0 +1,58 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# ptrace(2) test scenario + +# Test program can not be killed: +# https://people.freebsd.org/~pho/stress/log/kostik836.txt +# Fixed by r289660. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +export sleeptime=24 +./syscall4.sh 26 & + +sleep 240 +l=0 +while ps -Unobody | grep -v grep | grep -q syscall4; do + l=$((l + 1)) + if [ $l -gt 10 ]; then + ps -HlUnobody | grep syscall4 + echo FAIL + break + fi + sleep 10 +done +kill $! 2>/dev/null +pkill -9 swap syscall4 +while pgrep -q swap; do + pkill -9 swap +done +wait diff --git a/tools/test/stress2/misc/ptrace5.sh b/tools/test/stress2/misc/ptrace5.sh new file mode 100755 index 000000000000..5ff80cd68ca9 --- /dev/null +++ b/tools/test/stress2/misc/ptrace5.sh @@ -0,0 +1,200 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# It seems to be possible for ptrace(PT_ATTACH) to race with the delivery +# of a signal to the same process. + +# "panic: Assertion TD_IS_SLEEPING(td) failed at subr_sleepqueue.c:958". +# https://people.freebsd.org/~pho/stress/log/ptrace5.txt +# https://people.freebsd.org/~pho/stress/log/ptrace5-2.txt +# Fixed by r303426. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/ptrace5.c +mycc -o ptrace5 -Wall -Wextra -O0 -g ptrace5.c -pthread || exit 1 +rm -f ptrace5.c +cd $odir + +/tmp/ptrace5 +s=$? + +rm -rf /tmp/ptrace5 +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static pid_t pid; +static pthread_barrier_t barr; +static int cont; + +#define PARALLEL 4 +#define RUNTIME (5 * 60) + +static void +ahandler(int i __unused) +{ + system("ps -Hl"); + fprintf(stderr, "SIGALRM pid %d\n", pid); + exit(1); +} + +static void +handler(int i __unused) +{ +} + +static void * +t1(void *data __unused) +{ + int status; + + while (cont == 1) { + if (ptrace(PT_ATTACH, pid, 0, 0) == -1) + err(1, "ptrace(%d)", pid); + + if (waitpid(pid, &status, 0) == -1) + err(1, "waitpid"); + else if (!WIFSTOPPED(status)) + errx(1, "failed to stop child"); + if (ptrace(PT_DETACH, pid, 0, 0) == -1) + err(1, "ptrace"); + usleep(arc4random() % 200); + } + + return (NULL); +} + +static void * +t2(void *data __unused) +{ + while (cont == 1) { + if (kill(pid, SIGHUP) == -1) + err(1, "kill"); + usleep(arc4random() % 200); + } + + return (NULL); +} + +static void +test(void) +{ + pthread_t tid[2]; + struct sigaction sa; + int r, status; + + r = pthread_barrier_wait(&barr); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + errc(1, r, "pthread_barrier_wait"); + + sa.sa_handler = ahandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGALRM, &sa, NULL) == -1) + err(1, "sigaction"); + alarm(2 * RUNTIME); + sa.sa_handler = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGHUP, &sa, NULL) == -1) + err(1, "sigaction"); + + if ((pid = fork()) == 0) { + for(;;) + usleep(20); + + _exit(0); + } + + cont = 1; + if ((r = pthread_create(&tid[0], NULL, t1, NULL)) == -1) + errc(1, r, "pthread_create"); + if ((r = pthread_create(&tid[1], NULL, t2, NULL)) == -1) + errc(1, r, "pthread_create"); + + sleep(RUNTIME); + + cont = 0; + if ((r = pthread_join(tid[0], NULL)) == -1) + errc(1, r, "pthread_join"); + if ((r = pthread_join(tid[1], NULL)) == -1) + errc(1, r, "pthread_join"); + if (kill(pid, SIGKILL) != 0) + err(1, "kill(%d)", pid); + waitpid(pid, &status, 0); + + exit(0); +} + +int +main(void) +{ + pthread_barrierattr_t attr; + int e, i, pids[PARALLEL], r, status; + + if ((r = pthread_barrierattr_init(&attr)) != 0) + errc(1, r, "pthread_barrierattr_init"); + if ((r = pthread_barrierattr_setpshared(&attr, + PTHREAD_PROCESS_SHARED)) != 0) + errc(1, r, "pthread_barrierattr_setpshared"); + if ((r = pthread_barrier_init(&barr, &attr, PARALLEL)) != 0) + errc(1, r, "pthread_barrier_init"); + + e = 0; + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + for (i = 0; i < PARALLEL; i++) { + waitpid(pids[i], &status, 0); + e += status == 0 ? 0 : 1; + } + + if ((r = pthread_barrier_destroy(&barr)) > 0) + errc(1, r, "pthread_barrier_destroy"); + + return (e); +} diff --git a/tools/test/stress2/misc/ptrace6.sh b/tools/test/stress2/misc/ptrace6.sh new file mode 100755 index 000000000000..872c1c0d202c --- /dev/null +++ b/tools/test/stress2/misc/ptrace6.sh @@ -0,0 +1,204 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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: Assertion TD_IS_SLEEPING(td) failed at subr_sleepqueue.c:958. +# Fixed by r303426. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/ptrace6.c +mycc -o ptrace6 -Wall -Wextra -O0 -g ptrace6.c -pthread || exit 1 +rm -f ptrace6.c +cd $odir + +/tmp/ptrace6 +s=$? + +while pgrep -q swap; do + pkill -9 swap +done +rm -rf /tmp/ptrace6 +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static pid_t pid; +static pthread_barrier_t barr; +static int cont; +static int state; + +#define PARALLEL 4 +#define RUNTIME (4 * 60) + +static void +ahandler(int i __unused) +{ + system("ps -Hl"); + fprintf(stderr, "SIGALRM state %d, pid %d\n", state, pid); + exit(1); +} + +static void +handler(int i __unused) +{ +} + +static void * +t1(void *data __unused) +{ + int status; + + while (cont == 1) { + state = 1; + if (ptrace(PT_ATTACH, pid, 0, 0) == -1) + err(1, "ptrace(%d)", pid); + + state = 2; + if (waitpid(pid, &status, 0) == -1) + err(1, "waitpid"); + else if (!WIFSTOPPED(status)) + errx(1, "failed to stop child"); + state = 3; + if (ptrace(PT_DETACH, pid, 0, 0) == -1) + err(1, "ptrace"); + state = 4; + usleep(arc4random() % 200); + } + + return (NULL); +} + +static void * +t2(void *data __unused) +{ + while (cont == 1) { + if (kill(pid, SIGHUP) == -1) + err(1, "kill"); + usleep(arc4random() % 200); + } + + return (NULL); +} + +static void +test(void) +{ + pthread_t tid[2]; + struct sigaction sa; + int r; + + r = pthread_barrier_wait(&barr); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + errc(1, r, "pthread_barrier_wait"); + + sa.sa_handler = ahandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGALRM, &sa, NULL) == -1) + err(1, "sigaction"); + alarm(RUNTIME + 60); + + sa.sa_handler = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGHUP, &sa, NULL) == -1) + err(1, "sigaction"); + + if ((pid = fork()) == 0) { + for(;;) + usleep(arc4random() % 1000); + + _exit(0); + } + + cont = 1; + if ((r = pthread_create(&tid[0], NULL, t1, NULL)) == -1) + errc(1, r, "pthread_create"); + if ((r = pthread_create(&tid[1], NULL, t2, NULL)) == -1) + errc(1, r, "pthread_create"); + + sleep(RUNTIME); + + cont = 0; + if ((r = pthread_join(tid[0], NULL)) == -1) + errc(1, r, "pthread_join"); + if ((r = pthread_join(tid[1], NULL)) == -1) + errc(1, r, "pthread_join"); + if (kill(pid, SIGKILL) != 0) + err(1, "kill(%d)", pid); + waitpid(pid, NULL, 0); + + exit(0); +} + +int +main(void) +{ + pthread_barrierattr_t attr; + int e, i, pids[PARALLEL], r, status; + + if ((r = pthread_barrierattr_init(&attr)) != 0) + errc(1, r, "pthread_barrierattr_init"); + if ((r = pthread_barrierattr_setpshared(&attr, + PTHREAD_PROCESS_SHARED)) != 0) + errc(1, r, "pthread_barrierattr_setpshared"); + if ((r = pthread_barrier_init(&barr, &attr, PARALLEL)) != 0) + errc(1, r, "pthread_barrier_init"); + + e = 0; + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + for (i = 0; i < PARALLEL; i++) { + waitpid(pids[i], &status, 0); + e += status == 0 ? 0 : 1; + } + + if ((r = pthread_barrier_destroy(&barr)) > 0) + errc(1, r, "pthread_barrier_destroy"); + + return (e); +} diff --git a/tools/test/stress2/misc/ptrace7.sh b/tools/test/stress2/misc/ptrace7.sh new file mode 100755 index 000000000000..c6c810b60d01 --- /dev/null +++ b/tools/test/stress2/misc/ptrace7.sh @@ -0,0 +1,238 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# It seems to be possible for ptrace(PT_ATTACH) to race with the delivery +# of a signal to the same process. + +# $ while ./pt.sh; do date; done +# 15. juli 2016 kl. 05.59.05 CEST +# 15. juli 2016 kl. 06.03.07 CEST +# UID PID PPID CPU PRI NI VSZ RSS MWCHAN STAT TT TIME COMMAND +# 1001 863 862 0 44 0 13880 5268 wait Is 0 0:00,13 -bash (bash) +# 1001 21053 863 0 52 0 13188 3088 wait I+ 0 0:00,01 /bin/sh ./pt.sh +# 1001 21096 21053 0 52 0 10544 2308 wait I+ 0 0:00,00 /tmp/pt +# 1001 21103 21096 0 20 0 12852 2456 wait S+ 0 0:00,00 pt: main (pt) +# 1001 21103 21096 0 35 0 12852 2456 wait I+ 0 0:55,30 pt: main (pt) +# 1001 21104 21096 0 72 0 0 0 - Z+ 0 0:00,00 +# 1001 21105 21096 0 72 0 0 0 - Z+ 0 0:00,00 +# 1001 21116 21103 0 103 0 10544 2336 - RX+ 0 4:22,41 pt: spinner (pt) +# 1001 37711 21103 0 20 0 21200 2960 - R+ 0 0:00,00 ps -Hl +# 1001 890 879 0 20 0 22184 6196 select Ss+ 1 1:21,86 top -s 1 +# 1001 85222 85221 0 21 0 13880 5276 ttyin Is+ 2 0:00,23 -bash (bash) +# SIGALRM state 2, pid 21116 +# $ + +# Fixed by r303423. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/ptrace7.c +mycc -o ptrace7 -Wall -Wextra -O0 -g ptrace7.c -pthread || exit 1 +rm -f ptrace7.c +cd $odir + +/tmp/ptrace7 +s=$? + +while pgrep -q swap; do + pkill -9 swap +done +rm -rf /tmp/ptrace7 +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#ifdef __FreeBSD__ +#include +#define __NP__ +#endif +#include +#include +#include +#include +#include + +static pid_t pid; +static pthread_barrier_t barr; +static int cont; +static int state; + +#define PARALLEL 8 +#define RUNTIME (4 * 60) + +static void +ahandler(int i __unused) +{ + system("ps -Hl"); + fprintf(stderr, "SIGALRM state %d, pid %d\n", state, pid); + exit(1); +} + +static void +handler(int i __unused) +{ +} + +static void * +t1(void *data __unused) +{ + int status; + +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + while (cont == 1) { + state = 1; + if (ptrace(PT_ATTACH, pid, 0, 0) == -1) + err(1, "ptrace(%d)", pid); + + state = 2; + if (waitpid(pid, &status, 0) == -1) + err(1, "waitpid"); + else if (!WIFSTOPPED(status)) + errx(1, "failed to stop child"); + state = 3; + if (ptrace(PT_DETACH, pid, 0, 0) == -1) + err(1, "ptrace"); + state = 4; + usleep(arc4random() % 100 + 50); + } + + return (NULL); +} + +static void * +t2(void *data __unused) +{ +#ifdef __NP__ + pthread_set_name_np(pthread_self(), __func__); +#endif + while (cont == 1) { + if (kill(pid, SIGHUP) == -1) + err(1, "kill"); + usleep(arc4random() % 100 + 50); + } + + return (NULL); +} + +static void +test(void) +{ + pthread_t tid[2]; + struct sigaction sa; + int r, status; + + r = pthread_barrier_wait(&barr); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + errc(1, r, "pthread_barrier_wait"); + + sa.sa_handler = ahandler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGALRM, &sa, NULL) == -1) + err(1, "sigaction"); + alarm(RUNTIME + 60); + + sa.sa_handler = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGHUP, &sa, NULL) == -1) + err(1, "sigaction"); + + setproctitle("%s", "spinner"); + if ((pid = fork()) == 0) { + for(;;) + getuid(); + + _exit(0); + } + + cont = 1; + if ((r = pthread_create(&tid[0], NULL, t1, NULL)) == -1) + errc(1, r, "pthread_create"); + if ((r = pthread_create(&tid[1], NULL, t2, NULL)) == -1) + errc(1, r, "pthread_create"); + + setproctitle("%s", "main"); + sleep(RUNTIME); + + cont = 0; + if ((r = pthread_join(tid[0], NULL)) == -1) + errc(1, r, "pthread_join"); + if ((r = pthread_join(tid[1], NULL)) == -1) + errc(1, r, "pthread_join"); + if (kill(pid, SIGKILL) != 0) + err(1, "kill(%d)", pid); + if (waitpid(pid, &status, 0) == -1) + err(1, "waitpid(%d)", pid); + + exit(0); +} + +int +main(void) +{ + pthread_barrierattr_t attr; + int e, i, pids[PARALLEL], r, status; + + if ((r = pthread_barrierattr_init(&attr)) != 0) + errc(1, r, "pthread_barrierattr_init"); + if ((r = pthread_barrierattr_setpshared(&attr, + PTHREAD_PROCESS_SHARED)) != 0) + errc(1, r, "pthread_barrierattr_setpshared"); + if ((r = pthread_barrier_init(&barr, &attr, PARALLEL)) != 0) + errc(1, r, "pthread_barrier_init"); + + e = 0; + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + for (i = 0; i < PARALLEL; i++) { + if (waitpid(pids[i], &status, 0) == -1) + err(1, "waitpid%d)", pids[i]); + e += status == 0 ? 0 : 1; + } + + if ((r = pthread_barrier_destroy(&barr)) > 0) + errc(1, r, "pthread_barrier_destroy"); + + return (e); +} diff --git a/tools/test/stress2/misc/ptrace8.sh b/tools/test/stress2/misc/ptrace8.sh new file mode 100755 index 000000000000..2021c47905b4 --- /dev/null +++ b/tools/test/stress2/misc/ptrace8.sh @@ -0,0 +1,122 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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 regression test for r302919. +# Triggered a witness message: +# +# vmspace_free() called with the following non-sleepable locks held: +# shared rw vm object (vm object) r = 0 locked @ kern/sys_process.c:432 + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/ptrace8.c +mycc -o ptrace8 -Wall -Wextra -O0 -g ptrace8.c || exit 1 +rm -f ptrace8.c +cd $odir + +/tmp/ptrace8 +s=$? + +rm -rf /tmp/ptrace8 +exit $s + +EOF +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +volatile u_int *share; + +#define SYNC 0 + +int +main(void) +{ + struct ptrace_vm_entry ent; + size_t len; + int pid, r, status; + char path[MAXPATHLEN + 1]; + + len = PAGE_SIZE; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + if ((pid = fork()) == 0) { + while (share[SYNC] == 0) + sleep(1); + + _exit(0); + } + + if (ptrace(PT_ATTACH, pid, 0, 0) == -1) + err(1, "ptrace"); + + if (waitpid(pid, &status, 0) == -1) + err(1, "waitpid"); + else if (!WIFSTOPPED(status)) + errx(1, "failed to stop child"); + + ent.pve_entry = 0; + ent.pve_path = path; + ent.pve_pathlen = sizeof(path); + do { + r = ptrace(PT_VM_ENTRY, pid, (caddr_t)&ent, 0); +#if defined(DEBUG) + if (r == 0) + fprintf(stderr, "path = %s 0x%lx - 0x%lx\n", + ent.pve_path, ent.pve_start, ent.pve_end); +#endif + } while (r == 0); + if (r == -1 && errno != ENOENT) + err(1, "ptrace(PT_VM_ENTRY)"); + + share[SYNC] = 1; + if (ptrace(PT_DETACH, pid, 0, 0) == -1) + err(1, "ptrace"); + + if (waitpid(pid, &status, 0) == -1) + err(1, "waitpid(%d)", pid); + + return (status != 0); +} diff --git a/tools/test/stress2/misc/ptrace9.sh b/tools/test/stress2/misc/ptrace9.sh new file mode 100755 index 000000000000..ac1329fd1a2a --- /dev/null +++ b/tools/test/stress2/misc/ptrace9.sh @@ -0,0 +1,133 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2016 Mark Johnston +# +# 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. +# + +# ptrace(2) test scenario by Mark Johnston +# https://people.freebsd.org/~markj/ptrace_stop.c +# Fixed by r303423. + +. ../default.cfg + +cd /tmp +cat > ptrace9.c < +#include +#include + +#include +#include +#include +#include + +static void +sigalrm(int sig __unused) +{ + _exit(0); +} + +static void +sighup(int sig __unused) +{ +} + +int +main(void) +{ + struct sigaction act; + pid_t pid; + int e, status; + + signal(SIGALRM, sigalrm); + e = 1; + pid = fork(); + if (pid < 0) + err(1, "fork"); + if (pid == 0) { + act.sa_handler = sighup; + act.sa_flags = 0; + sigemptyset(&act.sa_mask); + if (sigaction(SIGHUP, &act, NULL) != 0) + err(1, "sigaction"); + alarm(5); + while (1) { + sleep(1); + } + } else { + alarm(5); + sleep(1); /* give the child a chance to call sigaction */ + + if (kill(pid, SIGSTOP) != 0) + err(1, "kill(SIGSTOP)"); + + printf("waiting for child to stop...\n"); + if (waitpid(pid, &status, WUNTRACED) != pid) + err(1, "waitpid"); + if (!WIFSTOPPED(status) || WSTOPSIG(status) != SIGSTOP) + errx(1, "unexpected status %d after SIGSTOP", status); + + if (kill(pid, SIGHUP) != 0) + err(1, "kill(SIGHUP)"); + + if (ptrace(PT_ATTACH, pid, NULL, 0) != 0) + err(1, "ptrace(PT_ATTACH)"); + if (waitpid(pid, &status, WUNTRACED) != pid) + err(1, "waitpid"); + if (!WIFSTOPPED(status)) + errx(1, "unexpected status %d after PT_ATTACH", status); + printf("stopping signal is %d\n", WSTOPSIG(status)); + if (ptrace(PT_DETACH, pid, NULL, 0) != 0) + err(1, "ptrace(PT_DETACH)"); + + /* if ptrace works as expected, we'll block here */ + printf("waiting on child...\n"); fflush(stdout); + if (waitpid(pid, &status, WUNTRACED) != pid) + err(1, "waitpid"); + if (!WIFSTOPPED(status)) + errx(1, "unexpected status %d after PT_DETACH", status); + printf("child is stopped after detach (sig %d)\n", + WSTOPSIG(status)); fflush(stdout); + e = 1; + } + + return (e); +} +EOF + +mycc -o ptrace9 -Wall -Wextra -O2 -g ptrace9.c || exit 1 +rm ptrace9.c + +echo "Expect: + waiting for child to stop... + stopping signal is 17 + waiting on child..." +./ptrace9 +s=$? + +pkill -9 ptrace9 +rm -f ptrace9 +exit $s diff --git a/tools/test/stress2/misc/pts.sh b/tools/test/stress2/misc/pts.sh new file mode 100755 index 000000000000..f994c1f89bc6 --- /dev/null +++ b/tools/test/stress2/misc/pts.sh @@ -0,0 +1,154 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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. +# + +# Page fault in ttydev_open+0x2d seen. Fixed in r237219. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pts.c +mycc -o pts -Wall -Wextra -O2 pts.c -lutil || exit 1 +rm -f pts.c + +/tmp/pts & +pid=$! + +while kill -0 $! 2>/dev/null; do + $here/../testcases/swap/swap -t 2m -i 20 > /dev/null +done +wait $pid +status=$? + +rm -f /tmp/pts +exit $status +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 10 +#define RUNTIME 60 + +void +churn(char *path) +{ + FTS *fts; + FTSENT *p; + time_t start; + int fd, ftsoptions; + char *args[2]; + + ftsoptions = FTS_PHYSICAL; + args[0] = path; + args[1] = 0; + + setproctitle("churn"); + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) { + if (p->fts_info == FTS_D || + p->fts_info == FTS_DP) + continue; + if ((fd = open(p->fts_path, O_RDONLY)) > 0) + close(fd); + + } + + if (errno != 0 && errno != ENOENT) + err(1, "fts_read"); + if (fts_close(fts) == -1) + err(1, "fts_close()"); + } + + _exit(0); +} + +void +pty(void) +{ + time_t start; + int master, slave; + char slname[1025]; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if (openpty(&master, &slave, slname, NULL, NULL) == -1) + err(1, "openpty"); + usleep(arc4random() % 10000); + if (close(master) == -1) + err(1, "close(master)"); + if (close(slave) == -1) + err(1, "close(%s)", slname); + } + _exit(0); +} + +int +main(void) +{ + int i, j, s, status; + + status = 0; + for (j = 0; j < LOOPS && status == 0; j++) { + for (i = 0; i < 2; i++) { + if (fork() == 0) + pty(); + } + for (i = 0; i < 2; i++) { + if (fork() == 0) + churn("/dev/pts"); + } + for (i = 0; i < 4; i++) { + wait(&s); + if (s != 0) + status = 1; + } + } + + return (status); +} diff --git a/tools/test/stress2/misc/pts2.sh b/tools/test/stress2/misc/pts2.sh new file mode 100755 index 000000000000..84f7bbd78255 --- /dev/null +++ b/tools/test/stress2/misc/pts2.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# pts leak seen. +# Fixed in r313496. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +kldstat -v | grep -q pty || { kldload pty || exit 0; } + +. ../default.cfg + +here=`pwd` +cd /tmp +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}'` +for i in `jot 10`; do + /tmp/pts2 +done +new=`vmstat -m | grep pts | awk '{print $2}'` +s=0 +[ $((new - pts)) -gt 1 ] && { s=1; echo "Leaked $((new - pts)) pts."; } + +rm -f /tmp/pts2 +exit $s +EOF +#include + +#include +#include +#include + +const char *master = "/dev/ptmx"; +int +main(void) +{ + int fd, fd2, slave; + char sl[80]; + + if ((fd = open(master, O_RDONLY)) == -1) + err(1, "open(%s)", master); + + if (ioctl(fd, TIOCGPTN, &slave) == -1) + err(1, "ioctl"); + + snprintf(sl, sizeof(sl), "/dev/pts/%d", slave); + + if ((fd2 = open(sl, O_RDONLY | O_EXLOCK)) == -1) + err(1, "open(%s)", sl); + + return (0); +} diff --git a/tools/test/stress2/misc/pts3.sh b/tools/test/stress2/misc/pts3.sh new file mode 100755 index 000000000000..b398e92916af --- /dev/null +++ b/tools/test/stress2/misc/pts3.sh @@ -0,0 +1,102 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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: Most recently used by tty" seen. +# Reported by syzbot+c9b6206303bf47bac87e@syzkaller.appspotmail.com +# Fixed by r349733 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +kldstat -v | grep -q pty || { kldload pty || exit 0; } + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pts3.c +mycc -o pts3 -Wall -Wextra -O2 pts3.c || exit 1 +rm -f pts3.c + +/tmp/pts3; s=$? + +rm -f /tmp/pts3 +exit $s +EOF +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; +#define SYNC 0 + +int +main(void) +{ + pid_t p, pid; + size_t len; + time_t start; + int fd; + char path[128]; + + len = PAGE_SIZE; + if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + p = getpid(); + sprintf(path, "/dev/ptmx"); + start = time(NULL); + while (time(NULL) - start < 60) { + share[SYNC] = 0; + if ((fd = open(path, O_RDWR)) == -1) + err(1,"open()"); + if ((pid = fork()) == 0) { + while (share[SYNC] == 0) + ; + _exit(0); + } + share[SYNC] = 1; + if (fcntl(fd, F_SETOWN, p) == -1) + warn("fcntl()"); + close(fd); + if (waitpid(pid, NULL, 0) != pid) + err(1, "waitpid()"); + } + + return (0); +} diff --git a/tools/test/stress2/misc/pty.sh b/tools/test/stress2/misc/pty.sh new file mode 100755 index 000000000000..a2b8ecbcc574 --- /dev/null +++ b/tools/test/stress2/misc/pty.sh @@ -0,0 +1,161 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# pty(4) test scenario. + +# "panic: make_dev_credv: bad si_name (error=17, si_name=ptysn)" seen. +# https://people.freebsd.org/~pho/stress/log/pty.txt + +# /dev/pty[l-sL-S][0-9a-v] Pseudo-terminal master devices. +# /dev/tty[l-sL-S][0-9a-v] Pseudo-terminal slave devices. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +kldstat -v | grep -q pty || { kldload pty || exit 0; } + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pty.c +mycc -o pty -Wall -Wextra -O2 pty.c || exit 1 +rm -f pty.c + +su $testuser -c /tmp/pty + +rm -f /tmp/pty +exit +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 4 +#define RUNTIME 300 + +char path[80]; + +void +churn(char *path) +{ + + FTS *fts; + FTSENT *p; + time_t start; + int fd, ftsoptions; + char *args[2]; + + ftsoptions = FTS_PHYSICAL; + args[0] = path; + args[1] = 0; + + setproctitle("churn"); + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if ((fts = fts_open(args, ftsoptions, NULL)) == NULL) + err(1, "fts_open"); + + while ((p = fts_read(fts)) != NULL) { + if (p->fts_info == FTS_D || + p->fts_info == FTS_DP) + continue; + if ((fd = open(p->fts_path, O_RDWR)) == -1) + if ((fd = open(p->fts_path, O_WRONLY)) == -1) + if ((fd = open(p->fts_path, O_RDONLY)) == -1) + continue; + usleep(arc4random() % 1000); + close(fd); + + } + + if (errno != 0 && errno != ENOENT) + err(1, "fts_read"); + if (fts_close(fts) == -1) + err(1, "fts_close()"); + } + + _exit(0); +} + +void +pty(void) +{ + int fd[512], i, j, n; + char c1, c2; + + n = 0; + c1 = 'l'; + for (i = 0; i < 16; i++) { + c2 = '0'; + for (j = 0; j < 32; j++) { + snprintf(path, sizeof(path), "/dev/pty%c%c", c1, c2); + fd[n++] = open(path, O_RDWR); + if (c2 == '9') + c2 = 'a'; + else + c2++; + } + if (c1 == 's') + c1 = 'L'; + else + c1++; + } + + for (i = 0; i < n; i++) + if (fd[i] != -1) + close(fd[i]); +} + +int +main(void) +{ + int i; + + time_t start; + + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + churn("/dev"); + + start = time(NULL); + while (time(NULL) - start < RUNTIME) + pty(); + + for (i = 0; i < PARALLEL; i++) + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/pty2.sh b/tools/test/stress2/misc/pty2.sh new file mode 100755 index 000000000000..b7cf346c994f --- /dev/null +++ b/tools/test/stress2/misc/pty2.sh @@ -0,0 +1,101 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# pty(4) test scenario. + +# "panic: make_dev_sv: bad si_name (error=17, si_name=ptyp0)" seen. +# Fixed by r293825. + +# Based on test scenario by Bruce Evans. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +kldstat -v | grep -q pty || { kldload pty || exit 0; } + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > pty2.c +mycc -o pty2 -Wall -Wextra -O2 pty2.c || exit 1 +rm -f pty2.c + +/tmp/pty2 + +rm -f /tmp/pty2 +exit +EOF +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 3 +#define RUNTIME 180 + +#define IN "/dev/ptyp0" + +void +test(void) +{ + time_t start; + int fd; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if ((fd = open(IN, O_RDONLY)) == -1) { + if (errno != EBUSY && errno != ENXIO && errno != ENOENT) + err(1, "open(%s)", IN); + } else + close(fd); + + } + _exit(0); +} + +int +main(void) +{ + int i; + + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + test(); + + for (i = 0; i < PARALLEL; i++) + wait(NULL); + + return(0); +} + diff --git a/tools/test/stress2/misc/quota1.sh b/tools/test/stress2/misc/quota1.sh new file mode 100755 index 000000000000..38e0fcd9c351 --- /dev/null +++ b/tools/test/stress2/misc/quota1.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2011 Peter Holm +# All rights reserved. +# +# 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 + +# Causes this: panic: mutex Giant not owned at ../../../kern/vfs_subr.c:1968 +# with a kernel compiled with "options QUOTA". +# This is not really a quota test. + +. ../default.cfg + +D=$diskimage +trap "rm -f $D" 0 +dd if=/dev/zero of=$D bs=1m count=128 status=none || exit 1 + +mount | grep "$mntpoint" | grep md${mdstart}$part > /dev/null && + umount $mntpoint +mdconfig -l | grep md$mdstart > /dev/null && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +export RUNDIR=$mntpoint/stressX +export runRUNTIME=10m # Run tests for 10 minutes +(cd ..; ./run.sh disk.cfg) +while mount | grep -q $mntpoint; do + umount $mntpoint > /dev/null 2>&1 || sleep 1 +done +mdconfig -d -u $mdstart +rm -f $D +exit 0 diff --git a/tools/test/stress2/misc/quota10.sh b/tools/test/stress2/misc/quota10.sh new file mode 100755 index 000000000000..1452f68538cf --- /dev/null +++ b/tools/test/stress2/misc/quota10.sh @@ -0,0 +1,105 @@ +#!/bin/sh + +# +# Copyright (c) 2008, 2011 Peter Holm +# All rights reserved. +# +# 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. +# + +# Hunt for deadlock that could occur running umount and quota at the same time +# "panic: dqsync: file" seen: +# https://people.freebsd.org/~pho/stress/log/quota10.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 + +. ../default.cfg + +mounts=15 # Number of parallel scripts +mdstart=$mdstart # Use md unit numbers from this point +D=$diskimage +export PATH_FSTAB=/tmp/fstab + +if [ $# -eq 0 ]; then + rm -f $PATH_FSTAB + for i in `jot $mounts`; do + m=$((i + mdstart - 1)) + [ ! -d ${mntpoint}$m ] && mkdir ${mntpoint}$m + mount | grep "$mntpoint" | grep -q md$m && + umount ${mntpoint}$m + [ -c /dev/md$m ] && mdconfig -d -u $m + + dd if=/dev/zero of=$D$m bs=1m count=1 status=none + mdconfig -a -t vnode -f $D$m -u $m + bsdlabel -w md$m auto + newfs md${m}$part > /dev/null 2>&1 + echo "/dev/md${m}$part ${mntpoint}$m ufs rw,userquota 2 2" \ + >> $PATH_FSTAB + mount ${mntpoint}$m + edquota -u -f ${mntpoint}$m -e \ + ${mntpoint}$m:100000:110000:15000:16000 root + umount ${mntpoint}$m + done + sync;sync;sync + + # start the parallel tests + touch /tmp/$0 + for i in `jot $mounts`; do + m=$((i + mdstart - 1)) + ./$0 $m & + ./$0 find $m & + done + wait + + for i in `jot $mounts`; do + m=$((i + mdstart - 1)) + mdconfig -d -u $m + rm -f $D$m + done + rm -f $PATH_FSTAB +else + if [ $1 = find ]; then + while [ -r /tmp/$0 ]; do + ( + quotaon ${mntpoint}$2 + quotaoff ${mntpoint}$2 + ) 2>&1 | egrep -v "No such file or directory" + done + else + + # The test: Parallel mount and unmounts + start=`date '+%s'` + while [ $((`date '+%s'` - start)) -lt 1200 ]; do + m=$1 + opt=`[ $(( m % 2 )) -eq 0 ] && echo -f` + mount $opt /dev/md${m}$part ${mntpoint}$m + while mount | grep -qw $mntpoint$m; do + opt=$([ $((`date '+%s'` % 2)) -eq 0 ] && + echo "-f") + umount $opt ${mntpoint}$m > /dev/null 2>&1 + done + done + rm -f /tmp/$0 + fi +fi +exit 0 diff --git a/tools/test/stress2/misc/quota11.sh b/tools/test/stress2/misc/quota11.sh new file mode 100755 index 000000000000..bf08f9e15db4 --- /dev/null +++ b/tools/test/stress2/misc/quota11.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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: share->excl" seen. +# http://people.freebsd.org/~pho/stress/log/kostik715.txt +# Fixed in r270795 and r270797 + +# Test scenario by Hiroki Sato + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 + +. ../default.cfg + +mount | grep "on $mntpoint " | grep -q md${mdstart}$part && umount $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +export PATH_FSTAB=/tmp/fstab +trap "rm -f $PATH_FSTAB" 0 +echo "/dev/md${mdstart}$part $mntpoint ufs rw,userquota 2 2" > $PATH_FSTAB +mount $mntpoint +edquota -u -f $mntpoint -e $mntpoint:1000:2000:100:200 root +quotaon $mntpoint + +while true; do repquota -av > /dev/null; done & + +dd if=/dev/random of=$mntpoint/foo.data bs=512 count=1024x1024 2>&1 | + egrep -v "trans|record" +kill $! +wait + +n=0 +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 + n=$((n + 1)) + [ $n -gt 60 ] && exit 1 +done +mdconfig -d -u $mdstart +exit 0 diff --git a/tools/test/stress2/misc/quota12.sh b/tools/test/stress2/misc/quota12.sh new file mode 100755 index 000000000000..78a5e0c0cd81 --- /dev/null +++ b/tools/test/stress2/misc/quota12.sh @@ -0,0 +1,80 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# Run marcus.cfg on a quota enabled FS + +# "Inability to allocate buffers" seen with WiP kernel code: +# https://people.freebsd.org/~pho/stress/log/kostik1218.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 + +. ../default.cfg + +mount | grep "on $mntpoint " | grep -q md${mdstart}$part && umount $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 2g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +export PATH_FSTAB=/tmp/fstab +trap "rm -f $PATH_FSTAB" 0 +echo "/dev/md${mdstart}$part $mntpoint ufs rw,userquota 2 2" > $PATH_FSTAB +mount $mntpoint +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$1 +export INODES=$2 +s=0 + +export QK=$((KBLOCKS / 1)) +export QI=$((INODES / 1)) +edquota -u -f $mntpoint -e \ + ${mntpoint}:$((QK - 50)):$QK:$((QI - 50 )):$QI $testuser > \ + /dev/null 2>&1 +quotaon $mntpoint + +chmod 777 $mntpoint +export runRUNTIME=15m +export RUNDIR=$mntpoint/stressX +su $testuser -c 'cd ..; ./run.sh marcus.cfg > /dev/null 2>&1' + +while ! quotaoff $mntpoint; do + sync + sleep 1 +done +quotacheck $mntpoint + +n=0 +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 + n=$((n + 1)) + [ $n -gt 60 ] && exit 1 +done +mdconfig -d -u $mdstart +exit 0 diff --git a/tools/test/stress2/misc/quota2.sh b/tools/test/stress2/misc/quota2.sh new file mode 100755 index 000000000000..9deb97726d60 --- /dev/null +++ b/tools/test/stress2/misc/quota2.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2011 Peter Holm +# All rights reserved. +# +# 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 +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 + +. ../default.cfg + +D=$diskimage +export PATH_FSTAB=/tmp/fstab +trap "rm -f $D $PATH_FSTAB" 0 +dd if=/dev/zero of=$D bs=1m count=128 status=none || exit 1 + +mount | grep "$mntpoint" | grep md${mdstart}$part > /dev/null && umount $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +echo "/dev/md${mdstart}$part $mntpoint ufs rw,userquota 2 2" > $PATH_FSTAB +mount $mntpoint +edquota -u -f $mntpoint -e $mntpoint:100000:110000:15000:16000 root +quotacheck $mntpoint +quotaon $mntpoint +export RUNDIR=$mntpoint/stressX +export runRUNTIME=10m # Run tests for 10 minutes +(cd ..; ./run.sh disk.cfg) 2>/dev/null +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +exit 0 diff --git a/tools/test/stress2/misc/quota3.sh b/tools/test/stress2/misc/quota3.sh new file mode 100755 index 000000000000..de4c60ec2810 --- /dev/null +++ b/tools/test/stress2/misc/quota3.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2011 Peter Holm +# All rights reserved. +# +# 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 +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 + +. ../default.cfg + +D=$diskimage +export PATH_FSTAB=/tmp/fstab +trap "rm -f $D $PATH_FSTAB" 0 +dd if=/dev/zero of=$D bs=1m count=1k status=none || exit 1 + +mount | grep "$mntpoint" | grep -q md${mdstart}$part && umount $mntpoint +mdconfig -l | grep md$mdstart > /dev/null && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +echo "/dev/md${mdstart}$part $mntpoint ufs rw,userquota 2 2" > $PATH_FSTAB +mount $mntpoint +edquota -u -f $mntpoint -e $mntpoint:850000:900000:130000:140000 root +quotacheck $mntpoint +quotaon $mntpoint +mksnap_ffs $mntpoint $mntpoint/.snap/stress2 +export RUNDIR=$mntpoint/stressX +export runRUNTIME=10m # Run tests for 10 minutes +(cd ..; ./run.sh disk.cfg) +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/quota4.sh b/tools/test/stress2/misc/quota4.sh new file mode 100755 index 000000000000..3eeae263cac2 --- /dev/null +++ b/tools/test/stress2/misc/quota4.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 + +# Has shown a deadlock after 7 hours of testing +# https://people.freebsd.org/~pho/stress/log/quota4.txt + +. ../default.cfg + +D=$diskimage +trap "rm -f $D" 0 +dd if=/dev/zero of=$D bs=1m count=1k status=none || exit 1 + +mount | grep "$mntpoint" | grep md${mdstart}$part > /dev/null && umount \ + $mntpoint +mdconfig -l | grep md$mdstart > /dev/null && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +echo "/dev/md${mdstart}$part $mntpoint ufs rw,userquota 2 2" >> \ + /etc/fstab +mount $mntpoint +edquota -u -f $mntpoint -e ${mntpoint}:850000:900000:130000:140000 root \ + > /dev/null 2>&1 +quotaon $mntpoint +sed -i -e "/md${mdstart}$part/d" /etc/fstab # clean up before any panics +export RUNDIR=$mntpoint/stressX +../testcases/rw/rw -t 2m -i 200 -h -n 2>/dev/null & +sleep 60 +false +while mount | grep -q $mntpoint; do + umount $([ $((`date '+%s'` % 2)) -eq 0 ] && echo "-f" || echo "") \ + $mntpoint > /dev/null 2>&1 +done +mdconfig -d -u $mdstart +rm -f $D +exit 0 diff --git a/tools/test/stress2/misc/quota5.sh b/tools/test/stress2/misc/quota5.sh new file mode 100755 index 000000000000..050ea4a822d9 --- /dev/null +++ b/tools/test/stress2/misc/quota5.sh @@ -0,0 +1,44 @@ +#!/bin/sh + +# +# Copyright (c) 2008-2011 Peter Holm +# All rights reserved. +# +# 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 +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 + +mount | grep -q "on /tmp (ufs," || exit 0 +if ! grep /tmp /etc/fstab | grep -q quota ; then + echo "Note: /tmp must have quota enabled for this test." + exit 0 +fi +edquota -u -f /tmp -e /tmp:1500000:1400000:200000:180000 $testuser +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" + +quotaoff /tmp diff --git a/tools/test/stress2/misc/quota6.sh b/tools/test/stress2/misc/quota6.sh new file mode 100755 index 000000000000..9cb3f5187f65 --- /dev/null +++ b/tools/test/stress2/misc/quota6.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 + +. ../default.cfg + +# Deadlock in umount(1) while out of disk space + +D=$diskimage +truncate -s 250M $D + +mount | grep $mntpoint | grep -q md${mdstart}$part && umount $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +export PATH_FSTAB=/tmp/fstab +echo "/dev/md${mdstart}$part $mntpoint ufs rw,userquota 2 2" > \ + $PATH_FSTAB +mount $mntpoint +edquota -u -f $mntpoint -e $mntpoint:850000:900000:130000:140000 root > \ + /dev/null 2>&1 +quotaon $mntpoint +export RUNDIR=$mntpoint/stressX +timeout 12m ../testcases/rw/rw -t 10m -i 200 -h -n & +pid=$! +for i in `jot 5`; do + echo "`date '+%T'` mksnap_ffs $mntpoint $mntpoint/.snap/snap$i" + mksnap_ffs $mntpoint $mntpoint/.snap/snap$i +done +for i in `jot 5`; do + rm -f $mntpoint/.snap/snap1 +done +kill $pid +wait +while mount | grep -q $mntpoint; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f $D $PATH_FSTAB +exit 0 diff --git a/tools/test/stress2/misc/quota7.sh b/tools/test/stress2/misc/quota7.sh new file mode 100755 index 000000000000..f098fceb0939 --- /dev/null +++ b/tools/test/stress2/misc/quota7.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Quota / snapshot test scenario by Kris@ +# Causes spin in ffs_sync or panic in panic: vfs_allocate_syncvnode: insmntque failed + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 + +. ../default.cfg + +D=$diskimage +trap "rm -f $D" 0 +dd if=/dev/zero of=$D bs=1m count=1k status=none + +mount | grep $mntpoint | grep -q md$mdstart && umount -f $mntpoint +mdconfig -l | grep -q md$mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +export PATH_FSTAB=/tmp/fstab +echo "/dev/md${mdstart}$part $mntpoint ufs rw,userquota 2 2" > $PATH_FSTAB +mount $mntpoint +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$(($1 / 21)) +export INODES=$(($2 / 21)) +export HOG=1 +export INCARNATIONS=40 + +export QK=$((KBLOCKS / 2)) +export QI=$((INODES / 2)) +edquota -u -f $mntpoint -e $mntpoint:$((QK - 50)):$QK:$((QI - 50 )):$QI $testuser +quotaon $mntpoint +export RUNDIR=$mntpoint/stressX +mkdir $mntpoint/stressX +chmod 777 $mntpoint/stressX +rm -rf /tmp/stressX.control/* +su $testuser -c "(cd ..;runRUNTIME=20m ./run.sh disk.cfg)"& # panic: vfs_allocate_syncvnode: insmntque failed +for i in `jot 20`; do + echo "`date '+%T'` mksnap_ffs $mntpoint $mntpoint/.snap/snap$i" + mksnap_ffs $mntpoint $mntpoint/.snap/snap$i + sleep 1 +done +i=$(($(date '+%S') % 20 + 1)) +echo "rm -f $mntpoint/.snap/snap$i" +rm -f $mntpoint/.snap/snap$i +wait + +while mount | grep -q $mntpoint; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f $D $PATH_FSTAB diff --git a/tools/test/stress2/misc/quota8.sh b/tools/test/stress2/misc/quota8.sh new file mode 100755 index 000000000000..a11418aba5d9 --- /dev/null +++ b/tools/test/stress2/misc/quota8.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. +# + +# Quota / snapshot test scenario by Kris@ +# Causes spin in ffs_sync or panic in panic: vfs_allocate_syncvnode: +# insmntque failed + +# "Fatal double fault" seen when compiling selected files +# with "-O0" on i386: +# https://people.freebsd.org/~pho/stress/log/quota8.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 + +. ../default.cfg + +D=$diskimage +trap "rm -f $D" 0 +dd if=/dev/zero of=$D bs=1m count=1k status=none || exit 1 + +mount | grep "$mntpoint" | grep -q md$mdstart && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +echo "/dev/md${mdstart}$part $mntpoint ufs rw,userquota 2 2" >> \ + /etc/fstab +mount $mntpoint +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$(($1 / 21)) +export INODES=$(($2 / 21)) +export HOG=1 +export INCARNATIONS=40 + +export QK=$((KBLOCKS / 2)) +export QI=$((INODES / 2)) +edquota -u -f $mntpoint -e ${mntpoint}:$((QK - 50)):$QK:$((QI - 50 )):$QI \ +$testuser +quotaon $mntpoint +sed -i -e "/md${mdstart}$part/d" /etc/fstab +export RUNDIR=$mntpoint/stressX +mkdir $mntpoint/stressX +chmod 777 $mntpoint/stressX +su $testuser -c 'sh -c "(cd ..;runRUNTIME=20m ./run.sh disk.cfg > \ + /dev/null 2>&1)"&' +for i in `jot 20`; do + echo "`date '+%T'` mksnap_ffs $mntpoint $mntpoint/.snap/snap$i" + mksnap_ffs $mntpoint $mntpoint/.snap/snap$i + sleep 1 +done +# Remove random snapshot file +i=$((`date +%S` % 20 + 1)) +echo "rm -f $mntpoint/.snap/snap$i" +rm -f $mntpoint/.snap/snap$i +wait + +su $testuser -c 'sh -c "../tools/killall.sh"' +while mount | grep -q $mntpoint; do + umount $([ $((`date '+%s'` % 2)) -eq 0 ] && echo "-f" || echo "") \ + $mntpoint > /dev/null 2>&1 +done +mdconfig -d -u $mdstart +exit 0 diff --git a/tools/test/stress2/misc/quota9.sh b/tools/test/stress2/misc/quota9.sh new file mode 100755 index 000000000000..01681bce8a01 --- /dev/null +++ b/tools/test/stress2/misc/quota9.sh @@ -0,0 +1,93 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 if quotacheck reports actual usage. + +. ../default.cfg + +export tmp=/tmp/$(basename $0).$$ +export D=$diskimage + +qc() { + local s + umount $1 + s=0 + quotacheck -v $1 > $tmp 2>&1 + grep -q fixed $tmp && { cat $tmp; s=1; } + mount $1 + return $s +} + +trap "rm -f $D $tmp" 0 +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ "`sysctl -in kern.features.ufs_quota`" != "1" ] && exit 0 + +dd if=/dev/zero of=$D bs=1m count=50 status=none || exit 1 + +mount | grep "$mntpoint" | grep -q md$mdstart && + umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t vnode -f $D -u $mdstart +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +export PATH_FSTAB=/tmp/fstab +echo "/dev/md${mdstart}$part $mntpoint ufs rw,userquota 2 2" \ + > $PATH_FSTAB +mount $mntpoint +mkdir $mntpoint/stressX +chown $testuser $mntpoint/stressX +set `df -ik $mntpoint | tail -1 | awk '{print $4,$7}'` +export KBLOCKS=$1 +export INODES=$2 + +export QK=$((KBLOCKS / 2)) +export QI=$((INODES / 2)) +edquota -u -f $mntpoint -e \ + ${mntpoint}:$((QK - 50)):$QK:$((QI - 50 )):$QI $testuser > \ + /dev/null 2>&1 +quotaon $mntpoint + +qc $mntpoint + +su $testuser -c ' + for i in `jot 20`; do + dd if=/dev/zero of=$mntpoint/stressX/d$i bs=1m count=1 \ + status=none + done + ' + +qc $mntpoint; s=$? + +while mount | grep -q $mntpoint; do + umount $([ $((`date '+%s'` % 2)) -eq 0 ] && + echo "-f" || echo "") $mntpoint > /dev/null 2>&1 +done +mdconfig -d -u $mdstart +rm -f $D $PATH_FSTAB +exit $s diff --git a/tools/test/stress2/misc/r335171.sh b/tools/test/stress2/misc/r335171.sh new file mode 100755 index 000000000000..2d2e9ad72fee --- /dev/null +++ b/tools/test/stress2/misc/r335171.sh @@ -0,0 +1,158 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2018 Dell EMC Isilon +# +# 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. +# + +# Handle the race between fork/vm_object_split() and faults. +# +# If fault started before vmspace_fork() locked the map, and then during +# fork, vm_map_copy_entry()->vm_object_split() is executed, it is +# possible that the fault instantiate the page into the original object +# when the page was already copied into the new object (see +# vm_map_split() for the orig/new objects terminology). This can happen +# if split found a busy page (e.g. from the fault) and slept dropping +# the objects lock, which allows the swap pager to instantiate +# read-behind pages for the fault. Then the restart of the scan can see +# a page in the scanned range, where it was already copied to the upper +# object. + +# No problems seen. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/template.c +mycc -o template -Wall -Wextra -O0 -g template.c || exit 1 +rm -f template.c +export MAXSWAPPCT=101 +(cd $odir/../testcases/swap; ./swap -t 5m -i 30 -l 100 -h) > /dev/null & +$dir/template > /dev/null +s=$? +[ -f template.core -a $s -eq 0 ] && + { ls -l template.core; mv template.core $dir; s=1; } +wait + +rm -rf $dir/template +exit $s +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; +static volatile char *cp; + +#define PARALLEL 16 +#define RUNTIME (5 * 60) +#define SYNC 0 + +static void +test(void) +{ + size_t len; + pid_t pid; + int i; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + usleep(200); + len = 1280 * PAGE_SIZE; + if ((cp = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + for (i = 0; i < (int)(len / sizeof(char)); i += PAGE_SIZE) + cp[i] = 1; + usleep(arc4random() % 500000); + if ((pid = fork()) == 0) { + usleep(arc4random() % 1000); + for (i = 0; i < (int)(len); i += PAGE_SIZE) + cp[i] = 2; + fprintf(stdout, ".\n"); fflush(stdout); + _exit(0); + } + if (pid == -1) + err(1, "fork()"); + for (i = 0; i < (int)(len / sizeof(char)); i += PAGE_SIZE) + cp[i] = 3; + if (waitpid(pid, NULL, 0) != pid) + err(1, "waitpid(%d)", pid); + + _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); +} diff --git a/tools/test/stress2/misc/racct.sh b/tools/test/stress2/misc/racct.sh new file mode 100755 index 000000000000..8249d7acf388 --- /dev/null +++ b/tools/test/stress2/misc/racct.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# Copyright (c) 2018 Dell EMC Isilon +# All rights reserved. +# +# 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 inspired by Andriy Gapon for Bug 222027 - panic on +# non-zero RACCT destroy. + +# "panic: destroying non-empty racct ..." seen. +# https://people.freebsd.org/~pho/stress/log/racct.txt +# "Page fault in slab_free_item()" seen: +# https://people.freebsd.org/~pho/stress/log/racct-2.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 +[ "`sysctl -in kern.racct.enable`" != "1" ] && + echo "Note: kern.racct.enable is disabled" +pgrep -Sq accounting || { service accounting onestart && started=1; } +(cd ../testcases/swap; ./swap -t 2m -i 5 -v -l 100) > /dev/null & +sleep .5 +start=`date +%s` +while [ $((`date +%s` - start)) -lt 120 ]; do + pids="" + for i in `jot 5`; do + for i in `jot 500`; do + exec su -c xuser -m root -c ':' & + done & + pids="$pids $!" + done + wait $pids + while [ `pgrep su | wc -l` -gt 100 ]; do sleep 1; done +done +wait +[ $started ] && service accounting onestop +exit 0 diff --git a/tools/test/stress2/misc/radix.sh b/tools/test/stress2/misc/radix.sh new file mode 100755 index 000000000000..4bca761c08b9 --- /dev/null +++ b/tools/test/stress2/misc/radix.sh @@ -0,0 +1,271 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Consume VM radix nodes + +# "panic: default pager with handle" seen with WiP kernel code. +# https://people.freebsd.org/~pho/stress/log/kostik1243.txt + +[ `sysctl vm.swap_total | sed 's/.* //'` -eq 0 ] && exit 0 + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/radix.c +mycc -o radix -Wall -Wextra radix.c || exit 1 +rm -f radix.c +cd $odir + +set -e +parallel=1 +usermem=`sysctl hw.usermem | sed 's/.* //'` +pagesize=`pagesize` +start=`date +%s` +while true; do + /tmp/radix $parallel > /tmp/radix.log 2>&1 + used=`awk '{print $4}' < /tmp/radix.log` + [ -z "$used" ] && break + [ $((`date +%s` - start)) -gt 300 ] && break + [ $used -gt $((usermem / pagesize)) ] && break + [ $parallel -eq 1 ] && + parallel=$((usermem / pagesize / used)) + parallel=$((parallel + 1)) + echo "`date +%T` parallel=$parallel" # XXX +done +cat /tmp/radix.log + +rm -f /tmp/radix #/tmp/radix.log +exit + +EOF +/* + On Wed, 17 Apr 2013 18:57:00 -0500 alc wrote: + + Suppose that I write a program for i386 that creates giant VM objects, + perhaps, using shm_open() + ftruncate(), and touches pages 0, 1, 8, 9, + 64, 65, 72, 73, 512, 513, 520, 521, 576, 577, 584, 585, 4096, 4097, + 4104, 4105, ... in each of the VM objects. (The sequence would be + different on amd64.) I could work around the 32-bit address space + limitation by mmap(2)ing and munmap(2)ing windows onto a VM object. + Each of the VM objects would have only one less interior node in the + radix tree than pages. If I create enough of these VM objects, then I + can consume all of the available pages and an almost equal number of + interior nodes. (Maybe it's worth writing this program so that some + experiments could be done?) +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __LP64__ +#define WIDTH 4 +#else +#define WIDTH 3 +#endif +#define N (int)howmany(sizeof(uint64_t) * NBBY, WIDTH) + +typedef uint64_t state_t[N]; + +static uint64_t pgs; +static int fds[2]; +static int parallel; +static volatile sig_atomic_t s1; +static int ps; + +static void +init(state_t state) +{ + int i; + + for (i = 0; i < N; i++) + state[i] = 0; +} + +static uint64_t +generator(state_t state) +{ + uint64_t value; + int i; + + value = 0; + for (i = 0; i < N; i++) + value += state[i] << (i * WIDTH); + for (i = 0; i < N; i++) + if (state[i] == 0) + break; + if (i < N) + state[i]++; + for (i--; i >= 0; i--) + state[i]--; + return (value); +} + +static int +wr(int fd, off_t pno) +{ + off_t len, offset; + void *p; + + offset = pno * ps; + len = ps; + p = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_NOSYNC, + fd, offset); + if (p == MAP_FAILED) { + if (errno == ENOMEM) + return (1); + err(1, "mmap(len 0x%jx, offset 0x%jx). %s:%d", len, offset, + __FILE__, __LINE__); + } + *(char *)p = 1; + pgs++; + + return (0); +} + +static void +handler(int s __unused) +{ + s1++; +} + +static void +ihandler(int s __unused) +{ + _exit(0); +} + +static int +radix(void) +{ + FILE *f; + int r; + + if ((f = popen("vmstat -z | grep RADIX | awk -F',' '{print $3}'", "r")) == NULL) + err(1, "popen"); + fscanf(f, "%d", &r); + pclose(f); + + return (r); +} + +static void +test(void) +{ + state_t state; + off_t offset; + int fd; + + signal(SIGHUP, ihandler); + for (;;) { + if (access("rendezvous", R_OK) == 0) + break; + usleep(2000); + } + + if ((fd = open("/dev/zero", O_RDWR)) == -1) + err(1, "open()"); + + init(state); + offset = generator(state); + do { + if (wr(fd, offset) != 0) + break; + offset = generator(state); + } while (offset != 0); + + if (write(fds[1], &pgs, sizeof(pgs)) != sizeof(pgs)) + err(1, "ewrite pipe"); + kill(getppid(), SIGHUP); + for (;;) + sleep(1); + close(fd); + + _exit(0); +} + +int +main(int argc, char **argv) +{ + uint64_t pages; + pid_t *pids; + int i, r1, r2, rfd; + + if (argc != 2) + errx(1, "Usage: %s .", argv[0]); + parallel = atoi(argv[1]); + + ps = getpagesize(); + signal(SIGHUP, handler); + unlink("rendezvous"); + pids = malloc(parallel * sizeof(pid_t)); + if (pipe(fds) == -1) + err(1, "pipe"); + r1 = radix(); + for (i = 0; i < parallel; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + if ((rfd = open("rendezvous", O_CREAT, 0644)) == -1) + err(1, "open()"); + close(rfd); + alarm(60); + while (s1 != parallel) + usleep(10000); + alarm(0); + r2 = radix(); + pages = 0; + for (i = 0; i < parallel; i++) { + kill(pids[i], SIGHUP); + if (read(fds[0], &pgs, sizeof(pgs)) != sizeof(pgs)) + err(1, "read pipe"); + pages += pgs; + } + fprintf(stderr, "A total of %jd pages (%.1f MB) touched, %d" + " RADIX nodes used, p/r = %.1f, parallel = %d.\n", + pages, pages * ps / 1024. / 1024, r2 - r1, + pages / (r2 - r1 + 0.), parallel); + + for (i = 0; i < parallel; i++) { + wait(NULL); + } + unlink("rendezvous"); + return (0); +} diff --git a/tools/test/stress2/misc/random.sh b/tools/test/stress2/misc/random.sh new file mode 100755 index 000000000000..04a0075d0c2c --- /dev/null +++ b/tools/test/stress2/misc/random.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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 regression test for short AES mode reads +# https://people.freebsd.org/~pho/stress/log/fsck-2.txt +# Fixed by r349176 + +for i in `jot 1024 1`; do + dd if=/dev/random of=/dev/null bs=$i count=1 status=none +done +exit 0 diff --git a/tools/test/stress2/misc/rdgsbase.sh b/tools/test/stress2/misc/rdgsbase.sh new file mode 100755 index 000000000000..66a44592d419 --- /dev/null +++ b/tools/test/stress2/misc/rdgsbase.sh @@ -0,0 +1,182 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2017 Konstantin Belousov +# +# 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 scenario for "D12023: Make WRFSBASE and WRGSBASE functional." + +[ `uname -m` = "amd64" ] || exit 0 + +. ../default.cfg + +cat > /tmp/rdgsbase.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void +hand(int i __unused) { /* handler */ + _exit(0); +} + +static void * +rungs(void *arg __unused) +{ + volatile char x[1024]; + unsigned i; + uint64_t y, oldbase; + + oldbase = rdgsbase(); + for (i = 0;;) { + wrgsbase((uintptr_t)&x[i]); + if (rdgsbase() != (uintptr_t)&x[i]) { + wrgsbase(oldbase); + printf("bug1 %lx %lx\n", rdgsbase(), (uintptr_t)&x[i]); + exit(1); + } + sysarch(AMD64_GET_GSBASE, &y); + if (y != (uintptr_t)&x[i]) { + wrgsbase(oldbase); + printf("bug2 %lx %lx\n", y, (uintptr_t)&x[i]); + exit(1); + } + i++; + if (i >= nitems(x)) + i = 0; + } + return (NULL); +} + +static void * +runfs(void *arg __unused) +{ + volatile char x[1024]; + unsigned i; + uint64_t y, oldbase; + + oldbase = rdfsbase(); + for (i = 0;;) { + wrfsbase((uintptr_t)&x[i]); + if (rdfsbase() != (uintptr_t)&x[i]) { + wrfsbase(oldbase); + printf("bug3 %lx %lx\n", rdfsbase(), (uintptr_t)&x[i]); + exit(1); + } + sysarch(AMD64_GET_FSBASE, &y); + if (y != (uintptr_t)&x[i]) { + wrfsbase(oldbase); + printf("bug4 %lx %lx\n", y, (uintptr_t)&x[i]); + exit(1); + } + i++; + if (i > nitems(x)) + i = 0; + } + return (NULL); +} + +static void +start(int nthreads) +{ + pthread_t thrs[nthreads * 2]; + int error, i; + + for (i = 0; i < nthreads; i++) { + error = pthread_create(&thrs[i], NULL, rungs, NULL); + if (error != 0) + errc(1, error, "pthread_create"); + } + for (; i < 2 * nthreads; i++) { + error = pthread_create(&thrs[i], NULL, runfs, NULL); + if (error != 0) + errc(1, error, "pthread_create"); + } +} + +int +main(void) +{ + static const int mib[2] = {CTL_HW, HW_NCPU}; + int error, nthreads; + u_int p[4]; + size_t len; + + do_cpuid(0, p); + if (p[0] < 0x7) { + fprintf(stderr, "CPU does not support extended functions\n"); + return (1); + } + cpuid_count(0x7, 0x0, p); + if ((p[1] & CPUID_STDEXT_FSGSBASE) == 0) { + fprintf(stderr, "CPU does not support RDGSBASE\n"); + return (0); + } + + len = sizeof(nthreads); + error = sysctl(mib, nitems(mib), &nthreads, &len, NULL, 0); + if (error == -1) + err(1, "sysctl hw.ncpu"); + signal(SIGALRM, hand); + alarm(10); + start(nthreads); + for (;;) + pause(); +} +EOF + +mycc -o /tmp/rdgsbase /tmp/rdgsbase.c -lpthread || exit 1 +rm /tmp/rdgsbase.c + +(cd /tmp; /tmp/rdgsbase) +s=$? + +rm -f /tmp/rdgsbase /tmp/rdgsbase.core +exit $s diff --git a/tools/test/stress2/misc/rdwr.sh b/tools/test/stress2/misc/rdwr.sh new file mode 100755 index 000000000000..c77c955dc210 --- /dev/null +++ b/tools/test/stress2/misc/rdwr.sh @@ -0,0 +1,118 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 with read/write length of INT_MAX (i386) or INT_MAX+1 (amd64) + +. ../default.cfg + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > rdwr.c +mycc -o rdwr -Wall rdwr.c || exit +rm -f rdwr.c + +oldclamp=`sysctl debug.devfs_iosize_max_clamp 2>/dev/null | + awk '{print $NF}'` +if [ `uname -m` = amd64 ]; then + [ "$oldclamp" = "1" ] && sysctl debug.devfs_iosize_max_clamp=0 +fi +for j in `jot 10`; do + /tmp/rdwr || { echo FAIL; break; } +done +if [ `uname -m` = amd64 ]; then + [ "$oldclamp" = "1" ] && sysctl debug.devfs_iosize_max_clamp=1 +fi + +rm -f /tmp/rdwr +exit +EOF +#include +#include +#include +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + int fd1, fd2; + size_t len; + void *p; + struct iovec iov; + + alarm(120); + if ((fd1 = open("/dev/null", O_RDWR, 0)) == -1) + err(1, "open /dev/null"); + + if ((fd2 = open("/dev/zero", O_RDWR)) == -1) + err(1, "open /dev/zero"); + + if (sizeof(size_t) == sizeof(int32_t)) + len = (size_t)INT_MAX; /* i386 */ + else + len = (size_t)INT_MAX + 1; /* amd64 */ + + if ((p = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd2, 0)) == + MAP_FAILED) + err(1, "mmap"); + + if (read(fd2, p, len) != len) + err(1, "read"); + + if (write(fd1, p, len) != len) + err(1, "write"); + + if (pread(fd2, p, len, 0) != len) + err(1, "pread"); + + if (pwrite(fd1, p, len, 0) != len) + err(1, "pwrite"); + + iov.iov_base = p; + iov.iov_len = len; + if (readv(fd2, &iov, 1) != len) + err(1, "readv"); + + if (writev(fd1, &iov, 1) != len) + err(1, "writev"); + + if (preadv(fd2, &iov, 1, 0) != len) + err(1, "preadv"); + + if (pwritev(fd1, &iov, 1, 0) != len) + err(1, "pwritev"); + + close(fd1); + close(fd2); + + return (0); +} diff --git a/tools/test/stress2/misc/readdir.sh b/tools/test/stress2/misc/readdir.sh new file mode 100755 index 000000000000..16523982d859 --- /dev/null +++ b/tools/test/stress2/misc/readdir.sh @@ -0,0 +1,179 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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. +# + +# readdir(3) fuzzing inspired by the iknowthis test suite +# by Tavis Ormandy + +# "panic: kmem_malloc(1328054272): kmem_map too small" seen + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > readdir.c +mycc -o readdir -Wall -Wextra readdir.c || exit 1 +rm -f readdir.c + +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)" +cp -a /usr/include $mntpoint +/tmp/readdir $mntpoint +umount $mntpoint + +echo "Testing fdescfs(5)" +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)" +mount -t procfs procfs $mntpoint +/tmp/readdir $mntpoint +umount $mntpoint + +if ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1; then + echo "Testing nfs" + mount -t nfs -o nfsv3,tcp,nolockd,retrycnt=3,soft,timeout=1 \ + $nfs_export $mntpoint + /tmp/readdir $mntpoint + umount $mntpoint +fi + +mdconfig -a -t swap -s 1g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +cp -a /usr/include $mntpoint +echo "Testing UFS" +/tmp/readdir $mntpoint +umount $mntpoint +mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +cp -a /usr/include $mntpoint +echo "Testing FFS" +/tmp/readdir $mntpoint +umount $mntpoint +mdconfig -d -u $mdstart + +mount -t nullfs /bin $mntpoint +echo "Testing nullfs(5)" +/tmp/readdir $mntpoint +umount $mntpoint + +rm -f /tmp/readdir +exit 0 +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RUNTIME 120 + +/* copy from /usr/src/lib/libc/gen/gen-private.h */ +struct _telldir; /* see telldir.h */ +struct pthread_mutex; + +/* + * Structure describing an open directory. + * + * NOTE. Change structure layout with care, at least dd_fd field has to + * remain unchanged to guarantee backward compatibility. + */ +struct _dirdesc { + int dd_fd; /* file descriptor associated with directory */ + long dd_loc; /* offset in current buffer */ + long dd_size; /* amount of data returned by getdirentries */ + char *dd_buf; /* data buffer */ + int dd_len; /* size of data buffer */ + long dd_seek; /* magic cookie returned by getdirentries */ + long dd_rewind; /* magic cookie for rewinding */ + int dd_flags; /* flags for readdir */ + struct pthread_mutex *dd_lock; /* lock */ + struct _telldir *dd_td; /* telldir position recording */ +}; +/* End copy */ + +static void +hand(int i __unused) { /* handler */ + _exit(1); +} + +static void +test(char *path) +{ + DIR *dirp, fuzz; + int i; + + signal(SIGSEGV, hand); + alarm(300); + for (i = 0; i < 2000; i++) { + if ((dirp = opendir(path)) == NULL) + break; + bcopy(dirp, &fuzz, sizeof(fuzz)); + fuzz.dd_len = arc4random(); + readdir(&fuzz); + closedir(dirp); + } + + _exit(0); +} + +int +main(int argc __unused, char **argv) +{ + time_t start; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if (fork() == 0) + test(argv[1]); + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/recursiveflushes.sh b/tools/test/stress2/misc/recursiveflushes.sh new file mode 100755 index 000000000000..1da843a2f1d1 --- /dev/null +++ b/tools/test/stress2/misc/recursiveflushes.sh @@ -0,0 +1,75 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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 recursive flushes in bdwrite(). + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +snap() { + for i in `jot 5`; do + mksnap_ffs $1 $2 + [ $? -eq 0 ] && break + done +} + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +old=`sysctl vfs.recursiveflushes | awk '{print $NF}'` +cd $mntpoint +rm -f $mntpoint/.snap/stress2.* +snap $mntpoint $mntpoint/.snap/stress2.1 +snap $mntpoint $mntpoint/.snap/stress2.2 +snap $mntpoint $mntpoint/.snap/stress2.3 +snap $mntpoint $mntpoint/.snap/stress2.4 +snap $mntpoint $mntpoint/.snap/stress2.5 + +for i in `jot 32`; do + # Create 32 Mb files + dd if=/dev/zero of=big.$i bs=16k count=2048 status=none +done +wait +for i in `jot 32`; do + rm -f big.$i +done + +rm -f $mntpoint/.snap/stress2.* +new=`sysctl vfs.recursiveflushes | awk '{print $NF}'` +[ $old != $new ] && echo "vfs.recursiveflushes changed from $old to $new" + +cd / +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/rename.sh b/tools/test/stress2/misc/rename.sh new file mode 100755 index 000000000000..93a1c9338ae4 --- /dev/null +++ b/tools/test/stress2/misc/rename.sh @@ -0,0 +1,130 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 race between ISDOTDOT lookups and directory removal/rename + +# With lookup_shared=1 rename() will fail from time to time with ENOENT and +# the following stat() will succed. + +# Test scenario by tegge + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > rename.c +mycc -o rename -Wall rename.c || exit 1 +rm -f rename.c + +rm -rf /tmp/rename.dir.* +for i in `jot 10`; do + for j in `jot 10`; do + /tmp/rename & + done + for j in `jot 10`; do + wait + done +done +rm -rf /tmp/rename.dir.* /tmp/rename +exit 0 +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define RUNTIME 30 + +static char dir1[128]; +static char dir2[128]; + +int +main(int argc, char **argv) +{ + time_t start; + int status; + struct stat sb; + pid_t p; + + sprintf(dir1, "rename.dir.%d", getpid()); + sprintf(dir2, "rename.dir.2.%d", getpid()); + if (mkdir(dir1, 0700) == -1) + err(1, "mkdir(%s)", dir1); + + if (chdir(dir1) == -1) + err(1, "chdir(%s)", dir1); + if ((p = fork()) == -1) + err(1, "fork()"); + if (p == 0) { + setproctitle("child"); + if (chdir("..") == -1) + err(1, "chdir(%s)", ".."); + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if (rename(dir1, dir2) == -1) { + warn("rename(%s, %s)", dir1, dir2); + stat(dir1, &sb); + if (stat(dir1, &sb) == -1) + err(1, "stat(%s)", dir1); + else + errx(1, "stat(%s) succeeded!", dir1); + } + if (rename(dir2, dir1) == -1) { + warn("rename(%s, %s)", dir2, dir1); + stat(dir2, &sb); + if (stat(dir2, &sb) == -1) + err(1, "stat(%s)", dir2); + else + errx(1, "stat(%s) succeeded!", dir2); + } + } + _exit(0); + } else { + setproctitle("parent"); + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if (stat("..", &sb) == -1) + err(1, "stat(..)"); + } + } + if (waitpid(p, &status, 0) == -1) + err(1, "waitpid()"); + if (chdir("..") == -1) + err(1, "chdir(%s)", ".."); + if (rmdir(dir1) == -1) + err(1, "rmdir(%s)", dir1); + + return (0); +} diff --git a/tools/test/stress2/misc/rename10.sh b/tools/test/stress2/misc/rename10.sh new file mode 100755 index 000000000000..5cbf39f3d3d2 --- /dev/null +++ b/tools/test/stress2/misc/rename10.sh @@ -0,0 +1,184 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 + +# Regression test for rename(2) problem with missing reference release of +# a busy "to" vnode, resulting in a leak. +# Fixed in r253998. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > rename10.c +mycc -o rename10 -Wall -Wextra -g -O2 rename10.c || exit 1 +rm -f rename10.c +cd $here + +mount | grep "on $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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +avail=`df -k $mntpoint | tail -1 | awk '{print $4}'` + +cd $mntpoint +/tmp/rename10; s=$? +cd $here + +for i in `jot 3`; do + sync + sleep 2 +done + +if [ `df -k $mntpoint | tail -1 | awk '{print $4}'` -lt $avail ]; then + echo FAIL + ls -ial $mntpoint + df -i $mntpoint +fi + +n=0 +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 + n=$((n + 1)) + [ $n -gt 5 ] && { umount -f $mntpoint; break; } +done + +checkfs /dev/md${mdstart}$part || s=$? +rm -f /tmp/rename10 +mdconfig -d -u $mdstart +exit $s +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PARALLEL 4 +#define SIZE (1 * 1024 * 1024) + +static char *logfile = "logfile"; +static char *oldfiles[] = { + "logfile.0", "logfile.1", "logfile.2", "logfile.3", "logfile.4" +}; + +void * +logger(void) +{ + int fd; + char * cp; + + setproctitle("logger"); + cp = calloc(1, SIZE); + for(;;) { + if ((fd = open(logfile, O_RDWR | O_APPEND)) != -1) { + if (write(fd, cp, SIZE) != SIZE) + err(1, "write()"); + close(fd); + } + usleep(1); + } + + _exit(0); +} + +void * +spin(void) +{ + int fd, i; + + setproctitle("spin"); + for(;;) { + for (i = 0; i < 5; i++) { + if ((fd = open(oldfiles[i], O_RDWR | O_APPEND)) != -1) + close(fd); + } + usleep(1); + } + _exit(0); +} + +void +renamer() +{ + int fd, i; + time_t start; + + setproctitle("renamer"); + start = time(NULL); + i = 0; + while (time(NULL) - start < 60) { + if ((fd = open(logfile, O_RDWR | O_CREAT | O_EXCL, 0644)) == -1) + err(1, "creat(%s)", logfile); + close(fd); + if (rename(logfile, oldfiles[i]) == -1) + err(1, "rename(%s, %s)", logfile, oldfiles[i]); + i = (i + 1) % 5; + } + for (i = 0; i < 5; i++) { + unlink(oldfiles[i]); + } + unlink(logfile); + +} + +int +main() { + pid_t pids[PARALLEL], spids[PARALLEL]; + int i; + + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + logger(); + if ((spids[i] = fork()) == 0) + spin(); + } + + renamer(); + + for (i = 0; i < PARALLEL; i++) { + if (kill(pids[i], SIGINT) == -1) + err(1, "kill(%d)", pids[i]); + if (kill(spids[i], SIGINT) == -1) + err(1, "kill(%d)", spids[i]); + } + for (i = 0; i < PARALLEL * 2; i++) + wait(NULL); + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/rename11.sh b/tools/test/stress2/misc/rename11.sh new file mode 100755 index 000000000000..19aaa16f92ea --- /dev/null +++ b/tools/test/stress2/misc/rename11.sh @@ -0,0 +1,139 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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 problem with "mkdir(d.008740.000987): Too many links" seen. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > rename11.c +mycc -o rename11 -Wall -Wextra rename11.c || exit 1 +rm -f rename11.c + +mount | grep "on $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 || exit 1 +bsdlabel -w md$mdstart auto + +[ $# -eq 1 ] && newfs_flags=$1 # Problem only seen with SU +echo newfs $newfs_flags md${mdstart}$part +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +mkdir $mntpoint/dir +( + cd $mntpoint/dir + /tmp/rename11 || echo FAIL +) + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done + +checkfs /dev/md${mdstart}$part; s=$? +mdconfig -d -u $mdstart +rm -rf /tmp/rename11 +exit $s +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define LOOPS 10 +#define PARALLEL 3 +#define ND 5000 + +static void +check(char *name) +{ + struct stat sb; + + if (stat(name, &sb) == -1) + warn("stat(%s)", name); + else + warnx("stat(%s) succeeded!", name); +} + +static void +dirs(void) +{ + pid_t pid; + int i, j; + char name[80], to[80]; + + pid = getpid(); + + for (j = 0; j < LOOPS; j++) { + for (i = 0; i < ND; i++) { + snprintf(name, sizeof(name), "d.%06d.%06d", pid, i); + if (mkdir(name, 0700) == -1) + err(1, "mkdir(%s)", name); + snprintf(to , sizeof(to ), "d2.%06d.%06d", pid, i); + if (rename(name, to) == -1) + warn("rename(%s, %s)", name, to); + if (rename(to, name) == -1) + warn("rename(%s, %s)", to, name); + if (rmdir(name) == -1) { + check(name); + err(1, "rmdir(%s)", name); + } + } + } + + _exit(0); +} + +int +main(void) +{ + int i, r, s; + + r = 0; + for (i = 0; i < PARALLEL; i++) { + if (fork() == 0) + dirs(); + } + + for (i = 0; i < PARALLEL; i++) { + wait(&s); + r += WEXITSTATUS(s); + } + + return (r); +} diff --git a/tools/test/stress2/misc/rename12.sh b/tools/test/stress2/misc/rename12.sh new file mode 100755 index 000000000000..3000e59b70d3 --- /dev/null +++ b/tools/test/stress2/misc/rename12.sh @@ -0,0 +1,192 @@ +#!/bin/sh + +# +# Copyright (c) 2013 EMC Corp. +# All rights reserved. +# +# 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. +# + +# No problems seen with SU. Panics with SU+J, just like suj30.sh + +# Triggers "known LOR in SU code" when crossmp8.sh is run first: +# https://people.freebsd.org/~pho/stress/log/rename12.txt. + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > rename12.c +mycc -o rename12 -Wall -Wextra rename12.c || exit 1 +rm -f rename12.c + +mount | grep "on $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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +inodes=`df -i $mntpoint | tail -1 | awk '{print $7}'` +loops=4 +parallel=12 +timeout=1200 +start=`date '+%s'` +for i in `jot $loops`; do + for j in `jot $parallel`; do + mkdir -p $mntpoint/d$j/dir1 + mkdir -p $mntpoint/d$j/dir2 + (cd $mntpoint/d$j; /tmp/rename12 $((inodes/parallel)) ) & + done + wait + for j in `jot $parallel`; do + rmdir $mntpoint/d$j/dir1 + rmdir $mntpoint/d$j/dir2 + done + [ $((`date '+%s'` - start)) -lt $timeout ] && break +done + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done + +checkfs /dev/md${mdstart}$part; s=$? +mdconfig -d -u $mdstart +rm -rf /tmp/rename12 +exit $s +EOF +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +pid_t crpid; +long n; +int mvpipe[2], rmpipe[2]; + +void +cr(void) +{ + pid_t pid; + int i; + char name[80]; + + setproctitle("cr"); + pid = getpid(); + usleep(arc4random() & 1000); + for (i = 0; i < n; i++) { + snprintf(name, sizeof(name), "dir1/d.%06d.%06d", pid, i); + if (mkdir(name, 0700) == -1) + err(1, "mkdir(%s). %s:%d", name, __FILE__, __LINE__); + if (write(mvpipe[1], &i, sizeof(i)) != sizeof(i)) + err(1, "write mvpipe"); + } + + _exit(0); +} + +void +mv(void) +{ + pid_t pid; + int i; + char name[80], to[80]; + + setproctitle("mv"); + pid = crpid; + i = 0; + while (i != n - 1 && + read(mvpipe[0], &i, sizeof(i)) == sizeof(i)) { + snprintf(name, sizeof(name), "dir1/d.%06d.%06d", pid, i); + snprintf(to , sizeof(to ), "dir2/d.%06d.%06d", pid, i); + if (rename(name, to) == -1) + warn("rename(%s, %s)", name, to); + if (write(rmpipe[1], &i, sizeof(i)) != sizeof(i)) + err(1, "write rmpipe"); + } + _exit(0); +} + +void +rm(void) +{ + pid_t pid; + int i; + char to[80]; + + setproctitle("rm"); + pid = crpid; + i = 0; + while (i != n - 1 && + read(rmpipe[0], &i, sizeof(i)) == sizeof(i)) { + snprintf(to, sizeof(to ), "dir2/d.%06d.%06d", pid, i); + if (rmdir(to) == -1) + warn("rmdir(%s)", to); + } + _exit(0); +} + +int +main(int argc, char **argv) +{ + int r, s; + + if (argc != 2) + errx(1, "Usage %s ", argv[0]); + n = atol(argv[1]); + if (n > 32765) { + n = 32765 - 1; + } + + if (pipe(mvpipe) == -1) + err(1, "pipe()"); + if (pipe(rmpipe) == -1) + err(1, "pipe()"); + + r = 0; + if ((crpid = fork()) == 0) + cr(); + if (fork() == 0) + mv(); + if (fork() == 0) + rm(); + + wait(&s); + r += WEXITSTATUS(s); + wait(&s); + r += WEXITSTATUS(s); + wait(&s); + r += WEXITSTATUS(s); + + return (r); +} diff --git a/tools/test/stress2/misc/rename13.sh b/tools/test/stress2/misc/rename13.sh new file mode 100755 index 000000000000..9234d4454751 --- /dev/null +++ b/tools/test/stress2/misc/rename13.sh @@ -0,0 +1,60 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 crossmp scenario: +# Bug 216380 - mv /[dir == mountpoint] causes kernel panic +# "panic: No vop_rename(0xfffff80033049000, 0xfffffe104d1e48a8)" seen. +# Fixed by r312645. + +# Test scenario by: fnacl@protonmail.com + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep -q "on $mntpoint " && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 512m -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +s=0 +to=/tmp/rename13.dir +mkdir $to +mv $mntpoint $to 2>/dev/null && s=1 + +for i in `jot 10`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint || sleep 1 +done +mount | grep -q "on $mntpoint " && { s=2; umount -f $mntpoint; } +mdconfig -d -u $mdstart +rm -rf $to +exit $s diff --git a/tools/test/stress2/misc/rename14.sh b/tools/test/stress2/misc/rename14.sh new file mode 100755 index 000000000000..83612a2632df --- /dev/null +++ b/tools/test/stress2/misc/rename14.sh @@ -0,0 +1,198 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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: handle_workitem_remove: DIRCHG and worklist not empty." seen: +# https://people.freebsd.org/~pho/stress/log/rename14.txt +# Fixed by r356714 + +# Based on a syzkaller scenario reported by tuexen@freebsd.org + +. ../default.cfg +[ `id -u` -ne 0 ] && echo "Must be root!" && exit 1 + +dir=/tmp +odir=`pwd` +cd $dir +sed -e '1,/^EOF/d' < $odir/$0 > $dir/rename14.c +mycc -o rename14 -Wall -Wextra -O0 -g rename14.c -lpthread || exit 1 +rm -f rename14.c +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 +[ `jot -r 1 0 1` -eq 1 ] && opt="-U -n" || opt="-j -n" +newfs -j -n md$mdstart > /dev/null +mount /dev/md$mdstart $mntpoint +set +e + +s=0 +(cd /mnt; /tmp/rename14) +[ -f rename14.core -a $s -eq 0 ] && + { ls -l rename14.core; mv rename14.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 +checkfs /dev/md$mdstart || s=2 +mdconfig -d -u $mdstart +rm -rf $dir/rename14 +exit $s + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static sig_atomic_t done_testing; +static volatile u_int *share; + +#define PARALLEL 10 +#define RUNTIME (3 * 60) +#define SYNC 0 + +static void * +t1(void *data __unused) +{ + char n1[80]; + + snprintf(n1, sizeof(n1), "file1.%d", getpid()); + while (done_testing == 0) { + rmdir(n1); + usleep(50000); + } + + return (NULL); +} + +static void * +t2(void *data __unused) +{ + time_t start; + char n0[80], n00[80], n1[80]; + + snprintf(n0, sizeof(n0), "file0.%d", getpid()); + snprintf(n00, sizeof(n00), "file0.%d/file0", getpid()); + snprintf(n1, sizeof(n1), "file1.%d", getpid()); + if (mkdir(n0, 0) == -1) + err(1, "mkdir(%s)", n0); + + start = time(NULL); + while (time(NULL) - start < 60) { + if (mkdir(n00, 0) == -1) + err(1, "mkdir(%s)", n00); + if (rename(n00, n1) == -1) + err(1, "rename(i%s, %s)", n00, n1); + } + if (rmdir(n0) == -1) + err(1, "rmdir(%s)", n0); + done_testing = 1; + + return (NULL); +} + +static void +test(void) +{ + pthread_t tid[2]; + int r; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + done_testing = 0; + 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"); + + _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); +} diff --git a/tools/test/stress2/misc/rename15.sh b/tools/test/stress2/misc/rename15.sh new file mode 100755 index 000000000000..aa884e045010 --- /dev/null +++ b/tools/test/stress2/misc/rename15.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2020 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. +# + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +# "panic: flush_newblk_dep: Bad newblk 0xfffff8015fd9e800" seen: +# https://people.freebsd.org/~pho/stress/log/rename15.txt + +. ../default.cfg + +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 +fl=$newfs_flags +fl='-j' +[ $fl = "-U" -a `jot -r 1 0 1` -eq 1 ] && fl="-j" +echo "newfs $fl md$mdstart" +newfs $fl md$mdstart > /dev/null +mount /dev/md$mdstart $mntpoint +chmod 777 $mntpoint + +export LOAD=80 +export MAXSWAPPCT=80 +export RUNDIR=$mntpoint/stressX +export dirnprenameLOAD=100 +export dirrenameLOAD=100 +export renameLOAD=100 +export runRUNTIME=10m +export rwLOAD=80 +export TESTPROGS=' +testcases/lockf2/lockf2 +testcases/symlink/symlink +testcases/openat/openat +testcases/rw/rw +testcases/fts/fts +testcases/link/link +testcases/creat/creat +testcases/mkdir/mkdir +testcases/rename/rename +testcases/swap/swap +testcases/dirnprename/dirnprename +testcases/dirrename/dirrename +' + +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' + +../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 +checkfs /dev/md$mdstart; s=$? +mdconfig -d -u $mdstart +exit $s diff --git a/tools/test/stress2/misc/rename2.sh b/tools/test/stress2/misc/rename2.sh new file mode 100755 index 000000000000..2c9781602d2c --- /dev/null +++ b/tools/test/stress2/misc/rename2.sh @@ -0,0 +1,103 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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. +# + +# With lookup_shared=1 rename() will fail from time to time with ENOENT and +# the following stat() will succeed. (Variation of rename.sh) + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > rename2.c +mycc -o rename2 -Wall rename2.c || exit 1 +rm -f rename2.c +cd $here + +rm -rf /tmp/rename.dir.* +start=`date +%s` +while [ $((`date +%s` - start -lt 300 ]; do + for j in `jot 10`; do + /tmp/rename2 & + done + wait +done +rm -rf /tmp/rename.dir.* /tmp/rename2 +exit 0 +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char dir1[128]; +static char dir2[128]; + +int +main(int argc, char **argv) +{ + struct stat sb; + time_t start; + + sprintf(dir1, "/tmp/rename.dir.%d", getpid()); + sprintf(dir2, "/tmp/rename.dir.2.%d", getpid()); + if (mkdir(dir1, 0700) == -1) + err(1, "mkdir(%s)", dir1); + + if (chdir(dir1) == -1) + err(1, "chdir(%s)", dir1); + if (chdir("..") == -1) + err(1, "chdir(%s)", ".."); + + start = time(NULL); + while ((time(NULL) - start) < 120) { + if (rename(dir1, dir2) == -1) { + warn("rename(%s, %s)", dir1, dir2); + if (stat(dir1, &sb) == -1) + err(1, "stat(%s)", dir1); + else + errx(1, "stat(%s) succeeded!", dir1); + } + if (rename(dir2, dir1) == -1) { + warn("rename(%s, %s)", dir2, dir1); + if (stat(dir2, &sb) == -1) + err(1, "stat(%s)", dir2); + else + errx(1, "stat(%s) succeeded!", dir2); + } + } + + if (rmdir(dir1) == -1) + err(1, "rmdir(%s)", dir1); + + return (0); +} diff --git a/tools/test/stress2/misc/rename3.sh b/tools/test/stress2/misc/rename3.sh new file mode 100755 index 000000000000..c7ce91f0d359 --- /dev/null +++ b/tools/test/stress2/misc/rename3.sh @@ -0,0 +1,51 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 vulnerability to transient failures when a directory closer +# to the root directory is renamed + +# Deadlocks seen: +# https://people.freebsd.org/~pho/stress/log/kostik447.txt +# https://people.freebsd.org/~pho/stress/log/kirk058.txt + +# Test scenario by Tor Egge + +root=/tmp +for i in `jot 10000`; 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 + cd $root/a/b/c/d/e/f + ( mv $root/a/b/c $root/a/c ) & + if ! mv z g/z; then + echo "FAILURE at loop $i" + break + fi + wait +done +rm -rf $root/a diff --git a/tools/test/stress2/misc/rename4.sh b/tools/test/stress2/misc/rename4.sh new file mode 100755 index 000000000000..1a8b1e0046e8 --- /dev/null +++ b/tools/test/stress2/misc/rename4.sh @@ -0,0 +1,62 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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. +# + +# lookup() does not return error when lookup of path ending on "/." is done +# for RENAME operation. + +# Tets scenario by Jim Meyering + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > rename4.c +mycc -o rename4 -Wall rename4.c +rm -f rename4.c +cd $RUNDIR + +rm -rf 1 2 +mkdir 1 2 + +/tmp/rename4 1 2/. + +rm -rf 1 2 /tmp/rename4 +exit +EOF +#include +#include + +int +main(int argc, char **argv) +{ + if (rename(argv[1], argv[2]) == -1) + err(1, "rename(%s, %s)", argv[1], argv[2]); + + return (0); +} diff --git a/tools/test/stress2/misc/rename5.sh b/tools/test/stress2/misc/rename5.sh new file mode 100755 index 000000000000..89779b79ec32 --- /dev/null +++ b/tools/test/stress2/misc/rename5.sh @@ -0,0 +1,137 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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 scenario from kern/156545 by Konstantin, +# konstantin malov kaspersky com + +# On 8.2-STABLE fsck reports +# "xxx IS AN EXTRANEOUS HARD LINK TO DIRECTORY yyy" +# Fixed by r220986 + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +. ../default.cfg + +mount | grep -q "$mntpoint" && umount $mntpoint +mdconfig -l | grep -q $mdstart && mdconfig -d -u $mdstart + +mdconfig -a -t swap -s 1g -u $mdstart +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > rename5.c +mycc -o rename5 -Wall -Wextra -O2 rename5.c +rm -f rename5.c + +cd $mntpoint + +/tmp/rename5 + +cd $here +rm -f /tmp/rename5 + +while mount | grep -q md${mdstart}$part; do + umount $mntpoint || sleep 1 +done + +checkfs /dev/md${mdstart}$part; s=$? + +mdconfig -d -u $mdstart +exit $s +EOF +#include +#include + +#include +#include +#include +#include +#include +#include + +#define N 1000 +#define RUNTIME (5 * 60) + +void +test(void) +{ + pid_t pid; + int i; + char from[128], to[128]; + + pid = getpid(); + for (i = 0; i < N; i++) { + snprintf(from, sizeof(from), "src/dir.%06d", i); + snprintf(to , sizeof(to), "src/dir.%06d.%06d", i, pid); + (void)rename(from, to); + } + _exit(0); +} + +int +main() +{ + time_t start; + int fd, i; + char dir[128], file[128]; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + if (mkdir("src", 0700) == -1) + err(1, "mkdir(src)"); + + for (i = 0; i < N; i++) { + snprintf(dir, sizeof(dir), "src/dir.%06d", i); + if (mkdir(dir, 0700) == -1) + err(1, "mkdir(%s)", dir); + snprintf(file, sizeof(file), "%s/meta", dir); + if ((fd = open(file, O_RDWR | O_CREAT, 0600)) < 0) + err(1, "open(%s)", file); + close(fd); + snprintf(file, sizeof(file), "%s/data", dir); + if ((fd = open(file, O_RDWR | O_CREAT, 0600)) < 0) + err(1, "open(%s)", file); + close(fd); + } + + for (i = 0; i < 2; i++) { + if (fork() == 0) + test(); + } + for (i = 0; i < 2; i++) + wait(NULL); + + system("rm -rf src > /dev/null 2>&1"); + } + + return (0); +} diff --git a/tools/test/stress2/misc/rename6.sh b/tools/test/stress2/misc/rename6.sh new file mode 100755 index 000000000000..6c27c5601d2a --- /dev/null +++ b/tools/test/stress2/misc/rename6.sh @@ -0,0 +1,149 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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 + +# Demonstrate rename(2) cache problem, where the original name lingers in the VFS cache. + +# Original test scenario by Anton Yuzhaninov + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > rename6.c +mycc -o rename6 -Wall -Wextra -O2 rename6.c +rm -f rename6.c +cd $here + +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +su $testuser -c "cd $mntpoint; /tmp/rename6" + +while mount | grep -q md${mdstart}$part; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/rename6 +exit +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +pid_t spid; +const char *logfile = "test.log"; + +void +cleanup() +{ + if (kill(spid, SIGINT) == -1 && errno != ESRCH) + err(1, "kill(%d)", spid); +} + +static void +Stat() +{ + struct stat sb; + int i; + + setproctitle("Stat"); + for (;;) { + for (i = 0; i < 1000; i++) { + stat(logfile, &sb); + } + usleep(1000); + } +} + +int +main(void) +{ + struct stat sb1, sb2; + int fd, i; + char new[128]; + + if ((spid = fork()) == 0) + Stat(); + + setproctitle("main"); + atexit(cleanup); + for (i = 0; i < 20000; i++) { + sprintf(new, "test.log.%05d", i); + if ((fd = open(logfile, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1) + err(1, "creat(%s)", logfile); + close(fd); +#if 1 + if (rename(logfile, new) == -1) + warn("rename(%s, %s)", logfile, new); +#else + /* No cache problem is seen */ + if (link(logfile, new) == -1) + err(1, "link(%s, %s)", logfile, new); + if (unlink(logfile) == -1) + err(1, "unlink(%s)", logfile); +#endif + /* + * stat() for logfile and new will be identical sometimes, + * but only when Stat() is running. + */ + if (stat(logfile, &sb1) == 0 && stat(new, &sb2) == 0 && + bcmp(&sb1, &sb2, sizeof(sb1)) == 0) { + fprintf(stderr, "At loop #%d\n", i); + fprintf(stderr, "%-15s: ino = %ju, nlink = %ju," + " size = %jd\n", logfile, (uintmax_t)sb1.st_ino, + (uintmax_t)sb1.st_nlink, sb1.st_blocks); + fprintf(stderr, "%-15s: ino = %ju, nlink = %ju, " + "size = %jd\n", new , (uintmax_t)sb2.st_ino, + (uintmax_t)sb2.st_nlink, sb2.st_blocks); + } + unlink(new); + } + + kill(spid, SIGINT); + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/rename7.sh b/tools/test/stress2/misc/rename7.sh new file mode 100755 index 000000000000..89edcd17e827 --- /dev/null +++ b/tools/test/stress2/misc/rename7.sh @@ -0,0 +1,150 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 + +# After a few runs this will happen: +# $ umount /mnt +# umount: unmount of /mnt failed: Device busy +# $ umount -f /mnt +# $ + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > rename7.c +mycc -o rename7 -Wall -Wextra -O2 rename7.c || exit +rm -f rename7.c +cd $here + +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +su $testuser -c "cd $mntpoint; /tmp/rename7 || echo FAIL" + +for i in `jot 10`; do + mount | grep -q md${mdstart}$part && \ + umount $mntpoint && mdconfig -d -u $mdstart && break +done +if mount | grep -q md${mdstart}$part; then + echo "Test failed" + exit 1 +fi +rm -f /tmp/rename7 +exit 0 +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char *logfile = "test.log"; +pid_t wpid, spid; + +void +r1(void) +{ + int i; + struct stat sb1, sb2; + + for (i = 0; i < 800000; i++) { + rename(logfile, "r1"); + if (stat("r1", &sb1) == 0 && stat("r2", &sb2) == 0 && + bcmp(&sb1, &sb2, sizeof(sb1)) == 0) { + fprintf(stderr, "r1 and r2 are identical after rename(%s, \"r1\")\n", logfile); + system("ls -ail"); + _exit(1); + } + } + _exit(0); +} + +void +r2(void) +{ + int i; + struct stat sb1, sb2; + +// _exit(0); /* No problems with only r1 running */ + for (i = 0; i < 800000; i++) { + rename(logfile, "r2"); + if (stat("r1", &sb1) == 0 && stat("r2", &sb2) == 0 && + bcmp(&sb1, &sb2, sizeof(sb1)) == 0) { + usleep(10000); + fprintf(stderr, "r1 and r2 are identical after rename(%s, \"r2\")\n", logfile); + system("ls -ail"); + _exit(1); + } + } + _exit(0); +} +int +main(void) +{ + pid_t wpid, spid; + int e, fd, i, status; + + if ((wpid = fork()) == 0) + r1(); + if ((spid = fork()) == 0) + r2(); + + setproctitle("main"); + e = 0; + + for (i = 0; i < 800000; i++) { + if ((fd = open(logfile, O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1) + warn("creat(%s)", logfile); + close(fd); + } + + kill(wpid, SIGINT); + kill(spid, SIGINT); + wait(&status); + e += WEXITSTATUS(status); + wait(&status); + e += WEXITSTATUS(status); + + return (e); +} diff --git a/tools/test/stress2/misc/rename8.sh b/tools/test/stress2/misc/rename8.sh new file mode 100755 index 000000000000..e0019cb353fa --- /dev/null +++ b/tools/test/stress2/misc/rename8.sh @@ -0,0 +1,173 @@ +#!/bin/sh + +# +# Copyright (c) 2011 Peter Holm +# All rights reserved. +# +# 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 + +# Cache inconsistency seen on "to" file for rename(2). + +# Scenario by jhb@ + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > rename8.c +mycc -o rename8 -Wall -Wextra -O2 rename8.c +rm -f rename8.c +cd $here + +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +su $testuser -c "cd $mntpoint; mkdir r; /tmp/rename8 r" +ls -li $mntpoint/r | egrep -v "^total" + +for i in `jot 10`; do + mount | grep -q md${mdstart}$part && \ + umount $mntpoint && mdconfig -d -u $mdstart && break + sleep 1 +done +if mount | grep -q md${mdstart}$part; then + fuser $mntpoint + echo "umount $mntpoint failed" + exit 1 +fi + +mdconfig -l | grep -q md$mdstart && + mdconfig -d -u $mdstart +rm -f /tmp/rename8 +exit +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char *always, *file1, *file2; +static ino_t always_ino; + +static void +usage(void) +{ + fprintf(stderr, "Usage: rename_race \n"); + exit(1); +} + +static void +child(void) +{ + struct stat sb; + + /* Exit as soon as our parent exits. */ + while (getppid() != 1) { + stat(file1, &sb); + } + exit(0); +} + +static void +create_file(const char *path) +{ + int fd; + + fd = open(path, O_CREAT, 0666); + if (fd < 0) + err(1, "open(%s)", path); + close(fd); +} + +int +main(int ac, char **av) +{ + struct stat sb, sb2; + pid_t pid; + int i, r; + + if (ac != 2) + usage(); + if (stat(av[1], &sb) != 0) + err(1, "stat(%s)", av[1]); + if (!S_ISDIR(sb.st_mode)) + errx(1, "%s not a directory", av[1]); + + asprintf(&always, "%s/file.always", av[1]); + asprintf(&file1, "%s/file1", av[1]); + asprintf(&file2, "%s/file2", av[1]); + + create_file(always); + if (stat(always, &sb) != 0) + err(1, "stat(%s)", always); + always_ino = sb.st_ino; + + pid = fork(); + if (pid < 0) + err(1, "fork"); + if (pid == 0) + child(); + r = 0; + for (i = 0; i < 100000; i++) { + if (unlink(file1) < 0 && errno != ENOENT) + err(1, "unlink(%s)", file1); + if (link(always, file1) < 0) + err(1, "link(%s, %s)", always, file1); + create_file(file2); + if (stat(file2, &sb2) < 0) + err(1, "stat(%s)", file2); + if (rename(file2, file1) < 0) + err(1, "rename(%s, %s)", file2, file1); + if (stat(file1, &sb) < 0) + err(1, "stat(%s)", file1); + if (sb.st_ino != sb2.st_ino || + sb.st_ino == always_ino) { + printf("FAIL. Bad stat: always: %ju file1: %ju (should be %ju)\n", + (uintmax_t)always_ino, (uintmax_t)sb.st_ino, + (uintmax_t)sb2.st_ino); + r = EXIT_FAILURE; + break; + } + } + kill(pid, SIGINT); + wait(NULL); + if (r == 0) { + unlink(always); + unlink(file1); + unlink(file2); + } + return (r); +} diff --git a/tools/test/stress2/misc/rename9.sh b/tools/test/stress2/misc/rename9.sh new file mode 100755 index 000000000000..e169c64af5ea --- /dev/null +++ b/tools/test/stress2/misc/rename9.sh @@ -0,0 +1,169 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 + +# Variation of rename6.sh. Cache problem of "to" file name seen. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > rename9.c +mycc -o rename9 -Wall -Wextra -O2 rename9.c +rm -f rename9.c +cd $here + +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 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +rm -rf $mntpoint/.snap +chmod 777 $mntpoint + +(while true; do ls -lRi $mntpoint > /dev/null 2>&1; done) & +su $testuser -c "cd $mntpoint; /tmp/rename9" +kill $! > /dev/null 2>&1 +wait +ls -ilR $mntpoint | egrep -v "^total " + +while mount | grep -q md${mdstart}$part; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/rename9 +exit +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +pid_t spid; +char *fromFile = "fromFile.log"; +char toFile[128]; + +void +cleanup() +{ + kill(spid, SIGINT); +} + +static void +statFrom() +{ + struct stat sb; + + setproctitle("Stat"); + for (;;) { + stat(fromFile, &sb); + } +} + +int +main(void) +{ + struct stat fb, tb, fa, ta; + int fd, i; + + if ((spid = fork()) == 0) + statFrom(); + + setproctitle("main"); + atexit(cleanup); + for (i = 0;i < 100000; i++) { + bzero(&fb, sizeof(fb)); + bzero(&tb, sizeof(tb)); + bzero(&fa, sizeof(fa)); + bzero(&ta, sizeof(ta)); + + if ((fd = open(fromFile, O_RDWR | O_CREAT | O_TRUNC, 0644)) + == -1) + err(1, "creat(%s)", fromFile); + close(fd); + + sprintf(toFile, "toFile.log.%05d", i); + if ((fd = open(toFile, O_RDWR | O_CREAT | O_TRUNC, 0644)) + == -1) + err(1, "creat(%s)", toFile); + write(fd, "xxx", 3); + close(fd); + + stat(fromFile, &fb); + stat(toFile, &tb); + if (rename(fromFile, toFile) == -1) + warn("rename(%s, %s)", fromFile, toFile); + stat(fromFile, &fa); + if (stat(toFile, &ta) == -1) + err(1, "stat(%s)", toFile); + + if (tb.st_ino == ta.st_ino) { + fprintf(stderr, "FAIL: old and new \"To\" inode " + "number is identical\n"); + fprintf(stderr, "stat() before the rename():\n"); + fprintf(stderr, + "%-16s: ino = %4ju, nlink = %ju, size = %jd\n", + fromFile, (uintmax_t)fb.st_ino, (uintmax_t)fb.st_nlink, + fb.st_blocks); + fprintf(stderr, + "%-16s: ino = %4ju, nlink = %ju, size = %jd\n", + toFile, (uintmax_t)tb.st_ino, (uintmax_t)tb.st_nlink, + tb.st_blocks); + fprintf(stderr, "\nstat() after the rename():\n"); + if (fa.st_ino != 0) + fprintf(stderr, + "%-16s: ino = %4ju, nlink = %ju, size = " + "%jd\n", fromFile, (uintmax_t)fa.st_ino, + (uintmax_t)fa.st_nlink, fa.st_blocks); + fprintf(stderr, + "%-16s: ino = %4ju, nlink = %ju, size = %jd\n", + toFile, (uintmax_t)ta.st_ino, (uintmax_t)ta.st_nlink, + ta.st_blocks); + kill(spid, SIGINT); + exit(1); + } + unlink(toFile); + } + + kill(spid, SIGINT); + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/revoke.sh b/tools/test/stress2/misc/revoke.sh new file mode 100755 index 000000000000..453cbc1001a5 --- /dev/null +++ b/tools/test/stress2/misc/revoke.sh @@ -0,0 +1,116 @@ +#!/bin/sh + +# +# Copyright (c) 2008 Peter Holm +# All rights reserved. +# +# 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. Causes panic on 6.1 + +. ../default.cfg + +odir=`pwd` +dir=/tmp + +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/revoke.c +mycc -o revoke -Wall revoke.c || exit 1 +rm -f revoke.c + +n=100 # Number of times to test +for i in `jot $n`; do + ./revoke /dev/ttyv9 > /dev/null 2>&1 & + ./revoke /dev/ttyva > /dev/null 2>&1 & + ./revoke /dev/ttyvb > /dev/null 2>&1 & + ./revoke /dev/ttyvc > /dev/null 2>&1 & + wait +done + +rm -f revoke + +exit +EOF +/* By Martin Blapp, */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/*#define TTY "/dev/ttyv9"*/ /* should be totally unused */ +#define CTTY "/dev/tty" + +int +main(int argc, char **argv) +{ + int ttyfd; + pid_t pid; + + if (argc != 2) { + fprintf(stderr, "Usage: %s /dev/ttyv?\n", argv[0]); + return 1; + } + + /* Get rid of my ctty. */ + printf("Parent starting: pid %d\n", getpid()); + pid = fork(); + if (pid < 0) { + err(1, "fork"); + exit(1); + } else if (pid > 0) { + int status; + /* parent */ + waitpid(pid, &status, 0); + exit(0); + } + /* child */ + printf("Child: pid %d\n", getpid()); + + if (setsid() < 0) { + err(1, "setsid"); + exit(1); + } + ttyfd = open(argv[1], O_RDWR); + if (ttyfd < 0) { + err(1, "open(%s)", argv[1]); + exit(1); + } + if (ioctl(ttyfd, TIOCSCTTY) < 0) { + err(1, "ioctl(TIOCSCTTY)"); + exit(1); + } + if (revoke(argv[1]) < 0) { + err(1, "revoke(%s)", argv[1]); + exit(1); + } + if (open(CTTY, O_RDWR) < 0) { + err(1, "open(%s)", CTTY); + exit(1); + } + return 0; +} diff --git a/tools/test/stress2/misc/rot.sh b/tools/test/stress2/misc/rot.sh new file mode 100755 index 000000000000..b658f35aad1b --- /dev/null +++ b/tools/test/stress2/misc/rot.sh @@ -0,0 +1,142 @@ +#!/bin/sh + +# +# Copyright (c) 2012 Peter Holm +# All rights reserved. +# +# 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 + +# Unmapped I/O test scenario: +# http://people.freebsd.org/~pho/stress/log/kostik515.txt + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > rot.c +mycc -o rot -Wall -Wextra -O2 -g rot.c || exit 1 +rm -f rot.c +cd $here + +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +(cd $mntpoint; /tmp/rot) +(cd `dirname $diskimage`; /tmp/rot) + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart +rm -f /tmp/rot +exit 0 +EOF +#include +#include +#include +#include +#include +#include +#include +#include + +#define N 10240 /* 40 Mb */ +#define PARALLEL 20 +#define RUNTIME (60 * 15) + +int +test(void) +{ + int fd, i, j, s; + unsigned char *buf; + char path[128]; + + s = getpagesize(); + + sprintf(path,"%s.%05d", getprogname(), getpid()); + if ((fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) + err(1, "open(%s)", path); + if (lseek(fd, s * N - 1, SEEK_SET) == -1) + err(1, "lseek error"); + + /* write a dummy byte at the last location */ + if (write(fd, "", 1) != 1) + err(1, "write error"); + + for (i = 0; i < N; i++) { + if ((buf = mmap(0, s, PROT_READ | PROT_WRITE, MAP_SHARED, fd, + i * s)) == MAP_FAILED) + err(1, "write map"); + for (j = 0; j < s; j++) + buf[j] = i % 256; + } + if (munmap(buf, s) == -1) + err(1, "unmap (write)"); + close(fd); + + if ((fd = open(path, O_RDONLY)) < 0) + err(1, "open(%s)", path); + for (i = 0; i < N; i++) { + if ((buf = mmap(0, s, PROT_READ, MAP_SHARED, fd, i * s)) == + MAP_FAILED) + err(1, "write map"); + for (j = 0; j < s; j++) + if (buf[j] != i % 256) + fprintf(stderr, "read %d, expected %d at %d\n", + buf[j], i % 256, i); + } + if (munmap(buf, s) == -1) + err(1, "unmap (read)"); + close(fd); + unlink(path); + + _exit(0); +} + +int +main(void) +{ + time_t start; + int i; + + start = time(NULL); + while (time(NULL) - start < RUNTIME) { + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + test(); + for (i = 0; i < PARALLEL; i++) + wait(NULL); + } + + return(0); +} diff --git a/tools/test/stress2/misc/routetbl.sh b/tools/test/stress2/misc/routetbl.sh new file mode 100755 index 000000000000..0a2b936f15e4 --- /dev/null +++ b/tools/test/stress2/misc/routetbl.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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 memory leak of routetbl allegedly caused by use free() in +# vfs_free_addrlist_af(), instead of rn_detachhead(). +# "routetbl grew 3868" seen on amd64. + +. ../default.cfg +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +pgrep -q mountd || exit 0 +mount | grep "on $mntpoint " | grep -q /dev/md && umount -f $mntpoint +[ -c /dev/md$mdstart ] && mdconfig -d -u $mdstart +mdconfig -a -t swap -s 128m -u $mdstart || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null + +routetbl=`vmstat -m | grep routetbl | awk '{print $2}'` +s=0 +start=`date +%s` +while [ $((`date +%s` - start)) -lt 60 ]; do + mount /dev/md${mdstart}$part $mntpoint && + umount $mntpoint +done +routetbl=$((`vmstat -m | grep routetbl | awk '{print $2}'` - routetbl)) +[ $routetbl -gt 0 ] && + { echo "routetbl grew $routetbl"; s=1; } + +for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && exit 1 +mdconfig -d -u $mdstart +rm -rf /tmp/template +exit $s diff --git a/tools/test/stress2/misc/ruby.sh b/tools/test/stress2/misc/ruby.sh new file mode 100755 index 000000000000..2ed1b023d0ec --- /dev/null +++ b/tools/test/stress2/misc/ruby.sh @@ -0,0 +1,38 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# "small MAP_STACK requests" scenario. + +# "
    : warning: pthread_create failed for timer: Resource temporarily +# unavailable, scheduling broken" seen. +# Fixed by r320339. + +[ -x "`which ruby`" ] || exit 0 + +ruby -v 2>&1 | tee $log | grep warning && s=1 || s=0 +exit $s diff --git a/tools/test/stress2/misc/rw.sh b/tools/test/stress2/misc/rw.sh new file mode 100755 index 000000000000..2cba9587c925 --- /dev/null +++ b/tools/test/stress2/misc/rw.sh @@ -0,0 +1,65 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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 + +# Simple read / write test scenario with VM pressure. + +# Out of VM seen: +# 100135 D vmwait 0xffffffff81d1a348 [CAM taskq] +# https://people.freebsd.org/~pho/stress/log/rw.txt + +. ../default.cfg + +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 || exit 1 +bsdlabel -w md$mdstart auto + +newfs $newfs_flags md${mdstart}$part > /dev/null + +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +export runRUNTIME=10m +export RUNDIR=$mntpoint/stressX + +export rwLOAD=100 +export swapLOAD=100 +export TESTPROGS=" +testcases/rw/rw +testcases/swap/swap +" + +su $testuser -c 'cd ..; ./testcases/run/run $TESTPROGS' + +while mount | grep "on $mntpoint " | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +mdconfig -d -u $mdstart diff --git a/tools/test/stress2/misc/rwlock_ronly.sh b/tools/test/stress2/misc/rwlock_ronly.sh new file mode 100755 index 000000000000..4a9b761ad98e --- /dev/null +++ b/tools/test/stress2/misc/rwlock_ronly.sh @@ -0,0 +1,82 @@ +#!/bin/sh + +# +# Copyright (c) 2013 Peter Holm +# All rights reserved. +# +# 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 scenario by kib@ +# Demonstrate process looping in kernel mode. +# Fixed in r251684. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/rwlock_ronly.c +mycc -o rwlock_ronly -Wall -Wextra rwlock_ronly.c || exit 1 +rm -f rwlock_ronly.c +cd $odir + +/tmp/rwlock_ronly || echo OK + +rm -f /tmp/rwlock_ronly +exit + +EOF +/* $Id: rwlock_ronly.c,v 1.2 2013/06/10 04:44:08 kostik Exp kostik $ */ + +#include +#include +#include +#include +#include +#include + +int +main(void) +{ + char *p; + struct urwlock *rw; + int error; + + p = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANON, -1, 0); + if (p == (char *)MAP_FAILED) + err(1, "mmap"); + + rw = (struct urwlock *)p; + rw->rw_state = URWLOCK_READ_WAITERS; + + error = mprotect(p, getpagesize(), PROT_READ); + if (error == -1) + err(1, "mprotect"); + + error = _umtx_op(p, UMTX_OP_RW_RDLOCK, 0, NULL, NULL); + if (error != 0) + err(1, "rdlock"); + + return (0); +} diff --git a/tools/test/stress2/misc/sched.sh b/tools/test/stress2/misc/sched.sh new file mode 100755 index 000000000000..f91055b3c289 --- /dev/null +++ b/tools/test/stress2/misc/sched.sh @@ -0,0 +1,161 @@ +#!/bin/sh + +# +# Copyright (c) 2014 EMC Corp. +# All rights reserved. +# +# 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 + +# Show scheduler fairness for ULE vs. 4BSD. + +. ../default.cfg + +here=`pwd` +cd /tmp +sed '1,/^EOF/d' < $here/$0 > sched.c +mycc -o sched -Wall -Wextra -O0 sched.c || exit 1 +rm -f sched.c +cd $here + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint +chmod 777 $mntpoint + +cpus=`sysctl hw.ncpu | sed 's/.*: //'` +uname -v +(cd $mntpoint; /tmp/sched $((cpus + 1))) > /dev/null 2>&1 & +sleep 30 +export LANG=C +top -U nobody -d 1 | grep nobody | awk '{print $11}' | sed 's/%//' | + ministat -A -w 73 | tail -1 | awk '{if ($NF > 1.0) exit 1}' || +{ echo Broken; top -U nobody -d 1 | grep nobody; } +killall sched +wait + +for i in `jot 3`; do + echo "run #$i" + (cd $mntpoint; /tmp/sched $((cpus + 1))) +done + +while mount | grep $mntpoint | grep -q /dev/md; do + umount $mntpoint || sleep 1 +done +rm -f /tmp/sched +mdconfig -d -u $mdstart +exit +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define N 100 * 1024 * 1024 + +double r; +int parallel; + +void +work(void) +{ + struct passwd *pw; + struct timespec start, finish; + double d1, d2; + int i, j; + volatile char *cp; + + while (access("rendezvous", R_OK) != 0) + usleep(1); + + if ((pw = getpwnam("nobody")) == NULL) + err(1, "no such user: nobody"); + 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(); + + d1 = d2 = 0; + cp = malloc(N); + clock_gettime(CLOCK_REALTIME_PRECISE, &start); + for (i = 0; i < 1; i++) { + for (j = 0; j < INT_MAX; j++) { + d1 = d1 + 1.0 / j; + d2 = d1 + 0.8 / j; + if (j % 1000 == 0) { + cp[arc4random() % N] = j % 255; + } + } + } + r = d1 + d2; + clock_gettime(CLOCK_REALTIME_PRECISE, &finish); + timespecsub(&finish, &start, &finish); +#if defined(DEBUG) + fprintf(stderr, "Elapsed time for pid %d: %.4f\n", getpid(), + finish.tv_sec + (double)finish.tv_nsec / 1e9); +#endif + + _exit(0); +} + +int +main(int argc, char **argv) +{ + int fd, i; + + if (argc == 2) + parallel = atoi(argv[1]); + else + errx(1, "Usage: %s ", argv[0]); + + for (i = 0; i < parallel; i++) { + if (fork() == 0) + work(); + } + if ((fd = open("rendezvous", O_CREAT, 0644)) == -1) + err(1, "open()"); + close(fd); + for (i = 0; i < parallel; i++) + wait(NULL); + + return (0); +} diff --git a/tools/test/stress2/misc/schedfuzz.sh b/tools/test/stress2/misc/schedfuzz.sh new file mode 100755 index 000000000000..c1a7918cc4fb --- /dev/null +++ b/tools/test/stress2/misc/schedfuzz.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# Sched fuzz test scenario. + +# "panic: sleeping thread" seen: +# https://people.freebsd.org/~pho/stress/log/schedfuzz.txt + +[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 + +sysctl kern.sched_fuzz.prof_on > /dev/null 2>&1 || exit 0 + +: ${pct1:=0.01} +: ${pct2:=0.1} +export pct1 pct2 + +seton() { + sysctl kern.sched_fuzz.sched_fuzz_scheduler="${pct1}%return(1)" + sysctl kern.sched_fuzz.sched_fuzz_sx_slock_delay="${pct1}%schedfuzz(82)" + sysctl kern.sched_fuzz.sched_fuzz_sx_xlock_delay="${pct1}%schedfuzz(82)" + sysctl kern.sched_fuzz.sched_fuzz_sx_slock_sleep="${pct1}%schedfuzz(82)" + sysctl kern.sched_fuzz.sched_fuzz_sx_xlock_sleep="${pct1}%schedfuzz(82)" + sysctl kern.sched_fuzz.sched_fuzz_mtx_spin_lock="${pct1}%schedfuzz(44)" + sysctl kern.sched_fuzz.sched_fuzz_mtx_spin_unlock="${pct1}%schedfuzz(44)" + sysctl kern.sched_fuzz.sched_fuzz_malloc="${pct1}%schedfuzz(62)" + sysctl kern.sched_fuzz.sched_fuzz_cv_wait="${pct2}%schedfuzz(100)" + sysctl kern.sched_fuzz.sched_fuzz_cv_timed_wait="${pct2}%schedfuzz(100)" + sysctl kern.sched_fuzz.sched_fuzz_cv_timed_wait_sig="${pct2}%schedfuzz(100)" + sysctl kern.sched_fuzz.sched_fuzz_mtx_lock="${pct1}%schedfuzz(22)" + sysctl kern.sched_fuzz.sched_fuzz_mtx_unlock="${pct1}%schedfuzz(22)" + sysctl kern.sched_fuzz.sched_fuzz_sleepq="${pct1}%schedfuzz(150)" + + sysctl kern.sched_fuzz.prof_on=1 +} + +setoff() { + sysctl kern.sched_fuzz.prof_on=0 +} + +if [ $# -eq 1 ]; then + case "$1" in + on) seton + ;; + off) setoff + ;; + *) echo "Usage: $0 [on|off]" + exit 1 + ;; + esac +else + seton + ./procfs.sh + setoff +fi diff --git a/tools/test/stress2/misc/sctp.sh b/tools/test/stress2/misc/sctp.sh new file mode 100755 index 000000000000..7e28deb5b300 --- /dev/null +++ b/tools/test/stress2/misc/sctp.sh @@ -0,0 +1,158 @@ +#!/bin/sh + +# Based on https://gist.github.com/zonque/7d03568eab14a2bb57cb by +# Daniel Mack github@zonque.org + +# "panic: general protection fault" seen: +# https://people.freebsd.org/~pho/stress/log/sctp.txt +# Fixed by r350626 + +kldstat -v | grep -q sctp || kldload sctp.ko +cat > /tmp/sctp.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int my_port_num; + +static void +die(const char *s) +{ + perror(s); + exit(1); +} + + static void +server(void) +{ + struct sctp_sndrcvinfo sndrcvinfo; + struct sockaddr_in servaddr = { + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(INADDR_ANY), + .sin_port = htons(my_port_num), + }; + struct sctp_initmsg initmsg = { + .sinit_num_ostreams = 5, + .sinit_max_instreams = 5, + .sinit_max_attempts = 4, + }; + int listen_fd, conn_fd, flags, ret, in; + + listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + if (listen_fd < 0) + die("socket"); + + ret = bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + if (ret < 0) + die("bind"); + + ret = setsockopt(listen_fd, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, + sizeof(initmsg)); + if (ret < 0) + die("setsockopt"); + + ret = listen(listen_fd, initmsg.sinit_max_instreams); + if (ret < 0) + die("listen"); + + for (;;) { + char buffer[1024]; + + printf("Waiting for connection\n"); + fflush(stdout); + + conn_fd = accept(listen_fd, (struct sockaddr *) NULL, NULL); + if(conn_fd < 0) + die("accept()"); + + printf("New client connected\n"); + fflush(stdout); + + /* Note that flags is uninitialized here */ + in = sctp_recvmsg(conn_fd, buffer, sizeof(buffer), NULL, 0, + &sndrcvinfo, &flags); + if (in > 0) { + printf("Received data: %s\n", buffer); + fflush(stdout); + } + + close(conn_fd); + } +} + +static void +client(void) +{ + struct sockaddr_in servaddr = { + .sin_family = AF_INET, + .sin_port = htons(my_port_num), + .sin_addr.s_addr = inet_addr("127.0.0.1"), + }; + int conn_fd, ret; + const char *msg = "Hello, Server!"; + + conn_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + if (conn_fd < 0) + die("socket()"); + + ret = connect(conn_fd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + if (ret < 0) + die("connect()"); + + ret = sctp_sendmsg(conn_fd, (void *) msg, strlen(msg) + 1, NULL, 0, 0, 0, 0, 0, 0 ); + if (ret < 0) + die("sctp_sendmsg"); + + close(conn_fd); +} + +int +main(int argc __unused, char *argv[]) +{ + + my_port_num = atoi(argv[1]); + if (strstr(basename(argv[0]), "server")) + server(); + else + client(); + + return (0); +} +EOF + +cc -o /tmp/server -Wall -Wextra -O2 /tmp/sctp.c || exit +ln -sf /tmp/server /tmp/client + +parallel=100 +for i in `jot $parallel 62324`; do + /tmp/server $i > /dev/null & +done +(cd ../testcases/swap; ./swap -t 1m -i 20 -l 100) & +sleep 2 + +start=`date +%s` +while [ $((`date +%s` - start)) -lt 60 ]; do + pids= + for i in `jot 50`; do + for j in `jot $parallel 62324`; do + /tmp/client $j & + pids="$pids $!" + done + done + for i in $pids; do + wait $i + done +done +pkill server +wait +while pkill swap; do :; done +wait +rm -f /tmp/sctp.c /tmp/server /tmp/client +exit 0 diff --git a/tools/test/stress2/misc/sctp2.sh b/tools/test/stress2/misc/sctp2.sh new file mode 100755 index 000000000000..45727e03c206 --- /dev/null +++ b/tools/test/stress2/misc/sctp2.sh @@ -0,0 +1,169 @@ +#!/bin/sh + +# Based on https://gist.github.com/zonque/7d03568eab14a2bb57cb by +# Daniel Mack github@zonque.org + +# Modified version of sctp.sh by Michael Tuexen : +# * Use loopback as the address of the server on both side initialized using +# htonl(INADDR_LOOPBACK). +# * Negotiate only 1 stream in both directions since only one stream is used. +# * Don't use initmsg.sinit_max_instreams as an argument in listen(), which +# does not make sense. +# Use an arbitrary positive integer, 5 in this case. +# * Initialize flags before calling sctp_recvmsg(). + +# "panic: Don't own TCB lock" seen: +# https://people.freebsd.org/~pho/stress/log/sctp2.txt + +# "panic: soclose: SS_NOFDREF on enter" seen: +# https://people.freebsd.org/~pho/stress/log/sctp2-2.txt + +kldstat -v | grep -q sctp || kldload sctp.ko +cat > /tmp/sctp2.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int my_port_num; + +static void +die(const char *s) +{ + perror(s); + exit(1); +} + +static void +server(void) +{ + struct sctp_sndrcvinfo sndrcvinfo; + struct sockaddr_in servaddr = { + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(INADDR_LOOPBACK), + .sin_port = htons(my_port_num), + }; + struct sctp_initmsg initmsg = { + .sinit_num_ostreams = 1, + .sinit_max_instreams = 1, + .sinit_max_attempts = 4, + }; + int listen_fd, conn_fd, flags, ret, in; + + listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + if (listen_fd < 0) + die("socket"); + + ret = bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + if (ret < 0) + die("bind"); + + ret = setsockopt(listen_fd, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, + sizeof(initmsg)); + if (ret < 0) + die("setsockopt"); + + ret = listen(listen_fd, 5); + if (ret < 0) + die("listen"); + + for (;;) { + char buffer[1024]; + + printf("Waiting for connection\n"); + fflush(stdout); + + conn_fd = accept(listen_fd, (struct sockaddr *) NULL, NULL); + if(conn_fd < 0) + die("accept()"); + + printf("New client connected\n"); + fflush(stdout); + + flags = 0; + in = sctp_recvmsg(conn_fd, buffer, sizeof(buffer), NULL, 0, + &sndrcvinfo, &flags); + if (in > 0) { + printf("Received data: %s\n", buffer); + fflush(stdout); + } + + close(conn_fd); + } +} + +static void +client(void) +{ + struct sockaddr_in servaddr = { + .sin_family = AF_INET, + .sin_port = htons(my_port_num), + .sin_addr.s_addr = htonl(INADDR_LOOPBACK), + }; + int conn_fd, ret; + const char *msg = "Hello, Server!"; + + conn_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + if (conn_fd < 0) + die("socket()"); + + ret = connect(conn_fd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + if (ret < 0) + die("connect()"); + + ret = sctp_sendmsg(conn_fd, (void *) msg, strlen(msg) + 1, NULL, 0, 0, 0, 0, 0, 0 ); + if (ret < 0) + die("sctp_sendmsg"); + + close(conn_fd); +} + +int +main(int argc __unused, char *argv[]) +{ + + my_port_num = atoi(argv[1]); + if (strstr(basename(argv[0]), "server")) + server(); + else + client(); + + return (0); +} +EOF + +cc -o /tmp/server -Wall -Wextra -O2 /tmp/sctp2.c || exit +ln -sf /tmp/server /tmp/client + +parallel=100 +for i in `jot $parallel 62324`; do + /tmp/server $i > /dev/null & +done +(cd ../testcases/swap; ./swap -t 1m -i 20 -l 100) & +sleep 2 + +start=`date +%s` +while [ $((`date +%s` - start)) -lt 60 ]; do + pids= + for i in `jot 50`; do + for j in `jot $parallel 62324`; do + /tmp/client $j & + pids="$pids $!" + done + done + for i in $pids; do + wait $i + done +done +pkill server +wait +while pkill swap; do :; done +wait +rm -f /tmp/sctp2.c /tmp/server /tmp/client +exit 0 diff --git a/tools/test/stress2/misc/sctp3.sh b/tools/test/stress2/misc/sctp3.sh new file mode 100755 index 000000000000..74017bb5194f --- /dev/null +++ b/tools/test/stress2/misc/sctp3.sh @@ -0,0 +1,172 @@ +#!/bin/sh + +# Based on https://gist.github.com/zonque/7d03568eab14a2bb57cb by +# Daniel Mack github@zonque.org + +# Modified version of sctp.sh by Michael Tuexen : +# Basically it is the first test without calling sctp_recvmsg() on +# the server side and the required cleanups to avoid unused variables. +# This program triggers pretty quickly the "Queues are not empty when +# handling SHUTDOWN-COMPLETE" panic. This happened "by accident" with +# the original sctp.sh, if the flags argument contained the value +# MSG_DONTWAIT and sctp_recvmsg() returned -1 indicating EAGAIN. This +# way no successful sctp_recvmsg() call happened. + +# "panic: Queues are not empty when handling SHUTDOWN-COMPLETE" seen. + +kldstat -v | grep -q sctp || kldload sctp.ko +cat > /tmp/sctp3.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int my_port_num; + +static void +die(const char *s) +{ + perror(s); + exit(1); +} + +static void +server(void) +{ +#if 0 + struct sctp_sndrcvinfo sndrcvinfo; +#endif + struct sockaddr_in servaddr = { + .sin_family = AF_INET, + .sin_addr.s_addr = htonl(INADDR_LOOPBACK), + .sin_port = htons(my_port_num), + }; + struct sctp_initmsg initmsg = { + .sinit_num_ostreams = 1, + .sinit_max_instreams = 1, + .sinit_max_attempts = 4, + }; + int listen_fd, conn_fd, ret; +#if 0 + int flags, in; +#endif + + listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + if (listen_fd < 0) + die("socket"); + + ret = bind(listen_fd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + if (ret < 0) + die("bind"); + + ret = setsockopt(listen_fd, IPPROTO_SCTP, SCTP_INITMSG, &initmsg, + sizeof(initmsg)); + if (ret < 0) + die("setsockopt"); + + ret = listen(listen_fd, 5); + if (ret < 0) + die("listen"); + + for (;;) { +#if 0 + char buffer[1024]; +#endif + printf("Waiting for connection\n"); + fflush(stdout); + + conn_fd = accept(listen_fd, (struct sockaddr *) NULL, NULL); + if(conn_fd < 0) + die("accept()"); + + printf("New client connected\n"); + fflush(stdout); + +#if 0 + flags = 0; + in = sctp_recvmsg(conn_fd, buffer, sizeof(buffer), NULL, 0, + &sndrcvinfo, &flags); + if (in > 0) { + printf("Received data: %s\n", buffer); + fflush(stdout); + } +#endif + close(conn_fd); + } +} + +static void +client(void) +{ + struct sockaddr_in servaddr = { + .sin_family = AF_INET, + .sin_port = htons(my_port_num), + .sin_addr.s_addr = htonl(INADDR_LOOPBACK), + }; + int conn_fd, ret; + const char *msg = "Hello, Server!"; + + conn_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_SCTP); + if (conn_fd < 0) + die("socket()"); + + ret = connect(conn_fd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + if (ret < 0) + die("connect()"); + + ret = sctp_sendmsg(conn_fd, (void *) msg, strlen(msg) + 1, NULL, 0, 0, 0, 0, 0, 0 ); + if (ret < 0) + die("sctp_sendmsg"); + + close(conn_fd); +} + +int +main(int argc __unused, char *argv[]) +{ + + my_port_num = atoi(argv[1]); + if (strstr(basename(argv[0]), "server")) + server(); + else + client(); + + return (0); +} +EOF + +cc -o /tmp/server -Wall -Wextra -O2 /tmp/sctp3.c || exit +ln -sf /tmp/server /tmp/client + +parallel=100 +for i in `jot $parallel 62324`; do + /tmp/server $i > /dev/null & +done +(cd ../testcases/swap; ./swap -t 1m -i 20 -l 100) & +sleep 2 + +start=`date +%s` +while [ $((`date +%s` - start)) -lt 60 ]; do + pids= + for i in `jot 50`; do + for j in `jot $parallel 62324`; do + /tmp/client $j & + pids="$pids $!" + done + done + for i in $pids; do + wait $i + done +done +pkill server +wait +while pkill swap; do :; done +wait +rm -f /tmp/sctp3.c /tmp/server /tmp/client +exit 0 diff --git a/tools/test/stress2/misc/seekdir.sh b/tools/test/stress2/misc/seekdir.sh new file mode 100755 index 000000000000..a6f3a3a6d19f --- /dev/null +++ b/tools/test/stress2/misc/seekdir.sh @@ -0,0 +1,157 @@ +#!/bin/sh + +# A regression test for seekdir/telldir +# submitted by julian@freebsd.org +# https://reviews.freebsd.org/D2410. +# Fixed by r282485 + +. ../default.cfg + +odir=`pwd` +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > seekdir.c +rm -f /tmp/seekdir +mycc -o seekdir -O2 seekdir.c || exit 1 +rm -f seekdir.c +cd $odir + +mount | grep -q "$mntpoint " && umount -f $mntpoint +mount -o size=1g -t tmpfs tmpfs $mntpoint + +cd $mntpoint +mkdir test2 +/tmp/seekdir > /dev/null +[ `echo $mntpoint/test2/* | wc -w` -eq 1 ] || + { echo FAIL; status=1; } +cd $odir + +while mount | grep $mntpoint | grep -q tmpfs; do + umount $mntpoint || sleep 1 +done +rm -f /tmp/seekdir +exit $status +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define CHUNKSIZE 5 +#define TOTALFILES 40 + +static void +SeekDir(DIR *dirp, long loc) +{ + printf("Seeking back to location %ld\n", loc); + seekdir(dirp, loc); +} + +static long +TellDir(DIR *dirp) +{ + long loc; + + loc = telldir(dirp); + printf("telldir assigned location %ld\n", loc); + return (loc); +} + +int +main(int argc, char *argv[]) +{ + DIR *dirp; + int i; + int j; + long offset = 0, prev_offset = 0; + char *files[100]; + char filename[100]; + int fd; + struct dirent *dp = NULL; + + if (chdir("./test2") != 0) { + err(EX_OSERR, "chdir"); + } + + /*****************************************************/ + /* Put a set of sample files in the target directory */ + /*****************************************************/ + + for (i=1; i < TOTALFILES ; i++) + { + sprintf(filename, "file-%d", i); + fd = open(filename, O_CREAT, 0666); + if (fd == -1) { + err(EX_OSERR, "open"); + } + close(fd); + } + dirp = opendir("."); + offset = TellDir(dirp); + for (i = 0; i < 20; i++) + files[i] = malloc(20); + + /*******************************************************/ + /* enumerate and delete small sets of files, one group */ + /* at a time. */ + /*******************************************************/ + do { + + /*****************************************/ + /* Read in up to CHUNKSIZE file names */ + /* i will be the number of files we hold */ + /*****************************************/ + for (i = 0; i < CHUNKSIZE; i++) { + if ((dp = readdir(dirp)) != NULL) { + strcpy(files[i], dp->d_name); + + printf("readdir (%ld) returned file %s\n", + offset, files[i]); + + prev_offset = offset; + offset = TellDir(dirp); + + } else { + printf("readdir returned null\n"); + break; + } + } + +/****************************************************************/ + /* Simuate the last entry not fitting into our (samba's) buffer */ + /* If we read someting in on the last slot, push it back */ + /* Pretend it didn't fit. This is approximately what SAMBA does.*/ +/****************************************************************/ + if (dp != NULL) { + /* Step back */ + SeekDir(dirp, prev_offset); + offset = TellDir(dirp); + i--; + printf("file %s returned\n", files[i]); + } + + /*****************************************/ + /* i is the number of names we have left.*/ + /* Delete them. */ + /*****************************************/ + for (j = 0; j < i; j++) { + if (*files[j] == '.') { + printf ("skipping %s\n", files[j]); + } else { + printf("Unlinking file %s\n", files[j]); + if (unlink(files[j]) != 0) { + err(EX_OSERR, "unlink"); + } + } + } + } while (dp != NULL); + + closedir(dirp); + //chdir(".."); + +} diff --git a/tools/test/stress2/misc/segnp.sh b/tools/test/stress2/misc/segnp.sh new file mode 100755 index 000000000000..3dbe91e04550 --- /dev/null +++ b/tools/test/stress2/misc/segnp.sh @@ -0,0 +1,57 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2017 Konstantin Belousov +# +# 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. +# + +# Trigger a SIGSEGV/SIGBUS _not_ caused by an access to the unmapped page. + +uname -a | egrep -q "i386|amd64" || exit 0 +. ../default.cfg + +cat > /tmp/segnp.c < + +int +main(void) +{ + + __asm __volatile ("movw %w0,%%ds\n" : : "q" (0x1117) : "memory"); + printf("Huh ?\n"); +} +EOF +mycc -o /tmp/segnp -Wall -Wextra -O2 /tmp/segnp.c || exit 1 +rm /tmp/segnp.c + +echo "expect: Bus error (core dumped)" +(cd /tmp; /tmp/segnp) +s=$? +[ $s -ne 138 ] && { echo "Expected 138, got $s", exit 1; } + +rm /tmp/segnp /tmp/segnp.core +exit 0 diff --git a/tools/test/stress2/misc/segregs.sh b/tools/test/stress2/misc/segregs.sh new file mode 100755 index 000000000000..0ecc3565546a --- /dev/null +++ b/tools/test/stress2/misc/segregs.sh @@ -0,0 +1,144 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2017 Konstantin Belousov +# +# 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. +# + +# Maxime Villard spotted this problem: +# Issue with segment registers on freebsd-i386 + +# Fixed in r323722 + +[ `uname -m` = "i386" ] || exit 0 + +. ../default.cfg + +cat > /tmp/mvillard_nest.c < +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int b, s; + +static void * +dealloc_ldt(void *arg __unused) +{ + u_int sl; + + for (;;) { + while (atomic_load_acq_int(&b) == 0) + ; + sl = s; + s = 0; + if (sl != 0) + i386_set_ldt(sl, NULL, 1); + atomic_store_rel_int(&b, 0); + } + return (NULL); +} + +static void +func(void) +{ + union descriptor desc; + u_int sel, sl; + + bzero(&desc, sizeof(desc)); + desc.sd.sd_type = SDT_MEMRWA; + desc.sd.sd_dpl = SEL_UPL; + desc.sd.sd_p = 1; + desc.sd.sd_def32 = 1; + desc.sd.sd_gran = 1; + desc.sd.sd_lolimit = 0xffff; + desc.sd.sd_hilimit = 0xf; + sl = i386_set_ldt(LDT_AUTO_ALLOC, &desc, 1); + if ((int)sl == -1) + err(1, "i386_set_ldt"); + sel = LSEL(sl, SEL_UPL); + s = sl; + __asm volatile("movw\t%w0,%%es" : : "r" (sel)); + atomic_store_rel_int(&b, 1); + while (atomic_load_acq_int(&b) != 0) + ; + getpid(); +} + +static void +sigsegv_handler(int signo __unused, siginfo_t *si __unused, void *rctx) +{ + ucontext_t *uc; + + uc = rctx; + uc->uc_mcontext.mc_es = uc->uc_mcontext.mc_ds; +} + +int +main(void) +{ + pthread_t thr; + time_t start; + struct sigaction sa; + int error; + + bzero(&sa, sizeof(sa)); + sa.sa_sigaction = sigsegv_handler; + sa.sa_flags = SA_SIGINFO; + error = sigaction(SIGSEGV, &sa, NULL); + if (error != 0) + err(1, "sigaction SIGSEGV"); + error = sigaction(SIGBUS, &sa, NULL); + if (error != 0) + err(1, "sigaction SIGBUS"); + + error = pthread_create(&thr, NULL, dealloc_ldt, NULL); + if (error != 0) + errc(1, error, "pthread_create"); + + start = time(NULL); + while (time(NULL) - start < 120) + func(); +} +EOF + +mycc -o /tmp/mvillard_nest -Wall -Wextra -O2 -g /tmp/mvillard_nest.c \ + -l pthread || exit 1 +rm /tmp/mvillard_nest.c + +/tmp/mvillard_nest; s=$? + +rm /tmp/mvillard_nest +exit $s diff --git a/tools/test/stress2/misc/select.sh b/tools/test/stress2/misc/select.sh new file mode 100755 index 000000000000..92652b0d41aa --- /dev/null +++ b/tools/test/stress2/misc/select.sh @@ -0,0 +1,168 @@ +#!/bin/sh + +# +# Copyright (c) 2016 EMC Corp. +# All rights reserved. +# +# 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. +# + +# The combination of ualarm() firing before and after the select(2) timeout +# triggers select() to return EINTR a number of times. +# Problem only seen on i386. + +# Test scenario suggestion by kib@ + +# "FAIL n = 2389" seen on r302369, no debug build. +# Fixed by: r302573. + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/select.c +mycc -o select -Wall -Wextra -O0 -g select.c -lpthread || exit 1 +rm -f select.c +cd $odir + +/tmp/select +s=$? + +rm -f /tmp/select +exit $s +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static pthread_barrier_t barr; +static sig_atomic_t alarms; +static int lines; + +#define LINES 128000 +#define N 2000 /* also seen fail with N = 20.000 */ +#define PARALLEL 16 /* Fails seen with 1 - 16 */ +#define RUNTIME (10 * 60) + +static void +handler(int i __unused) { + alarms++; +} + +static void +test(void) +{ + struct timeval tv; + int i, n, r, s; + + r = pthread_barrier_wait(&barr); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + errc(1, r, "pthread_barrier_wait"); + + signal(SIGALRM, handler); + s = 0; + for (i = 0; i < lines; i++) { + alarms = 0; + if (arc4random() % 100 < 50) + ualarm(N / 2, 0); + else + ualarm(N * 2, 0); + tv.tv_sec = 0; + tv.tv_usec = N; + n = 0; + do { + r = select(1, NULL, NULL, NULL, &tv); + n++; + } while (r == -1 && errno == EINTR); + if (r == -1) + err(1, "select"); + ualarm(0, 0); + if (n > 2) { + fprintf(stderr, "FAIL n = %d, tv = %ld.%06ld\n", + n, (long)tv.tv_sec, tv.tv_usec); + s = 1; + break; + } + if (alarms > 1) { + fprintf(stderr, "FAIL alarms = %d\n", (int)alarms); + s = 2; + break; + } + + } + + exit(s); +} + +int +main(void) +{ + pthread_barrierattr_t attr; + time_t start; + int e, i, j, pids[PARALLEL], r, status; + + lines = LINES / PARALLEL; + if (lines == 0) + lines = 1; + e = 0; + if ((r = pthread_barrierattr_init(&attr)) != 0) + errc(1, r, "pthread_barrierattr_init"); + if ((r = pthread_barrierattr_setpshared(&attr, + PTHREAD_PROCESS_SHARED)) != 0) + errc(1, r, "pthread_barrierattr_setpshared"); + if ((r = pthread_barrier_init(&barr, &attr, PARALLEL)) != 0) + errc(1, r, "pthread_barrier_init"); + + start = time(NULL); + while ((time(NULL) - start) < RUNTIME && e == 0) { + for (i = 0; i < PARALLEL; i++) { + if ((pids[i] = fork()) == 0) + test(); + } + for (i = 0; i < PARALLEL; i++) { + waitpid(pids[i], &status, 0); + e += status == 0 ? 0 : 1; + if (status != 0) { + for (j = i + 1; j < PARALLEL; j++) + kill(pids[j], SIGINT); + } + } + } + + if ((r = pthread_barrier_destroy(&barr)) > 0) + errc(1, r, "pthread_barrier_destroy"); + + return (e); +} diff --git a/tools/test/stress2/misc/select3.sh b/tools/test/stress2/misc/select3.sh new file mode 100755 index 000000000000..fde3a5c5430a --- /dev/null +++ b/tools/test/stress2/misc/select3.sh @@ -0,0 +1,39 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Check if M_SELECT leaks: nselect > threads + +m=`vmstat -m | grep -w select | awk '{print $2}'` +threads=`vmstat -z | sed 's/,/ /g' | grep THREAD | awk '{print $4}'` +free=`vmstat -z | sed 's/,/ /g' | grep THREAD | awk '{print $5}'` +[ $m -le $((threads + free)) ] && exit 0 + +echo FAIL +vmstat -m | sed -n '1p; /select/p' +vmstat -z | sed -n '1p;/THREAD/p' +exit 1 diff --git a/tools/test/stress2/misc/selfd.sh b/tools/test/stress2/misc/selfd.sh new file mode 100755 index 000000000000..5af48f0ec34c --- /dev/null +++ b/tools/test/stress2/misc/selfd.sh @@ -0,0 +1,152 @@ +#!/bin/sh + +# +# Copyright (c) 2015 EMC Corp. +# All rights reserved. +# +# 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. +# + +# selfd regression test attempt for r285310. Not reproduced. +# Watchdog fired seen: https://people.freebsd.org/~pho/stress/log/selfd.txt + +. ../default.cfg + +dir=/tmp +odir=`pwd` +cd $dir +sed '1,/^EOF/d' < $odir/$0 > $dir/selfd.c +mycc -o selfd -Wall -Wextra -O0 -g selfd.c -lpthread || exit 1 +rm -f selfd.c +cd $odir + +rm -rf /tmp/stressX.control +daemon sh -c "(cd ../testcases/swap; ./swap -t 10m -i 20 -l 100)" > \ + /dev/null 2>&1 +sleep 2 + +/tmp/selfd +s=$? + +while pgrep -q swap; do + pkill -9 swap +done + +rm -rf /tmp/selfd +exit $s + +EOF +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static pthread_barrier_t barr; + +#define PARALLEL 16 +#define PIPES 32 +#define RUNTIME (5 * 60) + +static void +handler(int s __unused) +{ +} + +static void +test(void) +{ + fd_set rset, tmpl; + struct sigaction sa; + struct timeval timeout; + time_t start; + int fds[PIPES][2], i, n, r; + + r = pthread_barrier_wait(&barr); + if (r != 0 && r != PTHREAD_BARRIER_SERIAL_THREAD) + errc(1, r, "pthread_barrier_wait"); + + FD_ZERO(&tmpl); + for (i = 0; i < PIPES; i++) { + if (pipe(fds[i]) == -1) + err(1, "pipe()"); + FD_SET(fds[i][0], &tmpl); + } + sa.sa_handler = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGALRM, &sa, NULL) == -1) + err(1, "sigaction"); + start = time(NULL); + while ((time(NULL) - start) < 10) { + rset = tmpl; + timeout.tv_sec = 0; + timeout.tv_usec = arc4random() % 10000 + 100; + n = arc4random() % PIPES; + ualarm(arc4random() % 10000 + 100, 0); + write(fds[n][1], "a", 1); + if ((n = select(PIPES, &rset, NULL, NULL, &timeout)) < 0) + if (errno != EINTR) + err(1, "select()"); + ualarm(0, 0); + } + + _exit(0); + +} + +int +main(void) +{ + pthread_barrierattr_t attr; + time_t start; + int i, r; + + if ((r = pthread_barrierattr_init(&attr)) != 0) + errc(1, r, "pthread_barrierattr_init"); + if ((r = pthread_barrierattr_setpshared(&attr, + PTHREAD_PROCESS_SHARED)) != 0) + errc(1, r, "pthread_barrierattr_setpshared"); + if ((r = pthread_barrier_init(&barr, &attr, PARALLEL)) != 0) + errc(1, r, "pthread_barrier_init"); + + start = time(NULL); + while ((time(NULL) - start) < RUNTIME) { + for (i = 0; i < PARALLEL; i++) + if (fork() == 0) + test(); + for (i = 0; i < PARALLEL; i++) + wait(NULL); + } + + return (0); +} diff --git a/tools/test/stress2/misc/sem.sh b/tools/test/stress2/misc/sem.sh new file mode 100755 index 000000000000..9b229ab662f5 --- /dev/null +++ b/tools/test/stress2/misc/sem.sh @@ -0,0 +1,142 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 panic in semexit_myhook +# Test scenario by kib@ + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > sem.c +mycc -o sem -Wall sem.c +rm -f sem.c + +cd $RUNDIR/.. +for i in `jot 5`; do + /tmp/sem& +done +for i in `jot 5`; do + wait +done + +rm -f /tmp/sem + +exit +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int semid = -1; +key_t semkey; +struct sembuf sop[2]; + +size_t pgsize; +pid_t pid; + +void +random_work(void) +{ + int i, n; + + n = (arc4random() % 5000) + 200; + for (i = 0; i < n; i++) + (void) getpid(); +} + +int +main() +{ + int i, j, seed, status; + + seed = getpid(); + semkey = ftok("/", seed); + + for (i = 0; i < 5000; i++) { + + pid = fork(); + if (pid == -1) { + perror("fork"); + exit(2); + } + + if (pid == 0) { /* child */ + j = 0; + /* get sem */ + do { + sched_yield(); + semid = semget(semkey, 0, 0); + } while (semid == -1 && j++ < 10000); + if (semid == -1) + exit(1); + + /* + * Attempt to acquire the semaphore. + */ + sop[0].sem_num = 0; + sop[0].sem_op = -1; + sop[0].sem_flg = SEM_UNDO; + + semop(semid, sop, 1); + random_work(); + _exit(0); + + } else { /* parent */ + /* create sem */ + if ((semid = semget(semkey, 1, IPC_CREAT | 010640)) == -1) + err(1, "semget (%s:%d)", __FILE__, __LINE__); + usleep(2000); + + sop[0].sem_num = 0; + sop[0].sem_op = 1; + sop[0].sem_flg = 0; + if (semop(semid, sop, 1) == -1) + warn("init: semop (%s:%d)", __FILE__, __LINE__); + + random_work(); + if (semctl(semid, 0, IPC_RMID, 0) == -1 && errno != EINVAL) + warn("shmctl IPC_RMID (%s:%d)", __FILE__, __LINE__); + + } + waitpid(pid, &status, 0); + } + return (0); +} diff --git a/tools/test/stress2/misc/sem_post.sh b/tools/test/stress2/misc/sem_post.sh new file mode 100755 index 000000000000..2f1d7c4c004f --- /dev/null +++ b/tools/test/stress2/misc/sem_post.sh @@ -0,0 +1,107 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# No problems seen. + +cat > /tmp/sem_post.c < +#include +#include +#include +#include +#include +#include +#include +#include + +static sem_t semaphore; + +static void * +threadfunc(void *data __unused) { + + for (;;) { + usleep(arc4random() % 100); + if (sem_wait(&semaphore) == -1) + err(1, "sem_wait"); + usleep(arc4random() % 100); + if (arc4random() % 100 < 3) + sleep(1); + if (sem_post(&semaphore) == -1) + err(1, "sem_post"); + } + + return (NULL); +} + +int +main(void) { + pthread_t mythread; + time_t start; + int r; + + // initialize semaphore and set value to 1 + if (sem_init(&semaphore, 0, 1) == -1) + err(1, "sem_init"); + + r = pthread_create(&mythread, NULL, threadfunc, NULL); + if (r != 0) + errc(1, r, "pthread_create"); + + usleep(50); + alarm(300); + start = time(NULL); + while (time(NULL) - start < 120) { + usleep(arc4random() % 100); + if (sem_wait(&semaphore) == -1) + err(1, "sem_wait"); + usleep(arc4random() % 100); + if (arc4random() % 100 < 3) + sleep(1); + if (sem_post(&semaphore) == -1) + err(1, "sem_post"); + } + if ((r = pthread_kill(mythread, SIGINT)) != 0) + errc(1, r, "pthread_kill"); + if ((r = pthread_join(mythread, NULL)) != 0) + errc(1, r, "pthread_join"); + + return (0); +} +EOF +cc -o /tmp/sem_post -Wall -Wextra -O2 /tmp/sem_post.c -lpthread || exit 1 +(cd ../testcases/swap; ./swap -t 3m -i 30 -h -l 100) & +sleep 20 +for i in `jot 128`; do + /tmp/sem_post > /dev/null & +done +while pgrep -q sem_post; do sleep .5; done +while pkill swap; do :; done +wait +rm -f /tmp/sem_post /tmp/sem_post.c +exit 0 diff --git a/tools/test/stress2/misc/sem_timedwait.sh b/tools/test/stress2/misc/sem_timedwait.sh new file mode 100755 index 000000000000..33e5c1933f37 --- /dev/null +++ b/tools/test/stress2/misc/sem_timedwait.sh @@ -0,0 +1,161 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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. +# + +# No problems seen. + +. ../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/sem_timedwait.c +mycc -o sem_timedwait -Wall -Wextra -O0 -g sem_timedwait.c || exit 1 +rm -f sem_timedwait.c +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 1g -u $mdstart +newfs $newfs_flags md$mdstart > /dev/null +mount /dev/md$mdstart $mntpoint +set +e + +(cd $odir/../testcases/swap; ./swap -t 5m -i 20 -h -l 100) > /dev/null & +cd $mntpoint +nice $dir/sem_timedwait +s=$? +[ -f sem_timedwait.core -a $s -eq 0 ] && + { ls -l sem_timedwait.core; mv sem_timedwait.core $dir; s=1; } +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 -rf $dir/sem_timedwait +exit $s + +EOF +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile u_int *share; + +#define PARALLEL 64 +#define RUNTIME (5 * 60) +#define SYNC 0 + +static void +test(void) +{ + struct timespec tm; + sem_t sem; + int i; + + atomic_add_int(&share[SYNC], 1); + while (share[SYNC] != PARALLEL) + ; + + sem_init(&sem, 0, 0); + i = 0; + do { + clock_gettime(CLOCK_REALTIME, &tm); + tm.tv_nsec += 1000; + if (tm.tv_nsec >= 1000000000L) { + tm.tv_nsec -= 1000000000L; + tm.tv_sec++; + } + + if (++i == 1000) + sem_post(&sem); + else + usleep(10000); + } while (sem_timedwait(&sem, &tm) == -1); + + _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); +} diff --git a/tools/test/stress2/misc/sem_wait.sh b/tools/test/stress2/misc/sem_wait.sh new file mode 100755 index 000000000000..6d8bc49c9199 --- /dev/null +++ b/tools/test/stress2/misc/sem_wait.sh @@ -0,0 +1,109 @@ +#!/bin/sh + +# +# SPDX-License-Identifier: BSD-2-Clause-FreeBSD +# +# Copyright (c) 2019 Dell EMC Isilon +# +# 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: vm_page_free_prep: freeing mapped page 0x657936c" seen. +# https://people.freebsd.org/~pho/stress/log/sem_wait.txt +# Fixed by r350005 + +. ../default.cfg + +cat > /tmp/sem_wait.c < +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static sem_t *semaphore; + +static void * +test(void) { + + setproctitle("%s", __func__); + alarm(300); + for (;;) { + if (sem_wait(semaphore) == -1) + err(1, "sem_wait"); + if (sem_post(semaphore) == -1) + err(1, "sem_post"); + } +} + +int +main(void) { + pid_t pid; + size_t len; + time_t start; + + setproctitle("%s", __func__); + alarm(300); + len = PAGE_SIZE; + if ((semaphore = mmap(NULL, len, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) + err(1, "mmap"); + + // initialize semaphore and set value to 1 + if (sem_init(semaphore, 1, 1) == -1) + err(1, "sem_init"); + + if ((pid = fork()) == 0) + test(); + if (pid == -1) + err(1, "fork()"); + + usleep(50); + alarm(300); + start = time(NULL); + while (time(NULL) - start < 60) { + if (sem_wait(semaphore) == -1) + err(1, "sem_wait"); + if (sem_post(semaphore) == -1) + err(1, "sem_post"); + } + kill(pid, SIGHUP); + if (waitpid(pid, NULL, 0) != pid) + err(1, "waitpid()"); + + return (0); +} +EOF +mycc -o /tmp/sem_wait -Wall -Wextra -O2 /tmp/sem_wait.c || exit 1 +timeout 6m /tmp/sem_wait; s=$? +[ $s -eq 124 ] && echo "Timed out" +rm -f /tmp/sem_wait /tmp/sem_wait.c +exit $s diff --git a/tools/test/stress2/misc/sendfile.sh b/tools/test/stress2/misc/sendfile.sh new file mode 100755 index 000000000000..408564bef0e2 --- /dev/null +++ b/tools/test/stress2/misc/sendfile.sh @@ -0,0 +1,213 @@ +#!/bin/sh + +# +# Copyright (c) 2009 Peter Holm +# All rights reserved. +# +# 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 scenario for sendfile livelock seen on 7.2-STABLE for non SMP + +# Scenario by kib@ + +. ../default.cfg + +odir=`pwd` + +cd /tmp +sed '1,/^EOF/d' < $odir/$0 > sendfile.c +mycc -o sendfile -Wall sendfile.c -pthread +rm -f sendfile.c +[ -d "$RUNDIR" ] || mkdir -p $RUNDIR +cd $RUNDIR + +in=inputFile +out=outputFile + +for i in 1 2 3 4 8 16 1k 2k 3k 4k 5k 1m 2m 3m 4m 5m ; do + rm -f $in $out + dd if=/dev/random of=$in bs=$i count=1 status=none + /tmp/sendfile $in $out 12345 + cmp $in $out || { echo FAIL; ls -l $in $out; } + rm -f $in $out +done +rm -f /tmp/sendfile +exit +EOF +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int port; +char *inputFile; +char *outputFile; +int bufsize = 4096; + +static void +reader(void) { + int tcpsock, msgsock; + int on; + socklen_t len; + struct sockaddr_in inetaddr, inetpeer; + int n, t, *buf, fd; + + 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__); + + t = 0; + if ((buf = malloc(bufsize)) == NULL) + err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__); + + if ((fd = open(outputFile, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) + err(1, "open(%s)", outputFile); + + for (;;) { + if ((n = read(msgsock, buf, bufsize)) < 0) + err(1, "read(), %s:%d", __FILE__, __LINE__); + t += n; + if (n == 0) + break; + + if ((write(fd, buf, n)) != n) + err(1, "write"); + } + close(msgsock); + close(fd); + return; +} + +static void +writer(void) { + int tcpsock, on; + struct sockaddr_in inetaddr; + struct hostent *hostent; + struct stat statb; + int i, r, fd; + off_t off = 0; +#if 1 + size_t size; +#endif + + 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__); + +#if 1 /* livelock trigger */ + size = getpagesize() -4; + if (setsockopt(tcpsock, SOL_SOCKET, SO_SNDBUF, (void *)&size, + sizeof(size)) < 0) + err(1, "setsockopt(SO_SNDBUF), %s:%d", + __FILE__, __LINE__); +#endif + + 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 (stat(inputFile, &statb) != 0) + err(1, "stat(%s)", inputFile); + + if ((fd = open(inputFile, O_RDONLY)) == -1) + err(1, "open(%s)", inputFile); + + if (sendfile(fd, tcpsock, 0, statb.st_size, NULL, &off, 0) == -1) + err(1, "sendfile"); + + return; +} + +int +main(int argc, char **argv) +{ + pid_t pid; + + if (argc != 4) { + fprintf(stderr, "Usage: %s 0) { + reader(); + kill(pid, SIGINT); + } else + err(1, "fork(), %s:%d", __FILE__, __LINE__); + + return (0); +} diff --git a/tools/test/stress2/misc/sendfile10.sh b/tools/test/stress2/misc/sendfile10.sh new file mode 100755 index 000000000000..0bfc4a83da71 --- /dev/null +++ b/tools/test/stress2/misc/sendfile10.sh @@ -0,0 +1,313 @@ +#!/bin/sh + +# +# Copyright (c) 2017 Dell EMC Isilon +# All rights reserved. +# +# 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. +# + +# Copy of sendfile8.sh with size validation added. + +# No problems seen (after r315910). + +. ../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/sendfile10.c +mycc -o sendfile10 -Wall -Wextra -O0 -g sendfile10.c || exit 1 +rm -f sendfile10.c +cd $odir + +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 || exit 1 +bsdlabel -w md$mdstart auto +newfs $newfs_flags -n md${mdstart}$part > /dev/null +mount /dev/md${mdstart}$part $mntpoint + +cd $mntpoint +dd if=/dev/random of=template bs=1m count=50 status=none +/tmp/sendfile10 template in out 76543 +s=$? +cd $odir + +for i in `jot 6`; do + mount | grep -q "on $mntpoint " || break + umount $mntpoint && break || sleep 10 +done +[ $i -eq 6 ] && exit 1 +mdconfig -d -u $mdstart +rm -rf /tmp/sendfile10 +exit $s + +EOF +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static volatile off_t *share; +static int port; +static char *input, *output; + +#define BUFSIZE 4096 +#define MX (100 * 1024 * 1024) +#define OSZ 1 +#define PARALLEL 1 +#define RUNTIME (2 * 60) +#define SZ 0 + +static void +mess(void) +{ + off_t length; + int fd; + + if ((fd = open(input, O_RDWR)) == -1) + err(1, "open(%s)", input); + length = arc4random() % MX; + if (ftruncate(fd, length) == -1) + err(1, "truncate(%jd)", length); + share[SZ] = length; + close(fd); +} + +static void +reader(void) { + off_t t; + int tcpsock, msgsock; + int on; + socklen_t len; + struct sockaddr_in inetaddr, inetpeer; + int n, *buf, fd; + + 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); + alarm(10); + if ((msgsock = accept(tcpsock, + (struct sockaddr *)&inetpeer, &len)) < 0) + err(1, "accept(), %s:%d", __FILE__, __LINE__); + alarm(0); + + t = 0; + if ((buf = malloc(BUFSIZE)) == NULL) + err(1, "malloc(%d), %s:%d", BUFSIZE, __FILE__, __LINE__); + + if ((fd = open(output, O_RDWR | O_CREAT | O_TRUNC, 0640)) == -1) + err(1, "open(%s)", output); + + for (;;) { + if ((n = read(msgsock, buf, BUFSIZE)) < 0) + err(1, "read(), %s:%d", __FILE__, __LINE__); + t += n; + if (n == 0) break; + + if ((write(fd, buf, n)) != n) + err(1, "write"); + } + close(msgsock); + close(fd); +#if 0 + if (t != share[SZ] && t != share[OSZ]) { + fprintf(stderr, "1) Send size %lu, original size %lu, " + "receive size %lu\n", + (unsigned long)share[SZ], + (unsigned long)share[OSZ], + (unsigned long)t); + exit(1); + } +#endif + return; +} + +static void +writer(void) { + struct sockaddr_in inetaddr; + struct hostent *hostent; + struct stat statb; + off_t off = 0; + size_t size; + int i, r, fd; + int tcpsock, on; + + 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() -4; + 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(input, O_RDONLY)) == -1) + err(1, "open(%s)", input); + + if (fstat(fd, &statb) != 0) + err(1, "stat(%s)", input); + share[SZ] = statb.st_size; + if (sendfile(fd, tcpsock, 0, statb.st_size, NULL, &off, 0) == -1) + err(1, "sendfile"); + close(fd); + close(tcpsock); + + return; +} + +static void +test(void) +{ + pid_t pid; + + if ((pid = fork()) == 0) { + writer(); + _exit(0); + } + reader(); + kill(pid, SIGINT); + if (waitpid(pid, NULL, 0) != pid) + err(1, "waitpid(%d)", pid); + + _exit(0); +} + +int +main(int argc, char *argv[]) +{ + struct stat statin, statorig, statout; + size_t len; + time_t start; + int e, i, pids[PARALLEL], status; + char help[80], *template; + + if (argc != 5) { + fprintf(stderr, "Usage: %s

    +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

  • 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