1#!/bin/sh 2 3# 4# Copyright (c) 2016 Dell EMC Isilon 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# Regression test for r310849. Hang in "vmpfw" was seen. 30 31# Test scenario suggestion by kib. 32 33[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 34 35. ../default.cfg 36 37RUNTIME=60 38old=`sysctl -n kern.ipc.shm_use_phys` 39trap "sysctl kern.ipc.shm_use_phys=$old" EXIT INT 40sysctl kern.ipc.shm_use_phys=1 41 42dir=/tmp 43odir=`pwd` 44cd $dir 45sed '1,/^EOF/d' < $odir/$0 > $dir/shm.c 46mycc -o shm -Wall -Wextra -O0 -g shm.c -pthread || exit 1 47rm -f shm.c 48 49/tmp/shm & 50 51s=0 52sleep $RUNTIME 53if pgrep -q shm; then 54 if pgrep shm | xargs ps -lHp | grep -q vmpfw; then 55 s=1 56 echo FAIL 57 pgrep shm | xargs ps -lHp 58 pkill -9 shm 59 fi 60fi 61wait 62 63rm -rf /tmp/shm 64exit $s 65 66EOF 67#include <sys/param.h> 68#include <sys/ipc.h> 69#include <sys/mman.h> 70#include <sys/shm.h> 71#include <sys/stat.h> 72#include <sys/wait.h> 73 74#include <err.h> 75#include <errno.h> 76#include <fcntl.h> 77#include <pthread.h> 78#include <pthread_np.h> 79#include <stdio.h> 80#include <stdlib.h> 81#include <time.h> 82#include <unistd.h> 83 84static void *shmp; 85static size_t len; 86static int cont, shmid; 87 88#define PAGES 64 89#define RUNTIME (1 * 60) 90#define STOP 1 91#define SYNC 0 92 93static void 94cleanup(void) 95{ 96 if (shmp != MAP_FAILED) 97 shmdt(shmp); 98 if (shmid != 0) 99 shmctl(shmid, IPC_RMID, NULL); 100} 101 102static void * 103t1(void *arg __unused) 104{ 105 time_t start; 106 char *cp; 107 108 pthread_set_name_np(pthread_self(), __func__); 109 start = time(NULL); 110 while (cont == 1 && (time(NULL) - start) < RUNTIME) { 111 if ((cp = mmap(NULL, len, PROT_READ | PROT_WRITE, 112 MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 113 err(1, "mmap"); 114 usleep(arc4random() % 400); 115 if (munmap(cp, len) == -1) 116 warn("unmap(%p, %zu)", shmp, len); 117 } 118 119 return (NULL); 120} 121 122static void * 123t2(void *arg __unused) 124{ 125 key_t shmkey; 126 size_t i; 127 time_t start; 128 char *cp; 129 130 pthread_set_name_np(pthread_self(), __func__); 131 shmkey = ftok("/tmp", getpid()); 132 start = time(NULL); 133 atexit(cleanup); 134 while ((time(NULL) - start) < RUNTIME) { 135 if ((shmid = shmget(shmkey, len, IPC_CREAT | IPC_EXCL | 136 0640)) == -1) { 137 if (errno != ENOSPC && errno != EEXIST) 138 err(1, "shmget (%s:%d)", __FILE__, __LINE__); 139 break; 140 } 141 if ((shmp = shmat(shmid, NULL, 0)) == (void *) -1) 142 break; 143 cp = (char *)(shmp); 144 for (i = 0; i < len; i = i + PAGE_SIZE) 145 cp[i] = 1; 146 if (shmdt(shmp) == -1) { 147 if (errno != EINVAL) 148 warn("shmdt(%p)", shmp); 149 } 150 if (shmctl(shmid, IPC_RMID, NULL) == -1) 151 warn("shmctl IPC_RMID"); 152 usleep(50); 153 154 shmp = MAP_FAILED; 155 shmid = 0; 156 } 157 cont = 0; 158 159 return (NULL); 160} 161 162static int 163test(void) 164{ 165 pthread_t tid[2]; 166 int i, rc; 167 168 shmp = MAP_FAILED; 169 170 cont = 1; 171 if ((rc = pthread_create(&tid[0], NULL, t1, NULL)) != 0) 172 errc(1, rc, "pthread_create()"); 173 if ((rc = pthread_create(&tid[1], NULL, t2, NULL)) != 0) 174 errc(1, rc, "pthread_create()"); 175 176 for (i = 0; i < 2; i++) 177 if ((rc = pthread_join(tid[i], NULL)) != 0) 178 errc(1, rc, "pthread_join(%d)", i); 179 180 return (0); 181} 182 183int 184main(void) 185{ 186 pid_t pid; 187 time_t start; 188 189 len = PAGES * PAGE_SIZE; 190 start = time(NULL); 191 while ((time(NULL) - start) < RUNTIME) { 192 if ((pid = fork()) == 0) { 193 test(); 194 exit(0); /* calls cleanup() */ 195 } 196 if (waitpid(pid, NULL,0) != pid) 197 err(1, "waitpid(%d)", pid); 198 } 199 200 return(0); 201} 202