ukernel: Fix AFS_GUNLOCK panic in rx_ServerProc
[openafs.git] / src / rx / UKERNEL / rx_knet.c
index d484f85..66f6f01 100644 (file)
 #include <afsconfig.h>
 #include "afs/param.h"
 
-RCSID
-    ("$Header$");
 
 #include "rx/rx_kcommon.h"
-
+#include "rx_atomic.h"
+#include "rx_internal.h"
 
 #define SECONDS_TO_SLEEP       0
 #define NANO_SECONDS_TO_SLEEP  100000000       /* 100 milliseconds */
 #define LOOPS_PER_WAITCHECK    10      /* once per second */
 
+struct usr_socket {
+    int sock;
+    short port;
+};
+
 unsigned short usr_rx_port = 0;
 
 struct usr_ifnet *usr_ifnet = NULL;
 struct usr_in_ifaddr *usr_in_ifaddr = NULL;
 
-void rxk_InitializeSocket();
+void rxk_InitializeSocket(void);
+extern int afs_osi_CheckTimedWaits(void);
 
 void
 afs_rxevent_daemon(void)
@@ -64,8 +69,7 @@ void
 rxi_ListenerProc(osi_socket usockp, int *tnop, struct rx_call **newcallp)
 {
     struct rx_packet *tp;
-    struct sockaddr_storage saddr;
-    int slen;
+    afs_uint32 host;
     u_short port;
     int rc;
 
@@ -75,11 +79,14 @@ rxi_ListenerProc(osi_socket usockp, int *tnop, struct rx_call **newcallp)
      * for processing.
      */
     while (1) {
+        /* See if a check for additional packets was issued */
+        rx_CheckPackets();
+
        tp = rxi_AllocPacket(RX_PACKET_CLASS_RECEIVE);
        usr_assert(tp != NULL);
-       rc = rxi_ReadPacket(usockp, tp, &saddr, &slen);
+       rc = rxi_ReadPacket(usockp, tp, &host, &port);
        if (rc != 0) {
-           tp = rxi_ReceivePacket(tp, usockp, &saddr, slen, tnop, newcallp);
+           tp = rxi_ReceivePacket(tp, usockp, host, port, tnop, newcallp);
            if (newcallp && *newcallp) {
                if (tp) {
                    rxi_FreePacket(tp);
@@ -135,8 +142,8 @@ rxk_Listener(void)
 /* This is the server process request loop. The server process loop
  * becomes a listener thread when rxi_ServerProc returns, and stays
  * listener thread until rxi_ListenerProc returns. */
-void
-rx_ServerProc(void)
+void *
+rx_ServerProc(void *unused)
 {
     osi_socket sock;
     int threadID;
@@ -148,7 +155,6 @@ rx_ServerProc(void)
      * number of threads handling incoming calls */
     threadID = rxi_availProcs++;
 
-    AFS_GUNLOCK();
     while (1) {
        sock = OSI_NULLSOCKET;
        rxi_ServerProc(threadID, newcall, &sock);
@@ -161,7 +167,7 @@ rx_ServerProc(void)
        /* assert(threadID != -1); */
        /* assert(newcall != NULL); */
     }
-    AFS_GLOCK();
+    return NULL;
 }
 
 /*
@@ -175,7 +181,7 @@ rxk_NewSocketHost(afs_uint32 ahost, short aport)
 {
     struct usr_socket *usockp;
 
-    usockp = (struct usr_socket *)afs_osi_Alloc(sizeof(struct usr_socket));
+    usockp = afs_osi_Alloc(sizeof(struct usr_socket));
     usr_assert(usockp != NULL);
 
     usockp->sock = -1;
@@ -198,11 +204,12 @@ rxk_NewSocket(short aport)
 void
 rxk_InitializeSocket(void)
 {
-    int rc, sock, i;
+    int rc, sock;
 #ifdef AFS_USR_AIX_ENV
     unsigned long len, optval, optval0, optlen;
 #else /* AFS_USR_AIX_ENV */
-    int len, optval, optval0, optlen;
+    socklen_t len, optlen;
+    int optval, optval0;
 #endif /* AFS_USR_AIX_ENV */
     struct usr_socket *usockp;
     struct sockaddr_in lcladdr;
@@ -210,7 +217,6 @@ rxk_InitializeSocket(void)
     usr_assert(rx_socket != NULL);
     usockp = (struct usr_socket *)rx_socket;
 
-#undef socket
     sock = socket(PF_INET, SOCK_DGRAM, 0);
     usr_assert(sock >= 0);
 
@@ -223,7 +229,7 @@ rxk_InitializeSocket(void)
     len = sizeof(struct sockaddr_in);
     rc = getsockname(sock, (struct sockaddr *)&lcladdr, &len);
     usr_assert(rc >= 0);
-#ifdef AFS_USR_LINUX22_ENV
+#ifdef AFS_USR_LINUX_ENV
     optval0 = 131070;
 #else
     optval0 = 131072;
@@ -236,7 +242,7 @@ rxk_InitializeSocket(void)
     rc = getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (void *)&optval, &optlen);
     usr_assert(rc == 0);
     /* usr_assert(optval == optval0); */
-#ifdef AFS_USR_LINUX22_ENV
+#ifdef AFS_USR_LINUX_ENV
     optval0 = 131070;
 #else
     optval0 = 131072;
@@ -257,6 +263,10 @@ rxk_InitializeSocket(void)
     usr_assert(rc == 0);
 #endif /* AFS_USR_AIX_ENV */
 
+#ifdef FD_CLOEXEC
+    fcntl(sock, F_SETFD, FD_CLOEXEC);
+#endif
+
     usockp->sock = sock;
     usockp->port = lcladdr.sin_port;
 
@@ -280,12 +290,11 @@ osi_StopListener(void)
 }
 
 int
-osi_NetSend(osi_socket sockp, struct sockaddr_storage *addr, int addrlen,
-           struct iovec *iov, int nio, afs_int32 size, int stack)
+osi_NetSend(osi_socket sockp, struct sockaddr_in *addr, struct iovec *iov,
+           int nio, afs_int32 size, int stack)
 {
     int rc;
     int i;
-    unsigned long tmp;
     struct usr_socket *usockp = (struct usr_socket *)sockp;
     struct msghdr msg;
     struct iovec tmpiov[64];
@@ -301,7 +310,7 @@ osi_NetSend(osi_socket sockp, struct sockaddr_storage *addr, int addrlen,
 
     memset(&msg, 0, sizeof(msg));
     msg.msg_name = (void *)addr;
-    msg.msg_namelen = addrlen;
+    msg.msg_namelen = sizeof(struct sockaddr_in);
     msg.msg_iov = &tmpiov[0];
     msg.msg_iovlen = nio;
 
@@ -334,9 +343,10 @@ rx_Finalize(void)
 int
 rxi_Recvmsg(osi_socket socket, struct msghdr *msg_p, int flags)
 {
+    struct usr_socket *usock = (struct usr_socket *)socket;
     int ret;
     do {
-       ret = recvmsg(socket->sock, msg_p, flags);
+       ret = recvmsg(usock->sock, msg_p, flags);
     } while (ret == -1 && errno == EAGAIN);
     return ret;
 }