]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
FBSD: clean up rx_socket teardown
authorBen Kaduk <kaduk@mit.edu>
Sun, 28 Nov 2010 04:25:03 +0000 (23:25 -0500)
committerDerrick Brashear <shadow@dementia.org>
Tue, 7 Dec 2010 05:36:17 +0000 (21:36 -0800)
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.

Reviewed-on: http://gerrit.openafs.org/3391
Reviewed-by: Matt Benjamin <matt@linuxbox.com>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
(cherry picked from commit 622403c87a8cbcedcd1212fd32414285d103887b)

Change-Id: Ic5cfc4db2ff5b55730de31832b64bc1bf0696767
Reviewed-on: http://gerrit.openafs.org/3459
Tested-by: Derrick Brashear <shadow@dementia.org>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
src/rx/FBSD/rx_knet.c

index 5b7863f24f7ca02f6fe40d21f3d4ef8373d0e385..5cb6956827ae2851b27d36d4f93d54f1a8815e03 100644 (file)
@@ -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,28 +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;
-      }
-      if (so_is_disconn(rx_socket))
-          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();
 }