Index: arlad/conn.c
===================================================================
RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/arlad/conn.c,v
retrieving revision 1.59
diff -u -w -r1.59 conn.c
--- arlad/conn.c	2000/05/23 04:04:12	1.59
+++ arlad/conn.c	2000/09/29 00:09:19
@@ -69,6 +69,9 @@
 int conn_rxkad_level = rxkad_auth;
 #endif
 
+/* # of seconds before sending ping on a connection */
+static int conn_keepalive;
+
 /*
  * Functions for handling entries into the connection cache.
  */
@@ -100,20 +103,15 @@
  */
 
 static void
-re_probe (ConnCacheEntry *e)
+probe_add (ConnCacheEntry *e)
 {
     Listitem *item;
-    struct timeval tv;
 
     assert (e->probe != NULL);
 
     if (e->probe_le != NULL)
 	listdel (connprobelist, e->probe_le);
 
-    gettimeofday (&tv, NULL);
-    e->probe_next = tv.tv_sec + (1 << e->ntries);
-    ++e->ntries;
-
     for (item = listhead (connprobelist);
 	 item;
 	 item = listnext (connprobelist, item)) {
@@ -130,6 +128,21 @@
 }
 
 /*
+ * Add this entry again to the probe list but without restarting ntries.
+ */
+
+static void
+re_probe (ConnCacheEntry *e)
+{
+    struct timeval tv;
+
+    gettimeofday (&tv, NULL);
+    e->probe_next = tv.tv_sec + (1 << e->ntries);
+    ++e->ntries;
+    probe_add (e);
+}
+
+/*
  * Initial add to probe list.
  */
 
@@ -188,7 +201,7 @@
 	listdel (connprobelist, item);
 	e->probe_le = NULL;
 
-	if (e->flags.alivep)
+	if (e->flags.alivep && conn_keepalive == 0) 
 	    continue;
 
 	addr.s_addr = e->host;
@@ -208,6 +221,7 @@
 
 	if (e->probe && ((*(e->probe))(e->connection) == 0)) {
 	    conn_alive (e);
+	    conn_works (e);
 	} else if (e->ntries <= MAX_RETRIES) {
 	    re_probe (e);
 	}
@@ -233,6 +247,7 @@
 	  entries[i].refcount   = 0;
 	  entries[i].parent     = NULL;
 	  entries[i].probe_le	= NULL;
+	  entries[i].last_use   = 0;
 	  listaddhead (connfreelist, &entries[i]);
      }
      nconnections += n;
@@ -523,6 +538,27 @@
 }
 
 /*
+ * ack that `conn' was actually a useful connection
+ */
+
+void
+conn_works (ConnCacheEntry *e)
+{
+    struct timeval tv;
+
+    assert (e->refcount > 0);
+
+    gettimeofday (&tv, NULL);
+    e->last_use = tv.tv_sec;
+    if (conn_keepalive) {
+	e->probe_next = tv.tv_sec + conn_keepalive;
+	probe_add (e);
+    }
+    if (e->parent)
+	conn_works (e->parent);
+}
+
+/*
  * Free a reference to a ConnCacheEntry.
  * If refcount drops to zero, it makes it eligible for re-use.
  */
@@ -598,6 +634,7 @@
 void
 conn_alive (ConnCacheEntry *e)
 {
+    if (!e->flags.alivep || (e->parent != NULL && !e->parent->flags.alivep)) {
     struct in_addr a;
     const char *s;
 
@@ -606,7 +643,9 @@
     if (s != NULL)
 	arla_warnx (ADEBWARN, "Server %s/%s up again", inet_ntoa(a), s);
     else
-	arla_warnx (ADEBWARN, "Server %s/%d up again", inet_ntoa(a), e->port);
+	    arla_warnx (ADEBWARN, "Server %s/%d up again", inet_ntoa(a),
+			e->port);
+    }
     e->flags.alivep = TRUE;
     if (e->parent != NULL)
 	e->parent->flags.alivep = TRUE;
@@ -630,8 +669,8 @@
 		       inet_ntoa(a), e->cell, e->port);
     }
     if (e->probe && ((*(e->probe))(e->connection) == 0)) {
-	if (!e->flags.alivep)
 	    conn_alive (e);
+	conn_works (e);
     } else {
 	if (e->flags.alivep)
 	    conn_dead (e);
@@ -819,4 +858,16 @@
     ConnCacheEntry **e2 = (ConnCacheEntry **)v2;
     
     return (*e1)->rtt - (*e2)->rtt;
+}
+
+void
+conn_set_keepalive (int x)
+{
+    conn_keepalive = x;
+}
+
+int
+conn_get_keepalive (void)
+{
+    return conn_keepalive;
 }
