From f6468e0f27c90b2e2385508f9a1f01b8b1d346d2 Mon Sep 17 00:00:00 2001 From: Chaskiel M Grundman Date: Wed, 7 Jun 2006 05:56:55 +0000 Subject: [PATCH] no-client-tcon-20060607 remove client->tcon and avoid locking issues --- src/viced/host.c | 101 +++++----------------------------------------- src/viced/host.h | 3 -- src/viced/viced.c | 1 - 3 files changed, 9 insertions(+), 96 deletions(-) diff --git a/src/viced/host.c b/src/viced/host.c index 58222e203..6f1c55912 100644 --- a/src/viced/host.c +++ b/src/viced/host.c @@ -175,6 +175,8 @@ GetCE() static void FreeCE(register struct client *entry) { + entry->VenusEpoch = 0; + entry->sid = 0; entry->next = CEFree; CEFree = entry; CEs--; @@ -749,10 +751,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); @@ -775,18 +773,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) @@ -845,25 +831,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 = NULL; - } - 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 * (have delete flag set); ditto for clients. (*proc) is always called with @@ -1434,14 +1401,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); } @@ -1671,7 +1630,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) { @@ -1744,26 +1704,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); @@ -1856,7 +1796,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 */ @@ -1870,9 +1811,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--; @@ -1885,8 +1823,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, rxr_AddrStringOf(tcon), @@ -1903,8 +1839,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); @@ -1936,30 +1870,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 %s:%d), VBUSYING\n", tcon, rxr_AddrStringOf(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, @@ -2055,7 +1979,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) { expTime = client->expTime; (void)afs_snprintf(tmpStr, sizeof tmpStr, " user id=%d, name=%s, sl=%s till %s", @@ -2068,12 +1991,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); diff --git a/src/viced/host.h b/src/viced/host.h index 49e81d6e5..4b9a665f4 100644 --- a/src/viced/host.h +++ b/src/viced/host.h @@ -119,8 +119,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 */ @@ -229,7 +227,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 void h_Enumerate_r(int (*proc) (), struct host *enumstart, char *param); extern struct host *h_GetHost_r(struct rx_connection *tcon); diff --git a/src/viced/viced.c b/src/viced/viced.c index 1c7296bf2..a7963372d 100644 --- a/src/viced/viced.c +++ b/src/viced/viced.c @@ -2046,7 +2046,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); -- 2.39.5