DEVEL15-linux-warning-reduction-20090318
[openafs.git] / src / afs / afs_server.c
index 91e3146..19f3092 100644 (file)
@@ -239,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
@@ -254,7 +254,7 @@ afs_ServerDown(struct srvAddr *sa)
     else
        print_internet_address("afs: Lost contact with file server ", sa, "",
                               1);
-
+    return 1;
 }                              /*ServerDown */
 
 
@@ -275,7 +275,7 @@ afs_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;
        }
     }
@@ -288,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);
@@ -488,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)
@@ -495,24 +531,30 @@ 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 = 0, delta;
-    afs_int32 m_error;
     osi_timeval_t tv;
     struct unixuser *tu;
     char tbuffer[CVBS];
     int srvAddrCount;
     struct srvAddr **addrs;
-    struct conn **conns;
+    struct afs_conn **conns;
     int nconns;
     struct rx_connection **rxconns;      
-    afs_int32 *conntimer, *deltas;
+    afs_int32 *conntimer, *deltas, *results;
 
     AFS_STATCNT(afs_CheckServers);
 
-    conns = (struct conn **)0;
+    /* 
+     * 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;
@@ -542,10 +584,11 @@ afs_CheckServers(int adown, struct cell *acellp)
     ReleaseReadLock(&afs_xsrvAddr);
     ReleaseReadLock(&afs_xserver);
 
-    conns = (struct conn **)afs_osi_Alloc(j * sizeof(struct conn *));
+    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;
@@ -600,13 +643,13 @@ afs_CheckServers(int adown, struct cell *acellp)
     multi_Rx(rxconns,nconns)
       {
        tv.tv_sec = tv.tv_usec = 0;
-       multi_RXAFS_GetTime(&tv.tv_sec, &tv.tv_usec);
+       multi_RXAFS_GetTime((afs_uint32 *)&tv.tv_sec, (afs_uint32 *)&tv.tv_usec);
        tc = conns[multi_i];
        sa = tc->srvr;
-       if (conntimer[multi_i] == 0)
-         rx_SetConnDeadTime(tc->id, AFS_RXDEADTIME);
+       if (conntimer[multi_i] == 1)
+         rx_SetConnDeadTime(tc->id, afs_rx_deadtime);
        end = osi_Time();
-       m_error=multi_error;
+       results[multi_i]=multi_error;
        if ((start == end) && !multi_error)
          deltas[multi_i] = end - tv.tv_sec;
        
@@ -617,7 +660,7 @@ afs_CheckServers(int adown, struct cell *acellp)
       tc = conns[i];
       sa = tc->srvr;
       
-      if (( m_error >= 0 ) && (sa->sa_flags & SRVADDR_ISDOWN) && (tc->srvr == sa)) {
+      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);
        
@@ -631,7 +674,7 @@ afs_CheckServers(int adown, struct cell *acellp)
          afs_osi_Wakeup(&afs_waitForever);
        }
       } else {
-       if (m_error < 0) {
+       if (results[i] < 0) {
          /* server crashed */
          afs_ServerDown(sa);
          ForceNewConnections(sa);  /* multi homed clients */
@@ -709,10 +752,11 @@ afs_CheckServers(int adown, struct cell *acellp)
     }
     
     afs_osi_Free(addrs, srvAddrCount * sizeof(*addrs));
-    afs_osi_Free(conns, j * sizeof(struct conn *));
+    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*/
 
@@ -1092,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)
@@ -1138,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;
@@ -1174,20 +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)
+    if ((ifnet_flags(ifaddr_ifnet(ifa)) & IFF_POINTOPOINT)
        && (myDstaddr == serverAddr)) {
-       if (ifa->ia_ifp->if_metric >= (MAXDEFRANK - MED) / PPWEIGHT)
+       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;
        }
@@ -1217,23 +1281,74 @@ static int afs_SetServerPrefs(struct srvAddr *sa) {
 #else                          /* AFS_USERSPACE_IP_ADDR */
 #if    defined(AFS_SUN5_ENV)
 #ifdef AFS_SUN510_ENV
-    ill_walk_context_t ctx;
+    int i = 0;
 #else
     extern struct ill_s *ill_g_headp;
     long *addr = (long *)ill_g_headp;
-#endif
     ill_t *ill;
     ipif_t *ipif;
+#endif
     int subnet, subnetmask, net, netmask;
 
     if (sa)
          sa->sa_iprank = 0;
 #ifdef AFS_SUN510_ENV
-    for (ill = ILL_START_WALK_ALL(&ctx) ; ill ; ill = ill_next(&ctx, ill)) {
+    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) {
-#endif
 #ifdef AFS_SUN58_ENV
        /* Make sure this is an IPv4 ILL */
        if (ill->ill_isv6)
@@ -1293,6 +1408,7 @@ static int afs_SetServerPrefs(struct srvAddr *sa) {
            }
        }
     }
+#endif /* AFS_SUN510_ENV */
 #else
 #ifndef USEIFADDR
     struct ifnet *ifn = NULL;
@@ -1360,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;
@@ -1620,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 */
@@ -1719,6 +1852,61 @@ 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()
 {