pass-pointers-for-uuid-printing-20030422
[openafs.git] / src / viced / host.c
index 209a006..b233197 100644 (file)
@@ -417,19 +417,14 @@ static char h_AddrInSameNetwork(afs_uint32 a_targetAddr, afs_uint32 a_candAddr)
 #endif /* FS_STATS_DETAILED */
 
 
-
+/* Assumptions: called with held host */
 void
 h_gethostcps_r(register struct host *host, register afs_int32 now)
 {
     register int code;
-    int  slept=0, held;
-
-    /* at this point, the host might not be locked, nor held */
-    /* make sure that we do not disappear behind the RPC     */
-    if ( !(held = h_Held_r(host)) )
-               h_Hold_r(host);
+    int  slept=0;
 
-       /* wait if somebody else is already doing the getCPS call */
+    /* wait if somebody else is already doing the getCPS call */
     while ( host->hostFlags & HCPS_INPROGRESS ) 
     {
        slept = 1;              /* I did sleep */
@@ -498,28 +493,24 @@ h_gethostcps_r(register struct host *host, register afs_int32 now)
                ViceLog(0, ("LWP_NoYieldSignal returns %d\n", code));
 #endif /* AFS_PTHREAD_ENV */
     }
-
-    /* if we had held the  host, release it now */
-    if ( !held ) 
-       h_Release_r(host);
 }
 
-void h_flushhostcps(hostaddr, hport)
-    register afs_uint32  hostaddr, hport;  /* net byte order */
+/* args in net byte order */
+void h_flushhostcps(register afs_uint32 hostaddr, register afs_uint32 hport)
 {
     register struct host *host;
-    int held;
+    int held = 0;
     
     H_LOCK
     host = h_Lookup_r(hostaddr, hport, &held);
     if (host) {
-      host->hcpsfailed = 1;
+       host->hcpsfailed = 1;
+       if (!held)
+           h_Release_r(host);
     }
-    if (!held)
-      h_Release_r(host);
     H_UNLOCK
 
-return;
+    return;
 }
 
 
@@ -565,7 +556,7 @@ struct host *h_Alloc_r(register struct rx_connection *r_con)
        if (serverentry)
            consolePort = serverentry->s_port;
        else
-           consolePort = DEF_ROPCONS;  /* Use a default */
+           consolePort = htons(DEF_ROPCONS);   /* Use a default */
     }
     if (host->port == consolePort) host->Console = 1;
     /* Make a callback channel even for the console, on the off chance that it
@@ -582,11 +573,10 @@ struct host *h_Alloc_r(register struct rx_connection *r_con)
     host->hostFlags = 0;
     host->hcps.prlist_val = NULL;
     host->hcps.prlist_len = 0;
-    host->hcps.prlist_val = NULL;
     host->interface = 0;
 #ifdef undef
     host->hcpsfailed = 0;      /* save cycles */
-    h_gethostcps(host);      /* do this under host lock */
+    h_gethostcps(host);      /* do this under host hold/lock */
 #endif
     host->FirstClient = 0;      
     h_Hold_r(host);
@@ -642,8 +632,10 @@ restart:
                 * 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.
+                *
+                * If we get here we still have a host hold.
                 */
-               h_gethostcps_r(host,now);
+               h_gethostcps_r(host,now); 
            }
            break;
        }
@@ -700,19 +692,26 @@ int h_TossStuff_r(register struct host *host)
     if (h_NBLock_r(host) != 0) {
        char hoststr[16];
        ViceLog(0, ("Warning:  h_TossStuff_r failed; Host %s:%d was locked.\n",
-                   afs_inet_ntoa_r(host->host, hoststr), host->port)); 
+                   afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port))); 
        return;
     } else {
        h_Unlock_r(host);
     }
 