Index: arlad/conn.h
===================================================================
RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/arlad/conn.h,v
retrieving revision 1.22
diff -u -w -r1.22 conn.h
--- arlad/conn.h	2000/02/20 04:23:48	1.22
+++ arlad/conn.h	2000/09/29 00:09:19
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * Copyright (c) 1995 - 2000 Kungliga Tekniska Högskolan
  * (Royal Institute of Technology, Stockholm, Sweden).
  * All rights reserved.
  * 
@@ -69,6 +69,7 @@
     unsigned ntries;
     struct conncacheentry *parent;
     int rtt;
+    time_t last_use;
 };
 
 typedef struct conncacheentry ConnCacheEntry;
@@ -95,6 +96,9 @@
 void
 conn_free (ConnCacheEntry *e);
 
+void
+conn_works (ConnCacheEntry *e);
+
 int32_t
 conn_host2cell (u_int32_t host, u_int16_t port, u_int16_t service);
 
@@ -112,6 +116,12 @@
 
 int
 conn_rtt_cmp (const void *v1, const void *v2);
+
+void
+conn_set_keepalive (int);
+
+int
+conn_get_keepalive (void);
 
 /*
  * Random factor to add to rtts when comparing them.
Index: arlad/fcache.c
===================================================================
RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/arlad/fcache.c,v
retrieving revision 1.293
diff -u -w -r1.293 fcache.c
--- arlad/fcache.c	2000/09/25 09:50:17	1.293
+++ arlad/fcache.c	2000/09/29 00:09:20
@@ -542,6 +542,8 @@
 	    fids.val = &entry->fid.fid;
 	    cbs.val  = &entry->callback;
 	    ret = RXAFS_GiveUpCallBacks (conn->connection, &fids, &cbs);
+	    if (ret >= 0)
+		conn_works (conn);
 	    conn_free (conn);
 	    if (ret)
 		arla_warn (ADEBFCACHE, ret, "RXAFS_GiveUpCallBacks");
@@ -1713,6 +1715,8 @@
 		cbs.val  = &entry->callback;
 		
 		ret = RXAFS_GiveUpCallBacks (conn->connection, &fids, &cbs);
+		if (ret >= 0)
+		    conn_works (conn);
 		conn_free (conn);
 		if (ret)
 		    arla_warn (ADEBFCACHE, ret, "RXAFS_GiveUpCallBacks");
@@ -1770,6 +1774,8 @@
 					 &status,
 					 &callback,
 					 &volsync);
+		if (ret >= 0)
+		    conn_works (conn);
 		if (ret)
 		    arla_warn (ADEBFCACHE, ret, "RXAFS_FetchStatus");
 		else
@@ -1875,6 +1881,8 @@
 				 &status,
 				 &callback,
 				 &volsync);
+	if (ret >= 0)
+	    conn_works (conn);
 
 	if (!try_next_fs (ret))
 	    break;
@@ -1980,6 +1988,7 @@
 	rx_EndCall(call, 0);
 	goto out;
     }
+    conn_works (conn);
     sizefs = ntohl (sizefs);
 
     assert (sizefs == entry->status.Length);
@@ -2016,6 +2025,7 @@
 	arla_warn (ADEBFCACHE, ret, "rx_EndCall");
 	goto out;
     }
+    conn_works (conn);
 
     fcache_counter.fetch_data++;
     
@@ -2107,6 +2117,7 @@
 	     break;
 	 }
 
+	 conn_works (conn);
 	 ret = copyfd2rx (fd, call, 0, sizefs);
 	 if (ret) {
 	     rx_EndCall(call, ret);
@@ -2127,6 +2138,7 @@
 	 if (ret) {
 	     arla_warn (ADEBFCACHE, ret, "rx_EndCall");
 	 }
+	 conn_works (conn);
 	 break;
      }
 
@@ -2223,6 +2235,7 @@
 	    break;
 	}
 
+
 	ret = EndRXAFS_StoreData (call,
 				  &status,
 				  &volsync);
@@ -2236,6 +2249,7 @@
 	 if (ret) {
 	     arla_warn (ADEBFCACHE, ret, "rx_EndCall");
 	 }
+	conn_works (conn);
 	 break;
     }
 
@@ -2287,6 +2301,8 @@
 				     store_status,
 				     &status,
 				     &volsync);
+	    if (ret >= 0)
+		conn_works (conn);
 	    if (ret == RX_CALL_DEAD) {
 		continue;
 	    } else if (ret) {
@@ -2366,6 +2382,8 @@
 				    &status,
 				    &callback,
 				    &volsync);
+	    if (ret >= 0)
+		conn_works (conn);
 	    if (ret == RX_CALL_DEAD) {
 		continue;
 	    } else if (ret) {
@@ -2502,6 +2520,8 @@
 				 &callback,
 				 &volsync);
 
+	    if (ret >= 0)
+		conn_works (conn);
 	    if (ret == RX_CALL_DEAD) {
 		continue;
 	    } else if (ret) {
@@ -2631,6 +2651,8 @@
 			     fetch_attr,
 			     &new_status,
 			     &volsync);
+	if (ret >= 0)
+	    conn_works (conn);
 	if (ret == RX_CALL_DEAD) {
 	    continue;
 	} else if (ret) {
@@ -2714,6 +2736,8 @@
 			  &new_status,
 			  &status,
 			  &volsync);
+	if (ret >= 0)
+	    conn_works (conn);
 	if (ret == RX_CALL_DEAD) {
 	    continue;
 	} else if (ret) {
@@ -2771,6 +2795,8 @@
 				name,
 				&status,
 				&volsync);
+	if (ret >= 0)
+	    conn_works (conn);
 	if (ret == RX_CALL_DEAD) {
 	    continue;
 	} else if (ret) {
@@ -2827,6 +2853,8 @@
 			       name,
 			       &status,
 			       &volsync);
+	if (ret >= 0)
+	    conn_works (conn);
 	if (ret == RX_CALL_DEAD) {
 	    continue;
 	} else if (ret) {
@@ -2889,6 +2917,8 @@
 			    &orig_status,
 			    &new_status,
 			    &volsync);
+	if (ret >= 0)
+	    conn_works (conn);
 	if (ret == RX_CALL_DEAD) {
 	    continue;
 	} else if (ret) {
@@ -3345,6 +3375,8 @@
 	stats.len = cbs.len = 0;
 
 	ret = RXAFS_BulkStatus (conn->connection, &fids, &stats, &cbs, &sync);
+	if (ret >= 0)
+	    conn_works (conn);
 	if (ret) {
 	    free (stats.val);
 	    free (cbs.val);
@@ -4101,6 +4133,8 @@
 	 conn = find_next_fs (&context, conn, fs_downp (ret))) {
 	ret = RXAFS_FetchACL (conn->connection, &fid.fid,
 			      opaque, &status, &volsync);
+	if (ret >= 0)
+	    conn_works (conn);
 	if (!try_next_fs (ret))
 	    break;
     }
@@ -4155,6 +4189,8 @@
 	 conn = find_next_fs (&context, conn, fs_downp (ret))) {
 	ret = RXAFS_StoreACL (conn->connection, &fid.fid,
 			      opaque, &status, &volsync);
+	if (ret >= 0)
+	    conn_works (conn);
 	if (!try_next_fs (ret))
 	    break;
     }
@@ -4212,6 +4248,8 @@
 	ret = RXAFS_GetVolumeStatus (conn->connection, fid.fid.Volume,
 				     volstat, volumename, offlinemsg,
 				     motd);
+	if (ret >= 0)
+	    conn_works (conn);
 	if (!try_next_fs (ret))
 	    break;
     }
@@ -4263,6 +4301,8 @@
 	ret = RXAFS_SetVolumeStatus (conn->connection, fid.fid.Volume,
 				     volstat, volumename, offlinemsg,
 				     motd);
+	if (ret >= 0)
+	    conn_works (conn);
 	if (!try_next_fs (ret))
 	    break;
     }
Index: arlad/volcache.c
===================================================================
RCS file: /afs/stacken.kth.se/src/SourceRepository/arla/arlad/volcache.c,v
retrieving revision 1.92
diff -u -w -r1.92 volcache.c
--- arlad/volcache.c	2000/09/01 00:43:38	1.92
+++ arlad/volcache.c	2000/09/29 00:09:23
@@ -650,6 +650,8 @@
 		} else
 		    error = VL_GetEntryByNameN (conns[i]->connection,
 						name, &e->entry);
+		if (error >= 0)
+		    conn_works (conns[i]);
 		if (error == RX_CALL_DEAD)
 		    conn_dead (conns[i]);
 		switch (error) {
@@ -774,7 +776,7 @@
 	if (volname_len >= sizeof(e->entry.name)) {
 	    arla_warnx (ADEBWARN,
 			"get_info: too long volume (%.*s)",
-			volname_len, volname);
+			(int)volname_len, volname);
 	    return ENAMETOOLONG;
 	}
 	memmove (e->entry.name, volname, volname_len);
