]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
RX: Avoid timing out non-kernel busy channels
authorAndrew Deason <adeason@sinenomine.net>
Mon, 7 Mar 2011 17:08:26 +0000 (11:08 -0600)
committerDerrick Brashear <shadow@dementia.org>
Wed, 9 Mar 2011 12:58:25 +0000 (04:58 -0800)
When we encounter a "busy" call channel (indicated by receiving
RX_PACKET_TYPE_BUSY packets), we can error out a call with
RX_CALL_TIMEOUT to try and get the application code to retry the call.
However, many RX applications are not aware of this, and will just
fail with an error upon receiving a single busy packet.

So instead, make this behavior optional, and only do it if the
application tells us what specific error it expects to receive when a
busy call channel is detected. Enable this behavior for the Unix cache
manager, as it can cope with receiving an RX_CALL_TIMEOUT error in
this scenario.

Bump shlibafsrpc minor version to 5 instead of 3, so we don't collide
with the shlibafsrpc versions on the master branch.

Reviewed-on: http://gerrit.openafs.org/4159
Reviewed-by: Jeffrey Altman <jaltman@openafs.org>
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
(cherry picked from commit eddcee3ad518dff9fbfda790640c5bfd2e97ef5a)

Change-Id: I38981ad3e3c2cbb03c516c02481a2f44cb5f9acf
Reviewed-on: http://gerrit.openafs.org/4182
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Derrick Brashear <shadow@dementia.org>
src/afs/afs_call.c
src/afs/afs_pag_call.c
src/libafsrpc/afsrpc.def
src/libafsrpc/afsrpc.exp
src/rx/rx.c
src/rx/rx_prototypes.h
src/shlibafsrpc/Makefile.in
src/shlibafsrpc/libafsrpc.map

index 909fb5c46c84ab6bda86b4935612f13411738536..2f7dae3fdeaf906a2c1cf1177de96a937ca176eb 100644 (file)
@@ -110,6 +110,8 @@ afs_InitSetup(int preallocs)
 
     memset(afs_zeros, 0, AFS_ZEROS);
 
+    rx_SetBusyChannelError(RX_CALL_TIMEOUT);
+
     /* start RX */
     if(!afscall_set_rxpck_received)
     rx_extraPackets = AFS_NRXPACKETS;  /* smaller # of packets */
index 2df8c02e4e64c8a99541cad5fdeac61ebfd0a042..b1ea8829540991024a4a4014844079a357b62de6 100644 (file)
@@ -101,6 +101,7 @@ afspag_Init(afs_int32 nfs_server_addr)
     AFS_GLOCK();
 
     afs_InitStats();
+    rx_SetBusyChannelError(RX_CALL_TIMEOUT);
     rx_Init(htons(7001));
 
     AFS_STATCNT(afs_ResourceInit);
index ef1d0f53a86f3b14eb697a3220d159e9f83acf67..08ae8dfe297d6263a72d622f2611805843f66b6f 100755 (executable)
@@ -284,6 +284,8 @@ EXPORTS
         registerthread                          @287
         swapthreadname                          @288
 
+       rx_SetBusyChannelError                  @304
+
 ; for performance testing
         rx_TSFPQGlobSize                        @2001 DATA
         rx_TSFPQLocalMax                        @2002 DATA
index 0355bc9b169a36d5adb2f9382d5f36f0bfe63556..7dd277991d3e352d5587bd4c1365aba4496a0543 100755 (executable)
@@ -34,6 +34,7 @@ rx_ReleaseCachedConnection
 rx_ServerProc
 rx_StartServer
 rx_WriteProc
+rx_SetBusyChannelError
 rxevent_Init
 rxevent_Post
 rxkad_GetServerInfo
index 5058ae53592daf52800af2089cb60441f7cb1771..4ff481fb745df4b40ab36842894f8a8860ccfa60 100644 (file)
@@ -158,6 +158,16 @@ static unsigned int rxi_rpc_peer_stat_cnt;
 
 static unsigned int rxi_rpc_process_stat_cnt;
 
