viced-alloc-hosts-held-and-locked-20030114
[openafs.git] / src / viced / host.c
index bba7bbc..7f40ead 100644 (file)
@@ -7,7 +7,11 @@
  * directory or online at http://www.openafs.org/dl/license10.html
  */
 
+#include <afsconfig.h>
 #include <afs/param.h>
+
+RCSID("$Header$");
+
 #include <stdio.h>
 #include <errno.h>
 #ifdef AFS_NT40_ENV
 #include <netdb.h>
 #include <netinet/in.h>
 #endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
+
 #include <afs/stds.h>
 #include <rx/xdr.h>
 #include <afs/assert.h>
@@ -41,6 +54,7 @@
 #include <rx/rx.h>
 #include <afs/cellconfig.h>
 #include <stdlib.h>
+#include "viced_prototypes.h"
 #include "viced.h"
 #include "host.h"
 
@@ -110,8 +124,10 @@ static void GetCEBlock()
     register int i;
 
     block = (struct CEBlock *)malloc(sizeof(struct CEBlock));
-    if (!block)
+    if (!block) {
+       ViceLog(0, ("Failed malloc in GetCEBlock\n"));
        ShutDownAndCore(PANIC);
+    }
 
     for(i = 0; i < (CESPERBLOCK -1); i++) {
        Lock_Init(&block->entry[i].lock);
@@ -127,28 +143,27 @@ static void GetCEBlock()
 
 /* get the next available CE */
 static struct client *GetCE()
-
 {
     register struct client *entry;
 
     if (CEFree == 0)
        GetCEBlock();
-    if (CEFree == 0)
+    if (CEFree == 0) {
+       ViceLog(0, ("CEFree NULL in GetCE\n"));
        ShutDownAndCore(PANIC);
+    }
 
     entry = CEFree;
     CEFree = entry->next;
     CEs++;
-    bzero((char *)entry, CLIENT_TO_ZERO(entry));
+    memset((char *)entry, 0, CLIENT_TO_ZERO(entry));
     return(entry);
 
 } /*GetCE*/
 
 
 /* return an entry to the free list */
-static void FreeCE(entry)
-    register struct client *entry;
-
+static void FreeCE(register struct client *entry)
 {
     entry->next = CEFree;
     CEFree = entry;
@@ -182,15 +197,16 @@ struct HTBlock            /* block of HTSPERBLOCK file entries */
 
 /* get a new block of HTs and chain it on HTFree */
 static void GetHTBlock()
-
 {
     register struct HTBlock *block;
     register int i;
     static int index = 0;
 
     block = (struct HTBlock *)malloc(sizeof(struct HTBlock));
-    if (!block)
+    if (!block) {
+       ViceLog(0, ("Failed malloc in GetHTBlock\n"));
        ShutDownAndCore(PANIC);
+    }
 
 #ifdef AFS_PTHREAD_ENV
     for(i=0; i < (h_HTSPERBLOCK); i++)
@@ -211,7 +227,6 @@ static void GetHTBlock()
 
 /* get the next available HT */
 static struct host *GetHT()
-
 {
     register struct host *entry;
 
@@ -221,16 +236,14 @@ static struct host *GetHT()
     entry = HTFree;
     HTFree = entry->next;
     HTs++;
-    bzero((char *)entry, HOST_TO_ZERO(entry));
+    memset((char *)entry, 0, HOST_TO_ZERO(entry));
     return(entry);
 
 } /*GetHT*/
 
 
 /* return an entry to the free list */
-static void FreeHT(entry)
-    register struct host *entry; 
-
+static void FreeHT(register struct host *entry)
 {
     entry->next = HTFree;
     HTFree = entry;
@@ -241,8 +254,7 @@ static void FreeHT(entry)
 
 static short consolePort = 0;
 
-int h_Release(host)
-    register struct host *host;
+int h_Release(register struct host *host)
 {
     H_LOCK
     h_Release_r(host);
@@ -256,33 +268,27 @@ int h_Release(host)
  * If either the HOSTDELETED or CLIENTDELETED flags are set
  * then toss the host
  */
-int h_Release_r(host)
-    register struct host *host;
+int h_Release_r(register struct host *host)
 {      
     
-    if (!((host)->holds[h_holdSlot()] &= ~h_holdbit()) ) {
+    if (!((host)->holds[h_holdSlot()] & ~h_holdbit()) ) {
        if (! h_OtherHolds_r(host) ) {
+           /* must avoid masking this until after h_OtherHolds_r runs
+              but it should be run before h_TossStuff_r */
+           (host)->holds[h_holdSlot()] &= ~h_holdbit();
            if ( (host->hostFlags & HOSTDELETED) || 
                (host->hostFlags & CLIENTDELETED) ) {
                h_TossStuff_r(host);
            }           
-       }
-    }
-    return 0;
-}
+       } else 
+           (host)->holds[h_holdSlot()] &= ~h_holdbit();
+    } else 
+      (host)->holds[h_holdSlot()] &= ~h_holdbit();
 
-int h_Held(host)
-    register struct host *host;
-{
-    int retVal;
-    H_LOCK
-    retVal = h_Held_r(host);
-    H_UNLOCK
-    return retVal;
+    return 0;
 }
 
-int h_OtherHolds_r(host)
-    register struct host *host;
+int h_OtherHolds_r(register struct host *host)
 {
     register int i, bit, slot;
     bit = h_holdbit();
@@ -295,18 +301,7 @@ int h_OtherHolds_r(host)
     return 0;
 }
 
-int h_OtherHolds(host)
-    register struct host *host;
-{
-    int retVal;
-    H_LOCK
-    retVal = h_OtherHolds_r(host);
-    H_UNLOCK
-    return retVal;
-}
-
-int h_Lock_r(host)
-    register struct host *host;
+int h_Lock_r(register struct host *host)
 {
     H_UNLOCK
     h_Lock(host);
@@ -320,8 +315,7 @@ int h_Lock_r(host)
   * else returns locks and returns 0
   */
 
-int h_NBLock_r(host)
-    register struct host *host;
+int h_NBLock_r(register struct host *host)
 {
     struct Lock *hostLock = &host->lock;
     int locked = 0;
@@ -370,10 +364,7 @@ int h_NBLock_r(host)
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-static char h_AddrInSameNetwork(a_targetAddr, a_candAddr)
-    afs_uint32 a_targetAddr;
-    afs_uint32 a_candAddr;
-
+static char h_AddrInSameNetwork(afs_uint32 a_targetAddr, afs_uint32 a_candAddr)
 { /*h_AddrInSameNetwork*/
 
     afs_uint32 targetNet;
@@ -427,9 +418,8 @@ static char h_AddrInSameNetwork(a_targetAddr, a_candAddr)
 
 
 
-h_gethostcps_r(host,now)
-    register struct host *host;
-    register afs_int32   now;
+void
+h_gethostcps_r(register struct host *host, register afs_int32 now)
 {
     register int code;
     int  slept=0, held;
@@ -440,10 +430,10 @@ h_gethostcps_r(host,now)
                h_Hold_r(host);
 
        /* wait if somebody else is already doing the getCPS call */
-    while ( host->hostFlags & HPCS_INPROGRESS ) 
+    while ( host->hostFlags & HCPS_INPROGRESS ) 
     {
        slept = 1;              /* I did sleep */
-       host->hostFlags |= HPCS_WAITING; /* I am sleeping now */
+       host->hostFlags |= HCPS_WAITING; /* I am sleeping now */
 #ifdef AFS_PTHREAD_ENV
        pthread_cond_wait(&host->cond, &host_glock_mutex);
 #else /* AFS_PTHREAD_ENV */
@@ -453,10 +443,10 @@ h_gethostcps_r(host,now)
     }
 
 
-    host->hostFlags |= HPCS_INPROGRESS;        /* mark as CPSCall in progress */
+    host->hostFlags |= HCPS_INPROGRESS;        /* mark as CPSCall in progress */
     if (host->hcps.prlist_val)
        free(host->hcps.prlist_val);    /* this is for hostaclRefresh */
-    host->hcps.prlist_val = (afs_int32 *)0;
+    host->hcps.prlist_val = NULL;
     host->hcps.prlist_len = 0;
     slept? (host->cpsCall = FT_ApproxTime()): (host->cpsCall = now );
 
@@ -491,16 +481,16 @@ h_gethostcps_r(host,now)
        }
        if (host->hcps.prlist_val)
            free(host->hcps.prlist_val);
-       host->hcps.prlist_val = (afs_int32 *)0;
+       host->hcps.prlist_val = NULL;
        host->hcps.prlist_len = 0;      /* Make sure it's zero */
     } else
        host->hcpsfailed = 0;
 
-    host->hostFlags &=  ~HPCS_INPROGRESS;
+    host->hostFlags &=  ~HCPS_INPROGRESS;
                                        /* signal all who are waiting */
-    if ( host->hostFlags & HPCS_WAITING) /* somebody is waiting */
+    if ( host->hostFlags & HCPS_WAITING) /* somebody is waiting */
     {
-        host->hostFlags &= ~HPCS_WAITING;
+        host->hostFlags &= ~HCPS_WAITING;
 #ifdef AFS_PTHREAD_ENV
        assert(pthread_cond_broadcast(&host->cond) == 0);
 #else /* AFS_PTHREAD_ENV */
@@ -518,12 +508,15 @@ void h_flushhostcps(hostaddr, hport)
     register afs_uint32  hostaddr, hport;  /* net byte order */
 {
     register struct host *host;
+    int held;
     
     H_LOCK
-    host = h_Lookup_r(hostaddr, hport);
+    host = h_Lookup_r(hostaddr, hport, &held);
     if (host) {
       host->hcpsfailed = 1;
     }
+    if (!held)
+      h_Release_r(host);
     H_UNLOCK
 
 return;
@@ -532,23 +525,11 @@ return;
 
 /*
  * Allocate a host.  It will be identified by the peer (ip,port) info in the
- * rx connection provided.  The host is returned un-held and un-locked
+ * rx connection provided.  The host is returned held and locked
  */
 #define        DEF_ROPCONS 2115
 
-struct host *h_Alloc(r_con)
-    register struct rx_connection *r_con;
-{
-    struct host *retVal;
-    H_LOCK
-    retVal = h_Alloc_r(r_con);
-    H_UNLOCK
-    return retVal;
-}
-
-struct host *h_Alloc_r(r_con)
-    register struct rx_connection *r_con;
-
+struct host *h_Alloc_r(register struct rx_connection *r_con)
 {
     register int code;
     struct servent *serverentry;
@@ -588,7 +569,7 @@ struct host *h_Alloc_r(r_con)
        makes a request that causes a break call back.  It shouldn't. */
     {
        if (!sc)
-           sc = (struct rx_securityClass *) rxnull_NewClientSecurityObject();
+           sc = rxnull_NewClientSecurityObject();
        host->callback_rxcon = rx_NewConnection (host->host, host->port,
                                                 1, sc, 0);
        rx_SetConnDeadTime(host->callback_rxcon, 50);
@@ -596,13 +577,17 @@ struct host *h_Alloc_r(r_con)
     }
     now = host->LastCall = host->cpsCall = host->ActiveCall = FT_ApproxTime();
     host->hostFlags = 0;
-    host->hcps.prlist_val = (afs_int32 *)0;
+    host->hcps.prlist_val = NULL;
     host->hcps.prlist_len = 0;
-    host->hcps.prlist_val = (afs_int32 *)0;
+    host->hcps.prlist_val = NULL;
     host->interface = 0;
-    /*host->hcpsfailed = 0;    /* save cycles */
-    /* h_gethostcps(host);      do this under host lock */
+#ifdef undef
+    host->hcpsfailed = 0;      /* save cycles */
+    h_gethostcps(host);      /* do this under host lock */
+#endif
     host->FirstClient = 0;      
+    h_Hold_r(host);
+    h_Lock_r(host);
     h_InsertList_r(host);      /* update global host List */
 #if FS_STATS_DETAILED
     /*
@@ -615,22 +600,14 @@ struct host *h_Alloc_r(r_con)
 #endif /* FS_STATS_DETAILED */
     return host;
 
-} /*h_Alloc*/
+} /*h_Alloc_r*/
 
 
 /* Lookup a host given an IP address and UDP port number. */
-struct host *h_Lookup(hostaddr, hport)
-    afs_uint32 hostaddr, hport;     /* network byte order */
-{
-    struct host *retVal;
-    H_LOCK
-    retVal = h_Lookup_r(hostaddr, hport);
-    H_UNLOCK
-    return retVal;
-}
-
-struct host *h_Lookup_r(hostaddr, hport)
-    afs_uint32 hostaddr, hport;     /* network byte order */
+/* hostaddr and hport are in network order */
+/* Note: host should be released by caller if 0 == *heldp and non-null */
+/* hostaddr and hport are in network order */
+struct host *h_Lookup_r(afs_uint32 hostaddr, afs_uint32 hport, int *heldp)
 {
     register afs_int32 now;
     register struct host *host=0;
@@ -638,17 +615,30 @@ struct host *h_Lookup_r(hostaddr, hport)
     register index = h_HashIndex(hostaddr);
     extern int hostaclRefresh;
 
+restart:
     for (chain=hostHashTable[index]; chain; chain=chain->next) {
        host = chain->hostPtr;
        assert(host);
         if (!(host->hostFlags & HOSTDELETED) && chain->addr == hostaddr
            && host->port == hport) {
+           *heldp = h_Held_r(host);
+           if (!*heldp)
+               h_Hold_r(host);
+           h_Lock_r(host);
+           if (host->hostFlags & HOSTDELETED) {
+               h_Unlock_r(host);
+               if (!*heldp)
+                   h_Release_r(host);
+               goto restart;
+           }
+           h_Unlock_r(host);
             now = FT_ApproxTime();             /* always evaluate "now" */
            if (host->hcpsfailed || (host->cpsCall+hostaclRefresh < now )) {
                /*
-                * Every hostaclRefresh period (def 2 hrs) get the new membership list for the host.
-                * Note this could be the first time that the host is added to a group.
-                * Also here we also retry on previous legitimate hcps failures
+                * Every hostaclRefresh period (def 2 hrs) get the new
+                * membership list for the host.  Note this could be the
+                * first time that the host is added to a group.  Also
+                * here we also retry on previous legitimate hcps failures.
                 */
                h_gethostcps_r(host,now);
            }
@@ -661,8 +651,7 @@ struct host *h_Lookup_r(hostaddr, hport)
 } /*h_Lookup*/
 
 /* Lookup a host given its UUID. */
-struct host *h_LookupUuid_r(uuidp)
-    afsUUID *uuidp;
+struct host *h_LookupUuid_r(afsUUID *uuidp)
 {
     register struct host *host=0;
     register struct h_hashChain* chain;
@@ -683,31 +672,18 @@ struct host *h_LookupUuid_r(uuidp)
 
 
 /*
- * h_Hold: Establish a hold by the current LWP on this host--the host
+ * h_Hold_r: Establish a hold by the current LWP on this host--the host
  * or its clients will not be physically deleted until all holds have
  * been released.
- *
  * NOTE: h_Hold_r is a macro defined in host.h.
  */
 
-int h_Hold(host)
-    register struct host *host;
-{
-    H_LOCK
-    h_Hold_r(host);
-    H_UNLOCK
-    return 0;
-}
-
-
-/* h_TossStuff:  Toss anything in the host structure (the host or
+/* h_TossStuff_r:  Toss anything in the host structure (the host or
  * clients marked for deletion.  Called from r_Release ONLY.
  * To be called, there must be no holds, and either host->deleted
  * or host->clientDeleted must be set.
  */
-h_TossStuff_r(host)
-    register struct host *host;
-
+int h_TossStuff_r(register struct host *host)
 {
     register struct client **cp, *client;
     int                i;
@@ -718,11 +694,11 @@ h_TossStuff_r(host)
        return;
 
     /* ASSUMPTION: r_FreeConnection() does not yield */
-    for (cp = &host->FirstClient; client = *cp; ) {
+    for (cp = &host->FirstClient; (client = *cp); ) {
        if ((host->hostFlags & HOSTDELETED) || client->deleted) {
            if ((client->ViceId != ANONYMOUSID) && client->CPS.prlist_val) {
                free(client->CPS.prlist_val);
-                client->CPS.prlist_val = (afs_int32 *)0;
+                client->CPS.prlist_val = NULL;
            }
            if (client->tcon) {
                rx_SetSpecific(client->tcon, rxcon_client_key, (void *)0);
@@ -732,6 +708,10 @@ h_TossStuff_r(host)
            FreeCE(client);
        } else cp = &client->next;
     }
+
+    /* We've just cleaned out all the deleted clients; clear the flag */
+    host->hostFlags &= ~CLIENTDELETED;
+
     if (host->hostFlags & HOSTDELETED) {
        register struct h_hashChain **hp, *th;
        register struct rx_connection *rxconn;
@@ -740,7 +720,7 @@ h_TossStuff_r(host)
        int i;
 
        if (host->Console & 1) Console--;
-       if (rxconn = host->callback_rxcon) {
+       if ((rxconn = host->callback_rxcon)) {
            host->callback_rxcon = (struct rx_connection *)0;
            /*
             * If rx_DestroyConnection calls h_FreeConnection we will
@@ -756,16 +736,16 @@ h_TossStuff_r(host)
        }
        if (host->hcps.prlist_val)
            free(host->hcps.prlist_val);
-       host->hcps.prlist_val = (afs_int32 *)0;
+       host->hcps.prlist_val = NULL;
        host->hcps.prlist_len = 0;
-       DeleteAllCallBacks_r(host);
+       DeleteAllCallBacks_r(host, 1);
        host->hostFlags &= ~RESETDONE;  /* just to be safe */
 
        /* if alternate addresses do not exist */
        if ( !(host->interface) )
        {
                for (hp = &hostHashTable[h_HashIndex(host->host)];
-                       th = *hp; hp = &th->next) 
+                       (th = *hp); hp = &th->next) 
                {
                        assert(th->hostPtr);
                        if (th->hostPtr == host) 
@@ -782,7 +762,7 @@ h_TossStuff_r(host)
            /* delete all hash entries for the UUID */
            uuidp = &host->interface->uuid;
            for (hp = &hostUuidHashTable[h_UuidHashIndex(uuidp)];
-                th = *hp; hp = &th->next) {
+                (th = *hp); hp = &th->next) {
                assert(th->hostPtr);
                if (th->hostPtr == host)
                {
@@ -797,7 +777,7 @@ h_TossStuff_r(host)
            {
                hostAddr = host->interface->addr[i];
                for (hp = &hostHashTable[h_HashIndex(hostAddr)];
-                       th = *hp; hp = &th->next) 
+                       (th = *hp); hp = &th->next) 
                {
                        assert(th->hostPtr);
                        if (th->hostPtr == host) 
@@ -818,9 +798,7 @@ h_TossStuff_r(host)
 
 
 /* Called by rx when a server connection disappears */
-h_FreeConnection(tcon)
-    struct rx_connection *tcon;
-
+int h_FreeConnection(struct rx_connection *tcon)
 {
     register struct client *client;
 
@@ -841,10 +819,7 @@ h_FreeConnection(tcon)
  * to (*proc) as the param held.  The proc should return 0 if the host should be
  * released, 1 if it should be held after enumeration.
  */
-h_Enumerate(proc, param)
-    int (*proc)();
-    char *param;
-
+void h_Enumerate(int (*proc)(), char *param)
 {
     register struct host *host, **list;
     register int *held;
@@ -875,18 +850,17 @@ h_Enumerate(proc, param)
     free((void *)held);
 } /*h_Enumerate*/
 
-/* h_Enumerate_r: Calls (*proc)(host, held, param) for at least each host in
- * the at the start of the enumeration (perhaps more).  Hosts may be deleted
- * (have delete flag set); ditto for clients.  (*proc) is always called with
+/* h_Enumerate_r (revised):
+ * Calls (*proc)(host, held, param) for each host in hostList, starting
+ * at enumstart
+ * Hosts may be deleted (have delete flag set); ditto for clients.
+ * (*proc) is always called with
  * host h_held() and the global host lock (H_LOCK) locked.The hold state of the
  * host with respect to this lwp is passed to (*proc) as the param held.
  * The proc should return 0 if the host should be released, 1 if it should
  * be held after enumeration.
  */
-h_Enumerate_r(proc, param)
-    int (*proc)();
-    char *param;
-
+void h_Enumerate_r(int (*proc)(), struct host* enumstart, char *param)
 {
     register struct host *host;
     register int held;
@@ -894,20 +868,34 @@ h_Enumerate_r(proc, param)
     if (hostCount == 0) {
        return;
     }
-    for (host = hostList ; host ; host = host->next) {
+    for (host = enumstart ; host ; host = host->next) {
        if (!(held = h_Held_r(host)))
            h_Hold_r(host);
        held = (*proc)(host, held, param);
        if (!held)
            h_Release_r(host);/* this might free up the host */
     }
-} /*h_Enumerate*/
+} /*h_Enumerate_r*/
 
+/* inserts a new HashChain structure corresponding to this UUID */
+void hashInsertUuid_r(struct afsUUID *uuid, struct host* host)
+{
+       int index;
+       struct h_hashChain*     chain;
 
-/* Host is returned held */
-struct host *h_GetHost_r(tcon)
-    struct rx_connection *tcon;
+       /* hash into proper bucket */
+       index = h_UuidHashIndex(uuid);
+
+        /* insert into beginning of list for this bucket */
+       chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
+       assert(chain);
+       chain->hostPtr = host;
+       chain->next = hostUuidHashTable[index];
+       hostUuidHashTable[index] = chain;
+}
 
+/* Host is returned held */
+struct host *h_GetHost_r(struct rx_connection *tcon)
 {
     struct host *host;
     struct host *oldHost;
@@ -915,32 +903,31 @@ struct host *h_GetHost_r(tcon)
     int held;
     struct interfaceAddr interf;
     int interfValid = 0;
-    afs_int32  buffer[AFS_MAX_INTERFACE_ADDR];
     struct Identity *identP = NULL;
     afs_int32 haddr;
     afs_int32 hport;
     int i, j, count;
+    char hoststr[16], hoststr2[16];
 
     haddr = rxr_HostOf(tcon);
     hport = rxr_PortOf(tcon);
 retry:
     code = 0;
     identP = (struct Identity *)rx_GetSpecific(tcon, rxcon_ident_key);
-    host = h_Lookup_r(haddr, hport);
+    host = h_Lookup_r(haddr, hport, &held);
     if (host && !identP && !(host->Console&1)) {
        /* This is a new connection, and we already have a host
         * structure for this address. Verify that the identity
         * of the caller matches the identity in the host structure.
         */
-       if (!(held = h_Held_r(host)))
-               h_Hold_r(host);
        h_Lock_r(host);
        if ( !(host->hostFlags & ALTADDR) )
        {
                /* Another thread is doing initialization */
                h_Unlock_r(host);
                if ( !held) h_Release_r(host);
-               ViceLog(125, ("Host %x starting h_Lookup again\n", host));
+               ViceLog(125, ("Host %s:%d starting h_Lookup again\n",
+                            afs_inet_ntoa_r(host->host, hoststr), host->port));
                goto retry;
        }
        host->hostFlags &= ~ALTADDR;
@@ -948,7 +935,7 @@ retry:
        code = RXAFSCB_WhoAreYou(host->callback_rxcon, &interf);
        H_LOCK
        if ( code == RXGEN_OPCODE ) {
-               identP = (struct Identity *)malloc(1);
+               identP = (struct Identity *)malloc(sizeof(struct Identity));
                identP->valid = 0;
                rx_SetSpecific(tcon, rxcon_ident_key, identP);
                /* The host on this connection was unable to respond to 
@@ -957,8 +944,8 @@ retry:
                 * that we maintain some extra callback state information */
                if (host->interface) {
                    ViceLog(0,
-                           ("Host %x used to support WhoAreYou, deleting.\n",
-                           host));
+                           ("Host %s:%d used to support WhoAreYou, deleting.\n",
+                           afs_inet_ntoa_r(host->host, hoststr), host->port));
                    host->hostFlags |= HOSTDELETED;
                    h_Unlock_r(host);
                    if (!held) h_Release_r(host);
@@ -977,8 +964,8 @@ retry:
                if ( !host->interface
                  || !afs_uuid_equal(&interf.uuid, &host->interface->uuid) ) {
                    ViceLog(25,
-                           ("Host %x has changed its identity, deleting.\n",
-                           host));
+                           ("Host %s:%d has changed its identity, deleting.\n",
+                           afs_inet_ntoa_r(host->host, hoststr), host->port));
                    host->hostFlags |= HOSTDELETED;
                    h_Unlock_r(host);
                    if (!held) h_Release_r(host);
@@ -986,26 +973,24 @@ retry:
                    goto retry;
                }
        } else {
-               char *hoststr = afs_inet_ntoa_r(host->host);
-               ViceLog(0,("CB: WhoAreYou failed for %s:%d, error %d\n", 
-                       hoststr, ntohs(host->port), code));
-               host->hostFlags |= VENUSDOWN;
-               free(hoststr);
+           afs_inet_ntoa_r(host->host, hoststr);
+           ViceLog(0,("CB: WhoAreYou failed for %s:%d, error %d\n", 
+                      hoststr, ntohs(host->port), code));
+           host->hostFlags |= VENUSDOWN;
        }
        host->hostFlags |= ALTADDR;
        h_Unlock_r(host);
     } else if (host) {
-       if (!(held = h_Held_r(host)))
-               h_Hold_r(host);
        if ( ! (host->hostFlags & ALTADDR) ) 
        {
                /* another thread is doing the initialisation */
-               ViceLog(125, ("Host %x waiting for host-init to complete\n",
-                               host));
+               ViceLog(125, ("Host %s:%d waiting for host-init to complete\n",
+                            afs_inet_ntoa_r(host->host, hoststr), host->port));
                h_Lock_r(host);
                h_Unlock_r(host);
                if ( !held) h_Release_r(host);
-               ViceLog(125, ("Host %x starting h_Lookup again\n", host));
+               ViceLog(125, ("Host %s:%d starting h_Lookup again\n",
+                            afs_inet_ntoa_r(host->host, hoststr), host->port));
                goto retry;
        }
        /* We need to check whether the identity in the host structure
@@ -1020,14 +1005,12 @@ retry:
                host->hostFlags |= HOSTDELETED;
                h_Unlock_r(host);
                if (!held) h_Release_r(host);
-               ViceLog(0,("CB: new identity for host %x, deleting\n",
-                          host->host));
+               ViceLog(0, ("CB: new identity for host %s:%d, deleting\n",
+                          afs_inet_ntoa_r(host->host, hoststr), host->port));
                goto retry;
        }
     } else {
-        host = h_Alloc_r(tcon);
-        h_Hold_r(host);
-        h_Lock_r(host);
+       host = h_Alloc_r(tcon); /* returned held and locked */
        h_gethostcps_r(host,FT_ApproxTime());
         if (!(host->Console&1)) {
            if (!identP || !interfValid) {
@@ -1035,12 +1018,12 @@ retry:
                code = RXAFSCB_WhoAreYou(host->callback_rxcon, &interf);
                H_LOCK
                if ( code == RXGEN_OPCODE ) {
-                   identP = (struct Identity *)malloc(1);
+                 identP = (struct Identity *)malloc(sizeof(struct Identity));
                    identP->valid = 0;
                    rx_SetSpecific(tcon, rxcon_ident_key, identP);
                    ViceLog(25,
-                           ("Host %x does not support WhoAreYou.\n",
-                           host->host));
+                           ("Host %s:%d does not support WhoAreYou.\n",
+                           afs_inet_ntoa_r(host->host, hoststr), host->port));
                    code = 0;
                } else if (code == 0) {
                    interfValid = 1;
@@ -1048,7 +1031,8 @@ retry:
                    identP->valid = 1;
                    identP->uuid = interf.uuid;
                    rx_SetSpecific(tcon, rxcon_ident_key, identP);
-                   ViceLog(25,("WhoAreYou success on %x\n", host->host));
+                   ViceLog(25, ("WhoAreYou success on %s:%d\n",
+                               afs_inet_ntoa_r(host->host, hoststr), host->port));
                }
            }
            if (code == 0 && !identP->valid) {
@@ -1064,8 +1048,9 @@ retry:
                    if (!(held = h_Held_r(oldHost)))
                        h_Hold_r(oldHost);
                    h_Lock_r(oldHost);
-                   ViceLog(25,("CB: new addr %x for old host %x\n",
-                               host->host, oldHost->host));
+                   ViceLog(25, ("CB: new addr %s:%d for old host %s:%d\n",
+                               afs_inet_ntoa_r(host->host, hoststr), host->port,
+                               afs_inet_ntoa_r(oldHost->host, hoststr2), oldHost->port));
                    host->hostFlags |= HOSTDELETED;
                    h_Unlock_r(host);
                    h_Release_r(host);
@@ -1079,19 +1064,18 @@ retry:
                                                      &FS_HostUUID);
                    H_LOCK
                    if (code == 0) {
-                       ViceLog(25,("InitCallBackState3 success on %x\n",
-                               host->host));
+                       ViceLog(25, ("InitCallBackState3 success on %s:%d\n",
+                                   afs_inet_ntoa_r(host->host, hoststr), host->port));
                        assert(interfValid == 1);
                        initInterfaceAddr_r(host, &interf);
                    }
                }
           }
           if (code) {
-               char *hoststr = afs_inet_ntoa_r(host->host);
-               ViceLog(0,("CB: RCallBackConnectBack failed for %s:%d\n", 
-                       hoststr, ntohs(host->port)));
-               host->hostFlags |= VENUSDOWN;
-               free(hoststr);
+               afs_inet_ntoa_r(host->host, hoststr);
+               ViceLog(0,("CB: RCallBackConnectBack failed for %s:%d\n", 
+                         hoststr, ntohs(host->port)));
+              host->hostFlags |= VENUSDOWN;
            }
            else
                host->hostFlags |= RESETDONE;
@@ -1125,11 +1109,7 @@ void h_InitHostPackage()
 #endif /* AFS_PTHREAD_ENV */
 }
 
-static MapName_r(aname, acell, aval)
-    char *aname;
-    char *acell;
-    afs_int32 *aval;
-
+static int MapName_r(char *aname, char *acell, afs_int32 *aval)
 {
     namelist lnames;
     idlist lids;
@@ -1145,7 +1125,7 @@ static MapName_r(aname, acell, aval)
     lnames.namelist_len = 1;
     lnames.namelist_val = (prname *) aname;  /* don't malloc in the common case */
     lids.idlist_len = 0;
-    lids.idlist_val = (afs_int32 *) 0;
+    lids.idlist_val = NULL;
 
     cnamelen=strlen(acell);
     if (cnamelen) {
@@ -1192,8 +1172,7 @@ static MapName_r(aname, acell, aval)
 
 
 /* NOTE: this returns the client with a Shared lock */
-struct client *h_ID2Client(vid)
-afs_int32 vid;
+struct client *h_ID2Client(afs_int32 vid)
 {
     register struct client *client;
     register struct host *host;
@@ -1217,7 +1196,7 @@ afs_int32 vid;
       }
 
     H_UNLOCK
-return 0;
+    return 0;
 }
 
 /*
@@ -1227,9 +1206,7 @@ return 0;
  * by one. The caller must call h_ReleaseClient_r when finished with
  * the client.
  */
-struct client *h_FindClient_r(tcon)
-    struct rx_connection *tcon;
-
+struct client *h_FindClient_r(struct rx_connection *tcon)
 {
     register struct client *client;
     register struct host *host;
@@ -1358,7 +1335,7 @@ ticket name length != 64
        if (client->CPS.prlist_val && (client->ViceId != ANONYMOUSID)) {
           free(client->CPS.prlist_val);
        }
-       client->CPS.prlist_val = (afs_int32 *)0;
+       client->CPS.prlist_val = NULL;
         client->ViceId = viceid;
        client->expTime = expTime;
 
@@ -1370,8 +1347,11 @@ ticket name length != 64
          code = pr_GetCPS(viceid, &client->CPS);
          H_LOCK
          if (code) {
-           ViceLog(0, ("pr_GetCPS failed(%d) for user %d, host %x.%d\n",
-                   code, viceid, client->host->host, ntohs(client->host->port)));
+           char hoststr[16];
+           ViceLog(0, ("pr_GetCPS failed(%d) for user %d, host %s:%d\n",
+                      code, viceid,
+                      afs_inet_ntoa_r(client->host->host, hoststr),
+                      client->host->port));
 
            /* Although ubik_Call (called by pr_GetCPS) traverses thru
             * all protection servers and reevaluates things if no
@@ -1402,7 +1382,7 @@ ticket name length != 64
      * required).  So, before setting the RPC's rock, we should disconnect
      * the RPC from the other client structure's rock.
      */
-    if (oldClient = (struct client *) rx_GetSpecific(tcon, rxcon_client_key)) {
+    if ((oldClient = (struct client *) rx_GetSpecific(tcon, rxcon_client_key))) {
        oldClient->tcon = (struct rx_connection *) 0;
        /* rx_SetSpecific will be done immediately below */
     }
@@ -1414,8 +1394,7 @@ ticket name length != 64
 
 } /*h_FindClient_r*/
 
-int h_ReleaseClient_r(client)
-    struct client *client;
+int h_ReleaseClient_r(struct client *client)
 {
     assert(client->refCount > 0);
     client->refCount--;
@@ -1430,10 +1409,7 @@ int h_ReleaseClient_r(client)
  * It does check tokens, since only the server routines can return the
  * VICETOKENDEAD error code
  */
-int GetClient(tcon, cp)
-    struct rx_connection * tcon;
-    struct client **cp;
-
+int GetClient(struct rx_connection * tcon, struct client **cp)
 {
     register struct client *client;
 
@@ -1444,8 +1420,11 @@ int GetClient(tcon, cp)
     assert(client && client->tcon && rxr_CidOf(client->tcon) == client->sid);
     if (client &&
        client->LastCall > client->expTime && client->expTime) {
-       ViceLog(1, ("Token for %s at %x.%d expired %d\n",
-               h_UserName(client), client->host->host, client->host->port, client->expTime));
+       char hoststr[16];
+       ViceLog(1, ("Token for %s at %s:%d expired %d\n",
+               h_UserName(client),
+               afs_inet_ntoa_r(client->host->host, hoststr),
+               client->host->port, client->expTime));
        H_UNLOCK
        return VICETOKENDEAD;
     }
@@ -1457,9 +1436,7 @@ int GetClient(tcon, cp)
 
 
 /* Client user name for short term use.  Note that this is NOT inexpensive */
-char *h_UserName(client)
-    struct client *client;
-
+char *h_UserName(struct client *client)
 {
     static char User[PR_MAXNAMELEN+1];
     namelist lnames;
@@ -1483,8 +1460,7 @@ char *h_UserName(client)
 } /*h_UserName*/
 
 
-h_PrintStats()
-
+void h_PrintStats()
 {
     ViceLog(0,
            ("Total Client entries = %d, blocks = %d; Host entries = %d, blocks = %d\n",
@@ -1493,23 +1469,23 @@ h_PrintStats()
 } /*h_PrintStats*/
 
 
-static int h_PrintClient(host, held, file)
-    register struct host *host;
-    int held;
-    StreamHandle_t *file;
+static int 
+h_PrintClient(register struct host *host, int held, StreamHandle_t *file)
 {
     register struct client *client;
     int i;
     char tmpStr[256];
     char tbuffer[32];
+    char hoststr[16];
 
     H_LOCK
     if (host->hostFlags & HOSTDELETED) {
        H_UNLOCK
        return held;
     }
-    sprintf(tmpStr,"Host %x.%d down = %d, LastCall %s", host->host,
-           host->port, (host->hostFlags & VENUSDOWN),
+    sprintf(tmpStr,"Host %s:%d down = %d, LastCall %s",
+           afs_inet_ntoa_r(host->host, hoststr), host->port,
+           (host->hostFlags & VENUSDOWN),
            afs_ctime((time_t *)&host->LastCall, tbuffer, sizeof(tbuffer)));
     STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
     for (client = host->FirstClient; client; client=client->next) {
@@ -1551,8 +1527,7 @@ static int h_PrintClient(host, held, file)
  * Print a list of clients, with last security level and token value seen,
  * if known
  */
-h_PrintClients()
-
+void h_PrintClients()
 {
     time_t now;
     char tmpStr[256];
@@ -1576,18 +1551,15 @@ h_PrintClients()
 
 
 
-static int h_DumpHost(host, held, file)
-    register struct host *host;
-    int held;
-    StreamHandle_t *file;
-
+static int 
+h_DumpHost(register struct host *host, int held, StreamHandle_t *file)
 {
     int i;
     char tmpStr[256];
 
     H_LOCK
-    sprintf(tmpStr, "ip:%x holds:%d port:%d hidx:%d cbid:%d lock:%x last:%u active:%u down:%d del:%d cons:%d cldel:%d\n\t hpfailed:%d hcpsCall:%u hcps [",
-           host->host, host->holds, host->port, host->index, host->cblist,
+    sprintf(tmpStr, "ip:%x port:%d hidx:%d cbid:%d lock:%x last:%u active:%u down:%d del:%d cons:%d cldel:%d\n\t hpfailed:%d hcpsCall:%u hcps [",
+           host->host, host->port, host->index, host->cblist,
            CheckLock(&host->lock), host->LastCall, host->ActiveCall, 
            (host->hostFlags & VENUSDOWN), host->hostFlags&HOSTDELETED, 
            host->Console, host->hostFlags & CLIENTDELETED, 
@@ -1605,16 +1577,23 @@ static int h_DumpHost(host, held, file)
            sprintf(tmpStr, " %x", host->interface->addr[i]);
            STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
        }
-    sprintf(tmpStr, "]\n");
+    sprintf(tmpStr, "] holds: ");
     STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
+
+    for (i = 0 ; i < h_maxSlots ; i++) {
+      sprintf(tmpStr, "%04x", host->holds[i]);
+      STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
+    }
+    sprintf(tmpStr, " slot/bit: %d/%d\n", h_holdSlot(), h_holdbit());
+    STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
+
     H_UNLOCK
     return held;
 
 } /*h_DumpHost*/
 
 
-h_DumpHosts()
-
+void h_DumpHosts()
 {
     time_t now;
     StreamHandle_t *file = STREAM_OPEN(AFSDIR_SERVER_HOSTDUMP_FILEPATH, "w");
@@ -1642,12 +1621,8 @@ h_DumpHosts()
  * recently).  An active workstation has received a call since the cutoff
  * time argument passed.
  */
-h_GetWorkStats(nump, activep, delp, cutofftime)
-    int *nump;
-    int *activep;
-    int *delp;
-    afs_int32 cutofftime;
-
+void 
+h_GetWorkStats(int *nump, int *activep, int *delp, afs_int32 cutofftime)
 {
     register int i;
     register struct host *host;
@@ -1705,14 +1680,10 @@ h_GetWorkStats(nump, activep, delp, cutofftime)
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-static void h_ClassifyAddress(a_targetAddr, a_candAddr, a_sameNetOrSubnetP,
-                      a_diffSubnetP, a_diffNetworkP)
-    afs_uint32 a_targetAddr;
-    afs_uint32 a_candAddr;
-    afs_int32 *a_sameNetOrSubnetP;
-    afs_int32 *a_diffSubnetP;
-    afs_int32 *a_diffNetworkP;
-
+static void h_ClassifyAddress(afs_uint32 a_targetAddr, afs_uint32 a_candAddr,
+                             afs_int32 *a_sameNetOrSubnetP, 
+                             afs_int32 *a_diffSubnetP, 
+                             afs_int32 *a_diffNetworkP)
 { /*h_ClassifyAddress*/
 
     register int i;                     /*Iterator thru host hash table*/
@@ -1821,13 +1792,8 @@ static void h_ClassifyAddress(a_targetAddr, a_candAddr, a_sameNetOrSubnetP,
  *     As advertised.
  *------------------------------------------------------------------------*/
 
-void h_GetHostNetStats(a_numHostsP, a_sameNetOrSubnetP, a_diffSubnetP,
-                      a_diffNetworkP)
-    afs_int32 *a_numHostsP;
-    afs_int32 *a_sameNetOrSubnetP;
-    afs_int32 *a_diffSubnetP;
-    afs_int32 *a_diffNetworkP;
-
+void h_GetHostNetStats(afs_int32 *a_numHostsP, afs_int32 *a_sameNetOrSubnetP,
+                      afs_int32 *a_diffSubnetP, afs_int32 *a_diffNetworkP)
 { /*h_GetHostNetStats*/
 
     register struct host *hostP;        /*Ptr to current host entry*/
@@ -1868,17 +1834,13 @@ static struct AFSFid zerofid;
 
 
 /*
- * XXXX: This routine could use Multi-R to avoid serializing the timeouts.
+ * XXXX: This routine could use Multi-Rx to avoid serializing the timeouts.
  * Since it can serialize them, and pile up, it should be a separate LWP
  * from other events.
  */
-int CheckHost(host, held)
-    register struct host *host;
-    int held;
-
+int CheckHost(register struct host *host, int held)
 {
     register struct client *client;
-    struct interfaceAddr interf;
     int code;
 
     /* Host is held by h_Enumerate */
@@ -1909,13 +1871,13 @@ int CheckHost(host, held)
                    host->hostFlags |= ALTADDR; /* alternate addresses valid */
                    if ( code )
                    {
-                       char *hoststr = afs_inet_ntoa_r(host->host);
-                       ViceLog(0,
-                           ("CB: RCallBackConnectBack (host.c) failed for host %s:%d\n",
-                           hoststr, ntohs(host->port)));
-                       host->hostFlags |= VENUSDOWN;
-                       free(hoststr);
-                    }
+                       char hoststr[16];
+                       afs_inet_ntoa_r(host->host, hoststr);
+                        ViceLog(0,
+                               ("CB: RCallBackConnectBack (host.c) failed for host %s:%d\n",
+                                hoststr, ntohs(host->port)));
+                        host->hostFlags |= VENUSDOWN;
+                   }
                    /* Note:  it's safe to delete hosts even if they have call
                     * back state, because break delayed callbacks (called when a
                     * message is received from the workstation) will always send a 
@@ -1933,12 +1895,12 @@ int CheckHost(host, held)
                        H_LOCK
                        if(code) {
                            if ( MultiProbeAlternateAddress_r(host) ) {
-                               char *hoststr = afs_inet_ntoa_r(host->host);
-                               ViceLog(0,
+                               char hoststr[16];
+                               afs_inet_ntoa_r(host->host, hoststr);
+                                ViceLog(0,
                                        ("ProbeUuid failed for host %s:%d\n",
                                         hoststr, ntohs(host->port)));
-                               host->hostFlags |= VENUSDOWN;
-                               free(hoststr);
+                                host->hostFlags |= VENUSDOWN;
                            }
                        }
                    } else {
@@ -1946,11 +1908,11 @@ int CheckHost(host, held)
                        code = RXAFSCB_Probe(host->callback_rxcon);
                        H_LOCK
                        if (code) {
-                           char *hoststr = afs_inet_ntoa_r(host->host);
-                           ViceLog(0, ("ProbeUuid failed for host %s:%d\n",
-                                   hoststr, ntohs(host->port)));
-                           host->hostFlags |= VENUSDOWN;
-                           free(hoststr);
+                           char hoststr[16];
+                           afs_inet_ntoa_r(host->host, hoststr);
+                           ViceLog(0, ("ProbeUuid failed for host %s:%d\n",
+                                       hoststr, ntohs(host->port)));
+                           host->hostFlags |= VENUSDOWN;
                        }
                    }
                }
@@ -1973,18 +1935,17 @@ int CheckHost(host, held)
  *
  * This routine is called roughly every 5 minutes.
  */
-h_CheckHosts() {
-
+void h_CheckHosts() {
     afs_uint32 now = FT_ApproxTime();
 
-    bzero((char *)&zerofid, sizeof(zerofid));
+    memset((char *)&zerofid, 0, sizeof(zerofid));
     /*
      * Send a probe to the workstation if it hasn't been heard from in
      * 15 minutes
      */
     checktime = now - 15*60;
     clientdeletetime = now - 120*60;   /* 2 hours ago */
-    h_Enumerate(CheckHost, (char *) 0);
+    h_Enumerate(CheckHost, NULL);
 
 } /*h_CheckHosts*/
 
@@ -1997,9 +1958,7 @@ h_CheckHosts() {
  * The addresses in the ineterfaceAddr list are in host byte order.
  */
 int
-initInterfaceAddr_r(host, interf)
-struct host*   host;
-struct interfaceAddr *interf;
+initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf)
 {
        int i, j;
        int number, count;
@@ -2014,11 +1973,11 @@ struct interfaceAddr *interf;
                host->host, interf->numberOfInterfaces));
 
        number = interf->numberOfInterfaces;
-       myPort   = host->port;
-       myHost   = host->host; /* current interface address */
+       myPort = host->port;
+       myHost = host->host; /* current interface address */
 
        /* validation checks */
-       if ( number < 0 )
+       if ( number < 0 || number > AFS_MAX_INTERFACE_ADDR )
         {
                ViceLog(0,("Number of alternate addresses returned is %d\n",
                         number));
@@ -2076,6 +2035,25 @@ struct interfaceAddr *interf;
        return 0;
 }
 
+/* inserts a new HashChain structure corresponding to this address */
+void hashInsert_r(afs_int32 addr, struct host* host)
+{
+       int index;
+       struct h_hashChain*     chain;
+
+       /* hash into proper bucket */
+       index = h_HashIndex(addr);
+
+        /* insert into beginning of list for this bucket */
+       chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
+       assert(chain);
+       chain->hostPtr = host;
+       chain->next = hostHashTable[index];
+       chain->addr = addr;
+       hostHashTable[index] = chain;
+
+}
+
 /*
  * This is called with host locked and held. At this point, the
  * hostHashTable should not be having entries for the alternate
@@ -2085,9 +2063,7 @@ struct interfaceAddr *interf;
  * All addresses are in network byte order.
  */
 int
-addInterfaceAddr_r(host, addr)
-struct host*   host;
-afs_int32 addr;
+addInterfaceAddr_r(struct host *host, afs_int32 addr)
 {
        int i;
        int number;
@@ -2131,58 +2107,16 @@ afs_int32 addr;
        return 0;
 }
 
-/* inserts  a new HashChain structure corresponding to this address */
-hashInsert_r(addr, host)
-afs_int32 addr;
-struct host* host;
-{
-       int index;
-       struct h_hashChain*     chain;
-
-       /* hash into proper bucket */
-       index = h_HashIndex(addr);
-
-        /* insert into beginning of list for this bucket */
-       chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
-       assert(chain);
-       chain->hostPtr = host;
-       chain->next = hostHashTable[index];
-       chain->addr = addr;
-       hostHashTable[index] = chain;
-
-}
-
-/* inserts  a new HashChain structure corresponding to this UUID */
-hashInsertUuid_r(uuid, host)
-struct afsUUID *uuid;
-struct host* host;
-{
-       int index;
-       struct h_hashChain*     chain;
-
-       /* hash into proper bucket */
-       index = h_UuidHashIndex(uuid);
-
-        /* insert into beginning of list for this bucket */
-       chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
-       assert(chain);
-       chain->hostPtr = host;
-       chain->next = hostUuidHashTable[index];
-       hostUuidHashTable[index] = chain;
-}
-
 /* deleted a HashChain structure for this address and host */
 /* returns 1 on success */
 int
-hashDelete_r(addr, host)
-afs_int32 addr;
-struct host* host;
+hashDelete_r(afs_int32 addr, struct host* host)
 {
        int flag;
        int index;
        register struct h_hashChain **hp, *th;
 
-        for (hp = &hostHashTable[h_HashIndex(addr)]; th = *hp; )
+        for (hp = &hostHashTable[h_HashIndex(addr)]; (th = *hp); )
         {
                assert(th->hostPtr);
                if (th->hostPtr == host && th->addr == addr)
@@ -2203,9 +2137,8 @@ struct host* host;
 ** prints out all alternate interface address for the host. The 'level'
 ** parameter indicates what level of debugging sets this output
 */
-printInterfaceAddr(host, level)
-struct host*   host;
-int            level;
+void
+printInterfaceAddr(struct host *host, int level)
 {
        int i, number;
         if ( host-> interface )