STABLE14-no-client-tcon-20060607

remove client->tcon and avoid locking issues
This commit is contained in:
Chaskiel M Grundman 2006-06-07 05:55:25 +00:00 committed by Derrick Brashear
parent c9b812ccb3
commit e9f6a9d8a6
3 changed files with 9 additions and 95 deletions

View File

@ -161,6 +161,8 @@ GetCE()
static void
FreeCE(register struct client *entry)
{
entry->VenusEpoch = 0;
entry->sid = 0;
entry->next = CEFree;
CEFree = entry;
CEs--;
@ -729,10 +731,6 @@ h_TossStuff_r(register struct host *host)
if ((client->ViceId != ANONYMOUSID) && client->CPS.prlist_val)
free(client->CPS.prlist_val);
client->CPS.prlist_val = NULL;
if (client->tcon) {
rx_SetSpecific(client->tcon, rxcon_client_key, (void *)0);
rx_PutConnection(client->tcon);
}
CurrentConnections--;
*cp = client->next;
ReleaseWriteLock(&client->lock);
@ -755,18 +753,6 @@ h_TossStuff_r(register struct host *host)
Console--;
if ((rxconn = host->callback_rxcon)) {
host->callback_rxcon = (struct rx_connection *)0;
/*
* If rx_DestroyConnection calls h_FreeConnection we will
* deadlock on the host_glock_mutex. Work around the problem
* by unhooking the client from the connection before
* destroying the connection.
*/
client = rx_GetSpecific(rxconn, rxcon_client_key);
if (client && client->tcon == rxconn) {
rx_PutConnection(client->tcon);
client->tcon = NULL;
}
rx_SetSpecific(rxconn, rxcon_client_key, (void *)0);
rx_DestroyConnection(rxconn);
}
if (host->hcps.prlist_val)
@ -825,24 +811,6 @@ h_TossStuff_r(register struct host *host)
} /*h_TossStuff_r */
/* Called by rx when a server connection disappears */
int
h_FreeConnection(struct rx_connection *tcon)
{
register struct client *client;
client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
if (client) {
H_LOCK;
if (client->tcon == tcon) {
rx_PutConnection(client->tcon);
client->tcon = (struct rx_connection *)0;
}
H_UNLOCK;
}
return 0;
} /*h_FreeConnection */
/* h_Enumerate: Calls (*proc)(host, held, param) for at least each host in the
* system at the start of the enumeration (perhaps more). Hosts may be deleted
@ -1409,14 +1377,6 @@ h_GetHost_r(struct rx_connection *tcon)
* destroying the connection.
*/
client = rx_GetSpecific(rxconn, rxcon_client_key);
if (client) {
if (client->tcon != rxconn)
ViceLog(0,("CB: client %x tcon %x didn't match rxconn %x\n", client, client->tcon, rxconn));
else {
rx_PutConnection(client->tcon);
client->tcon = NULL;
}
}
rx_SetSpecific(rxconn, rxcon_client_key, (void *)0);
rx_DestroyConnection(rxconn);
}
@ -1633,7 +1593,8 @@ h_FindClient_r(struct rx_connection *tcon)
int created = 0;
client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
if (client) {
if (client && client->sid == rxr_CidOf(tcon)
&& client->VenusEpoch == rxr_GetEpoch(tcon)) {
client->refCount++;
h_Hold_r(client->host);
if (!client->deleted && client->prfail != 2) {
@ -1706,26 +1667,6 @@ h_FindClient_r(struct rx_connection *tcon)
for (client = host->FirstClient; client; client = client->next) {
if (!client->deleted && (client->sid == rxr_CidOf(tcon))
&& (client->VenusEpoch == rxr_GetEpoch(tcon))) {
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));
}
rx_PutConnection(client->tcon);
client->tcon = (struct rx_connection *)0;
}
client->refCount++;
H_UNLOCK;
ObtainWriteLock(&client->lock);
@ -1818,7 +1759,8 @@ h_FindClient_r(struct rx_connection *tcon)
* the RPC from the other client structure's rock.
*/
oldClient = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
if (oldClient && oldClient->tcon == tcon) {
if (oldClient && oldClient->sid == rxr_CidOf(tcon)
&& oldClient->VenusEpoch == rxr_GetEpoch(tcon)) {
char hoststr[16];
if (!oldClient->deleted) {
/* if we didn't create it, it's not ours to put back */
@ -1832,9 +1774,6 @@ h_FindClient_r(struct rx_connection *tcon)
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);
}
}
/* We should perhaps check for 0 here */
client->refCount--;
@ -1847,8 +1786,6 @@ h_FindClient_r(struct rx_connection *tcon)
oldClient->refCount++;
client = oldClient;
} else {
rx_PutConnection(oldClient->tcon);
oldClient->tcon = (struct rx_connection *)0;
ViceLog(0, ("FindClient: deleted client %x(%x) already had conn %x (host %s:%d), stolen by client %x(%x)\n",
oldClient, oldClient->sid, tcon,
afs_inet_ntoa_r(rxr_HostOf(tcon), hoststr),
@ -1865,8 +1802,6 @@ h_FindClient_r(struct rx_connection *tcon)
h_Unlock_r(host);
CurrentConnections++; /* increment number of connections */
}
rx_GetConnection(tcon);
client->tcon = tcon;
rx_SetSpecific(tcon, rxcon_client_key, client);
ReleaseWriteLock(&client->lock);
@ -1898,30 +1833,20 @@ GetClient(struct rx_connection *tcon, struct client **cp)
H_LOCK;
*cp = NULL;
client = (struct client *)rx_GetSpecific(tcon, rxcon_client_key);
if (client == NULL || client->tcon == NULL) {
if (client == NULL) {
ViceLog(0,
("GetClient: no client in conn %x (host %x:%d), VBUSYING\n",
tcon, rxr_HostOf(tcon),ntohs(rxr_PortOf(tcon))));
H_UNLOCK;
return VBUSY;
}
if (rxr_CidOf(client->tcon) != client->sid) {
if (rxr_CidOf(tcon) != client->sid || rxr_GetEpoch(tcon) != client->VenusEpoch) {
ViceLog(0,
("GetClient: tcon %x tcon sid %d client sid %d\n",
client->tcon, rxr_CidOf(client->tcon), client->sid));
tcon, rxr_CidOf(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));
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];
ViceLog(1,
@ -2015,7 +1940,6 @@ h_PrintClient(register struct host *host, int held, StreamHandle_t * file)
(void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
for (client = host->FirstClient; client; client = client->next) {
if (!client->deleted) {
if (client->tcon) {
(void)afs_snprintf(tmpStr, sizeof tmpStr,
" user id=%d, name=%s, sl=%s till %s",
client->ViceId, h_UserName(client),
@ -2028,12 +1952,6 @@ h_PrintClient(register struct host *host, int held, StreamHandle_t * file)
sizeof(tbuffer))
: "No Limit\n");
(void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
} else {
(void)afs_snprintf(tmpStr, sizeof tmpStr,
" user=%s, no current server connection\n",
h_UserName(client));
(void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);
}
(void)afs_snprintf(tmpStr, sizeof tmpStr, " CPS-%d is [",
client->CPS.prlist_len);
(void)STREAM_WRITE(tmpStr, strlen(tmpStr), 1, file);

View File

@ -113,8 +113,6 @@ struct client {
struct client *next; /* next client entry for host */
struct host *host; /* ptr to parent host entry */
afs_int32 sid; /* Connection number from this host */
struct rx_connection *tcon; /* most recent server connection
* associated with this client */
prlist CPS; /* cps for authentication */
int ViceId; /* Vice ID of user */
afs_int32 expTime; /* RX-only: expiration time */
@ -205,7 +203,6 @@ extern struct host *h_Lookup_r(afs_uint32 hostaddr, afs_uint16 hport,
extern void hashInsert_r(afs_uint32 addr, afs_uint16 port,
struct host* host);
extern struct host *h_LookupUuid_r(afsUUID * uuidp);
extern int h_FreeConnection(struct rx_connection *tcon);
extern void h_Enumerate(int (*proc) (), char *param);
extern struct host *h_GetHost_r(struct rx_connection *tcon);
extern struct client *h_FindClient_r(struct rx_connection *tcon);

View File

@ -1827,7 +1827,6 @@ main(int argc, char *argv[])
("Failed to initialize RX, probably two servers running.\n"));
exit(-1);
}
rx_SetDestroyConnProc(tservice, (void (*)())h_FreeConnection);
rx_SetMinProcs(tservice, 3);
rx_SetMaxProcs(tservice, lwps);
rx_SetCheckReach(tservice, 1);