]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-server-meltdown-avoidance-20080509
authorDerrick Brashear <shadow@dementia.org>
Fri, 20 Jun 2008 16:49:09 +0000 (16:49 +0000)
committerDerrick Brashear <shadow@dementia.org>
Fri, 20 Jun 2008 16:49:09 +0000 (16:49 +0000)
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)

src/rx/rx.c
src/rx/rx.h
src/viced/viced.c

index 3f45c04690ae0060dcece0e24f990a7e069cf111..ea52e55881660d762fa4644733d0cadcbfb79118 100644 (file)
@@ -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))) {
index 7ea5eb8bdaa90e5415ada154d9551bdd0293aa2b..9df69670947f63abe3e84c53ab4338bbe91ebda3 100644 (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))
@@ -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 */
index cc7838b2cbb6b5b420ecec9f732c468415aa0b42..a42950b480d14d0467c724c51ff724ab79568d2f 100644 (file)
@@ -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,