DEVEL15-linux-warning-reduction-20090318
[openafs.git] / src / afs / afs_server.c
index 0cbe000..19f3092 100644 (file)
@@ -57,6 +57,7 @@ RCSID
 
 #include "afsincludes.h"       /* Afs-based standard headers */
 #include "afs/afs_stats.h"     /* afs statistics */
+#include "rx/rx_multi.h"
 
 #if    defined(AFS_SUN56_ENV)
 #include <inet/led.h>
@@ -238,14 +239,14 @@ afs_MarkServerUpOrDown(struct srvAddr *sa, int a_isDown)
 }                              /*MarkServerUpOrDown */
 
 
-void
+afs_int32
 afs_ServerDown(struct srvAddr *sa)
 {
     register struct server *aserver = sa->server;
 
     AFS_STATCNT(ServerDown);
-    if (aserver->flags & SRVR_ISDOWN || sa->sa_flags & SRVADDR_ISDOWN)
-       return;
+    if (aserver->flags & SRVR_ISDOWN || sa->sa_flags & SRVADDR_ISDOWN) 
+       return 0;
     afs_MarkServerUpOrDown(sa, SRVR_ISDOWN);
     if (sa->sa_portal == aserver->cell->vlport)
        print_internet_address
@@ -253,13 +254,13 @@ afs_ServerDown(struct srvAddr *sa)
     else
        print_internet_address("afs: Lost contact with file server ", sa, "",
                               1);
-
+    return 1;
 }                              /*ServerDown */
 
 
 /* return true if we have any callback promises from this server */
-static int
-HaveCallBacksFrom(struct server *aserver)
+int
+afs_HaveCallBacksFrom(struct server *aserver)
 {
     register afs_int32 now;
     register int i;
@@ -274,7 +275,7 @@ HaveCallBacksFrom(struct server *aserver)
             * from the required host
             */
            if (aserver == tvc->callback && tvc->cbExpires >= now
-               && ((tvc->states & CRO) == 0))
+               && ((tvc->f.states & CRO) == 0))
                return 1;
        }
     }
@@ -287,7 +288,7 @@ static void
 CheckVLServer(register struct srvAddr *sa, struct vrequest *areq)
 {
     register struct server *aserver = sa->server;
-    register struct conn *tc;
+    register struct afs_conn *tc;
     register afs_int32 code;
 
     AFS_STATCNT(CheckVLServer);
@@ -487,6 +488,42 @@ afs_CountServers(void)
 }                              /*afs_CountServers */
 
 
+void
+ForceAllNewConnections()
+{
+    int srvAddrCount;
+    struct srvAddr **addrs;
+    struct srvAddr *sa;
+    afs_int32 i, j;
+
+    ObtainReadLock(&afs_xserver);      /* Necessary? */
+    ObtainReadLock(&afs_xsrvAddr);
+
+    srvAddrCount = 0;
+    for (i = 0; i < NSERVERS; i++) {
+       for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
+           srvAddrCount++;
+       }
+    }
+
+    addrs = afs_osi_Alloc(srvAddrCount * sizeof(*addrs));
+    j = 0;
+    for (i = 0; i < NSERVERS; i++) {
+       for (sa = afs_srvAddrs[i]; sa; sa = sa->next_bkt) {
+           if (j >= srvAddrCount)
+               break;
+           addrs[j++] = sa;
+       }
+    }
+
+    ReleaseReadLock(&afs_xsrvAddr);
+    ReleaseReadLock(&afs_xserver);
+    for (i = 0; i < j; i++) {
+        sa = addrs[i];
+       ForceNewConnections(sa);
+    }
+}
+
 /* check down servers (if adown), or running servers (if !adown) */
 void
 afs_CheckServers(int adown, struct cell *acellp)
@@ -494,20 +531,35 @@ afs_CheckServers(int adown, struct cell *acellp)
     struct vrequest treq;
     struct server *ts;
     struct srvAddr *sa;
