From: Derrick Brashear Date: Mon, 3 Jul 2006 19:46:06 +0000 (+0000) Subject: DEVEL15-fileserver-hates-pruclient-20060626 X-Git-Tag: openafs-devel-1_5_3~11 X-Git-Url: https://git.michaelhowe.org/gitweb/?a=commitdiff_plain;h=3d018d4b41bf20495e72477b9e07ed7a37763ffa;p=packages%2Fo%2Fopenafs.git DEVEL15-fileserver-hates-pruclient-20060626 right now there is one struct ubik_client shared by all threads in the fileserver, which sucks when one has it locked let's, uh, fix that. (cherry picked from commit 791b2141809fc0ad2da78ab3cd91303ac0ec482d) --- diff --git a/src/viced/afsfileprocs.c b/src/viced/afsfileprocs.c index 220b93d49..7e5184e6f 100644 --- a/src/viced/afsfileprocs.c +++ b/src/viced/afsfileprocs.c @@ -309,6 +309,8 @@ CallPreamble(register struct rx_call *acall, int activecall, int retry_flag = 1; int code = 0; char hoststr[16], hoststr2[16]; + struct ubik_client *uclient; + if (!tconn) { ViceLog(0, ("CallPreamble: unexpected null tconn!\n")); return -1; @@ -332,9 +334,20 @@ CallPreamble(register struct rx_call *acall, int activecall, /* Take down the old connection and re-read the key file */ ViceLog(0, ("CallPreamble: Couldn't get CPS. Reconnect to ptserver\n")); +#ifdef AFS_PTHREAD_ENV + uclient = (struct ubik_client *)pthread_getspecific(viced_uclient_key); + + /* Is it still necessary to drop this? We hit the net, we should... */ H_UNLOCK; - code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0); + if (uclient) + hpr_End(uclient); + code = hpr_Initialize(&uclient); + + assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0); H_LOCK; +#else + code = pr_Initialize(2, AFSDIR_SERVER_ETC_DIRPATH, 0); +#endif if (code) { h_ReleaseClient_r(tclient); h_Release_r(thost); diff --git a/src/viced/host.c b/src/viced/host.c index 335ab97cc..69df056fb 100644 --- a/src/viced/host.c +++ b/src/viced/host.c @@ -269,6 +269,230 @@ FreeHT(register struct host *entry) } /*FreeHT */ +afs_int32 +hpr_Initialize(struct ubik_client **uclient) +{ + afs_int32 code; + struct rx_connection *serverconns[MAXSERVERS]; + struct rx_securityClass *sc[3]; + struct afsconf_dir *tdir; + char tconfDir[100] = ""; + char tcell[64] = ""; + struct ktc_token ttoken; + afs_int32 scIndex; + struct afsconf_cell info; + afs_int32 i; + char cellstr[64]; + + tdir = afsconf_Open(AFSDIR_SERVER_ETC_DIRPATH); + if (!tdir) { + fprintf(stderr, + "libprot: Could not open configuration directory: %s.\n", + AFSDIR_SERVER_ETC_DIRPATH); + return -1; + } + + code = afsconf_GetLocalCell(tdir, cellstr, sizeof(cellstr)); + if (code) { + fprintf(stderr, + "libprot: Could not get local cell. [%d]\n", code); + return code; + } + + code = afsconf_GetCellInfo(tdir, cellstr, "afsprot", &info); + if (code) { + fprintf(stderr, "libprot: Could not locate cell %s in %s/%s\n", + cellstr, confDir, AFSDIR_CELLSERVDB_FILE); + return code; + } + + afsconf_Close(tdir); + + code = rx_Init(0); + if (code) { + fprintf(stderr, "libprot: Could not initialize rx.\n"); + return code; + } + + scIndex = 2; + sc[0] = 0; + sc[1] = 0; + sc[2] = 0; + /* Most callers use secLevel==1, however, the fileserver uses secLevel==2 + * to force use of the KeyFile. secLevel == 0 implies -noauth was + * specified. */ + if ((afsconf_GetLatestKey(tdir, 0, 0) == 0)) { + code = afsconf_ClientAuthSecure(tdir, &sc[2], &scIndex); + if (code) + fprintf(stderr, + "libprot: clientauthsecure returns %d %s" + " (so trying noauth)\n", code, error_message(code)); + if (code) + scIndex = 0; /* use noauth */ + if (scIndex != 2) + /* if there was a problem, an unauthenticated conn is returned */ + sc[scIndex] = sc[2]; + } else { + struct ktc_principal sname; + strcpy(sname.cell, info.name); + sname.instance[0] = 0; + strcpy(sname.name, "afs"); + code = ktc_GetToken(&sname, &ttoken, sizeof(ttoken), NULL); + if (code) + scIndex = 0; + else { + if (ttoken.kvno >= 0 && ttoken.kvno <= 256) + /* this is a kerberos ticket, set scIndex accordingly */ + scIndex = 2; + else { + fprintf(stderr, + "libprot: funny kvno (%d) in ticket, proceeding\n", + ttoken.kvno); + scIndex = 2; + } + sc[2] = + rxkad_NewClientSecurityObject(rxkad_clear, &ttoken.sessionKey, + ttoken.kvno, ttoken.ticketLen, + ttoken.ticket); + } + } + if ((scIndex == 0) && (sc[0] == 0)) + sc[0] = rxnull_NewClientSecurityObject(); + if ((scIndex == 0)) + com_err("fileserver", code, + "Could not get afs tokens, running unauthenticated."); + + memset(serverconns, 0, sizeof(serverconns)); /* terminate list!!! */ + for (i = 0; i < info.numServers; i++) { + serverconns[i] = + rx_NewConnection(info.hostAddr[i].sin_addr.s_addr, + info.hostAddr[i].sin_port, PRSRV, sc[scIndex], + scIndex); + } + + code = ubik_ClientInit(serverconns, uclient); + if (code) { + com_err("fileserver", code, "ubik client init failed."); + } + + code = rxs_Release(sc[scIndex]); + return code; +} + +int +hpr_End(struct ubik_client *uclient) +{ + int code = 0; + + if (uclient) { + code = ubik_ClientDestroy(uclient); + } + return code; +} + +int +hpr_GetHostCPS(afs_int32 host, prlist *CPS) +{ +#ifdef AFS_PTHREAD_ENV + register afs_int32 code; + afs_int32 over; + struct ubik_client *uclient = + (struct ubik_client *)pthread_getspecific(viced_uclient_key); + + if (!uclient) { + code = hpr_Initialize(&uclient); + assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0); + } + + over = 0; + code = ubik_Call(PR_GetHostCPS, uclient, 0, host, CPS, &over); + if (code != PRSUCCESS) + return code; + if (over) { + /* do something about this, probably make a new call */ + /* don't forget there's a hard limit in the interface */ + fprintf(stderr, + "membership list for host id %d exceeds display limit\n", + host); + } + return 0; +#else + return pr_GetHostCPS(host, CPS); +#endif +} + +int +hpr_NameToId(namelist *names, idlist *ids) +{ +#ifdef AFS_PTHREAD_ENV + register afs_int32 code; + register afs_int32 i; + struct ubik_client *uclient = + (struct ubik_client *)pthread_getspecific(viced_uclient_key); + + if (!uclient) { + code = hpr_Initialize(&uclient); + assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0); + } + + for (i = 0; i < names->namelist_len; i++) + stolower(names->namelist_val[i]); + code = ubik_Call(PR_NameToID, uclient, 0, names, ids); + return code; +#else + return pr_NameToId(names, ids); +#endif +} + +int +hpr_IdToName(idlist *ids, namelist *names) +{ +#ifdef AFS_PTHREAD_ENV + register afs_int32 code; + struct ubik_client *uclient = + (struct ubik_client *)pthread_getspecific(viced_uclient_key); + + if (!uclient) { + code = hpr_Initialize(&uclient); + assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0); + } + + code = ubik_Call(PR_IDToName, uclient, 0, ids, names); + return code; +#else + return pr_IdToName(ids, names); +#endif +} + +int +hpr_GetCPS(afs_int32 id, prlist *CPS) +{ +#ifdef AFS_PTHREAD_ENV + register afs_int32 code; + afs_int32 over; + struct ubik_client *uclient = + (struct ubik_client *)pthread_getspecific(viced_uclient_key); + + if (!uclient) { + code = hpr_Initialize(&uclient); + assert(pthread_setspecific(viced_uclient_key, (void *)uclient) == 0); + } + + over = 0; + code = ubik_Call(PR_GetCPS, uclient, 0, id, CPS, &over); + if (code != PRSUCCESS) + return code; + if (over) { + /* do something about this, probably make a new call */ + /* don't forget there's a hard limit in the interface */ + fprintf(stderr, "membership list for id %d exceeds display limit\n", + id); + } + return 0; +#else + return pr_GetCPS(id, CPS); +#endif +} static short consolePort = 0; @@ -466,7 +690,7 @@ h_gethostcps_r(register struct host *host, register afs_int32 now) host->cpsCall = slept ? (FT_ApproxTime()) : (now); H_UNLOCK; - code = pr_GetHostCPS(ntohl(host->host), &host->hcps); + code = hpr_GetHostCPS(ntohl(host->host), &host->hcps); H_LOCK; if (code) { /* @@ -1545,7 +1769,7 @@ MapName_r(char *aname, char *acell, afs_int32 * aval) } H_UNLOCK; - code = pr_NameToId(&lnames, &lids); + code = hpr_NameToId(&lnames, &lids); H_LOCK; if (code == 0) { if (lids.idlist_val) { @@ -1660,7 +1884,7 @@ h_FindClient_r(struct rx_connection *tcon) expTime = 0x7fffffff; } else if (authClass == 2) { afs_int32 kvno; - + /* kerberos ticket */ code = rxkad_GetServerInfo(tcon, /*level */ 0, &expTime, tname, tinst, tcell, &kvno); @@ -1757,7 +1981,7 @@ h_FindClient_r(struct rx_connection *tcon) client->CPS.prlist_val = AnonCPS.prlist_val; } else { H_UNLOCK; - code = pr_GetCPS(viceid, &client->CPS); + code = hpr_GetCPS(viceid, &client->CPS); H_LOCK; if (code) { char hoststr[16]; @@ -1924,6 +2148,7 @@ h_UserName(struct client *client) static char User[PR_MAXNAMELEN + 1]; namelist lnames; idlist lids; + afs_int32 code; lids.idlist_len = 1; lids.idlist_val = (afs_int32 *) malloc(1 * sizeof(afs_int32)); @@ -1934,7 +2159,7 @@ h_UserName(struct client *client) lnames.namelist_len = 0; lnames.namelist_val = (prname *) 0; lids.idlist_val[0] = client->ViceId; - if (pr_IdToName(&lids, &lnames)) { + if (hpr_IdToName(&lids, &lnames)) { /* We need to free id we alloced above! */ free(lids.idlist_val); return "*UNKNOWN USER NAME*"; diff --git a/src/viced/host.h b/src/viced/host.h index 06b68ce5f..9a797b9de 100644 --- a/src/viced/host.h +++ b/src/viced/host.h @@ -30,6 +30,7 @@ extern pthread_mutex_t host_glock_mutex; assert(pthread_mutex_lock(&host_glock_mutex) == 0) #define H_UNLOCK \ assert(pthread_mutex_unlock(&host_glock_mutex) == 0) +extern pthread_key_t viced_uclient_key; #else /* AFS_PTHREAD_ENV */ #define H_LOCK #define H_UNLOCK diff --git a/src/viced/viced.c b/src/viced/viced.c index 1440e8bd3..f20e04d2a 100644 --- a/src/viced/viced.c +++ b/src/viced/viced.c @@ -203,6 +203,10 @@ int sendBufSize = 16384; /* send buffer size */ struct timeval tp; +#ifdef AFS_PTHREAD_ENV +pthread_key_t viced_uclient_key; +#endif + /* * FileServer's name and IP address, both network byte order and * host byte order. @@ -1519,6 +1523,11 @@ InitPR() ("Couldn't initialize protection library; code=%d.\n", code)); return code; } + +#ifdef AFS_PTHREAD_ENV + assert(pthread_key_create(&viced_uclient_key, NULL) == 0); +#endif + SystemId = SYSADMINID; SystemAnyUser = ANYUSERID; SystemAnyUserCPS.prlist_len = 0;