]> git.michaelhowe.org Git - packages/o/openafs.git/commitdiff
STABLE14-fileserver-hates-pruclient-20060626
authorDerrick Brashear <shadow@dementia.org>
Mon, 31 Jul 2006 18:15:48 +0000 (18:15 +0000)
committerDerrick Brashear <shadow@dementia.org>
Mon, 31 Jul 2006 18:15:48 +0000 (18:15 +0000)
right now there is one struct ubik_client shared by all threads in the fileserve
r, which sucks when one has it locked

let's, uh, fix that.

(cherry picked from commit 791b2141809fc0ad2da78ab3cd91303ac0ec482d)

src/ptserver/ptprocs.c
src/ptserver/ptuser.c
src/util/casestrcpy.c
src/viced/afsfileprocs.c
src/viced/host.c
src/viced/host.h
src/viced/viced.c

index cb006e6ea994e588f64c7539d003cedee3ae2f5a..224dcf482a6030e9c9149a45ff0978102866b92a 100644 (file)
@@ -103,7 +103,6 @@ afs_int32 listElements(), listOwned(), isAMemberOf(), idToName();
 afs_int32 listSuperGroups();
 #endif
 
-static stolower();
 extern int IDCmp();
 
 extern int prp_group_default;
@@ -2229,19 +2228,6 @@ isAMemberOf(call, uid, gid, flag, cid)
     return code;
 }
 
-
-static
-stolower(s)
-     register char *s;
-{
-    register int tc;
-    while ((tc = *s)) {
-       if (isupper(tc))
-           *s = tolower(tc);
-       s++;
-    }
-}
-
 #if IP_WILDCARDS
 afs_int32
 addWildCards(tt, alist, host)
index 467a20524b1a81e62f56a03649c189aa5349ff0b..a0cb12a770bfcd36a57cb766cd5177283084db53 100644 (file)
@@ -765,14 +765,3 @@ pr_SetFieldsEntry(afs_int32 id, afs_int32 mask, afs_int32 flags, afs_int32 ngrou
                  nusers, 0, 0);
     return code;
 }
-
-int
-stolower(char *s)
-{
-    while (*s) {
-       if (isupper(*s))
-           *s = tolower(*s);
-       s++;
-    }
-    return 0;
-}
index b715ee8665d88a793358883aaed748950554e59c..4645d1f3b1d89b38b7dfe93de4ef73db1c4db951 100644 (file)
@@ -67,6 +67,28 @@ ucstring(char *d, char *s, int n)
     return original_d;
 }
 
+int
+stolower(char *s)
+{
+  while (*s) {
+        if (isupper(*s))
+            *s = tolower(*s);
+        s++;
+    }
+    return 0;
+}
+
+int
+stoupper(char *s)
+{
+  while (*s) {
+        if (islower(*s))
+            *s = toupper(*s);
+        s++;
+    }
+    return 0;
+}
+
 /* strcompose - concatenate strings passed to it.
  * Input: 
  *   buf: storage for the composed string. Any data in it will be lost.
index 94810142b687532b67d0ca66cf978a102d8e633f..74c3a700aafe2f0a7f80e5c1c7e5d7749c84392d 100644 (file)
@@ -306,6 +306,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;
@@ -329,9 +331,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);
index 49f098b97e094eab8e3e8401e82c711f2ba7a828..6a146728223fb7470775e3d49bed98a407ddea91 100644 (file)
@@ -255,6 +255,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;
 
@@ -452,7 +676,7 @@ h_gethostcps_r(register struct host *host, register afs_int32 now)
     slept ? (host->cpsCall = FT_ApproxTime()) : (host->cpsCall = now);
 
     H_UNLOCK;
-    code = pr_GetHostCPS(ntohl(host->host), &host->hcps);
+    code = hpr_GetHostCPS(ntohl(host->host), &host->hcps);
     H_LOCK;
     if (code) {
        /*
@@ -1509,7 +1733,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) {
@@ -1624,7 +1848,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);
@@ -1721,7 +1945,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];
@@ -1888,6 +2112,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));
@@ -1898,7 +2123,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*";
index 0094ca0810f2879a098f690efb8cadd28f6a9ec7..9973df96669f00c01d77d6552a1b00d6036830af 100644 (file)
@@ -25,6 +25,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
index efd47c2b458cb76f49e94f523a2b5d53fec64b15..527dcb1284f2730015ac478d68916d94241b2559 100644 (file)
@@ -198,6 +198,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.
@@ -1302,6 +1306,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;