-    /* ASSUMPTION: r_FreeConnection() does not yield */
+    /* ASSUMPTION: rxi_FreeConnection() does not yield */
     for (cp = &host->FirstClient; (client = *cp); ) {
        if ((host->hostFlags & HOSTDELETED) || client->deleted) {
+           if (client->refCount) {
+               char hoststr[16];
+               ViceLog(0, ("Warning: Host %s:%d client %x refcount %d while deleting.\n",
+                           afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
+                           client, client->refCount)); 
+           }
            if ((client->ViceId != ANONYMOUSID) && client->CPS.prlist_val) {
                free(client->CPS.prlist_val);
                 client->CPS.prlist_val = NULL;
            }
+           client->CPS.prlist_len = 0;
            if (client->tcon) {
                rx_SetSpecific(client->tcon, rxcon_client_key, (void *)0);
            }
@@ -931,13 +930,21 @@ struct host *h_GetHost_r(struct rx_connection *tcon)
     afs_int32 hport;
     int i, j, count;
     char hoststr[16], hoststr2[16];
+    Capabilities caps;
+
+    caps.Capabilities_val = NULL;
 
     haddr = rxr_HostOf(tcon);
     hport = rxr_PortOf(tcon);
 retry:
+    if (caps.Capabilities_val)
+       free(caps.Capabilities_val);
+    caps.Capabilities_val = NULL;
+    caps.Capabilities_len = 0;
+
     code = 0;
-    identP = (struct Identity *)rx_GetSpecific(tcon, rxcon_ident_key);
     host = h_Lookup_r(haddr, hport, &held);
+    identP = (struct Identity *)rx_GetSpecific(tcon, rxcon_ident_key);
     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
@@ -950,12 +957,15 @@ retry:
                h_Unlock_r(host);
                if ( !held) h_Release_r(host);
                ViceLog(125, ("Host %s:%d starting h_Lookup again\n",
-                            afs_inet_ntoa_r(host->host, hoststr), host->port));
+                            afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
                goto retry;
        }
        host->hostFlags &= ~ALTADDR;
        H_UNLOCK
-       code = RXAFSCB_WhoAreYou(host->callback_rxcon, &interf);
+       code = RXAFSCB_TellMeAboutYourself(host->callback_rxcon, &interf,
+                                          &caps);
+       if ( code == RXGEN_OPCODE ) 
+           code = RXAFSCB_WhoAreYou(host->callback_rxcon, &interf);
        H_LOCK
        if ( code == RXGEN_OPCODE ) {
                identP = (struct Identity *)malloc(sizeof(struct Identity));
@@ -972,7 +982,7 @@ retry:
                if (host->interface) {
                    ViceLog(0,
                            ("Host %s:%d used to support WhoAreYou, deleting.\n",
-                           afs_inet_ntoa_r(host->host, hoststr), host->port));
+                           afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
                    host->hostFlags |= HOSTDELETED;
                    h_Unlock_r(host);
                    if (!held) h_Release_r(host);
@@ -1009,6 +1019,11 @@ retry:
                       hoststr, ntohs(host->port), code));
            host->hostFlags |= VENUSDOWN;
        }
+       if (caps.Capabilities_val && 
+           (caps.Capabilities_val[0] & CAPABILITY_ERRORTRANS)) 
+           host->hostFlags |= HERRORTRANS;
+       else
+           host->hostFlags &= ~(HERRORTRANS);
        host->hostFlags |= ALTADDR;
        h_Unlock_r(host);
     } else if (host) {
@@ -1016,12 +1031,12 @@ retry:
        {
                /* another thread is doing the initialisation */
                ViceLog(125, ("Host %s:%d waiting for host-init to complete\n",
-                            afs_inet_ntoa_r(host->host, hoststr), host->port));
+                            afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
                h_Lock_r(host);
                h_Unlock_r(host);
                if ( !held) h_Release_r(host);
                ViceLog(125, ("Host %s:%d starting h_Lookup again\n",
-                            afs_inet_ntoa_r(host->host, hoststr), host->port));
+                            afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
                goto retry;
        }
        /* We need to check whether the identity in the host structure
@@ -1034,55 +1049,69 @@ retry:
              && !afs_uuid_equal(&identP->uuid, &host->interface->uuid) ) ) ) 
        {
            char uuid1[128], uuid2[128];
-           /* The host in the cache is not the host for this connection */
-           host->hostFlags |= HOSTDELETED;
-           h_Unlock_r(host);
-           if (!held) h_Release_r(host);
-
            if (identP->valid)
-               afsUUID_to_string(identP->uuid, uuid1, 127);
+               afsUUID_to_string(&identP->uuid, uuid1, 127);
            if (host->interface)
-               afsUUID_to_string(host->interface->uuid, uuid2, 127);
+               afsUUID_to_string(&host->interface->uuid, uuid2, 127);
            ViceLog(0, 
                    ("CB: new identity for host %s:%d, deleting(%x %x %s %s)\n", 
-                    afs_inet_ntoa_r(host->host, hoststr), host->port, 
+                    afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port), 
                     identP->valid, host->interface, identP->valid ? uuid1 : 
                     "", host->interface ? uuid2 : ""));