-    struct conn *tc;
+    struct afs_conn *tc;
     afs_int32 i, j;
     afs_int32 code;
-    afs_int32 start, end, delta;
+    afs_int32 start, end = 0, delta;
     osi_timeval_t tv;
-    int setTimer;
     struct unixuser *tu;
     char tbuffer[CVBS];
     int srvAddrCount;
     struct srvAddr **addrs;
-    XSTATS_DECLS;
+    struct afs_conn **conns;
+    int nconns;
+    struct rx_connection **rxconns;      
+    afs_int32 *conntimer, *deltas, *results;
 
     AFS_STATCNT(afs_CheckServers);
-    if ((code = afs_InitReq(&treq, &afs_osi_cred)))
+
+    /* 
+     * No sense in doing the server checks if we are running in disconnected
+     * mode
+     */
+    if (AFS_IS_DISCONNECTED)
+        return;
+
+    conns = (struct afs_conn **)0;
+    rxconns = (struct rx_connection **) 0;
+    conntimer = 0;
+    nconns = 0;
+
+    if ((code = afs_InitReq(&treq, afs_osi_credp)))
        return;
     ObtainReadLock(&afs_xserver);      /* Necessary? */
     ObtainReadLock(&afs_xsrvAddr);
@@ -532,7 +584,14 @@ afs_CheckServers(int adown, struct cell *acellp)
     ReleaseReadLock(&afs_xsrvAddr);
     ReleaseReadLock(&afs_xserver);
 