+/*
+ * rxi_busyChannelError is the error to return to the application when a call
+ * channel appears busy (inferred from the receipt of RX_PACKET_TYPE_BUSY
+ * packets on the channel), and there are other call channels in the
+ * connection that are not busy. If 0, we do not return errors upon receiving
+ * busy packets; we just keep trying on the same call channel until we hit a
+ * timeout.
+ */
+static afs_int32 rxi_busyChannelError = 0;
+
 #if !defined(offsetof)
 #include <stddef.h>            /* for definition of offsetof() */
 #endif
@@ -612,6 +622,20 @@ rx_Init(u_int port)
     return rx_InitHost(htonl(INADDR_ANY), port);
 }
 
+/**
+ * Sets the error generated when a busy call channel is detected.
+ *
+ * @param[in] error The error to return for a call on a busy channel.
+ *
+ * @pre Neither rx_Init nor rx_InitHost have been called yet
+ */
+void
+rx_SetBusyChannelError(afs_int32 error)
+{
+    osi_Assert(rxinit_status != 0);
+    rxi_busyChannelError = error;
+}
+
 /* called with unincremented nRequestsRunning to see if it is OK to start
  * a new thread in this service.  Could be "no" for two reasons: over the
  * max quota, or would prevent others from reaching their min quota.
@@ -2830,6 +2854,7 @@ rxi_FindConnection(osi_socket socket, afs_uint32 host,
  *      call->conn->lastBusy[call->channel] != 0)
  *
  * @pre call->lock is held
+ * @pre rxi_busyChannelError is nonzero
  *
  * @note call->lock is dropped and reacquired
  */
@@ -2894,10 +2919,10 @@ rxi_CheckBusy(struct rx_call *call)
         * rx_conn that the application thread might be able to use. We know
         * that we have the correct call since callNumber is unchanged, and we
         * know that the call is still busy. So, set the call error state to
-        * RX_CALL_TIMEOUT so the application can retry the request, presumably
-        * on a less-busy call channel. */
+        * rxi_busyChannelError so the application can retry the request,
+        * presumably on a less-busy call channel. */
 
-       rxi_CallError(call, RX_CALL_TIMEOUT);
+       rxi_CallError(call, rxi_busyChannelError);
     }
 }
 
@@ -5778,7 +5803,7 @@ rxi_Start(struct rxevent *event,
        call->resendEvent = NULL;
        resending = 1;
 
-       if ((call->flags & RX_CALL_PEER_BUSY)) {
+       if (rxi_busyChannelError && (call->flags & RX_CALL_PEER_BUSY)) {
            rxi_CheckBusy(call);
        }
 
index 52bbf6d12b93d1fe42d32a862b1dc6ee7f6d3c78..522756605274f06e7bf23621526e04db6025e769 100644 (file)
@@ -24,6 +24,7 @@ extern int (*rx_almostSent) (struct rx_packet *, struct sockaddr_in *);
 extern void rx_SetEpoch(afs_uint32 epoch);
 extern int rx_Init(u_int port);
 extern int rx_InitHost(u_int host, u_int port);
+extern void rx_SetBusyChannelError(afs_int32 error);
 #ifdef AFS_NT40_ENV
 extern void rx_DebugOnOff(int on);
 extern void rx_StatsOnOff(int on);
index 51d3d9f20b9cd961503477f683e5c6b17390c7a3..6363b5e9577eba7f19c45fc2cf6cce279dbe4978 100644 (file)
@@ -1,7 +1,7 @@
 # API version. When something changes, increment as appropriate. 
 # Ignore at your own risk.
 LIBAFSRPCMAJOR=1
-LIBAFSRPCMINOR=2
+LIBAFSRPCMINOR=5
 
 # Copyright 2000, International Business Machines Corporation and others.
 # All Rights Reserved.
index 326b3954ba89232d5b06701a6703c6c70e386473..2baef659900432cbc2d3c771b42c3900248a8e42 100755 (executable)
        afs_xdr_string;
        afs_xdr_vector;
        rx_InterruptCall;
+       rx_SetBusyChannelError;
     local:
        *;
 };