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# Threaded version of unix_socket_detach.sh by 30# Mark Johnston <markj@FreeBSD.org> 31 32# "panic: __rw_wlock_hard: recursing but non-recursive rw unp_link_rwlock @ 33# ../../../kern/uipc_usrreq.c:655" seen. 34# Fixed in r303855. 35 36. ../default.cfg 37 38cd /tmp 39cat > unix_socket_detach2.c <<EOF 40#include <sys/types.h> 41#include <sys/socket.h> 42#include <sys/un.h> 43 44#include <machine/atomic.h> 45 46#include <err.h> 47#include <fcntl.h> 48#include <pthread.h> 49#include <signal.h> 50#include <stdio.h> 51#include <stdlib.h> 52#include <string.h> 53#include <unistd.h> 54 55static sig_atomic_t done_testing; 56static struct sockaddr_un sun; 57static long success; 58static char *file; 59 60static void 61handler(int i __unused) { 62 done_testing = 1; 63} 64 65static void * 66t1(void *data __unused) 67{ 68 int one, sd; 69 70 while (done_testing == 0) { 71 sd = socket(PF_LOCAL, SOCK_STREAM, 0); 72 if (sd < 0) 73 err(1, "socket"); 74 one = 1; 75 if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &one, 76 sizeof(one)) < 0) 77 err(1, "setsockopt"); 78 if (bind(sd, (struct sockaddr *)&sun, sizeof(sun)) < 0) { 79 close(sd); 80 continue; 81 } 82 if (listen(sd, 10) != 0) 83 err(1, "listen"); 84 usleep(random() % 10); 85 success++; 86 (void)close(sd); 87 (void)unlink(file); 88 } 89 90 return (NULL); 91} 92 93static void * 94t2(void *data __unused) 95{ 96 int flags, sd; 97 98 while (done_testing == 0) { 99 sd = socket(PF_LOCAL, SOCK_STREAM, 0); 100 if (sd < 0) 101 err(1, "socket"); 102 if ((flags = fcntl(sd, F_GETFL, 0)) < 0) 103 err(1, "fcntl(F_GETFL)"); 104 flags |= O_NONBLOCK; 105 if (fcntl(sd, F_SETFL, flags) < 0) 106 err(1, "fcntl(F_SETFL)"); 107 (void)connect(sd, (struct sockaddr *)&sun, sizeof(sun)); 108 usleep(random() % 10); 109 (void)close(sd); 110 } 111 112 return (NULL); 113} 114 115int 116main(void) 117{ 118 pthread_t tid[2]; 119 int r; 120 121 file = "unix_socket_detach2.socket"; 122 memset(&sun, 0, sizeof(sun)); 123 sun.sun_family = AF_LOCAL; 124 sun.sun_len = sizeof(sun); 125 snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", file); 126 127 signal(SIGALRM, handler); 128 alarm(300); 129 130 if ((r = pthread_create(&tid[0], NULL, t1, NULL)) != 0) 131 errc(1, r, "pthread_create"); 132 if ((r = pthread_create(&tid[1], NULL, t2, NULL)) != 0) 133 errc(1, r, "pthread_create"); 134 135 if ((r = pthread_join(tid[0], NULL)) != 0) 136 errc(1, r, "pthread_join"); 137 if ((r = pthread_join(tid[1], NULL)) != 0) 138 errc(1, r, "pthread_join"); 139 140 if (success < 100) { 141 fprintf(stderr, "FAIL with only %ld\n", success); 142 return (1); 143 } 144 145 return (0); 146} 147EOF 148 149mycc -o unix_socket_detach2 -Wall -Wextra -O2 -g unix_socket_detach2.c \ 150 -lpthread || exit 1 151 152rm -f unix_socket_detach2.socket 153/tmp/unix_socket_detach2 154s=$? 155 156rm -f unix_socket_detach2.c unix_socket_detach2 unix_socket_detach2.socket 157exit $s 158