--- src/afs/afs.h 2001/10/08 22:15:24 1.10 +++ src/afs/afs.h 2001/10/09 12:49:33 @@ -189,6 +190,7 @@ #define CNoSUID 2 /* 1 if no suid progs can run from this cell */ #define CHasVolRef 16 /* Volumes were referenced in this cell*/ #define CLinkedCell 32 +#define CAlias 64 /* This cell entry is an alias */ struct cell { struct afs_q lruq; /* lru q next and prev */ @@ -201,6 +203,7 @@ short states; /* state flags */ short cellIndex; /* relative index number per cell */ time_t timeout; /* data expire time, if non-zero */ + struct cell *alias; /* what this cell is an alias for */ }; #define afs_PutCell(cellp, locktype) --- src/afs/afs_call.c 2001/10/05 20:38:57 1.16 +++ src/afs/afs_call.c 2001/10/09 12:49:34 @@ -610,6 +610,7 @@ afs_int32 *kmsg = afs_osi_Alloc(kmsgLen); char *cellname = afs_osi_Alloc(cellLen); + AFS_COPYIN((afs_int32 *)parm2, cellname, cellLen, code); AFS_COPYIN((afs_int32 *)parm3, kmsg, kmsgLen, code); if (!code) { code = afs_AfsdbHandler(cellname, cellLen, kmsg); --- src/afs/afs_cell.c 2001/10/05 20:36:59 1.8 +++ src/afs/afs_cell.c 2001/10/09 12:49:34 @@ -52,19 +52,30 @@ /* Local variables. */ struct cell *afs_rootcell = 0; +/* Handler waiting for request from client */ static char afs_AfsdbHandlerWait; +/* Client waiting for handler to become available or finish request */ static char afs_AfsdbLookupWait; +/* Set to 1 when we've seen the userspace AFSDB process at least once */ char afs_AfsdbHandlerPresent = 0; +/* Set to 1 when there is a client interacting with the AFSDB handler. + * Protects the in and out variables below. Protected by GLOCK. */ char afs_AfsdbHandlerInuse = 0; +/* Set to 1 when AFSDB has been shut down */ char afs_AfsdbHandlerShutdown = 0; +/* Input to handler from the client: cell name to look up */ char *afs_AfsdbHandler_CellName; +/* Outputs from handler to client: cell hosts, TTL, and real cell name */ afs_int32 *afs_AfsdbHandler_CellHosts; int *afs_AfsdbHandler_Timeout; +char **afs_AfsdbHandler_RealName; -char afs_AfsdbHandler_ReqPending; -char afs_AfsdbHandler_Completed; +/* Client sets ReqPending to 1 whenever it queues a request for it */ +char afs_AfsdbHandler_ReqPending = 0; +/* Handler sets Completed to 1 when it completes the client request */ +char afs_AfsdbHandler_Completed = 0; struct cell *afs_GetCellByName_int(); @@ -115,6 +126,9 @@ *afs_AfsdbHandler_Timeout = kernelMsg[1]; if (*afs_AfsdbHandler_Timeout) *afs_AfsdbHandler_Timeout += osi_Time(); + *afs_AfsdbHandler_RealName = afs_osi_Alloc(strlen(acellName) + 1); + strcpy(*afs_AfsdbHandler_RealName, acellName); + for (i=0; i= hostCount) afs_AfsdbHandler_CellHosts[i] = 0; @@ -153,10 +167,11 @@ #endif -int afs_GetCellHostsFromDns(acellName, acellHosts, timeout) +int afs_GetCellHostsFromDns(acellName, acellHosts, timeout, realName) char *acellName; afs_int32 *acellHosts; int *timeout; + char **realName; { #ifdef AFS_AFSDB_ENV char grab_glock = 0; @@ -180,6 +195,7 @@ afs_AfsdbHandler_CellName = acellName; afs_AfsdbHandler_CellHosts = acellHosts; afs_AfsdbHandler_Timeout = timeout; + afs_AfsdbHandler_RealName = realName; /* Wake up the AFSDB handler */ afs_AfsdbHandler_Completed = 0; @@ -207,20 +223,25 @@ void afs_RefreshCell(tc) register struct cell *tc; { - afs_int32 acellHosts[MAXCELLHOSTS]; + afs_int32 cellHosts[MAXCELLHOSTS]; + char *realName; int timeout; /* Don't need to do anything if no timeout or it's not expired */ if (!tc->timeout || tc->timeout > osi_Time()) return; - - if (!afs_GetCellHostsFromDns(tc->cellName, acellHosts, &timeout)) { - afs_NewCell(tc->cellName, acellHosts, tc->states, - tc->lcellp ? tc->lcellp->cellName : (char *) 0, - tc->fsport, tc->vlport, timeout); - } - /* In case of a DNS failure, keep old cell data.. */ - return; + if (afs_GetCellHostsFromDns(tc->cellName, cellHosts, &timeout, &realName)) + /* In case of lookup failure, keep old data */ + return; + + afs_NewCell(realName, cellHosts, tc->states, + tc->lcellp ? tc->lcellp->cellName : (char *) 0, + tc->fsport, tc->vlport, timeout, (char *) 0); + + /* If this is an alias, update the alias entry too */ + if (afs_strcasecmp(tc->cellName, realName)) + afs_NewCell(tc->cellName, 0, CAlias, (char *) 0, 0, 0, + timeout, realName); } @@ -228,19 +249,28 @@ register char *acellName; afs_int32 locktype; { - afs_int32 acellHosts[MAXCELLHOSTS]; + afs_int32 cellHosts[MAXCELLHOSTS]; + char *realName; int timeout; - if (afs_GetCellHostsFromDns(acellName, acellHosts, &timeout)) + if (afs_GetCellHostsFromDns(acellName, cellHosts, &timeout, &realName)) return (struct cell *) 0; - if (afs_NewCell(acellName, acellHosts, CNoSUID, (char *) 0, 0, 0, timeout)) + if (afs_NewCell(realName, cellHosts, CNoSUID, (char *) 0, 0, 0, + timeout, (char *) 0)) return (struct cell *) 0; + /* If this is an alias, create an entry for it too */ + if (afs_strcasecmp(acellName, realName)) { + if (afs_NewCell(acellName, 0, CAlias, (char *) 0, 0, 0, + timeout, realName)) + return (struct cell *) 0; + } + return afs_GetCellByName_int(acellName, locktype, 0); } -struct cell *afs_GetCellByName_int(acellName, locktype, trydns) +static struct cell *afs_GetCellByName_int(acellName, locktype, trydns) register char *acellName; afs_int32 locktype; char trydns; @@ -257,6 +287,10 @@ QAdd(&CellLRU, &tc->lruq); ReleaseWriteLock(&afs_xcell); afs_RefreshCell(tc); + if (tc->states & CAlias) { + tc = tc->alias; + afs_RefreshCell(tc); + } return tc; } } @@ -327,20 +361,21 @@ } /*afs_GetCellByIndex*/ -afs_int32 afs_NewCell(acellName, acellHosts, aflags, linkedcname, fsport, vlport, timeout) +afs_int32 afs_NewCell(acellName, acellHosts, aflags, linkedcname, fsport, vlport, timeout, aliasFor) int aflags; char *acellName; register afs_int32 *acellHosts; char *linkedcname; u_short fsport, vlport; int timeout; + char *aliasFor; { register struct cell *tc, *tcl=0; register afs_int32 i, newc=0, code=0; register struct afs_q *cq, *tq; AFS_STATCNT(afs_NewCell); - if (*acellHosts == 0) + if (!(aflags & CAlias) && *acellHosts == 0) /* need >= one host to gen cell # */ return EINVAL; @@ -414,6 +449,26 @@ tc->timeout = timeout; memset((char *)tc->cellHosts, 0, sizeof(tc->cellHosts)); + if (aflags & CAlias) { + struct cell *tca = NULL; + + if (!aliasFor) { + code = EINVAL; + goto bad; + } + for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { + tca = QTOC(cq); tq = QNext(cq); + if (!afs_strcasecmp(tca->cellName, aliasFor)) + break; + } + if (!tca) { + code = ENOENT; + goto bad; + } + tc->alias = tca; + goto done; + } + for (i=0; icellHosts, MAXCELLHOSTS); /* randomize servers */ +done: ReleaseWriteLock(&afs_xcell); return 0; bad: --- src/afs/afs_pioctl.c 2001/10/08 22:15:24 1.23 +++ src/afs/afs_pioctl.c 2001/10/09 12:49:34 @@ -2295,7 +2295,7 @@ } linkedstate |= CNoSUID; /* setuid is disabled by default for fs newcell */ - code = afs_NewCell(newcell, cellHosts, linkedstate, linkedcell, fsport, vlport, (int)0); + code = afs_NewCell(newcell, cellHosts, linkedstate, linkedcell, fsport, vlport, (int)0, (char *) 0); return code; } --- src/afsd/afsd.c 2001/10/05 21:03:16 1.17 +++ src/afsd/afsd.c 2001/10/09 12:49:34 @@ -1066,6 +1066,10 @@ struct afsconf_cell acellInfo; int i; + kernelMsg[0] = 0; + kernelMsg[1] = 0; + acellName[0] = '\0'; + while (1) { /* On some platforms you only get 4 args to an AFS call */ int sizeArg = ((sizeof acellName) << 16) | (sizeof kernelMsg); @@ -1090,6 +1094,8 @@ kernelMsg[1] = 0; for (i=0; iname, host, sizeof(acellInfo->name)); p += code + QFIXEDSZ; /* Skip name */ @@ -625,6 +625,15 @@ short afsdb_type; afsdb_type = (p[0] << 8) | p[1]; + if (afsdb_type == 1) { + /* + * We know this is an AFSDB record for our cell, of the + * right AFSDB type. Write down the true cell name that + * the resolver gave us above. + */ + strcpy(realCellName, host); + } + code = dn_expand(answer, answer+len, p+2, host, sizeof(host)); if (code < 0) return AFSCONF_NOTFOUND; @@ -649,6 +658,7 @@ if (server_num == 0) /* No AFSDB records */ return AFSCONF_NOTFOUND; + strncpy(acellInfo->name, realCellName, sizeof(acellInfo->name)); acellInfo->numServers = server_num; if (aservice) {