From: Ben Kaduk Date: Sun, 28 Nov 2010 04:25:03 +0000 (-0500) Subject: FBSD: clean up rx_socket teardown X-Git-Tag: openafs-devel-1_7_1~1165 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=622403c87a8cbcedcd1212fd32414285d103887b FBSD: clean up rx_socket teardown We had previously been waiting for the SO_ISDISCONNECTED flag to show up in the so_state field, but the flags are not really used for stateless protocols such as UDP, and that flag never shows up. Even with a full three-second wait, the rxk_Listener sometimes still failed to fully terminate, preventing the reuse of the rx port for a restarted afsd. Copy from Solaris and loop until rxk_ListenerPid is zero, doing bogus one-byte NetSends in the body of the loop. Change-Id: I6a5ad4509549fa64c551af642ef5867602b182c0 Reviewed-on: http://gerrit.openafs.org/3391 Reviewed-by: Matt Benjamin Tested-by: BuildBot Reviewed-by: Derrick Brashear --- diff --git a/src/rx/FBSD/rx_knet.c b/src/rx/FBSD/rx_knet.c index cbc6deb..5cb6956 100644 --- a/src/rx/FBSD/rx_knet.c +++ b/src/rx/FBSD/rx_knet.c @@ -70,13 +70,15 @@ osi_NetReceive(osi_socket asocket, struct sockaddr_in *addr, return code; } -#define so_is_disconn(so) ((so)->so_state & SS_ISDISCONNECTED) - extern int rxk_ListenerPid; void osi_StopListener(void) { + struct sockaddr_in taddr; + struct iovec dvec; struct proc *p; + char c; + c = '\0'; /* * Have to drop global lock to safely do this. @@ -95,27 +97,25 @@ osi_StopListener(void) } else afs_warn("osi_StopListener: rxk_Listener not found (pid %u)\n", rxk_ListenerPid); -#ifdef AFS_FBSD70_ENV - { - /* Avoid destroying socket until osi_NetReceive has - * had a chance to clean up */ - int tries; - struct mtx s_mtx; - - MUTEX_INIT(&s_mtx, "rx_shutdown_mutex", MUTEX_DEFAULT, 0); - MUTEX_ENTER(&s_mtx); - tries = 3; - while ((tries > 0) && (!so_is_disconn(rx_socket))) { - afs_warn("osi_StopListener: waiting (%d) ", tries); - msleep(&osi_StopListener, &s_mtx, PSOCK | PCATCH, - "rx_shutdown_timedwait", 1 * hz); - --tries; - } - soclose(rx_socket); - MUTEX_EXIT(&s_mtx); - MUTEX_DESTROY(&s_mtx); + + /* Avoid destroying socket until osi_NetReceive has + * had a chance to clean up. Otherwise we can't restart. */ + bzero(&taddr, sizeof(taddr)); + taddr.sin_len = sizeof(struct sockaddr_in); + taddr.sin_family = AF_INET; + taddr.sin_port = rx_port; + taddr.sin_addr.s_addr = htonl(0x7f000001); /* no place like localhost */ + bzero(&dvec, sizeof(dvec)); + dvec.iov_base = &c; + dvec.iov_len = 1; + while(rxk_ListenerPid) { + afs_warn("waiting for rxk_ListenerPid to die\n"); + osi_NetSend(rx_socket, &taddr, &dvec, 1, 1, 0); + afs_osi_Sleep(&rxk_ListenerPid); } -#endif + /* in theory, we are now the only people doing anything with rx_socket */ + soclose(rx_socket); + if (haveGlock) AFS_GLOCK(); }