DEVEL15-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)
This commit is contained in:
Derrick Brashear 2008-05-09 19:50:56 +00:00
parent 1ab2f6811e
commit f4abd38342
3 changed files with 21 additions and 1 deletions

View File

@ -1328,6 +1328,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;
@ -2389,6 +2390,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);
for (i = 0; i < RX_MAXCALLS; i++) {
conn->twind[i] = rx_initSendWindow;
conn->rwind[i] = rx_initReceiveWindow;
@ -4922,7 +4924,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:
@ -5386,6 +5388,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;
}
@ -5459,6 +5464,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))) {

View File

@ -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))
@ -265,6 +269,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 */
};
@ -309,6 +314,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 */
@ -505,6 +511,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 */

View File

@ -2097,6 +2097,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,