+
+           /* The host in the cache is not the host for this connection */
+           host->hostFlags |= HOSTDELETED;
+           h_Unlock_r(host);
+           if (!held) h_Release_r(host);
            goto retry;
        }
     } else {
        host = h_Alloc_r(tcon); /* returned held and locked */
        h_gethostcps_r(host,FT_ApproxTime());
         if (!(host->Console&1)) {
-           if (!identP || !interfValid) {
-               H_UNLOCK
+           int pident = 0;
+           H_UNLOCK
+           code = RXAFSCB_TellMeAboutYourself(host->callback_rxcon, 
+                                              &interf, &caps);
+           if ( code == RXGEN_OPCODE ) 
                code = RXAFSCB_WhoAreYou(host->callback_rxcon, &interf);
-               H_LOCK
-               if ( code == RXGEN_OPCODE ) {
+           H_LOCK
+           if ( code == RXGEN_OPCODE ) {
+               if (!identP)
                    identP = (struct Identity *)malloc(sizeof(struct Identity));
-                   if (!identP) {
-                       ViceLog(0, ("Failed malloc in h_GetHost_r\n"));
-                       assert(0);
-                   }
-                   identP->valid = 0;
+               else
+                   pident = 1;
+
+               if (!identP) {
+                   ViceLog(0, ("Failed malloc in h_GetHost_r\n"));
+                   assert(0);
+               }
+               identP->valid = 0;
+               if (!pident)
                    rx_SetSpecific(tcon, rxcon_ident_key, identP);
-                   ViceLog(25,
-                           ("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;
+               ViceLog(25,
+                       ("Host %s:%d does not support WhoAreYou.\n",
+                        afs_inet_ntoa_r(host->host, hoststr), 
+                        ntohs(host->port)));
+               code = 0;
+           } else if (code == 0) {
+               if (!identP)
                    identP = (struct Identity *)malloc(sizeof(struct Identity));
-                   if (!identP) {
-                       ViceLog(0, ("Failed malloc in h_GetHost_r\n"));
-                       assert(0);
-                   }
-                   identP->valid = 1;
-                   identP->uuid = interf.uuid;
-                   rx_SetSpecific(tcon, rxcon_ident_key, identP);
-                   ViceLog(25, ("WhoAreYou success on %s:%d\n",
-                               afs_inet_ntoa_r(host->host, hoststr), host->port));
+               else 
+                   pident = 1;
+
+               if (!identP) {
+                   ViceLog(0, ("Failed malloc in h_GetHost_r\n"));
+                   assert(0);
                }
+               identP->valid = 1;
+               interfValid = 1;
+               identP->uuid = interf.uuid;
+               if (!pident)
+                   rx_SetSpecific(tcon, rxcon_ident_key, identP);
+               ViceLog(25, ("WhoAreYou success on %s:%d\n",
+                            afs_inet_ntoa_r(host->host, hoststr), 
+                            ntohs(host->port)));
            }
            if (code == 0 && !identP->valid) {
                H_UNLOCK
@@ -1098,8 +1127,8 @@ retry:
                        h_Hold_r(oldHost);
                    h_Lock_r(oldHost);
                    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));
+                               afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
+                               afs_inet_ntoa_r(oldHost->host, hoststr2), ntohs(oldHost->port)));
                    host->hostFlags |= HOSTDELETED;
                    h_Unlock_r(host);
                    h_Release_r(host);
@@ -1114,7 +1143,7 @@ retry:
                    H_LOCK
                    if (code == 0) {
                        ViceLog(25, ("InitCallBackState3 success on %s:%d\n",
-                                   afs_inet_ntoa_r(host->host, hoststr), host->port));
+                                   afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port)));
                        assert(interfValid == 1);
                        initInterfaceAddr_r(host, &interf);
                    }
@@ -1130,9 +1159,18 @@ retry:
                host->hostFlags |= RESETDONE;
 
         }
+       if (caps.Capabilities_val && 
+           (caps.Capabilities_val[0] & CAPABILITY_ERRORTRANS)) 
+           host->hostFlags |= HERRORTRANS;
+       else
+           host->hostFlags &= ~(HERRORTRANS);
        host->hostFlags |= ALTADDR;/* host structure iniatilisation complete */
        h_Unlock_r(host);
     }
+    if (caps.Capabilities_val)
+       free(caps.Capabilities_val);
+    caps.Capabilities_val = NULL;
+    caps.Capabilities_len = 0;
     return host;
 
 } /*h_GetHost_r*/
