From b5f9a8c0aa4223d5decb8048fc97d317a494d846 Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Wed, 9 Mar 2011 07:51:02 -0500 Subject: [PATCH] Windows: handle rx busy call channel Register an error code for rx busy call channel detection. Force a retry whenever CM_RX_BUSY_CALL_CHANNEL is received by cm_Analyze(). Log the event to both the internal trace log and the Windows Event Log along with the server address. Reviewed-on: http://gerrit.openafs.org/4183 Reviewed-by: Derrick Brashear Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman (cherry picked from commit 75c2f96364d598ec0c134cb6b366ce067b8b7f49) Change-Id: I932c3d1fdb89f697347c0acc06dc628b3b6175da Reviewed-on: http://gerrit.openafs.org/4185 Tested-by: BuildBot Reviewed-by: Derrick Brashear --- src/WINNT/afsd/afsd_eventlog.c | 1 + src/WINNT/afsd/afsd_eventmessages.mc | 8 ++++++++ src/WINNT/afsd/afsd_init.c | 2 ++ src/WINNT/afsd/cm.h | 3 +++ src/WINNT/afsd/cm_conn.c | 30 ++++++++++++++++++++++------ 5 files changed, 38 insertions(+), 6 deletions(-) diff --git a/src/WINNT/afsd/afsd_eventlog.c b/src/WINNT/afsd/afsd_eventlog.c index 0709246b7..b617d6319 100644 --- a/src/WINNT/afsd/afsd_eventlog.c +++ b/src/WINNT/afsd/afsd_eventlog.c @@ -214,6 +214,7 @@ LogEvent(WORD wEventType, DWORD dwEventID, ...) case MSG_SMB_SEND_PACKET_FAILURE: case MSG_UNEXPECTED_SMB_SESSION_CLOSE: case MSG_RX_MSGSIZE_EXCEEDED: + case MSG_RX_BUSY_CALL_CHANNEL: wNumArgs = 1; lpArgs[0] = va_arg(listArgs, LPTSTR); break; diff --git a/src/WINNT/afsd/afsd_eventmessages.mc b/src/WINNT/afsd/afsd_eventmessages.mc index 9e714a6de..7bbc0d35f 100644 --- a/src/WINNT/afsd/afsd_eventmessages.mc +++ b/src/WINNT/afsd/afsd_eventmessages.mc @@ -430,4 +430,12 @@ Language=English Path MTU may have been exceeded when communicating with server %1, retrying ... . +MessageId= +Severity=Warning +Facility=System +SymbolicName=MSG_RX_BUSY_CALL_CHANNEL +Language=English +Busy call channel when communicating with server %1, retrying ... +. + ;#endif /* __AFSD_EVENTMESSAGES_H_ 1 */ diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index d7e7c2172..37a42cccf 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -1343,6 +1343,8 @@ afsd_InitCM(char **reasonP) afsi_log("rx_SetUdpBufSize %d", rx_udpbufsize); } + rx_SetBusyChannelError(CM_RX_RETRY_BUSY_CALL); + /* initialize RX, and tell it to listen to the callbackport, * which is used for callback RPC messages. */ diff --git a/src/WINNT/afsd/cm.h b/src/WINNT/afsd/cm.h index 1bf23a06b..2474ab483 100644 --- a/src/WINNT/afsd/cm.h +++ b/src/WINNT/afsd/cm.h @@ -100,6 +100,9 @@ #define CM_ERROR_RPC_MOREDATA (CM_ERROR_BASE+63) #define CM_ERROR_BUFFER_OVERFLOW (CM_ERROR_BASE+64) +/* Private RX Errors */ +#define CM_RX_RETRY_BUSY_CALL (-13) + /* Used by cm_FollowMountPoint and cm_FindVolumeByName */ /* And as an index in cm_volume_t */ #define RWVOL 0 diff --git a/src/WINNT/afsd/cm_conn.c b/src/WINNT/afsd/cm_conn.c index 5ccd1feb5..3e519dae2 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -729,18 +729,35 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, * with a smaller mtu size. */ - if (serverp) { + if (serverp) sprintf(addr, "%d.%d.%d.%d", ((serverp->addr.sin_addr.s_addr & 0xff)), ((serverp->addr.sin_addr.s_addr & 0xff00)>> 8), ((serverp->addr.sin_addr.s_addr & 0xff0000)>> 16), ((serverp->addr.sin_addr.s_addr & 0xff000000)>> 24)); - LogEvent(EVENTLOG_WARNING_TYPE, MSG_RX_MSGSIZE_EXCEEDED, addr); - osi_Log1(afsd_logp, "cm_Analyze: Path MTU may have been exceeded addr[%s]", - osi_LogSaveString(afsd_logp,addr)); - } + LogEvent(EVENTLOG_WARNING_TYPE, MSG_RX_MSGSIZE_EXCEEDED, addr); + osi_Log1(afsd_logp, "cm_Analyze: Path MTU may have been exceeded addr[%s]", + osi_LogSaveString(afsd_logp,addr)); + + retry = 1; + } + else if (errorCode == CM_RX_RETRY_BUSY_CALL) { + /* + * RPC failed because the selected call channel + * is currently busy on the server. Unconditionally + * retry the request so an alternate call channel can be used. + */ + if (serverp) + sprintf(addr, "%d.%d.%d.%d", + ((serverp->addr.sin_addr.s_addr & 0xff)), + ((serverp->addr.sin_addr.s_addr & 0xff00)>> 8), + ((serverp->addr.sin_addr.s_addr & 0xff0000)>> 16), + ((serverp->addr.sin_addr.s_addr & 0xff000000)>> 24)); + LogEvent(EVENTLOG_WARNING_TYPE, MSG_RX_BUSY_CALL_CHANNEL, addr); + osi_Log1(afsd_logp, "cm_Analyze: Retry RPC due to busy call channel addr[%s]", + osi_LogSaveString(afsd_logp,addr)); retry = 1; } else if (errorCode >= -64 && errorCode < 0) { @@ -967,7 +984,8 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, } /* If not allowed to retry, don't */ - if (!forcing_new && (reqp->flags & CM_REQ_NORETRY) && (errorCode != RX_MSGSIZE)) + if (!forcing_new && (reqp->flags & CM_REQ_NORETRY) && + (errorCode != RX_MSGSIZE && errorCode != CM_RX_RETRY_BUSY_CALL)) retry = 0; else if (retry && dead_session) retry = 0; -- 2.39.5