1*8a272653SPeter Holm#!/bin/sh 2*8a272653SPeter Holm 3*8a272653SPeter Holm# 4*8a272653SPeter Holm# Copyright (c) 2012 Peter Holm <pho@FreeBSD.org> 5*8a272653SPeter Holm# All rights reserved. 6*8a272653SPeter Holm# 7*8a272653SPeter Holm# Redistribution and use in source and binary forms, with or without 8*8a272653SPeter Holm# modification, are permitted provided that the following conditions 9*8a272653SPeter Holm# are met: 10*8a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright 11*8a272653SPeter Holm# notice, this list of conditions and the following disclaimer. 12*8a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright 13*8a272653SPeter Holm# notice, this list of conditions and the following disclaimer in the 14*8a272653SPeter Holm# documentation and/or other materials provided with the distribution. 15*8a272653SPeter Holm# 16*8a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17*8a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18*8a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19*8a272653SPeter Holm# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20*8a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21*8a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22*8a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23*8a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24*8a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25*8a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26*8a272653SPeter Holm# SUCH DAMAGE. 27*8a272653SPeter Holm# 28*8a272653SPeter Holm 29*8a272653SPeter Holm# Scenario based on pr. kern/166340 30*8a272653SPeter Holm# Process under FreeBSD 9.0 hangs in uninterruptable sleep with apparently 31*8a272653SPeter Holm# no syscall (empty wchan). 32*8a272653SPeter Holm 33*8a272653SPeter Holm# http://people.freebsd.org/~pho/stress/log/callout_reset_on.txt 34*8a272653SPeter Holm# Fixed in r243901. 35*8a272653SPeter Holm 36*8a272653SPeter Holm# panic: Bad link elm 0xfffff80012ba8ec8 prev->next != elm 37*8a272653SPeter Holm# https://people.freebsd.org/~pho/stress/log/rrs005.txt 38*8a272653SPeter Holm# Fixed in r278623. 39*8a272653SPeter Holm 40*8a272653SPeter Holm# "ritwait DE 0- 0:00.01 crlogger: writer" seen. 41*8a272653SPeter Holm# https://people.freebsd.org/~pho/stress/log/kostik917.txt 42*8a272653SPeter Holm# Fixed in r302981 43*8a272653SPeter Holm 44*8a272653SPeter Holm. ../default.cfg 45*8a272653SPeter Holm 46*8a272653SPeter Holmrm -f /tmp/crwriter /tmp/crlogger || exit 1 47*8a272653SPeter Holm 48*8a272653SPeter Holmcat > /tmp/crwriter.c <<EOF 49*8a272653SPeter Holm#include <stdio.h> 50*8a272653SPeter Holm#include <stdlib.h> 51*8a272653SPeter Holm#include <string.h> 52*8a272653SPeter Holm#include <unistd.h> 53*8a272653SPeter Holm 54*8a272653SPeter Holmchar *txt[] = { 55*8a272653SPeter Holm "0 This is a line of text: abcdefghijklmnopqrstuvwxyz", 56*8a272653SPeter Holm "1 Another line of text: ABCDEFGHIJKLMNOPQRSTUVWXYZ", 57*8a272653SPeter Holm "2 A different line of text", 58*8a272653SPeter Holm "3 A very, very different text", 59*8a272653SPeter Holm "4 A much longer line with a lot of characters in the line", 60*8a272653SPeter Holm "5 Now this is a quite long line of text, with both upper and lower case letters, and one digit!" 61*8a272653SPeter Holm}; 62*8a272653SPeter Holm 63*8a272653SPeter Holmint 64*8a272653SPeter Holmmain(void) 65*8a272653SPeter Holm{ 66*8a272653SPeter Holm int i, j, n; 67*8a272653SPeter Holm char help[256]; 68*8a272653SPeter Holm 69*8a272653SPeter Holm for (i = 0; i < 100000; i++) { 70*8a272653SPeter Holm j = arc4random() % 6; 71*8a272653SPeter Holm n = arc4random() % strlen(txt[j]); 72*8a272653SPeter Holm strncpy(help, txt[j], n); 73*8a272653SPeter Holm help[n] = 0; 74*8a272653SPeter Holm printf("%s\n", txt[j]); 75*8a272653SPeter Holm if ((arc4random() % 1000) == 1) 76*8a272653SPeter Holm usleep(100000); 77*8a272653SPeter Holm } 78*8a272653SPeter Holm 79*8a272653SPeter Holm return (0); 80*8a272653SPeter Holm} 81*8a272653SPeter HolmEOF 82*8a272653SPeter Holmmycc -o /tmp/crwriter -Wall -Wextra -O2 -g /tmp/crwriter.c 83*8a272653SPeter Holmrm -f /tmp/crwriter.c 84*8a272653SPeter Holm 85*8a272653SPeter Holmcat > /tmp/crlogger.c <<EOF 86*8a272653SPeter Holm#include <sys/param.h> 87*8a272653SPeter Holm#include <sys/socket.h> 88*8a272653SPeter Holm#include <netinet/in.h> 89*8a272653SPeter Holm#include <netdb.h> 90*8a272653SPeter Holm#include <stdio.h> 91*8a272653SPeter Holm#include <stdlib.h> 92*8a272653SPeter Holm#include <unistd.h> 93*8a272653SPeter Holm#include <signal.h> 94*8a272653SPeter Holm#include <errno.h> 95*8a272653SPeter Holm#include <string.h> 96*8a272653SPeter Holm#include <err.h> 97*8a272653SPeter Holm#include <sys/types.h> 98*8a272653SPeter Holm#include <err.h> 99*8a272653SPeter Holm#include <fcntl.h> 100*8a272653SPeter Holm#include <stdio.h> 101*8a272653SPeter Holm#include <sys/wait.h> 102*8a272653SPeter Holm#include <unistd.h> 103*8a272653SPeter Holm 104*8a272653SPeter Holm#define BARRIER_CREATE 1 105*8a272653SPeter Holm#define BARRIER_WAIT 2 106*8a272653SPeter Holm#define BARRIER_DELETE 3 107*8a272653SPeter Holm 108*8a272653SPeter Holmvoid 109*8a272653SPeter Holmbarrier(int mode) 110*8a272653SPeter Holm{ 111*8a272653SPeter Holm int fd; 112*8a272653SPeter Holm char path[128]; 113*8a272653SPeter Holm 114*8a272653SPeter Holm if (mode == BARRIER_CREATE) { 115*8a272653SPeter Holm snprintf(path, sizeof(path), "barrier.%d", getpid()); 116*8a272653SPeter Holm if ((fd = open(path, O_RDWR | O_CREAT | O_TRUNC, 0600)) < 0) 117*8a272653SPeter Holm err(1, "%s", path); 118*8a272653SPeter Holm } else if (mode == BARRIER_WAIT) { 119*8a272653SPeter Holm snprintf(path, sizeof(path), "barrier.%d", getppid()); 120*8a272653SPeter Holm for(;;) { 121*8a272653SPeter Holm if (access(path, R_OK) == -1) 122*8a272653SPeter Holm break; 123*8a272653SPeter Holm usleep(10000); 124*8a272653SPeter Holm } 125*8a272653SPeter Holm } else if (mode == BARRIER_DELETE) { 126*8a272653SPeter Holm snprintf(path, sizeof(path), "barrier.%d", getpid()); 127*8a272653SPeter Holm if (unlink(path) == -1) 128*8a272653SPeter Holm err(1, "unlink(%s)", path); 129*8a272653SPeter Holm } else 130*8a272653SPeter Holm errx(1, "Bad barrier mode: %d", mode); 131*8a272653SPeter Holm} 132*8a272653SPeter Holm 133*8a272653SPeter Holmpid_t pid; 134*8a272653SPeter Holmint bufsize; 135*8a272653SPeter Holmint port; 136*8a272653SPeter Holmint alarm_exit; 137*8a272653SPeter Holm 138*8a272653SPeter Holmvoid 139*8a272653SPeter Holmkiller(void) 140*8a272653SPeter Holm{ 141*8a272653SPeter Holm setproctitle("killer"); 142*8a272653SPeter Holm alarm(120); 143*8a272653SPeter Holm barrier(BARRIER_WAIT); 144*8a272653SPeter Holm for (;;) { 145*8a272653SPeter Holm if (pid == 0) 146*8a272653SPeter Holm break; 147*8a272653SPeter Holm if (kill(pid, SIGUSR1) == -1) 148*8a272653SPeter Holm break; 149*8a272653SPeter Holm usleep(1000); 150*8a272653SPeter Holm } 151*8a272653SPeter Holm _exit(0); 152*8a272653SPeter Holm} 153*8a272653SPeter Holm 154*8a272653SPeter Holmvoid 155*8a272653SPeter Holmhandler(int s __unused) 156*8a272653SPeter Holm{ 157*8a272653SPeter Holm} 158*8a272653SPeter Holm 159*8a272653SPeter Holmvoid 160*8a272653SPeter Holmahandler(int s __unused) 161*8a272653SPeter Holm{ 162*8a272653SPeter Holm if (alarm_exit) 163*8a272653SPeter Holm _exit(0); 164*8a272653SPeter Holm} 165*8a272653SPeter Holm 166*8a272653SPeter Holm/* Read form socket, discard */ 167*8a272653SPeter Holmstatic void 168*8a272653SPeter Holmreader(void) { 169*8a272653SPeter Holm int tcpsock, msgsock; 170*8a272653SPeter Holm int on; 171*8a272653SPeter Holm socklen_t len; 172*8a272653SPeter Holm struct sockaddr_in inetaddr, inetpeer; 173*8a272653SPeter Holm int n, *buf; 174*8a272653SPeter Holm 175*8a272653SPeter Holm setproctitle("reader - init"); 176*8a272653SPeter Holm on = 1; 177*8a272653SPeter Holm if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 178*8a272653SPeter Holm err(1, "socket(), %s:%d", __FILE__, __LINE__); 179*8a272653SPeter Holm 180*8a272653SPeter Holm if (setsockopt(tcpsock, 181*8a272653SPeter Holm SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 182*8a272653SPeter Holm err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); 183*8a272653SPeter Holm 184*8a272653SPeter Holm inetaddr.sin_family = AF_INET; 185*8a272653SPeter Holm inetaddr.sin_addr.s_addr = INADDR_ANY; 186*8a272653SPeter Holm inetaddr.sin_port = htons(port); 187*8a272653SPeter Holm inetaddr.sin_len = sizeof(inetaddr); 188*8a272653SPeter Holm 189*8a272653SPeter Holm signal(SIGUSR1, handler); 190*8a272653SPeter Holm alarm(60); 191*8a272653SPeter Holm if (bind(tcpsock, 192*8a272653SPeter Holm (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) 193*8a272653SPeter Holm err(1, "bind(), %s:%d", __FILE__, __LINE__); 194*8a272653SPeter Holm 195*8a272653SPeter Holm if (listen(tcpsock, 5) < 0) 196*8a272653SPeter Holm err(1, "listen(), %s:%d", __FILE__, __LINE__); 197*8a272653SPeter Holm 198*8a272653SPeter Holm len = sizeof(inetpeer); 199*8a272653SPeter Holm if ((msgsock = accept(tcpsock, 200*8a272653SPeter Holm (struct sockaddr *)&inetpeer, &len)) < 0) 201*8a272653SPeter Holm err(1, "accept(), %s:%d", __FILE__, __LINE__); 202*8a272653SPeter Holm 203*8a272653SPeter Holm if ((buf = malloc(bufsize)) == NULL) 204*8a272653SPeter Holm err(1, "malloc(%d), %s:%d", bufsize, __FILE__, __LINE__); 205*8a272653SPeter Holm setproctitle("reader"); 206*8a272653SPeter Holm alarm(0); 207*8a272653SPeter Holm signal(SIGALRM, ahandler); 208*8a272653SPeter Holm for (;;) { 209*8a272653SPeter Holm ualarm(5000, 0); 210*8a272653SPeter Holm if ((n = recvfrom(msgsock, buf, 4, 0, NULL, NULL)) < 0) { 211*8a272653SPeter Holm if (errno == EAGAIN) 212*8a272653SPeter Holm continue; 213*8a272653SPeter Holm err(1, "read(), %s:%d", __FILE__, __LINE__); 214*8a272653SPeter Holm } 215*8a272653SPeter Holm if (n == 0) 216*8a272653SPeter Holm break; 217*8a272653SPeter Holm if (write(msgsock, "OK", 3) != 3) 218*8a272653SPeter Holm err(1, "write ack. %s:%d", __FILE__, __LINE__); 219*8a272653SPeter Holm 220*8a272653SPeter Holm } 221*8a272653SPeter Holm close(msgsock); 222*8a272653SPeter Holm _exit(0); 223*8a272653SPeter Holm} 224*8a272653SPeter Holm 225*8a272653SPeter Holm/* read from stdin, write to socket */ 226*8a272653SPeter Holmstatic void 227*8a272653SPeter Holmwriter(void) { 228*8a272653SPeter Holm int tcpsock, on; 229*8a272653SPeter Holm struct sockaddr_in inetaddr; 230*8a272653SPeter Holm struct hostent *hostent; 231*8a272653SPeter Holm int i, r; 232*8a272653SPeter Holm char line[1024], ack[80];; 233*8a272653SPeter Holm 234*8a272653SPeter Holm setproctitle("writer - init"); 235*8a272653SPeter Holm signal(SIGUSR1, handler); 236*8a272653SPeter Holm alarm(60); 237*8a272653SPeter Holm on = 1; 238*8a272653SPeter Holm for (i = 1; i < 5; i++) { 239*8a272653SPeter Holm if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) 240*8a272653SPeter Holm err(1, "socket(), %s:%d", __FILE__, __LINE__); 241*8a272653SPeter Holm 242*8a272653SPeter Holm if (setsockopt(tcpsock, 243*8a272653SPeter Holm SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) 244*8a272653SPeter Holm err(1, "setsockopt(), %s:%d", __FILE__, __LINE__); 245*8a272653SPeter Holm 246*8a272653SPeter Holm hostent = gethostbyname ("localhost"); 247*8a272653SPeter Holm bzero(&inetaddr, sizeof(inetaddr)); 248*8a272653SPeter Holm memcpy (&inetaddr.sin_addr.s_addr, hostent->h_addr, 249*8a272653SPeter Holm sizeof (struct in_addr)); 250*8a272653SPeter Holm 251*8a272653SPeter Holm inetaddr.sin_family = AF_INET; 252*8a272653SPeter Holm inetaddr.sin_port = htons(port); 253*8a272653SPeter Holm inetaddr.sin_len = sizeof(inetaddr); 254*8a272653SPeter Holm 255*8a272653SPeter Holm r = connect(tcpsock, (struct sockaddr *) &inetaddr, 256*8a272653SPeter Holm sizeof(inetaddr)); 257*8a272653SPeter Holm if (r == 0) 258*8a272653SPeter Holm break; 259*8a272653SPeter Holm sleep(1); 260*8a272653SPeter Holm close(tcpsock); 261*8a272653SPeter Holm } 262*8a272653SPeter Holm if (r < 0) 263*8a272653SPeter Holm err(1, "connect(), %s:%d", __FILE__, __LINE__); 264*8a272653SPeter Holm 265*8a272653SPeter Holm setproctitle("writer"); 266*8a272653SPeter Holm barrier(BARRIER_DELETE); 267*8a272653SPeter Holm alarm(0); 268*8a272653SPeter Holm while (fgets(line, sizeof(line), stdin) != NULL) { 269*8a272653SPeter Holm alarm(10); 270*8a272653SPeter Holm alarm_exit = 1; 271*8a272653SPeter Holm if (write(tcpsock, line, strlen(line)) < 0) 272*8a272653SPeter Holm err(1, "socket write(). %s:%d", __FILE__, __LINE__); 273*8a272653SPeter Holm alarm_exit = 0; 274*8a272653SPeter Holm ualarm(5000, 0); 275*8a272653SPeter Holm if (recvfrom(tcpsock, ack, 4, 0, NULL, NULL) < 0) { 276*8a272653SPeter Holm if (errno == EAGAIN) 277*8a272653SPeter Holm continue; 278*8a272653SPeter Holm err(1, "read(), %s:%d", __FILE__, __LINE__); 279*8a272653SPeter Holm } 280*8a272653SPeter Holm } 281*8a272653SPeter Holm sleep(30); 282*8a272653SPeter Holm return; 283*8a272653SPeter Holm} 284*8a272653SPeter Holm 285*8a272653SPeter Holmint 286*8a272653SPeter Holmmain(int argc, char **argv) 287*8a272653SPeter Holm{ 288*8a272653SPeter Holm 289*8a272653SPeter Holm pid_t kpid; 290*8a272653SPeter Holm 291*8a272653SPeter Holm if (argc != 2) 292*8a272653SPeter Holm errx(1, "Usage: %s <port number>\n", argv[0]); 293*8a272653SPeter Holm port = atoi(argv[1]); 294*8a272653SPeter Holm bufsize = 128; 295*8a272653SPeter Holm 296*8a272653SPeter Holm barrier(BARRIER_CREATE); 297*8a272653SPeter Holm signal(SIGCHLD, SIG_IGN); 298*8a272653SPeter Holm if ((pid = fork()) == 0) 299*8a272653SPeter Holm reader(); 300*8a272653SPeter Holm 301*8a272653SPeter Holm if ((kpid = fork()) == 0) 302*8a272653SPeter Holm killer(); 303*8a272653SPeter Holm 304*8a272653SPeter Holm writer(); 305*8a272653SPeter Holm sleep(1); 306*8a272653SPeter Holm kill(pid, SIGINT); 307*8a272653SPeter Holm kill(kpid, SIGINT); 308*8a272653SPeter Holm 309*8a272653SPeter Holm return (0); 310*8a272653SPeter Holm} 311*8a272653SPeter HolmEOF 312*8a272653SPeter Holmmycc -o /tmp/crlogger -Wall -Wextra -O2 -g /tmp/crlogger.c 313*8a272653SPeter Holmrm -f /tmp/crlogger.c 314*8a272653SPeter Holm 315*8a272653SPeter HolmN=200 316*8a272653SPeter Holmcd /tmp 317*8a272653SPeter Holmstart=`date '+%s'` 318*8a272653SPeter Holmfor i in `jot 40`; do 319*8a272653SPeter Holm for j in `jot $N`; do 320*8a272653SPeter Holm /tmp/crwriter | /tmp/crlogger 1236$j 2>/dev/null & 321*8a272653SPeter Holm done 322*8a272653SPeter Holm 323*8a272653SPeter Holm for j in `jot $N`; do 324*8a272653SPeter Holm wait 325*8a272653SPeter Holm done 326*8a272653SPeter Holm [ $((`date '+%s'` - start)) -gt 1200 ] && break 327*8a272653SPeter Holmdone 328*8a272653SPeter Holmrm -f /tmp/crwriter /tmp/crlogger ./barrier.* 329*8a272653SPeter Holmexit 0 330