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# pipe(2) test 30 31. ../default.cfg 32[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1 33 34dir=/tmp 35odir=`pwd` 36cd $dir 37sed '1,/^EOF/d' < $odir/$0 > $dir/pipe2.c 38mycc -o pipe2 -Wall -Wextra -O0 -g pipe2.c || exit 1 39rm -f pipe2.c 40 41daemon sh -c "(cd $odir/../testcases/swap; ./swap -t 10m -i 20)" > \ 42 /dev/null 2>&1 43sleep 10 44 45su $testuser -c /tmp/pipe2 46s=$? 47 48while pgrep -q swap; do 49 pkill -9 swap 50done 51 52rm -rf /tmp/pipe2 53exit $s 54 55EOF 56#include <sys/param.h> 57#include <sys/mman.h> 58 59#include <machine/atomic.h> 60 61#include <err.h> 62#include <errno.h> 63#include <fcntl.h> 64#include <signal.h> 65#include <stdio.h> 66#include <stdlib.h> 67#include <unistd.h> 68 69volatile u_int *share, *share2; 70 71#define R1 1 /* sync start */ 72#define R2 2 /* forks */ 73 74#define PIPES 128 75#define PARALLEL 32 76 77static void 78hand(int i __unused) { /* handler */ 79 fprintf(stderr, "Timed out\n"); 80 _exit(1); 81} 82 83void 84test(void) 85{ 86 size_t len; 87 int fds[2], r; 88 int token; 89 90 len = PAGE_SIZE; 91 if ((share = mmap(NULL, len, PROT_READ | PROT_WRITE, 92 MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 93 err(1, "mmap"); 94 95 if (pipe(fds) == -1) 96 err(1, "pipe"); 97 token = 0; 98 write(fds[1], &token, sizeof(token)); 99 for (;;) { 100 if (share[R2] >= PIPES) 101 break; 102 if ((r = fork()) == 0) { 103 atomic_add_int(&share[R2], 1); 104 if (read(fds[0], &token, sizeof(token)) != sizeof(token)) 105 err(1, "read"); 106 close(fds[0]); 107 if (pipe(fds) == -1) 108 err(1, "pipe"); 109 token++; 110 if (write(fds[1], &token, sizeof(token)) != sizeof(token)) 111 err(1, "write"); 112 } 113 if (r == -1) 114 err(1, "fork()"); 115 if (r != 0) 116 _exit(0); 117 } 118 119 if (share[R2] == PIPES) { 120#if defined(DEBUG) 121 if (read(fds[0], &token, sizeof(token)) != sizeof(token)) 122 err(1, "final read"); 123 fprintf(stderr, "FINAL read %d from %d\n", token, fds[0]); 124#endif 125 atomic_add_int(&share2[R1], 1); 126 } 127 _exit(0); 128} 129 130int 131main(void) 132{ 133 struct sigaction sa; 134 size_t len; 135 int i; 136 137 len = PAGE_SIZE; 138 if ((share2 = mmap(NULL, len, PROT_READ | PROT_WRITE, 139 MAP_ANON | MAP_SHARED, -1, 0)) == MAP_FAILED) 140 err(1, "mmap"); 141 142 sa.sa_handler = SIG_IGN; 143 sigemptyset(&sa.sa_mask); 144 sa.sa_flags = 0; 145 if (sigaction(SIGCHLD, &sa, 0) == -1) 146 err(1, "sigaction"); 147 148 for (i = 0; i < PARALLEL; i++) { 149 if (fork() == 0) 150 test(); 151 } 152 153 signal(SIGALRM, hand); 154 alarm(300); 155 while (share2[R1] != PARALLEL) { 156 sleep(1); 157#if defined(DEBUG) 158 fprintf(stderr, "share2 = %d\n", share2[R1]); 159#endif 160 } 161 162 return (0); 163} 164