From: Derrick Brashear Date: Fri, 20 Jun 2008 16:49:09 +0000 (+0000) Subject: STABLE14-server-meltdown-avoidance-20080509 X-Git-Tag: openafs-stable-1_4_8pre1~73 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=d00f07a6ef9a4c24088b5d3c0a5ba02eb62deaca;p=packages%2Fo%2Fopenafs.git STABLE14-server-meltdown-avoidance-20080509 LICENSE IPL10 if the server is melting down or otherwise unable to reply with data, it will cut itself off. (cherry picked from commit c26dc0e6aaefedc55ed5c35a5744b5c01ba39ea1) --- diff --git a/src/rx/rx.c b/src/rx/rx.c index 3f45c0469..ea52e5588 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -1325,6 +1325,7 @@ rx_NewServiceHost(afs_uint32 host, u_short port, u_short serviceId, service->minProcs = 0; service->maxProcs = 1; service->idleDeadTime = 60; + service->idleDeadErr = 0; service->connDeadTime = rx_connDeadTime; service->executeRequestProc = serviceProc; service->checkReach = 0; @@ -2399,6 +2400,7 @@ rxi_FindConnection(osi_socket socket, register afs_int32 host, conn->specific = NULL; rx_SetConnDeadTime(conn, service->connDeadTime); rx_SetConnIdleDeadTime(conn, service->idleDeadTime); + rx_SetServerConnIdleDeadErr(conn, service->idleDeadErr); /* Notify security object of the new connection */ RXS_NewConnection(conn->securityObject, conn); /* XXXX Connection timeout? */ @@ -4877,7 +4879,7 @@ rxi_SendList(struct rx_call *call, struct rx_packet **list, int len, /* Update last send time for this call (for keep-alive * processing), and for the connection (so that we can discover * idle connections) */ - conn->lastSendTime = call->lastSendTime = clock_Sec(); + call->lastSendData = conn->lastSendTime = call->lastSendTime = clock_Sec(); } /* When sending packets we need to follow these rules: @@ -5347,6 +5349,9 @@ rxi_Send(register struct rx_call *call, register struct rx_packet *p, * processing), and for the connection (so that we can discover * idle connections) */ conn->lastSendTime = call->lastSendTime = clock_Sec(); + /* Don't count keepalives here, so idleness can be tracked. */ + if (p->header.type != RX_PACKET_TYPE_ACK) + call->lastSendData = call->lastSendTime; } @@ -5420,6 +5425,13 @@ rxi_CheckCall(register struct rx_call *call) return -1; } } + if (call->lastSendData && conn->idleDeadTime && (conn->idleDeadErr != 0) + && ((call->lastSendData + conn->idleDeadTime) < now)) { + if (call->state == RX_STATE_ACTIVE) { + rxi_CallError(call, conn->idleDeadErr); + return -1; + } + } /* see if we have a hard timeout */ if (conn->hardDeadTime && (now > (conn->hardDeadTime + call->startTime.sec))) { diff --git a/src/rx/rx.h b/src/rx/rx.h index 7ea5eb8bd..9df696709 100644 --- a/src/rx/rx.h +++ b/src/rx/rx.h @@ -145,6 +145,9 @@ int ntoh_syserr_conv(int error); /* 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 rx_SetServerIdleDeadErr(service,err) ((service)->idleDeadErr = (err)) + /* Define procedures for getting and setting before and after execute-request procs */ #define rx_SetAfterProc(service,proc) ((service)->afterProc = (proc)) #define rx_SetBeforeProc(service,proc) ((service)->beforeProc = (proc)) @@ -165,6 +168,7 @@ int ntoh_syserr_conv(int error); /* Set connection hard and idle timeouts for a connection */ #define rx_SetConnHardDeadTime(conn, seconds) ((conn)->hardDeadTime = (seconds)) #define rx_SetConnIdleDeadTime(conn, seconds) ((conn)->idleDeadTime = (seconds)) +#define rx_SetServerConnIdleDeadErr(conn,err) ((conn)->idleDeadErr = (err)) /* Set the overload threshold and the overload error */ #define rx_SetBusyThreshold(threshold, code) (rx_BusyThreshold=(threshold),rx_BusyError=(code)) @@ -263,6 +267,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; int nSpecific; /* number entries in specific data */ void **specific; /* pointer to connection specific data */ }; @@ -307,6 +312,7 @@ struct rx_service { u_short connDeadTime; /* Seconds until a client of this service will be declared dead, if it is not responding */ u_short idleDeadTime; /* Time a server will wait for I/O to start up again */ u_char checkReach; /* Check for asymmetric clients? */ + afs_int32 idleDeadErr; }; #endif /* KDUMP_RX_LOCK */ @@ -503,6 +509,7 @@ struct rx_call { int abortCount; /* number of times last error was sent */ u_int lastSendTime; /* Last time a packet was sent on this call */ u_int lastReceiveTime; /* Last time a packet was received for this call */ + u_int lastSendData; /* Last time a nonping was sent on this call */ void (*arrivalProc) (register struct rx_call * call, register void * mh, register int index); /* Procedure to call when reply is received */ void *arrivalProcHandle; /* Handle to pass to replyFunc */ int arrivalProcArg; /* Additional arg to pass to reply Proc */ diff --git a/src/viced/viced.c b/src/viced/viced.c index cc7838b2c..a42950b48 100644 --- a/src/viced/viced.c +++ b/src/viced/viced.c @@ -1875,6 +1875,7 @@ main(int argc, char *argv[]) rx_SetMinProcs(tservice, 3); rx_SetMaxProcs(tservice, lwps); rx_SetCheckReach(tservice, 1); + rx_SetServerIdleDeadErr(tservice, VNOSERVICE); tservice = rx_NewService(0, RX_STATS_SERVICE_ID, "rpcstats", sc, 4,