From: Jeffrey Altman Date: Mon, 28 Nov 2011 17:58:02 +0000 (-0500) Subject: rx: RX_CALL_IDLE and RX_CALL_BUSY X-Git-Tag: openafs-stable-1_8_0pre1~2815 X-Git-Url: https://git.openafs.org/?p=openafs.git;a=commitdiff_plain;h=c7673f4fad8e8b9390564e3cbfa11d5f1b52ba2f rx: RX_CALL_IDLE and RX_CALL_BUSY Allocate new Rx error codes for Idle and Busy calls but do not send these errors on the wire. They are only intended for local use. RX_CALL_IDLE is an indication to an application that requests it that the rx peer is maintaining an open call channel but has not sent any actual data for the length of the registered idle dead timeout. RX_CALL_BUSY is an indication to an application that requests it that the rx peer believes the selected call channel is in use by a pre-existing call. When either RX_CALL_IDLE or RX_CALL_BUSY are assigned as the call error and an abort must be sent to the rx peer, the errors are translated to RX_CALL_TIMEOUT. This is necessary because it is not possible to add new Rx error values in a method that is safe for peers that are not expecting them. This patchset also documents which Rx errors defined in rx.h are used on the wire and which are not. The Unix and Windows cache managers are updated to build with these new error codes. Change-Id: Ib236f27b88d503c68134534bb069e12dd83537d8 Reviewed-on: http://gerrit.openafs.org/6128 Tested-by: BuildBot Reviewed-by: Jeffrey Altman Tested-by: Jeffrey Altman --- diff --git a/src/WINNT/afsd/afsd_init.c b/src/WINNT/afsd/afsd_init.c index d4dc292..8d195bf 100644 --- a/src/WINNT/afsd/afsd_init.c +++ b/src/WINNT/afsd/afsd_init.c @@ -1412,7 +1412,7 @@ afsd_InitCM(char **reasonP) afsi_log("rx_SetUdpBufSize %d", rx_udpbufsize); } - rx_SetBusyChannelError(CM_RX_RETRY_BUSY_CALL); + rx_SetBusyChannelError(1); /* Activate busy call channel reporting */ /* 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 c7513b5..5d9f293 100644 --- a/src/WINNT/afsd/cm.h +++ b/src/WINNT/afsd/cm.h @@ -34,9 +34,6 @@ #define CM_FLAG_NOPROBE 0x100 /* For use with cm_GetCellxxx - do not probe server status */ #define CM_FLAG_DFS_REFERRAL 0x200 /* The request is a DFS Referral - the last char of the lookup name may be missing */ -/* 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 0b07c05..bf33e49 100644 --- a/src/WINNT/afsd/cm_conn.c +++ b/src/WINNT/afsd/cm_conn.c @@ -776,7 +776,7 @@ cm_Analyze(cm_conn_t *connp, cm_user_t *userp, cm_req_t *reqp, retry = 1; } - else if (errorCode == CM_RX_RETRY_BUSY_CALL) { + else if (errorCode == RX_CALL_BUSY) { /* * RPC failed because the selected call channel * is currently busy on the server. Unconditionally @@ -1019,7 +1019,7 @@ 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 && errorCode != CM_RX_RETRY_BUSY_CALL)) + (errorCode != RX_MSGSIZE && errorCode != RX_CALL_BUSY)) retry = 0; else if (retry && dead_session) retry = 0; @@ -1237,13 +1237,10 @@ static void cm_NewRXConnection(cm_conn_t *tcp, cm_ucell_t *ucellp, rx_SetConnDeadTime(tcp->rxconnp, ConnDeadtimeout); rx_SetConnHardDeadTime(tcp->rxconnp, HardDeadtimeout); - /* Disable Idle Dead Timeout processing as it can lead to data corruption. */ - rx_SetConnIdleDeadTime(tcp->rxconnp, IdleDeadtimeout); - /* - * Register the error to be returned on an idle dead timeout + * Setting idle dead timeout to a non-zero value activates RX_CALL_IDLE errors */ - rx_SetServerConnIdleDeadErr(tcp->rxconnp, RX_CALL_DEAD); + rx_SetConnIdleDeadTime(tcp->rxconnp, IdleDeadtimeout); /* * Let the Rx library know that we can auto-retry if an diff --git a/src/WINNT/afsd/cm_server.c b/src/WINNT/afsd/cm_server.c index 32eeff8..0dba842 100644 --- a/src/WINNT/afsd/cm_server.c +++ b/src/WINNT/afsd/cm_server.c @@ -172,13 +172,13 @@ cm_PingServer(cm_server_t *tsp) } /* got an unauthenticated connection to this server */ lock_ObtainMutex(&tsp->mx); - if (code >= 0 || code == RXGEN_OPCODE || code == CM_RX_RETRY_BUSY_CALL) { + if (code >= 0 || code == RXGEN_OPCODE || code == RX_CALL_BUSY) { /* mark server as up */ _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN); tsp->downTime = 0; /* we currently handle 32-bits of capabilities */ - if (code != RXGEN_OPCODE && code != CM_RX_RETRY_BUSY_CALL && + if (code != RXGEN_OPCODE && code != RX_CALL_BUSY && caps.Capabilities_len > 0) { tsp->capabilities = caps.Capabilities_val[0]; xdr_free((xdrproc_t) xdr_Capabilities, &caps); @@ -457,13 +457,13 @@ static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp) wasDown = tsp->flags & CM_SERVERFLAG_DOWN; if (results[i] >= 0 || results[i] == RXGEN_OPCODE || - results[i] == CM_RX_RETRY_BUSY_CALL) { + results[i] == RX_CALL_BUSY) { /* mark server as up */ _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN); tsp->downTime = 0; /* we currently handle 32-bits of capabilities */ - if (results[i] != RXGEN_OPCODE && results[i] != CM_RX_RETRY_BUSY_CALL && + if (results[i] != RXGEN_OPCODE && results[i] != RX_CALL_BUSY && caps[i].Capabilities_len > 0) { tsp->capabilities = caps[i].Capabilities_val[0]; xdr_free((xdrproc_t) xdr_Capabilities, &caps[i]); @@ -623,7 +623,7 @@ static void cm_CheckServersMulti(afs_uint32 flags, cm_cell_t *cellp) lock_ObtainMutex(&tsp->mx); wasDown = tsp->flags & CM_SERVERFLAG_DOWN; - if (results[i] >= 0 || results[i] == CM_RX_RETRY_BUSY_CALL) { + if (results[i] >= 0 || results[i] == RX_CALL_BUSY) { /* mark server as up */ _InterlockedAnd(&tsp->flags, ~CM_SERVERFLAG_DOWN); tsp->downTime = 0; diff --git a/src/WINNT/afsd/cm_utils.c b/src/WINNT/afsd/cm_utils.c index 0d2f713..2b2119c 100644 --- a/src/WINNT/afsd/cm_utils.c +++ b/src/WINNT/afsd/cm_utils.c @@ -213,6 +213,8 @@ long cm_MapRPCError(long error, cm_req_t *reqp) if (error == RX_CALL_DEAD || error == RX_CALL_TIMEOUT || + error == RX_CALL_BUSY || + error == RX_CALL_IDLE || error == RX_MSGSIZE) error = CM_ERROR_RETRY; else if (error < 0) @@ -277,6 +279,8 @@ long cm_MapRPCErrorRmdir(long error, cm_req_t *reqp) if (error == RX_CALL_DEAD || error == RX_CALL_TIMEOUT || + error == RX_CALL_BUSY || + error == RX_CALL_IDLE || error == RX_MSGSIZE) error = CM_ERROR_RETRY; else if (error == VNOVNODE) @@ -325,6 +329,8 @@ long cm_MapVLRPCError(long error, cm_req_t *reqp) if (error == RX_CALL_DEAD || error == RX_CALL_TIMEOUT || + error == RX_CALL_BUSY || + error == RX_CALL_IDLE || error == RX_MSGSIZE) error = CM_ERROR_RETRY; else if (error == RX_RESTARTING) diff --git a/src/afs/afs_analyze.c b/src/afs/afs_analyze.c index 0023d5b..6950c96 100644 --- a/src/afs/afs_analyze.c +++ b/src/afs/afs_analyze.c @@ -569,7 +569,7 @@ afs_Analyze(struct afs_conn *aconn, struct rx_connection *rxconn, shouldRetry = 1; goto out; } - if (acode == RX_CALL_TIMEOUT) { + if (acode == RX_CALL_TIMEOUT || acode == RX_CALL_IDLE || acode == RX_CALL_BUSY) { serversleft = afs_BlackListOnce(areq, afid, tsp); if (afid) tvp = afs_FindVolume(afid, READ_LOCK); diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index cdb034e..34b0655 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -113,7 +113,7 @@ afs_InitSetup(int preallocs) memset(afs_zeros, 0, AFS_ZEROS); - rx_SetBusyChannelError(RX_CALL_TIMEOUT); + rx_SetBusyChannelError(1); /* turn on busy call error reporting */ /* start RX */ if(!afscall_set_rxpck_received) diff --git a/src/afs/afs_conn.c b/src/afs/afs_conn.c index 8d456a4..957365b 100644 --- a/src/afs/afs_conn.c +++ b/src/afs/afs_conn.c @@ -460,8 +460,8 @@ afs_ConnBySA(struct srvAddr *sap, unsigned short aport, afs_int32 acell, if (service == 52) { rx_SetConnHardDeadTime(tc->id, afs_rx_harddead); } - /* set to a RX_CALL_TIMEOUT error to allow MTU retry to trigger */ - rx_SetServerConnIdleDeadErr(tc->id, RX_CALL_DEAD); + + /* Setting idle dead time to non-zero activates RX_CALL_IDLE errors. */ rx_SetConnIdleDeadTime(tc->id, afs_rx_idledead); /* diff --git a/src/afs/afs_pag_call.c b/src/afs/afs_pag_call.c index 941fda5..6094428 100644 --- a/src/afs/afs_pag_call.c +++ b/src/afs/afs_pag_call.c @@ -98,7 +98,7 @@ afspag_Init(afs_int32 nfs_server_addr) AFS_GLOCK(); afs_InitStats(); - rx_SetBusyChannelError(RX_CALL_TIMEOUT); + rx_SetBusyChannelError(1); /* turn on busy call error reporting */ rx_Init(htons(7001)); AFS_STATCNT(afs_ResourceInit); diff --git a/src/libafsrpc/afsrpc.def b/src/libafsrpc/afsrpc.def index a178e2a..5cc9143 100755 --- a/src/libafsrpc/afsrpc.def +++ b/src/libafsrpc/afsrpc.def @@ -308,7 +308,7 @@ EXPORTS rx_GetSecurityHeaderSize @315 rx_SetSecurityMaxTrailerSize @316 rx_GetSecurityMaxTrailerSize @317 - rx_SetServerConnIdleDeadErr @318 + ; @318 is available rx_SetMsgsizeRetryErr @319 rx_IsServerConn @320 rx_IsClientConn @321 diff --git a/src/rx/rx.c b/src/rx/rx.c index e3a4c6a..2a4580e 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -163,12 +163,12 @@ 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. + * rxi_busyChannelError is a boolean. It indicates whether or not RX_CALL_BUSY + * errors should be reported 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; @@ -755,17 +755,17 @@ rx_rto_setPeerTimeoutSecs(struct rx_peer *peer, int secs) { } /** - * Sets the error generated when a busy call channel is detected. + * Enables or disables the busy call channel error (RX_CALL_BUSY). * - * @param[in] error The error to return for a call on a busy channel. + * @param[in] onoff Non-zero to enable busy call channel errors. * * @pre Neither rx_Init nor rx_InitHost have been called yet */ void -rx_SetBusyChannelError(afs_int32 error) +rx_SetBusyChannelError(afs_int32 onoff) { osi_Assert(rxinit_status != 0); - rxi_busyChannelError = error; + rxi_busyChannelError = onoff ? 1 : 0; } /** @@ -1111,6 +1111,7 @@ void rx_SetConnIdleDeadTime(struct rx_connection *conn, int seconds) { conn->idleDeadTime = seconds; + conn->idleDeadDetection = (seconds ? 1 : 0); rxi_CheckConnTimeouts(conn); } @@ -2980,8 +2981,8 @@ rxi_FindConnection(osi_socket socket, afs_uint32 host, conn->nSpecific = 0; conn->specific = NULL; rx_SetConnDeadTime(conn, service->connDeadTime); - rx_SetConnIdleDeadTime(conn, service->idleDeadTime); - rx_SetServerConnIdleDeadErr(conn, service->idleDeadErr); + conn->idleDeadTime = service->idleDeadTime; + conn->idleDeadDetection = service->idleDeadErr ? 1 : 0; for (i = 0; i < RX_MAXCALLS; i++) { conn->twind[i] = rx_initSendWindow; conn->rwind[i] = rx_initReceiveWindow; @@ -3081,7 +3082,7 @@ rxi_CheckBusy(struct rx_call *call) * rxi_busyChannelError so the application can retry the request, * presumably on a less-busy call channel. */ - rxi_CallError(call, rxi_busyChannelError); + rxi_CallError(call, RX_CALL_BUSY); } } @@ -5008,18 +5009,27 @@ struct rx_packet * rxi_SendCallAbort(struct rx_call *call, struct rx_packet *packet, int istack, int force) { - afs_int32 error; + afs_int32 error, cerror; struct clock when, now; if (!call->error) return packet; + switch (call->error) { + case RX_CALL_IDLE: + case RX_CALL_BUSY: + cerror = RX_CALL_TIMEOUT; + break; + default: + cerror = call->error; + } + /* Clients should never delay abort messages */ if (rx_IsClientConn(call->conn)) force = 1; - if (call->abortCode != call->error) { - call->abortCode = call->error; + if (call->abortCode != cerror) { + call->abortCode = cerror; call->abortCount = 0; } @@ -5029,7 +5039,7 @@ rxi_SendCallAbort(struct rx_call *call, struct rx_packet *packet, rxevent_Cancel(&call->delayedAbortEvent, call, RX_CALL_REFCOUNT_ABORT); } - error = htonl(call->error); + error = htonl(cerror); call->abortCount++; packet = rxi_SendSpecial(call, call->conn, packet, RX_PACKET_TYPE_ABORT, @@ -6127,6 +6137,7 @@ rxi_CheckCall(struct rx_call *call) afs_uint32 fudgeFactor; int cerror = 0; int newmtu = 0; + int idle_timeout = 0; #ifdef AFS_GLOBAL_RXLOCK_KERNEL if (call->flags & RX_CALL_TQ_BUSY) { @@ -6204,25 +6215,29 @@ rxi_CheckCall(struct rx_call *call) * attached process can die reasonably gracefully. */ } - if (conn->idleDeadTime) { - idleDeadTime = conn->idleDeadTime + fudgeFactor; - } + if (conn->idleDeadDetection) { + if (conn->idleDeadTime) { + idleDeadTime = conn->idleDeadTime + fudgeFactor; + } - /* see if we have a non-activity timeout */ - if (call->startWait && idleDeadTime - && ((call->startWait + idleDeadTime) < now) && - (call->flags & RX_CALL_READER_WAIT)) { - if (call->state == RX_STATE_ACTIVE) { - cerror = RX_CALL_TIMEOUT; - goto mtuout; - } - } - if (call->lastSendData && idleDeadTime && (conn->idleDeadErr != 0) - && ((call->lastSendData + idleDeadTime) < now)) { - if (call->state == RX_STATE_ACTIVE) { - cerror = conn->idleDeadErr; - goto mtuout; - } + if (idleDeadTime) { + /* see if we have a non-activity timeout */ + if (call->startWait && ((call->startWait + idleDeadTime) < now) && + (call->flags & RX_CALL_READER_WAIT)) { + if (call->state == RX_STATE_ACTIVE) { + cerror = RX_CALL_TIMEOUT; + goto mtuout; + } + } + + if (call->lastSendData && ((call->lastSendData + idleDeadTime) < now)) { + if (call->state == RX_STATE_ACTIVE) { + cerror = conn->service ? conn->service->idleDeadErr : RX_CALL_IDLE; + idle_timeout = 1; + goto mtuout; + } + } + } } if (conn->hardDeadTime) { @@ -6238,8 +6253,8 @@ rxi_CheckCall(struct rx_call *call) } return 0; mtuout: - if (conn->msgsizeRetryErr && cerror != RX_CALL_TIMEOUT - && call->lastReceiveTime) { + if (conn->msgsizeRetryErr && cerror != RX_CALL_TIMEOUT && !idle_timeout && + call->lastReceiveTime) { int oldMTU = conn->peer->ifMTU; /* if we thought we could send more, perhaps things got worse */ @@ -6459,7 +6474,7 @@ rxi_GrowMTUEvent(struct rxevent *event, void *arg1, void *dummy, int dummy2) */ if ((conn->peer->maxPacketSize != 0) && (conn->peer->natMTU < RX_MAX_PACKET_SIZE) && - (conn->idleDeadErr)) + conn->idleDeadDetection) (void)rxi_SendAck(call, NULL, 0, RX_ACK_MTU, 0); rxi_ScheduleGrowMTUEvent(call, 0); MUTEX_EXIT(&call->lock); diff --git a/src/rx/rx.h b/src/rx/rx.h index 8572834..5ab0c46 100644 --- a/src/rx/rx.h +++ b/src/rx/rx.h @@ -79,7 +79,6 @@ extern void rx_SetSecurityHeaderSize(struct rx_connection *conn, int size); extern int rx_GetSecurityHeaderSize(struct rx_connection *conn); extern void rx_SetSecurityMaxTrailerSize(struct rx_connection *conn, int size); extern int rx_GetSecurityMaxTrailerSize(struct rx_connection *conn); -extern void rx_SetServerConnIdleDeadErr(struct rx_connection *conn, int err); extern void rx_SetMsgsizeRetryErr(struct rx_connection *conn, int err); extern int rx_IsServerConn(struct rx_connection *conn); extern int rx_IsClientConn(struct rx_connection *conn); @@ -242,7 +241,10 @@ rx_IsLoopbackAddr(afs_uint32 addr) /* Define procedure to set service dead time */ #define rx_SetIdleDeadTime(service,time) ((service)->idleDeadTime = (time)) -/* Define error to return in server connections when failing to answer */ +/* + * Define error to return in server connections when failing to answer. + * (server only) For example, AFS viced sends VNOSERVICE. + */ #define rx_SetServerIdleDeadErr(service,err) ((service)->idleDeadErr = (err)) /* Define procedures for getting and setting before and after execute-request procs */ @@ -264,7 +266,6 @@ rx_IsLoopbackAddr(afs_uint32 addr) /* Enable or disable asymmetric client checking for a service */ #define rx_SetCheckReach(service, x) ((service)->checkReach = (x)) - /* Set the overload threshold and the overload error */ #define rx_SetBusyThreshold(threshold, code) (rx_BusyThreshold=(threshold),rx_BusyError=(code)) @@ -546,34 +547,57 @@ struct rx_ackPacket { #define RX_CHECKREACH_TIMEOUT 2 /* Number of seconds before another ping is generated */ #define RX_CHECKREACH_TTL 60 /* Re-check reachability this often */ -/* RX error codes. RX uses error codes from -1 to -64. Rxgen may use other error codes < -64; user programs are expected to return positive error codes */ +/* + * RX error codes. RX uses error codes from -1 to -64 and -100. + * Rxgen uses other error codes < -64 (see src/rxgen/rpc_errors.h); + * user programs are expected to return positive error codes + */ /* Something bad happened to the connection; temporary loss of communication */ #define RX_CALL_DEAD (-1) -/* An invalid operation, such as a client attempting to send data after having received the beginning of a reply from the server */ +/* + * An invalid operation, such as a client attempting to send data + * after having received the beginning of a reply from the server. + */ #define RX_INVALID_OPERATION (-2) /* An optional timeout per call may be specified */ #define RX_CALL_TIMEOUT (-3) -/* End of data on a read */ +/* End of data on a read. Not currently in use. */ #define RX_EOF (-4) -/* Some sort of low-level protocol error */ +/* Some sort of low-level protocol error. */ #define RX_PROTOCOL_ERROR (-5) -/* Generic user abort code; used when no more specific error code needs to be communicated. For example, multi rx clients use this code to abort a multi rx call */ +/* + * Generic user abort code; used when no more specific error code needs to be + * communicated. For example, multi rx clients use this code to abort a multi- + * rx call. + */ #define RX_USER_ABORT (-6) -/* Port already in use (from rx_Init) */ +/* Port already in use (from rx_Init). This error is never sent on the wire. */ #define RX_ADDRINUSE (-7) /* EMSGSIZE returned from network. Packet too big, must fragment */ #define RX_MSGSIZE (-8) +/* + * Idle dead timeout error. This error is never sent on the wire. + * rxi_SendCallAbort() translates RX_CALL_IDLE to RX_CALL_TIMEOUT. + */ +#define RX_CALL_IDLE (-9) + +/* + * Busy call channel error. This error is never sent on the wire. + * rxi_SendCallAbort() translates RX_CALL_BUSY to RX_CALL_TIMEOUT. + */ +#define RX_CALL_BUSY (-10) + /* transient failure detected ( possibly the server is restarting ) */ -/* this shud be equal to VRESTARTING ( util/errors.h ) for old clients to work */ +/* this should be equal to VRESTARTING ( util/errors.h ) for old clients to work */ #define RX_RESTARTING (-100) typedef enum { diff --git a/src/rx/rx_conn.c b/src/rx/rx_conn.c index 91a4f5f..f6b8d41 100644 --- a/src/rx/rx_conn.c +++ b/src/rx/rx_conn.c @@ -78,12 +78,6 @@ rx_GetSecurityMaxTrailerSize(struct rx_connection *conn) } void -rx_SetServerConnIdleDeadErr(struct rx_connection *conn, int err) -{ - conn->idleDeadErr = err; -} - -void rx_SetMsgsizeRetryErr(struct rx_connection *conn, int err) { conn->msgsizeRetryErr = err; diff --git a/src/rx/rx_conn.h b/src/rx/rx_conn.h index 15b7e83..82c7642 100644 --- a/src/rx/rx_conn.h +++ b/src/rx/rx_conn.h @@ -72,7 +72,7 @@ struct rx_connection { u_short idleDeadTime; /* max time a call can be idle (no data) */ u_char ackRate; /* how many packets between ack requests */ u_char makeCallWaiters; /* how many rx_NewCalls are waiting */ - afs_int32 idleDeadErr; + u_char idleDeadDetection; /* detect idle dead timeouts? */ afs_int32 secondsUntilNatPing; /* how often to ping conn */ struct rxevent *natKeepAliveEvent; /* Scheduled to keep connection open */ afs_int32 msgsizeRetryErr; diff --git a/src/rx/rx_prototypes.h b/src/rx/rx_prototypes.h index 4d7a2c7..b9dddb9 100644 --- a/src/rx/rx_prototypes.h +++ b/src/rx/rx_prototypes.h @@ -25,7 +25,7 @@ extern void rx_rto_setPeerTimeoutSecs(struct rx_peer *, int secs); 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); +extern void rx_SetBusyChannelError(afs_int32 onoff); #ifdef AFS_NT40_ENV extern void rx_DebugOnOff(int on); extern void rx_StatsOnOff(int on);