1#!/bin/sh 2 3# 4# Copyright (c) 2016 EMC Corp. 5# All rights reserved. 6# 7# Redistribution and use in source and binary forms, with or without 8# modification, are permitted provided that the following conditions 9# are met: 10# 1. Redistributions of source code must retain the above copyright 11# notice, this list of conditions and the following disclaimer. 12# 2. Redistributions in binary form must reproduce the above copyright 13# notice, this list of conditions and the following disclaimer in the 14# documentation and/or other materials provided with the distribution. 15# 16# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26# SUCH DAMAGE. 27# 28 29# Variation of nfs15.sh, using lockd(8). 30# "panic: Failed to register NFS lock locally - error=11" seen: 31# https://people.freebsd.org/~pho/stress/log/kostik897.txt 32 33[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 34 35. ../default.cfg 36 37[ -z "$nfs_export" ] && exit 0 38ping -c 2 `echo $nfs_export | sed 's/:.*//'` > /dev/null 2>&1 || 39 exit 0 40 41here=`pwd` 42cd /tmp 43sed '1,/^EOF/d' < $here/$0 > nfs16.c 44mycc -o nfs16 -Wall -Wextra -O2 -g nfs16.c -lpthread || exit 1 45rm -f nfs16.c 46cd $here 47 48mount | grep "on $mntpoint " | grep nfs > /dev/null && umount $mntpoint 49 50mount -t nfs -o tcp -o retrycnt=3 -o soft -o rw \ 51 $nfs_export $mntpoint 52sleep 2 53wd=$mntpoint/nfs16.dir 54rm -rf $wd 55mkdir $wd 56 57(cd $wd; /tmp/nfs16) 58rm -rf $wd 59 60while mount | grep "on $mntpoint " | grep -q nfs; do 61 umount $mntpoint || sleep 1 62done 63 64rm -f /tmp/nfs16 65exit 0 66EOF 67#include <sys/stat.h> 68#include <sys/param.h> 69#include <sys/mman.h> 70#include <sys/wait.h> 71 72#include <machine/atomic.h> 73 74#include <err.h> 75#include <errno.h> 76#include <fcntl.h> 77#include <pthread.h> 78#include <signal.h> 79#include <stdio.h> 80#include <stdlib.h> 81#include <string.h> 82#include <unistd.h> 83 84#define PARALLEL 4 85#define RUNTIME 300 86#define SYNC 0 87 88volatile u_int *share; 89 90static void * 91t1(void *data __unused) 92{ 93 atomic_add_int(&share[SYNC], 1); 94 usleep(arc4random() % 8000); 95 raise(SIGABRT); 96 97 return (NULL); 98} 99 100static void * 101t2(void *data __unused) 102{ 103 int fd, i, r; 104 char file[80]; 105 106 for (i = 0; i < 100; i++) { 107 atomic_add_int(&share[SYNC], 1); 108 snprintf(file, sizeof(file), "file.%06d", i); 109 if ((fd = open(file, O_WRONLY | O_CREAT | O_APPEND, DEFFILEMODE)) == -1) 110 err(1, "open(%s)", file); 111 do { 112 r = lockf(fd, F_LOCK, 0); 113 } while (r == -1 && errno == EDEADLK); 114 if (r == -1) 115 err(1, "lockf(%s, F_LOCK)", file); 116 write(fd, "x", 1); 117 usleep(arc4random() % 1000); 118 if (lseek(fd, 0, SEEK_SET) == -1) 119 err(1, "lseek"); 120 if (lockf(fd, F_ULOCK, 0) == -1) 121 err(1, "lockf(%s, F_ULOCK)", file); 122 close(fd); 123 } 124 125 return (NULL); 126} 127 128int 129test(void) 130{ 131 pthread_t tid[3]; 132 int i, rc; 133 134 for (i = 0; i < 10; i++) { 135 if ((rc = pthread_create(&tid[0], NULL, t2, NULL)) == -1) 136 errc(1, rc, "pthread_create"); 137 if ((rc = pthread_create(&tid[1], NULL, t2, NULL)) == -1) 138 errc(1, rc, "pthread_create"); 139 if ((rc = pthread_create(&tid[2], NULL, t1, NULL)) == -1) 140 errc(1, rc, "pthread_create"); 141 142 if ((rc = pthread_join(tid[0], NULL)) == -1) 143 errc(1, rc, "pthread_join"); 144 if ((rc = pthread_join(tid[1], NULL)) == -1) 145 errc(1, rc, "pthread_join"); 146 if ((rc = pthread_join(tid[2], NULL)) == -1) 147 errc(1, rc, "pthread_join"); 148 } 149 150 _exit(0); 151} 152 153int 154main(void) 155{ 156 pid_t pids[PARALLEL]; 157 size_t len; 158 time_t start; 159 int i, status; 160 161 len = PAGE_SIZE; 162 if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, 163 MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 164 err(1, "mmap"); 165 166 start = time(NULL); 167 while (time(NULL) - start < RUNTIME) { 168 for (i = 0; i < PARALLEL; i++) { 169 if ((pids[i] = fork()) == 0) 170 test(); 171 } 172 173 for(;;) { 174 if (share[SYNC] > 0) 175 atomic_add_int(&share[SYNC], -1); 176 for (i = 0; i < PARALLEL; i++) 177 kill(pids[i], SIGSTOP); 178 usleep(1000); 179 for (i = 0; i < PARALLEL; i++) 180 kill(pids[i], SIGCONT); 181 usleep(100 + arc4random() % 400); 182 if (share[SYNC] == 0) { /* If all procs are done */ 183 usleep(500); 184 if (share[SYNC] == 0) 185 break; 186 } 187 } 188 189 for (i = 0; i < PARALLEL; i++) { 190 if (waitpid(pids[i], &status, 0) != pids[i]) 191 err(1, "waitpid"); 192 } 193 } 194 195 return (0); 196} 197