+    conns = (struct afs_conn **)afs_osi_Alloc(j * sizeof(struct afs_conn *));
+    rxconns = (struct rx_connection **)afs_osi_Alloc(j * sizeof(struct rx_connection *));
+    conntimer = (afs_int32 *)afs_osi_Alloc(j * sizeof (afs_int32));
+    deltas = (afs_int32 *)afs_osi_Alloc(j * sizeof (afs_int32));
+    results = (afs_int32 *)afs_osi_Alloc(j * sizeof (afs_int32));
+
     for (i = 0; i < j; i++) {
+       deltas[i] = 0;
        sa = addrs[i];
        ts = sa->server;
        if (!ts)
@@ -565,114 +624,146 @@ afs_CheckServers(int adown, struct cell *acellp)
        if (!tc)
            continue;
 
-       if ((sa->sa_flags & SRVADDR_ISDOWN) || HaveCallBacksFrom(ts)
+       if ((sa->sa_flags & SRVADDR_ISDOWN) || afs_HaveCallBacksFrom(sa->server)
            || (tc->srvr->server == afs_setTimeHost)) {
+           conns[nconns]=tc; 
+           rxconns[nconns]=tc->id;
            if (sa->sa_flags & SRVADDR_ISDOWN) {
                rx_SetConnDeadTime(tc->id, 3);
-               setTimer = 1;
+               conntimer[nconns]=1;
            } else {
-               setTimer = 0;
+               conntimer[nconns]=0;
            }
+           nconns++;
+       }
+    } /* Outer loop over addrs */
+
+    start = osi_Time();         /* time the gettimeofday call */
+    AFS_GUNLOCK(); 
+    multi_Rx(rxconns,nconns)
+      {
+       tv.tv_sec = tv.tv_usec = 0;
+       multi_RXAFS_GetTime((afs_uint32 *)&tv.tv_sec, (afs_uint32 *)&tv.tv_usec);
+       tc = conns[multi_i];
+       sa = tc->srvr;
+       if (conntimer[multi_i] == 1)
+         rx_SetConnDeadTime(tc->id, afs_rx_deadtime);
+       end = osi_Time();
+       results[multi_i]=multi_error;
+       if ((start == end) && !multi_error)
+         deltas[multi_i] = end - tv.tv_sec;
+       
+      } multi_End;
+    AFS_GLOCK(); 
+    
+    for(i=0;i<nconns;i++){
+      tc = conns[i];
+      sa = tc->srvr;
+      
+      if (( results[i] >= 0 ) && (sa->sa_flags & SRVADDR_ISDOWN) && (tc->srvr == sa)) {
+       /* server back up */
+       print_internet_address("afs: file server ", sa, " is back up", 2);
+       
+       ObtainWriteLock(&afs_xserver, 244);
+       ObtainWriteLock(&afs_xsrvAddr, 245);        
+       afs_MarkServerUpOrDown(sa, 0);
+       ReleaseWriteLock(&afs_xsrvAddr);
+       ReleaseWriteLock(&afs_xserver);
+       
+       if (afs_waitForeverCount) {
+         afs_osi_Wakeup(&afs_waitForever);
+       }
+      } else {
+       if (results[i] < 0) {
+         /* server crashed */
+         afs_ServerDown(sa);
+         ForceNewConnections(sa);  /* multi homed clients */
+       }
+      }
+    }
 
-           XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_GETTIME);
-           start = osi_Time(); /* time the gettimeofday call */
-           RX_AFS_GUNLOCK();
-           code =
-               RXAFS_GetTime(tc->id, (afs_int32 *) & tv.tv_sec,
-                             (afs_int32 *) & tv.tv_usec);
-           RX_AFS_GLOCK();
-           end = osi_Time();
-           XSTATS_END_TIME;
-           /*
-            * If we're supposed to set the time, and the call worked
-            * quickly (same second response) and this is the host we
-            * use for the time and the time is really different, then
-            * really set the time
-            */
-           if (code == 0 && start == end && afs_setTime != 0
-               && (tc->srvr->server == afs_setTimeHost ||
-                   /* Sync only to a server in the local cell */
-                   (afs_setTimeHost == (struct server *)0
-                    && afs_IsPrimaryCell(ts->cell)))) {
-
-               char msgbuf[90];        /* strlen("afs: setting clock...") + slop */
+    /*
+     * If we're supposed to set the time, and the call worked
+     * quickly (same second response) and this is the host we
+     * use for the time and the time is really different, then
+     * really set the time
+     */
+    if (afs_setTime != 0) {
+       for (i=0; i<nconns; i++) {
+           delta = deltas[i];
+           tc = conns[i];
+           sa = tc->srvr;
+           
+           if ((tc->srvr->server == afs_setTimeHost ||
+                /* Sync only to a server in the local cell */
+                (afs_setTimeHost == (struct server *)0 &&
+                 afs_IsPrimaryCell(sa->server->cell)))) {
                /* set the time */
-               delta = end - tv.tv_sec;        /* how many secs fast we are */
+               char msgbuf[90];  /* strlen("afs: setting clock...") + slop */
+               delta = end - tv.tv_sec;   /* how many secs fast we are */
+               
+               afs_setTimeHost = tc->srvr->server;
                /* see if clock has changed enough to make it worthwhile */
                if (delta >= AFS_MINCHANGE || delta <= -AFS_MINCHANGE) {
+                   end = osi_Time();
                    if (delta > AFS_MAXCHANGEBACK) {
                        /* setting clock too far back, just do it a little */
                        tv.tv_sec = end - AFS_MAXCHANGEBACK;
+                   } else {
+                       tv.tv_sec = end - delta;
                    }
                    afs_osi_SetTime(&tv);
                    if (delta > 0) {
                        strcpy(msgbuf, "afs: setting clock back ");
                        if (delta > AFS_MAXCHANGEBACK) {
-                           afs_strcat(msgbuf,
-                                      afs_cv2string(&tbuffer[CVBS],
+                           afs_strcat(msgbuf, 
+                                      afs_cv2string(&tbuffer[CVBS], 
                                                     AFS_MAXCHANGEBACK));
                            afs_strcat(msgbuf, " seconds (of ");
-                           afs_strcat(msgbuf,
-                                      afs_cv2string(&tbuffer[CVBS],
-                                                    delta -
+                           afs_strcat(msgbuf, 
+                                      afs_cv2string(&tbuffer[CVBS], 
+                                                    delta - 
                                                     AFS_MAXCHANGEBACK));
                            afs_strcat(msgbuf, ", via ");
-                           print_internet_address(msgbuf, sa,
+                           print_internet_address(msgbuf, sa, 
                                                   "); clock is still fast.",
                                                   0);
                        } else {
-                           afs_strcat(msgbuf,
+                           afs_strcat(msgbuf, 
                                       afs_cv2string(&tbuffer[CVBS], delta));
                            afs_strcat(msgbuf, " seconds (via ");
                            print_internet_address(msgbuf, sa, ").", 0);
                        }
                    } else {
                        strcpy(msgbuf, "afs: setting clock ahead ");
-                       afs_strcat(msgbuf,
+                       afs_strcat(msgbuf, 
                                   afs_cv2string(&tbuffer[CVBS], -delta));
                        afs_strcat(msgbuf, " seconds (via ");
                        print_internet_address(msgbuf, sa, ").", 0);
                    }
-               }
-               afs_setTimeHost = tc->srvr->server;
-           }
-           if (setTimer)
-               rx_SetConnDeadTime(tc->id, afs_rx_deadtime);
-           if (code >= 0 && (sa->sa_flags & SRVADDR_ISDOWN)
-               && (tc->srvr == sa)) {
-               /* server back up */
-               print_internet_address("afs: file server ", sa, " is back up",
-                                      2);
-
-               ObtainWriteLock(&afs_xserver, 244);
-               ObtainWriteLock(&afs_xsrvAddr, 245);
-               afs_MarkServerUpOrDown(sa, 0);
-               ReleaseWriteLock(&afs_xsrvAddr);
-               ReleaseWriteLock(&afs_xserver);
-
-               if (afs_waitForeverCount) {
-                   afs_osi_Wakeup(&afs_waitForever);
-               }
-           } else {
-               if (code < 0) {
-                   /* server crashed */
-                   afs_ServerDown(sa);
-                   ForceNewConnections(sa);    /* multi homed clients */
+                    /* We're only going to set it once; why bother looping? */
+                   break; 
                }
            }
        }
-
-       afs_PutConn(tc, SHARED_LOCK);   /* done with it now */
-    }                          /* Outer loop over addrs */
-
+    }
+    for (i = 0; i < nconns; i++) {
+       afs_PutConn(conns[i], SHARED_LOCK);     /* done with it now */
+    }
+    
     afs_osi_Free(addrs, srvAddrCount * sizeof(*addrs));
-
-}                              /*afs_CheckServers */
+    afs_osi_Free(conns, j * sizeof(struct afs_conn *));
+    afs_osi_Free(rxconns, j * sizeof(struct rx_connection *));
+    afs_osi_Free(conntimer, j * sizeof(afs_int32));
+    afs_osi_Free(deltas, j * sizeof(afs_int32));
+    afs_osi_Free(results, j * sizeof(afs_int32));
+    
+} /*afs_CheckServers*/
 
 
 /* find a server structure given the host address */
 struct server *
-afs_FindServer(afs_int32 aserver, ushort aport, afsUUID * uuidp,
+afs_FindServer(afs_int32 aserver, afs_uint16 aport, afsUUID * uuidp,
               afs_int32 locktype)
 {
     struct server *ts;
@@ -1011,7 +1102,7 @@ typedef struct ill_s {
  * afs_uint32 subnetmask;         subnet mask of local addr in net order
  *
  */
-int
+void
 afsi_SetServerIPRank(struct srvAddr *sa, afs_int32 addr,
                     afs_uint32 subnetmask)
 {
@@ -1045,6 +1136,7 @@ afsi_SetServerIPRank(struct srvAddr *sa, afs_int32 addr,
            sa->sa_iprank = afs_min(sa->sa_iprank, MED);
        }
     }
+    return;
 }
 #else /* AFS_USERSPACE_IP_ADDR */
 #if (! defined(AFS_SUN5_ENV)) && !defined(AFS_DARWIN60_ENV) && defined(USEIFADDR)
@@ -1091,24 +1183,43 @@ afsi_SetServerIPRank(struct srvAddr *sa, struct in_ifaddr *ifa)
 void
 afsi_SetServerIPRank(sa, ifa)
      struct srvAddr *sa;
+#ifdef AFS_DARWIN80_ENV
+     ifaddr_t ifa;
+#else
      struct ifaddr *ifa;
+#endif
 {
+    struct sockaddr sout;
     struct sockaddr_in *sin;
     int t;
 
     afs_uint32 subnetmask, myAddr, myNet, myDstaddr, mySubnet, netMask;
     afs_uint32 serverAddr;
 
-    if (ifa->ifa_addr->sa_family != AF_INET)
+    if (ifaddr_address_family(ifa) != AF_INET)
        return;
-    sin = (struct sockaddr_in *)ifa->ifa_addr;
-    myAddr = ntohl(sin->sin_addr.s_addr);      /* one of my IP addr in host order */
+    t = ifaddr_address(ifa, &sout, sizeof(sout));
+    if (t == 0) {
+       sin = (struct sockaddr_in *)&sout;
+       myAddr = ntohl(sin->sin_addr.s_addr);   /* one of my IP addr in host order */
+    } else {
+       myAddr = 0;
+    }
     serverAddr = ntohl(sa->sa_ip);     /* server's IP addr in host order */
-    sin = (struct sockaddr_in *)ifa->ifa_netmask;
-    subnetmask = ntohl(sin->sin_addr.s_addr);  /* subnet mask in host order */
-    sin = (struct sockaddr_in *)ifa->ifa_dstaddr;
-    if (sin)
+    t = ifaddr_netmask(ifa, &sout, sizeof(sout));
+    if (t == 0) {
+       sin = (struct sockaddr_in *)&sout;
+       subnetmask = ntohl(sin->sin_addr.s_addr);       /* subnet mask in host order */
+    } else {
+       subnetmask = 0;
+    }
+    t = ifaddr_dstaddress(ifa, &sout, sizeof(sout));
+    if (t == 0) {
+       sin = (struct sockaddr_in *)&sout;
        myDstaddr = sin->sin_addr.s_addr;
+    } else {
+       myDstaddr = 0;
+    }
 
     if (IN_CLASSA(myAddr))
        netMask = IN_CLASSA_NET;
@@ -1127,21 +1238,20 @@ afsi_SetServerIPRank(sa, ifa)
            if (serverAddr == myAddr) { /* same machine */
                sa->sa_iprank = afs_min(sa->sa_iprank, TOPR);
            } else {            /* same subnet */
-               sa->sa_iprank = afs_min(sa->sa_iprank, HI + ifa->ifa_metric);
+               sa->sa_iprank = afs_min(sa->sa_iprank, HI + ifnet_metric(ifaddr_ifnet(ifa)));
            }
        } else {                /* same net */
-           sa->sa_iprank = afs_min(sa->sa_iprank, MED + ifa->ifa_metric);
+           sa->sa_iprank = afs_min(sa->sa_iprank, MED + ifnet_metric(ifaddr_ifnet(ifa)));
        }
     }
 #ifdef  IFF_POINTTOPOINT
     /* check for case #4 -- point-to-point link */
-    if ((ifa->ia_ifp->if_flags & IFF_POINTOPOINT)
-       && (myDstaddr == serverAddr))
-       ) {
-       if (ifa->ia_ifp->if_metric >= (MAXDEFRANK - MED) / PPWEIGHT)
+    if ((ifnet_flags(ifaddr_ifnet(ifa)) & IFF_POINTOPOINT)
+       && (myDstaddr == serverAddr)) {
+       if (ifnet_metric(ifaddr_ifnet(ifa)) >= (MAXDEFRANK - MED) / PPWEIGHT)
            t = MAXDEFRANK;
        else
-           t = MED + (PPWEIGHT << ifa->->ifa_metric);
+           t = MED + (PPWEIGHT << ifnet_metric(ifaddr_ifnet(ifa)));
        if (sa->sa_iprank > t)
            sa->sa_iprank = t;
        }
@@ -1170,14 +1280,73 @@ static int afs_SetServerPrefs(struct srvAddr *sa) {
     }
 #else                          /* AFS_USERSPACE_IP_ADDR */
 #if    defined(AFS_SUN5_ENV)
+#ifdef AFS_SUN510_ENV
+    int i = 0;
+#else
     extern struct ill_s *ill_g_headp;
+    long *addr = (long *)ill_g_headp;
     ill_t *ill;
     ipif_t *ipif;
+#endif
     int subnet, subnetmask, net, netmask;
-    long *addr = (long *)ill_g_headp;
 
     if (sa)
          sa->sa_iprank = 0;
+#ifdef AFS_SUN510_ENV
+    rw_enter(&afsifinfo_lock, RW_READER);
+
+    for (i = 0; (afsifinfo[i].ipaddr != NULL) && (i < ADDRSPERSITE); i++) {
+
+       if (IN_CLASSA(afsifinfo[i].ipaddr)) {
+           netmask = IN_CLASSA_NET;
+       } else if (IN_CLASSB(afsifinfo[i].ipaddr)) {
+           netmask = IN_CLASSB_NET;
+       } else if (IN_CLASSC(afsifinfo[i].ipaddr)) {
+           netmask = IN_CLASSC_NET;
+       } else {
+           netmask = 0;
+       }
+       net = afsifinfo[i].ipaddr & netmask;
+
+#ifdef notdef
+       if (!s) {
+           if (afsifinfo[i].ipaddr != 0x7f000001) {    /* ignore loopback */
+               *cnt += 1;
+               if (*cnt > 16)
+                   return;
+               *addrp++ = afsifinfo[i].ipaddr;
+           }
+       } else
+#endif /* notdef */
+        {
+            /* XXXXXX Do the individual ip ranking below XXXXX */
+            if ((sa->sa_ip & netmask) == net) {
+                if ((sa->sa_ip & subnetmask) == subnet) {
+                    if (afsifinfo[i].ipaddr == sa->sa_ip) {   /* ie, ME!  */
+                        sa->sa_iprank = TOPR;
+                    } else {
+                        sa->sa_iprank = HI + afsifinfo[i].metric; /* case #2 */
+                    }
+                } else {
+                    sa->sa_iprank = MED + afsifinfo[i].metric;    /* case #3 */
+                }
+            } else {
+                    sa->sa_iprank = LO + afsifinfo[i].metric;     /* case #4 */
+            }
+            /* check for case #5 -- point-to-point link */
+            if ((afsifinfo[i].flags & IFF_POINTOPOINT)
+                && (afsifinfo[i].dstaddr == sa->sa_ip)) {
+
+                    if (afsifinfo[i].metric >= (MAXDEFRANK - MED) / PPWEIGHT)
+                        sa->sa_iprank = MAXDEFRANK;
+                    else
+                        sa->sa_iprank = MED + (PPWEIGHT << afsifinfo[i].metric);
+            }
+        }
+    }
+    
+    rw_exit(&afsifinfo_lock);
+#else
     for (ill = (struct ill_s *)*addr /*ill_g_headp */ ; ill;
         ill = ill->ill_next) {
 #ifdef AFS_SUN58_ENV
@@ -1239,6 +1408,7 @@ static int afs_SetServerPrefs(struct srvAddr *sa) {
            }
        }
     }
+#endif /* AFS_SUN510_ENV */
 #else
 #ifndef USEIFADDR
     struct ifnet *ifn = NULL;
@@ -1306,6 +1476,27 @@ static int afs_SetServerPrefs(struct srvAddr *sa) {
 #ifdef AFS_SGI62_ENV
     (void)hash_enum(&hashinfo_inaddr, afsi_enum_set_rank, HTF_INET, NULL,
                    (caddr_t) sa, NULL);
+#elif defined(AFS_DARWIN80_ENV)
+    {
+       errno_t t;
+       unsigned int count;
+       int cnt=0, m, j;
+       ifaddr_t *ifads;
+       ifnet_t *ifn;
+
+       if (!ifnet_list_get(AF_INET, &ifn, &count)) {
+           for (m = 0; m < count; m++) {
+               if (!ifnet_get_address_list(ifn[m], &ifads)) {
+                   for (j = 0; ifads[j] != NULL && cnt < ADDRSPERSITE; j++) {
+                       afsi_SetServerIPRank(sa, ifads[j]);
+                       cnt++;
+                   }
+                   ifnet_free_address_list(ifads);
+               }
+           }
+           ifnet_list_free(ifn);
+       }
+    }
 #elif defined(AFS_DARWIN60_ENV)
     {
        struct ifnet *ifn;
@@ -1566,11 +1757,7 @@ struct server *afs_GetServer(afs_uint32 * aserverp, afs_int32 nservers,
 
        /* Compute preference values and resort */
        if (!newsa->sa_iprank) {
-           if (aport == fsport) {
-               afs_SetServerPrefs(newsa);      /* new fileserver rank */
-           } else {
-               newsa->sa_iprank = 10000 + afs_randomMod127();  /* new vlserver rank */
-           }
+           afs_SetServerPrefs(newsa);  /* new server rank */
        }
     }
     afs_SortOneServer(newts);  /* Sort by rank */
@@ -1664,3 +1851,86 @@ void afs_ActivateServer(struct srvAddr *sap) {
        }
     }
 }
+
+void afs_RemoveAllConns()
+{
+    int i;
+    struct server *ts, *nts;
+    struct srvAddr *sa;
+    struct afs_conn *tc, *ntc;
+
+    ObtainReadLock(&afs_xserver);
+    ObtainWriteLock(&afs_xconn, 1001);
+    
+    /*printf("Destroying connections ... ");*/
+    for (i = 0; i < NSERVERS; i++) {
+        for (ts = afs_servers[i]; ts; ts = nts) {
+            nts = ts->next;
+            for (sa = ts->addr; sa; sa = sa->next_sa) {
+                if (sa->conns) {
+                    tc = sa->conns;
+                    while (tc) {
+                        ntc = tc->next;
+                        AFS_GUNLOCK();
+                        rx_DestroyConnection(tc->id);
+                        AFS_GLOCK();
+                        afs_osi_Free(tc, sizeof(struct afs_conn));
+                        tc = ntc;
+                    }
+                    sa->conns = NULL;
+                }
+            }
+        }
+    }
+    /*printf("done\n");*/
+
+    ReleaseWriteLock(&afs_xconn);
+    ReleaseReadLock(&afs_xserver);
+    
+}
+
+void afs_MarkAllServersUp()
+{
+    int i;
+    struct server *ts;
+    struct srvAddr *sa;
+
+    ObtainWriteLock(&afs_xserver, 721);
+    ObtainWriteLock(&afs_xsrvAddr, 722);
+    for (i = 0; i< NSERVERS; i++) {
+       for (ts = afs_servers[i]; ts; ts = ts->next) {
+           for (sa = ts->addr; sa; sa = sa->next_sa) {
+               afs_MarkServerUpOrDown(sa, 0);
+           }
+       }
+    }
+    ReleaseWriteLock(&afs_xsrvAddr);
+    ReleaseWriteLock(&afs_xserver);
+}
+
+void shutdown_server()
+{
+    int i;
+
+    for (i = 0; i < NSERVERS; i++) {
+       struct server *ts, *next;
+
+        ts = afs_servers[i];
+        while(ts) {
+           next = ts->next;
+           afs_osi_Free(ts, sizeof(struct server));
+           ts = next;
+        }
+    }
+
+    for (i = 0; i < NSERVERS; i++) {
+       struct srvAddr *sa, *next;
+
+        sa = afs_srvAddrs[i];
+        while(sa) {
+           next = sa->next_bkt;
+           afs_osi_Free(sa, sizeof(struct srvAddr));
+           sa = next;
+        }
+    }
+}