#include <rx/rx.h>
#include <afs/cellconfig.h>
#include <stdlib.h>
+#include "viced_prototypes.h"
#include "viced.h"
#include "host.h"
#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 */
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)
/*
* 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(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(register struct rx_connection *r_con)
{
register int code;
host = GetHT();
h_hashChain = (struct h_hashChain*) malloc(sizeof(struct h_hashChain));
- assert(h_hashChain);
+ if (!h_hashChain) {
+ ViceLog(0, ("Failed malloc in h_Alloc_r\n"));
+ assert(0);
+ }
h_hashChain->hostPtr = host;
h_hashChain->addr = rxr_HostOf(r_con);
h_hashChain->next = hostHashTable[index];
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);
+ h_Lock_r(host);
h_InsertList_r(host); /* update global host List */
#if FS_STATS_DETAILED
/*
#endif /* FS_STATS_DETAILED */
return host;
-} /*h_Alloc*/
+} /*h_Alloc_r*/
/* Lookup a host given an IP address and UDP port number. */
* 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;
}
*/
/* h_TossStuff_r: Toss anything in the host structure (the host or
- * clients marked for deletion. Called from r_Release ONLY.
+ * clients marked for deletion. Called from h_Release_r ONLY.
* To be called, there must be no holds, and either host->deleted
* or host->clientDeleted must be set.
*/
if (i!=h_maxSlots)
return;
- /* ASSUMPTION: r_FreeConnection() does not yield */
+ /* if somebody still has this host locked */
+ 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));
+ return;
+ } else {
+ h_Unlock_r(host);
+ }
+
+ /* ASSUMPTION: rxi_FreeConnection() does not yield */
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 = NULL;
}
+ client->CPS.prlist_len = 0;
if (client->tcon) {
rx_SetSpecific(client->tcon, rxcon_client_key, (void *)0);
}
free(host->hcps.prlist_val);
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 */
return;
}
list = (struct host **)malloc(hostCount * sizeof(struct host *));
- assert(list != NULL);
+ if (!list) {
+ ViceLog(0, ("Failed malloc in h_Enumerate\n"));
+ assert(0);
+ }
held = (int *)malloc(hostCount * sizeof(int));
- assert(held != NULL);
+ if (!held) {
+ ViceLog(0, ("Failed malloc in h_Enumerate\n"));
+ assert(0);
+ }
for (count = 0, host = hostList ; host ; host = host->next, count++) {
list[count] = host;
if (!(held[count] = h_Held_r(host)))
/* insert into beginning of list for this bucket */
chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
+ if (!chain) {
+ ViceLog(0, ("Failed malloc in hashInsertUuid_r\n"));
+ assert(0);
+ }
assert(chain);
chain->hostPtr = host;
chain->next = hostUuidHashTable[index];
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;
H_LOCK
if ( code == RXGEN_OPCODE ) {
identP = (struct Identity *)malloc(sizeof(struct Identity));
+ if (!identP) {
+ ViceLog(0, ("Failed malloc in h_GetHost_r\n"));
+ assert(0);
+ }
identP->valid = 0;
rx_SetSpecific(tcon, rxcon_ident_key, identP);
/* The host on this connection was unable to respond to
} else if (code == 0) {
interfValid = 1;
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);
&& ( ( !identP->valid && host->interface )
|| ( identP->valid && !host->interface )
|| ( identP->valid
- && !afs_uuid_equal(&identP->uuid, &host->interface->uuid) ) ) ) {
- /* 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);
- ViceLog(0, ("CB: new identity for host %s:%d, deleting\n",
- afs_inet_ntoa_r(host->host, hoststr), host->port));
- goto 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);
+ if (host->interface)
+ 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,
+ identP->valid, host->interface, identP->valid ? uuid1 :
+ "", host->interface ? uuid2 : ""));
+ 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) {
code = RXAFSCB_WhoAreYou(host->callback_rxcon, &interf);
H_LOCK
if ( code == RXGEN_OPCODE ) {
- identP = (struct Identity *)malloc(sizeof(struct Identity));
+ identP = (struct Identity *)malloc(sizeof(struct Identity));
+ if (!identP) {
+ ViceLog(0, ("Failed malloc in h_GetHost_r\n"));
+ assert(0);
+ }
identP->valid = 0;
rx_SetSpecific(tcon, rxcon_ident_key, identP);
ViceLog(25,
} else if (code == 0) {
interfValid = 1;
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);
}
foreign = 1; /* attempt cross-cell authentication */
tname = (char *) malloc(anamelen+cnamelen+2);
+ if (!tname) {
+ ViceLog(0, ("Failed malloc in MapName_r\n"));
+ assert(0);
+ }
strcpy(tname, aname);
tname[anamelen] = '@';
strcpy(tname+anamelen+1, acell);
h_Hold_r(client->host);
if (client->prfail != 2) { /* Could add shared lock on client here */
/* note that we don't have to lock entry in this path to
- * ensure CPS is initialized, since we don't call rxr_SetSpecific
+ * ensure CPS is initialized, since we don't call rx_SetSpecific
* until initialization is done, and we only get here if
* rx_GetSpecific located the client structure.
*/
if (client->tcon && (client->tcon != tcon)) {
ViceLog(0, ("*** Vid=%d, sid=%x, tcon=%x, Tcon=%x ***\n",
client->ViceId, client->sid, client->tcon, tcon));
+ oldClient = (struct client *) rx_GetSpecific(client->tcon,
+ rxcon_client_key);
+ if (oldClient) {
+ if (oldClient == client)
+ rx_SetSpecific(client->tcon, rxcon_client_key, NULL);
+ else
+ ViceLog(0,
+ ("Client-conn mismatch: CL1=%x, CN=%x, CL2=%x\n",
+ client, client->tcon, oldClient));
+ }
client->tcon = (struct rx_connection *)0;
}
client->refCount++;
client->sid = rxr_CidOf(tcon);
client->VenusEpoch = rxr_GetEpoch(tcon);
client->CPS.prlist_val = 0;
+ client->CPS.prlist_len = 0;
client->refCount = 1;
CurrentConnections++; /* increment number of connections */
}
free(client->CPS.prlist_val);
}
client->CPS.prlist_val = NULL;
+ client->CPS.prlist_len = 0;
client->ViceId = viceid;
client->expTime = expTime;
* 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))) {
+ oldClient = (struct client *) rx_GetSpecific(tcon, rxcon_client_key);
+ if (oldClient && oldClient->tcon == tcon) {
oldClient->tcon = (struct rx_connection *) 0;
/* rx_SetSpecific will be done immediately below */
}
H_LOCK
*cp = client = (struct client *) rx_GetSpecific(tcon, rxcon_client_key);
- /* XXXX debug */
- assert(client && client->tcon && rxr_CidOf(client->tcon) == client->sid);
+ if (!(client && client->tcon && rxr_CidOf(client->tcon) == client->sid)) {
+ if (!client)
+ ViceLog(0, ("GetClient: no client in conn %x\n", tcon));
+ else
+ ViceLog(0, ("GetClient: tcon %x tcon sid %d client sid %d\n",
+ client->tcon, client->tcon ? rxr_CidOf(client->tcon)
+ : -1, client->sid));
+ assert(0);
+ }
if (client &&
client->LastCall > client->expTime && client->expTime) {
char hoststr[16];
lids.idlist_len = 1;
lids.idlist_val = (afs_int32 *)malloc(1*sizeof(afs_int32));
+ if (!lids.idlist_val) {
+ ViceLog(0, ("Failed malloc in h_UserName\n"));
+ assert(0);
+ }
lnames.namelist_len = 0;
lnames.namelist_val = (prname *)0;
lids.idlist_val[0] = client->ViceId;
int CheckHost(register struct host *host, int held)
{
register struct client *client;
- struct interfaceAddr interf;
int code;
/* Host is held by h_Enumerate */
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));
interface = (struct Interface *)
malloc(sizeof(struct Interface) +
(sizeof(afs_int32) * (count-1)));
- assert(interface);
+ if (!interface) {
+ ViceLog(0, ("Failed malloc in initInterfaceAddr_r\n"));
+ assert(0);
+ }
interface->numberOfInterfaces = count;
} else {
interface = (struct Interface *)
/* insert into beginning of list for this bucket */
chain = (struct h_hashChain *)malloc(sizeof(struct h_hashChain));
- assert(chain);
+ if (!chain) {
+ ViceLog(0, ("Failed malloc in hashInsert_r\n"));
+ assert(0);
+ }
chain->hostPtr = host;
chain->next = hostHashTable[index];
chain->addr = addr;
interface = (struct Interface *)
malloc(sizeof(struct Interface) +
(sizeof(afs_int32) * number));
+ if (!interface) {
+ ViceLog(0, ("Failed malloc in addInterfaceAddr_r\n"));
+ assert(0);
+ }
interface->numberOfInterfaces = number + 1;
interface->uuid = host->interface->uuid;
for (i = 0 ; i < number ; i++)