@@ -1376,6 +1414,7 @@ ticket name length != 64
        if (!client) {
          client = GetCE();
          ObtainWriteLock(&client->lock);
+         client->refCount = 1;
          client->host = host;
          client->next = host->FirstClient;
          host->FirstClient = client;
@@ -1388,7 +1427,7 @@ ticket name length != 64
          client->sid = rxr_CidOf(tcon);
          client->VenusEpoch = rxr_GetEpoch(tcon);
          client->CPS.prlist_val = 0;
-         client->refCount = 1;
+         client->CPS.prlist_len = 0;
          CurrentConnections++; /* increment number of connections */
        }
     }
@@ -1399,6 +1438,7 @@ ticket name length != 64
           free(client->CPS.prlist_val);
        }
        client->CPS.prlist_val = NULL;
+       client->CPS.prlist_len = 0;
         client->ViceId = viceid;
        client->expTime = expTime;
 
@@ -1414,7 +1454,7 @@ ticket name length != 64
            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));
+                      ntohs(client->host->port)));
 
            /* Although ubik_Call (called by pr_GetCPS) traverses thru
             * all protection servers and reevaluates things if no
@@ -1480,6 +1520,19 @@ int GetClient(struct rx_connection * tcon, struct client **cp)
     H_LOCK
 
     *cp = client = (struct client *) rx_GetSpecific(tcon, rxcon_client_key);
+    if (client == NULL || client->tcon == NULL) {
+       ViceLog(0, ("GetClient: no client in conn %x (host %x), VBUSYING\n", 
+                   tcon, rx_HostOf(rx_PeerOf(tcon))));
+       H_UNLOCK
+       return VBUSY;
+    }
+    if (rxr_CidOf(client->tcon) != client->sid) {
+       ViceLog(0, ("GetClient: tcon %x tcon sid %d client sid %d\n",
+                   client->tcon, rxr_CidOf(client->tcon),
+                   client->sid));
+       H_UNLOCK
+       return VBUSY;
+    }
     if (!(client && client->tcon && rxr_CidOf(client->tcon) == client->sid)) {
        if (!client)
            ViceLog(0, ("GetClient: no client in conn %x\n", tcon));
@@ -1495,7 +1548,7 @@ int GetClient(struct rx_connection * tcon, struct client **cp)
        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));
+               ntohs(client->host->port), client->expTime));
        H_UNLOCK
        return VICETOKENDEAD;
     }
@@ -1559,7 +1612,7 @@ h_PrintClient(register struct host *host, int held, StreamHandle_t *file)
        return held;
     }
     sprintf(tmpStr,"Host %s:%d down = %d, LastCall %s",
-           afs_inet_ntoa_r(host->host, hoststr), host->port,
+           afs_inet_ntoa_r(host->host, hoststr), ntohs(host->port),
            (host->hostFlags & VENUSDOWN),
            afs_ctime((time_t *)&host->LastCall, tbuffer, sizeof(tbuffer)));
     STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
@@ -1634,7 +1687,7 @@ h_DumpHost(register struct host *host, int held, StreamHandle_t *file)
 
     H_LOCK
     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,
+           host->host, ntohs(host->port), host->index, host->cblist,
            CheckLock(&host->lock), host->LastCall, host->ActiveCall, 
            (host->hostFlags & VENUSDOWN), host->hostFlags&HOSTDELETED, 
            host->Console, host->hostFlags & CLIENTDELETED, 
@@ -1985,7 +2038,7 @@ int CheckHost(register struct host *host, int held)
                        if (code) {
                            char hoststr[16];
                            afs_inet_ntoa_r(host->host, hoststr);
-                           ViceLog(0, ("ProbeUuid failed for host %s:%d\n",
+                           ViceLog(0, ("Probe failed for host %s:%d\n",
                                        hoststr, ntohs(host->port)));
                            host->hostFlags |= VENUSDOWN;
                        }
@@ -2037,7 +2090,7 @@ initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf)
 {
        int i, j;
        int number, count;
-       afs_int32               myPort, myHost;
+       afs_int32               myHost;
        int found;
        struct Interface *interface;
 
@@ -2048,7 +2101,6 @@ initInterfaceAddr_r(struct host *host, struct interfaceAddr *interf)
                host->host, interf->numberOfInterfaces));
 
        number = interf->numberOfInterfaces;
-       myPort = host->port;
        myHost = host->host; /* current interface address */
 
        /* validation checks */