dynroot-allow-cell-aliases-20011101

allow cell aliases. includes support for non-'V' pioctls
This commit is contained in:
Nickolai Zeldovich 2001-11-01 05:24:30 +00:00 committed by Derrick Brashear
parent 78d9433851
commit b28927c752
19 changed files with 586 additions and 83 deletions

9
NEWS
View File

@ -1,4 +1,11 @@
OpenAFS News -- history of user-visible changes. October 13, 2001
OpenAFS News -- history of user-visible changes. October 19, 2001
* Changes incorporated in OpenAFS 1.2.3
** Cell aliases for dynroot can be specified in the CellAlias file in
/usr/vice/etc or /usr/local/etc/openafs, in format "realname alias",
one per line. They can also be managed at runtime with "fs newalias"
and "fs listaliases".
* Changes incorporated in OpenAFS 1.2.2

View File

@ -537,7 +537,7 @@ afs_vget(OSI_VFS_DECL(afsp), vnode_t **avcp, struct fid *fidp)
afid2 = (afs_fid2_t*)fidp;
if (afid2->af_len == sizeof(afs_fid2_t) - sizeof(afid2->af_len)) {
/* It's a checkpoint restart fid. */
tcell = afs_GetCellByIndex(afid2->af_cell, READ_LOCK);
tcell = afs_GetCellByIndex(afid2->af_cell, READ_LOCK, 0 /* !refresh */);
if (!tcell) {
code = ENOENT;
goto out;

View File

@ -232,6 +232,10 @@ afs_remove(OSI_VC_ARG(adp), aname, acred)
afs_Trace2(afs_iclSetp, CM_TRACE_REMOVE, ICL_TYPE_POINTER, adp,
ICL_TYPE_STRING, aname);
/* Check if this is dynroot */
if (afs_IsDynroot(adp))
return afs_DynrootVOPRemove(adp, acred, aname);
if (code = afs_InitReq(&treq, acred))
return code;
tagain:

View File

@ -78,6 +78,10 @@ afs_symlink
AFS_STATCNT(afs_symlink);
afs_Trace2(afs_iclSetp, CM_TRACE_SYMLINK, ICL_TYPE_POINTER, adp,
ICL_TYPE_STRING, aname);
if (afs_IsDynroot(adp))
return afs_DynrootVOPSymlink(adp, acred, aname, atargetName);
if (code = afs_InitReq(&treq, acred))
return code;

View File

@ -200,7 +200,7 @@ struct cell {
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 */
char *realName; /* who this cell is an alias for */
};
#define afs_PutCell(cellp, locktype)
@ -967,6 +967,7 @@ extern struct brequest afs_brs[NBRS]; /* request structures */
extern struct cell *afs_GetCell();
extern struct cell *afs_GetCellByName();
extern struct cell *afs_GetCellByName2();
extern struct cell *afs_GetCellByIndex();
extern struct unixuser *afs_GetUser();
extern struct volume *afs_GetVolume();
@ -1010,6 +1011,8 @@ extern void afs_PutDynroot();
extern int afs_DynrootNewVnode();
extern int afs_SetDynrootEnable();
extern int afs_GetDynrootEnable();
extern int afs_DynrootVOPSymlink();
extern int afs_DynrootVOPRemove();
/* Performance hack - we could replace VerifyVCache2 with the appropriate

View File

@ -326,6 +326,33 @@ long parm, parm2, parm3, parm4, parm5, parm6;
osi_FreeSmallSpace(tbuffer);
osi_FreeSmallSpace(tbuffer1);
}
else if (parm == AFSOP_ADDCELLALIAS) {
/*
* Call arguments:
* parm2 is the alias name
* parm3 is the real cell name
*/
#if defined(AFS_SGI61_ENV) || defined(AFS_SUN57_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
size_t bufferSize;
#else /* AFS_SGI61_ENV */
u_int bufferSize;
#endif /* AFS_SGI61_ENV */
char *aliasName = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
char *cellName = osi_AllocSmallSpace(AFS_SMALLOCSIZ);
AFS_COPYINSTR((char *)parm2, aliasName, AFS_SMALLOCSIZ, &bufferSize, code);
if (!code) AFS_COPYINSTR((char *)parm3, cellName, AFS_SMALLOCSIZ, &bufferSize, code);
if (!code) afs_NewCell(aliasName, /* new entry name */
0, /* host list */
CAlias, /* flags */
(char *) 0, /* linked cell */
0, 0, /* fs & vl ports */
0, /* timeout */
cellName); /* real cell name */
osi_FreeSmallSpace(aliasName);
osi_FreeSmallSpace(cellName);
}
else if (parm == AFSOP_CACHEINIT) {
struct afs_cacheParams cparms;

View File

@ -78,7 +78,7 @@ char afs_AfsdbHandler_ReqPending = 0;
char afs_AfsdbHandler_Completed = 0;
static struct cell *afs_GetCellByName_int();
struct cell *afs_GetCellByName2();
int afs_strcasecmp(s1, s2)
register char *s1, *s2;
@ -271,7 +271,7 @@ struct cell *afs_GetCellByName_Dns(acellName, locktype)
if (realName)
afs_osi_Free(realName, strlen(realName) + 1);
return afs_GetCellByName_int(acellName, locktype, 0);
return afs_GetCellByName2(acellName, locktype, 0);
bad:
if (realName)
@ -280,15 +280,17 @@ bad:
}
static struct cell *afs_GetCellByName_int(acellName, locktype, trydns)
struct cell *afs_GetCellByName2(acellName, locktype, trydns)
register char *acellName;
afs_int32 locktype;
char trydns;
{
register struct cell *tc;
register struct afs_q *cq, *tq;
int didAlias = 0;
AFS_STATCNT(afs_GetCellByName);
retry:
ObtainWriteLock(&afs_xcell,100);
for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
tc = QTOC(cq); tq = QNext(cq);
@ -297,9 +299,11 @@ static struct cell *afs_GetCellByName_int(acellName, locktype, trydns)
QAdd(&CellLRU, &tc->lruq);
ReleaseWriteLock(&afs_xcell);
afs_RefreshCell(tc);
if (tc->states & CAlias) {
tc = tc->alias;
afs_RefreshCell(tc);
if ((tc->states & CAlias) && (didAlias == 0)) {
acellName = tc->realName;
if (!acellName) return (struct cell *) 0;
didAlias = 1;
goto retry;
}
return tc;
}
@ -308,14 +312,14 @@ static struct cell *afs_GetCellByName_int(acellName, locktype, trydns)
return trydns ? afs_GetCellByName_Dns(acellName, locktype)
: (struct cell *) 0;
} /*afs_GetCellByName_int*/
} /*afs_GetCellByName2*/
struct cell *afs_GetCellByName(acellName, locktype)
register char *acellName;
afs_int32 locktype;
{
return afs_GetCellByName_int(acellName, locktype, 1);
return afs_GetCellByName2(acellName, locktype, 1);
} /*afs_GetCellByName*/
@ -346,9 +350,10 @@ struct cell *afs_GetCell(acell, locktype)
} /*afs_GetCell*/
struct cell *afs_GetCellByIndex(cellindex, locktype)
struct cell *afs_GetCellByIndex(cellindex, locktype, refresh)
register afs_int32 cellindex;
afs_int32 locktype;
afs_int32 refresh;
{
register struct cell *tc;
register struct afs_q *cq, *tq;
@ -361,7 +366,7 @@ struct cell *afs_GetCellByIndex(cellindex, locktype)
QRemove(&tc->lruq);
QAdd(&CellLRU, &tc->lruq);
ReleaseWriteLock(&afs_xcell);
afs_RefreshCell(tc);
if (refresh) afs_RefreshCell(tc);
return tc;
}
}
@ -419,6 +424,7 @@ afs_int32 afs_NewCell(acellName, acellHosts, aflags, linkedcname, fsport, vlport
}
else {
tc = (struct cell *) afs_osi_Alloc(sizeof(struct cell));
memset((char *)tc, 0, sizeof(*tc));
QAdd(&CellLRU, &tc->lruq); /* put in lruq */
tc->cellName = (char *) afs_osi_Alloc(strlen(acellName)+1);
strcpy(tc->cellName, acellName);
@ -464,25 +470,19 @@ afs_int32 afs_NewCell(acellName, acellHosts, aflags, linkedcname, fsport, vlport
}
tc->states |= aflags;
tc->timeout = timeout;
/* Allow converting an alias into a real cell */
if (!(aflags & CAlias)) tc->states &= ~CAlias;
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;
if (tc->realName) afs_osi_Free(tc->realName, strlen(tc->realName)+1);
tc->realName = (char *) afs_osi_Alloc(strlen(aliasFor)+1);
strcpy(tc->realName, aliasFor);
goto done;
}

View File

@ -20,6 +20,8 @@
* afs_DynrootNewVnode
* afs_SetDynrootEnable
* afs_GetDynrootEnable
* afs_DynrootVOPRemove
* afs_DynrootVOPSymlink
*
*/
@ -41,9 +43,22 @@
#define AFS_DYNROOT_VNODE 1
#define AFS_DYNROOT_UNIQUE 1
#define VNUM2CIDX(vnum) ((vnum) >> 2)
#define VNUM2RW(vnum) (((vnum) >> 1) & 1)
#define CIDXRW2VNUM(cidx, rw) (((cidx) << 2) | ((rw) << 1))
/*
* Vnode numbers in dynroot are composed of a type field (upper 8 bits)
* and a type-specific identifier in the lower 24 bits.
*/
#define VN_TYPE_CELL 0x01 /* Corresponds to a struct cell */
#define VN_TYPE_SYMLINK 0x02 /* User-created symlink in /afs */
#define VNUM_TO_VNTYPE(vnum) ((vnum) >> 24)
#define VNUM_TO_VNID(vnum) ((vnum) & 0x00ffffff)
#define VNUM_FROM_TYPEID(type, id) \
((type) << 24 | (id))
#define VNUM_TO_CIDX(vnum) (VNUM_TO_VNID(vnum) >> 2)
#define VNUM_TO_RW(vnum) (VNUM_TO_VNID(vnum) >> 1 & 1)
#define VNUM_FROM_CIDX_RW(cidx, rw) \
VNUM_FROM_TYPEID(VN_TYPE_CELL, \
((cidx) << 2 | (rw) << 1))
static int afs_dynrootEnable = 0;
@ -57,6 +72,20 @@ static int afs_dynrootVersion = 1;
static int afs_dynrootVersionHigh = 1;
/* End of variables protected by afs_dynrootDirLock */
/* A dynamically-created symlink in a dynroot /afs */
struct afs_dynSymlink {
struct afs_dynSymlink *next;
int index;
char *name;
char *target;
};
static afs_rwlock_t afs_dynSymlinkLock;
/* Start of variables protected by afs_dynSymlinkLock */
static struct afs_dynSymlink *afs_dynSymlinkBase = NULL;
static int afs_dynSymlinkIndex = 0;
/* End of variables protected by afs_dynSymlinkLock */
extern afs_int32 afs_cellindex;
extern afs_rwlock_t afs_xvcache;
@ -178,13 +207,15 @@ afs_RefreshDynroot()
int cellidx, maxcellidx, i;
struct cell *c;
int curChunk, curPage;
int dirSize;
int dirSize, sizeOfCurEntry;
char *newDir, *dotCell;
struct DirHeader *dirHeader;
struct PageHeader *pageHeader;
struct DirEntry *dirEntry;
int doFlush = 0;
int linkCount = 0;
struct afs_dynSymlink *ts;
int newCellCount;
/*
* Save afs_cellindex here, in case it changes between the
@ -199,9 +230,7 @@ afs_RefreshDynroot()
curPage = 0;
for (cellidx = 0; cellidx < maxcellidx; cellidx++) {
int sizeOfCurEntry;
c = afs_GetCellByIndex(cellidx, READ_LOCK);
c = afs_GetCellByIndex(cellidx, READ_LOCK, 0 /* don't refresh */);
if (!c) continue;
sizeOfCurEntry = afs_dir_NameBlobs(c->cellName);
@ -224,6 +253,18 @@ afs_RefreshDynroot()
afs_PutCell(c, READ_LOCK);
}
ObtainReadLock(&afs_dynSymlinkLock);
ts = afs_dynSymlinkBase;
while (ts) {
sizeOfCurEntry = afs_dir_NameBlobs(ts->name);
if (curChunk + sizeOfCurEntry > EPP) {
curPage++;
curChunk = 1;
}
curChunk += sizeOfCurEntry;
ts = ts->next;
}
dirSize = (curPage + 1) * AFS_PAGESIZE;
newDir = afs_osi_Alloc(dirSize);
@ -254,31 +295,41 @@ afs_RefreshDynroot()
linkCount += 2;
for (cellidx = 0; cellidx < maxcellidx; cellidx++) {
c = afs_GetCellByIndex(cellidx, READ_LOCK);
c = afs_GetCellByIndex(cellidx, READ_LOCK, 0 /* don't refresh */);
afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk,
c->cellName, CIDXRW2VNUM(cellidx, 0));
c->cellName, VNUM_FROM_CIDX_RW(cellidx, 0));
dotCell = afs_osi_Alloc(strlen(c->cellName) + 2);
strcpy(dotCell, ".");
strcat(dotCell, c->cellName);
afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk,
dotCell, CIDXRW2VNUM(cellidx, 1));
linkCount += 2;
dotCell, VNUM_FROM_CIDX_RW(cellidx, 1));
if (!(c->states & CAlias)) linkCount += 2;
afs_PutCell(c, READ_LOCK);
}
ts = afs_dynSymlinkBase;
while (ts) {
int vnum = VNUM_FROM_TYPEID(VN_TYPE_SYMLINK, ts->index);
afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk,
ts->name, vnum);
ts = ts->next;
}
newCellCount = maxcellidx + afs_dynSymlinkIndex;
ReleaseReadLock(&afs_dynSymlinkLock);
ObtainWriteLock(&afs_dynrootDirLock, 549);
if (afs_dynrootDir) afs_osi_Free(afs_dynrootDir, afs_dynrootDirLen);
afs_dynrootDir = newDir;
afs_dynrootDirLen = dirSize;
afs_dynrootDirLinkcnt = linkCount;
if (afs_dynrootCellCount != maxcellidx) {
if (afs_dynrootCellCount != newCellCount) {
/*
* New cells added -- bump data version, invalidate vcache.
* New cells/symlinks added -- bump data version, invalidate vcache.
*/
afs_dynrootCellCount = maxcellidx;
afs_dynrootCellCount = newCellCount;
afs_dynrootVersion++;
afs_dynrootVersionHigh = osi_Time();
doFlush = 1;
@ -376,37 +427,75 @@ afs_DynrootNewVnode(avc, status)
struct cell *c;
int namelen, linklen, cellidx, rw;
cellidx = VNUM2CIDX(avc->fid.Fid.Vnode);
rw = VNUM2RW(avc->fid.Fid.Vnode);
memset(status, 0, sizeof(struct AFSFetchStatus));
c = afs_GetCellByIndex(cellidx, READ_LOCK);
status->FileType = SymbolicLink;
status->LinkCount = 1;
status->DataVersion = 1;
status->CallerAccess = PRSFS_LOOKUP | PRSFS_READ;
status->AnonymousAccess = PRSFS_LOOKUP | PRSFS_READ;
status->ParentVnode = 1;
status->ParentUnique = 1;
if (VNUM_TO_VNTYPE(avc->fid.Fid.Vnode) == VN_TYPE_SYMLINK) {
struct afs_dynSymlink *ts;
int index = VNUM_TO_VNID(avc->fid.Fid.Vnode);
ObtainReadLock(&afs_dynSymlinkLock);
ts = afs_dynSymlinkBase;
while (ts) {
if (ts->index == index) break;
ts = ts->next;
}
if (ts) {
linklen = strlen(ts->target);
avc->linkData = afs_osi_Alloc(linklen + 1);
strcpy(avc->linkData, ts->target);
status->Length = linklen;
status->UnixModeBits = 0755;
}
ReleaseReadLock(&afs_dynSymlinkLock);
return ts ? 1 : 0;
}
if (VNUM_TO_VNTYPE(avc->fid.Fid.Vnode) != VN_TYPE_CELL) {
afs_warn("dynroot vnode inconsistency, unknown VNTYPE %d\n",
VNUM_TO_VNTYPE(avc->fid.Fid.Vnode));
return 0;
}
cellidx = VNUM_TO_CIDX(avc->fid.Fid.Vnode);
rw = VNUM_TO_RW(avc->fid.Fid.Vnode);
c = afs_GetCellByIndex(cellidx, READ_LOCK, 1 /* refresh */);
if (!c) {
afs_warn("dynroot vnode inconsistency, can't find cell %d\n",
cellidx);
return 0;
}
memset(status, 0, sizeof(struct AFSFetchStatus));
if (c->states & CAlias) {
/*
* linkData needs to contain the name of the cell
* we're aliasing for.
*/
struct cell *tca = c->alias;
char *realName = c->realName;
if (!tca) {
afs_warn("dynroot: alias %s missing cell alias pointer\n",
if (!realName) {
afs_warn("dynroot: alias %s missing real cell name\n",
c->cellName);
linklen = 7;
avc->linkData = afs_osi_Alloc(linklen + 1);
strcpy(avc->linkData, "unknown");
} else {
int namelen = strlen(tca->cellName);
int namelen = strlen(realName);
linklen = rw + namelen;
avc->linkData = afs_osi_Alloc(linklen + 1);
strcpy(avc->linkData, rw ? "." : "");
strcat(avc->linkData, tca->cellName);
strcat(avc->linkData, realName);
}
status->UnixModeBits = 0755;
@ -424,15 +513,7 @@ afs_DynrootNewVnode(avc, status)
status->UnixModeBits = 0644;
}
status->FileType = SymbolicLink;
status->LinkCount = 1;
status->Length = linklen;
status->DataVersion = 1;
status->CallerAccess = PRSFS_LOOKUP | PRSFS_READ;
status->AnonymousAccess = PRSFS_LOOKUP | PRSFS_READ;
status->ParentVnode = 1;
status->ParentUnique = 1;
status->Length = linklen;
afs_PutCell(c, READ_LOCK);
return 1;
}
@ -459,3 +540,100 @@ afs_GetDynrootEnable()
{
return afs_dynrootEnable;
}
/*
* Remove a temporary symlink entry from /afs.
*/
int
afs_DynrootVOPRemove(avc, acred, aname)
struct vcache *avc;
struct AFS_UCRED *acred;
char *aname;
{
struct afs_dynSymlink **tpps;
struct afs_dynSymlink *tps;
struct cell *c;
int found = 0;
if (acred->cr_uid)
return EPERM;
ObtainWriteLock(&afs_dynSymlinkLock, 97);
tpps = &afs_dynSymlinkBase;
while (*tpps) {
tps = *tpps;
if (afs_strcasecmp(aname, tps->name) == 0) {
afs_osi_Free(tps->name, strlen(tps->name) + 1);
afs_osi_Free(tps->target, strlen(tps->target) + 1);
*tpps = tps->next;
afs_osi_Free(tps, sizeof(*tps));
afs_dynSymlinkIndex++;
found = 1;
break;
}
tpps = &(tps->next);
}
ReleaseWriteLock(&afs_dynSymlinkLock);
if (found) {
afs_RefreshDynroot();
return 0;
}
/* Check if this is an actual cell? */
c = afs_GetCellByName2(aname, READ_LOCK, 0 /* no AFSDB */);
if (c) {
afs_PutCell(c, READ_LOCK);
return EROFS;
} else {
return ENOENT;
}
}
/*
* Create a temporary symlink entry in /afs.
*/
int
afs_DynrootVOPSymlink(avc, acred, aname, atargetName)
struct vcache *avc;
struct AFS_UCRED *acred;
char *aname;
char *atargetName;
{
struct afs_dynSymlink *tps;
struct cell *c;
if (acred->cr_uid)
return EPERM;
/* Check if it's already a cell */
c = afs_GetCellByName2(aname, READ_LOCK, 0 /* no AFSDB */);
if (c) {
afs_PutCell(c, READ_LOCK);
return EEXIST;
}
/* Check if it's already a symlink */
ObtainWriteLock(&afs_dynSymlinkLock, 91);
tps = afs_dynSymlinkBase;
while (tps) {
if (afs_strcasecmp(aname, tps->name) == 0) {
ReleaseWriteLock(&afs_dynSymlinkLock);
return EEXIST;
}
tps = tps->next;
}
/* Doesn't already exist -- go ahead and create it */
tps = afs_osi_Alloc(sizeof(*tps));
tps->index = afs_dynSymlinkIndex++;
tps->next = afs_dynSymlinkBase;
tps->name = afs_osi_Alloc(strlen(aname) + 1);
strcpy(tps->name, aname);
tps->target = afs_osi_Alloc(strlen(atargetName) + 1);
strcpy(tps->target, atargetName);
afs_dynSymlinkBase = tps;
ReleaseWriteLock(&afs_dynSymlinkLock);
afs_RefreshDynroot();
return 0;
}

View File

@ -55,7 +55,7 @@ int afs_osi_vget(struct vcache **avcpp, struct fid *afidp,
*/
struct cell *tcell;
cellindex = (Sfid.CellAndUnique >> 24) & 0xff;
tcell = afs_GetCellByIndex(cellindex, READ_LOCK);
tcell = afs_GetCellByIndex(cellindex, READ_LOCK, 0 /* don't refresh */);
if (!tcell) {
return ENOENT;
}

View File

@ -66,13 +66,14 @@ static int PGetCPrefs(), PSetCPrefs(); /* client network addresses */
static int PGetInitParams(), PFlushMount(), PRxStatProc(), PRxStatPeer();
static int PGetRxkcrypt(), PSetRxkcrypt();
static int PPrefetchFromTape(), PResidencyCmd();
static int PNewAlias(), PListAliases();
int PExportAfs();
static int HandleClientContext(struct afs_ioctl *ablob, int *com, struct AFS_UCRED **acred, struct AFS_UCRED *credp);
extern struct cm_initparams cm_initParams;
static int (*(pioctlSw[]))() = {
static int (*(VpioctlSw[]))() = {
PBogus, /* 0 */
PSetAcl, /* 1 */
PGetAcl, /* 2 */
@ -141,6 +142,13 @@ static int (*(pioctlSw[]))() = {
PNoop, /* 65 -- arla: break callback */
PPrefetchFromTape, /* 66 -- MR-AFS: prefetch file from tape */
PResidencyCmd, /* 67 -- MR-AFS: generic commnd interface */
PNoop, /* 68 -- arla: fetch stats */
};
static int (*(CpioctlSw[]))() = {
PBogus, /* 0 */
PNewAlias, /* 1 -- create new cell alias */
PListAliases, /* 2 -- list cell aliases */
};
#define PSetClientContext 99 /* Special pioctl to setup caller's creds */
@ -741,21 +749,6 @@ afs_syscall_pioctl(path, com, cmarg, follow)
#endif
AFS_STATCNT(afs_syscall_pioctl);
if (follow) follow = 1; /* compat. with old venus */
#ifndef AFS_SUN5_ENV
if (! _VALIDVICEIOCTL(com)) {
PIOCTL_FREE_CRED();
#if defined(AFS_OSF_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV)
return EINVAL;
#else /* AFS_OSF_ENV */
#if defined(AFS_SGI64_ENV) || defined(AFS_LINUX22_ENV)
return EINVAL;
#else
setuerror(EINVAL);
return EINVAL;
#endif
#endif
}
#endif
code = copyin_afs_ioctl(cmarg, &data);
if (code) {
PIOCTL_FREE_CRED();
@ -1036,16 +1029,31 @@ afs_HandlePioctl(avc, acom, ablob, afollow, acred)
{
struct vrequest treq;
register afs_int32 code;
register afs_int32 function;
register afs_int32 function, device;
afs_int32 inSize, outSize;
char *inData, *outData;
int (*(*pioctlSw))();
int pioctlSwSize;
afs_Trace3(afs_iclSetp, CM_TRACE_PIOCTL, ICL_TYPE_INT32, acom & 0xff,
ICL_TYPE_POINTER, avc, ICL_TYPE_INT32, afollow);
AFS_STATCNT(HandlePioctl);
if (code = afs_InitReq(&treq, *acred)) return code;
device = (acom & 0xff00) >> 8;
switch (device) {
case 'V': /* Original pioctl's */
pioctlSw = VpioctlSw;
pioctlSwSize = sizeof(VpioctlSw);
break;
case 'C': /* Coordinated/common pioctl's */
pioctlSw = CpioctlSw;
pioctlSwSize = sizeof(CpioctlSw);
break;
default:
return EINVAL;
}
function = acom & 0xff;
if (function >= (sizeof(pioctlSw) / sizeof(char *))) {
if (function >= (pioctlSwSize / sizeof(char *))) {
return EINVAL; /* out of range */
}
inSize = ablob->in_size;
@ -1061,7 +1069,7 @@ afs_HandlePioctl(avc, acom, ablob, afollow, acred)
}
outData = osi_AllocLargeSpace(AFS_LRALLOCSIZ);
outSize = 0;
if (function == 3) /* PSetTokens */
if (function == 3 && device == 'V') /* PSetTokens */
code = (*pioctlSw[function])(avc, function, &treq, inData, outData, inSize, &outSize, acred);
else
code = (*pioctlSw[function])(avc, function, &treq, inData, outData, inSize, &outSize, *acred);
@ -2299,6 +2307,53 @@ static PNewCell(avc, afun, areq, ain, aout, ainSize, aoutSize, acred)
return code;
}
static PNewAlias(avc, afun, areq, ain, aout, ainSize, aoutSize, acred)
struct vcache *avc;
int afun;
struct vrequest *areq;
register char *ain;
char *aout;
afs_int32 ainSize;
struct AFS_UCRED *acred;
afs_int32 *aoutSize; /* set this */
{
/* create a new cell alias */
register struct cell *tcell;
char *tp = ain;
register afs_int32 code;
char *realName, *aliasName;
register struct afs_q *cq, *tq;
if ( !afs_resourceinit_flag ) /* afs deamons havn't started yet */
return EIO; /* Inappropriate ioctl for device */
if (!afs_osi_suser(acred))
return EACCES;
aliasName = tp;
tp += strlen(aliasName) + 1;
realName = tp;
/*
* Prevent user from shooting themselves in the foot -- don't allow
* creation of aliases when a real cell already exists with that name.
*/
ObtainReadLock(&afs_xcell);
for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
tcell = QTOC(cq); tq = QNext(cq);
if ((afs_strcasecmp(tcell->cellName, aliasName) == 0) &&
!(tcell->states & CAlias)) {
ReleaseReadLock(&afs_xcell);
return EEXIST;
}
}
ReleaseReadLock(&afs_xcell);
code = afs_NewCell(aliasName, 0, CAlias, 0, 0, 0, 0, realName);
*aoutSize = 0;
return code;
}
static PListCells(avc, afun, areq, ain, aout, ainSize, aoutSize)
struct vcache *avc;
int afun;
@ -2321,8 +2376,12 @@ static PListCells(avc, afun, areq, ain, aout, ainSize, aoutSize)
ObtainReadLock(&afs_xcell);
for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
tcell = QTOC(cq); tq = QNext(cq);
if (tcell->states & CAlias) {
tcell = 0;
continue;
}
if (whichCell == 0) break;
if (tq == &CellLRU) tcell = 0;
tcell = 0;
whichCell--;
}
if (tcell) {
@ -2343,6 +2402,51 @@ static PListCells(avc, afun, areq, ain, aout, ainSize, aoutSize)
else return EDOM;
}
static PListAliases(avc, afun, areq, ain, aout, ainSize, aoutSize)
struct vcache *avc;
int afun;
struct vrequest *areq;
char *ain, *aout;
afs_int32 ainSize;
afs_int32 *aoutSize; /* set this */
{
afs_int32 whichAlias;
register struct cell *tcell=0;
register char *cp, *tp = ain;
register struct afs_q *cq, *tq;
if ( !afs_resourceinit_flag ) /* afs deamons havn't started yet */
return EIO; /* Inappropriate ioctl for device */
if (ainSize < sizeof(afs_int32))
return EINVAL;
memcpy((char *)&whichAlias, tp, sizeof(afs_int32));
tp += sizeof(afs_int32);
ObtainReadLock(&afs_xcell);
for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
tcell = QTOC(cq); tq = QNext(cq);
if (!(tcell->states & CAlias)) {
tcell = 0;
continue;
}
if (whichAlias == 0) break;
tcell = 0;
whichAlias--;
}
if (tcell) {
cp = aout;
strcpy(cp, tcell->cellName);
cp += strlen(tcell->cellName)+1;
strcpy(cp, tcell->realName);
cp += strlen(tcell->realName)+1;
*aoutSize = cp - aout;
}
ReleaseReadLock(&afs_xcell);
if (tcell) return 0;
else return EDOM;
}
static PRemoveMount(avc, afun, areq, ain, aout, ainSize, aoutSize)
struct vcache *avc;
int afun;

View File

@ -1058,6 +1058,16 @@ struct afsconf_dir *adir; {
return 0;
}
static ConfigCellAlias(aca, arock, adir)
register struct afsconf_cellalias *aca;
char *arock;
struct afsconf_dir *adir;
{
/* push the alias into the kernel */
call_syscall(AFSOP_ADDCELLALIAS, aca->aliasName, aca->realName);
return 0;
}
#ifdef AFS_AFSDB_ENV
static AfsdbLookupHandler()
{
@ -1612,6 +1622,7 @@ mainproc(as, arock)
lookingForHomeCell = 1;
afsconf_CellApply(cdir, ConfigCell, (char *) 0);
afsconf_CellAliasApply(cdir, ConfigCellAlias, (char *) 0);
/*
* If we're still looking for the home cell after the whole cell configuration database

View File

@ -357,6 +357,7 @@ char clones[];
FILE *tf;
register char *tp, *bp;
register struct afsconf_entry *curEntry;
struct afsconf_aliasentry *curAlias;
register afs_int32 code;
afs_int32 i;
char tbuffer[256], tbuf1[256];
@ -469,7 +470,44 @@ char clones[];
curEntry->next = adir->entries;
adir->entries = curEntry;
}
/* Read in the alias list */
strcompose(tbuffer, 256, adir->name, "/", AFSDIR_CELLALIAS_FILE, NULL);
tf = fopen(tbuffer, "r");
while (tf) {
char *aliasPtr;
tp = fgets(tbuffer, sizeof(tbuffer), tf);
if (!tp) break;
TrimLine(tbuffer); /* remove white space */
if (tbuffer[0] == '\0' ||
tbuffer[0] == '\n' ||
tbuffer[0] == '#') continue; /* empty line */
tp = tbuffer;
while (tp[0] != '\0' && tp[0] != ' ' && tp[0] != '\t') tp++;
if (tp[0] == '\0') continue; /* invalid line */
while (tp[0] != '\0' && (tp[0] == ' ' || tp[0] == '\t')) 0[tp++] = '\0';
if (tp[0] == '\0') continue; /* invalid line */
aliasPtr = tp;
while (tp[0] != '\0' && tp[0] != ' ' && tp[0] != '\t' &&
tp[0] != '\r' && tp[0] != '\n') tp++;
tp[0] = '\0';
curAlias = malloc(sizeof(*curAlias));
memset(curAlias, 0, sizeof(*curAlias));
strcpy(curAlias->aliasInfo.aliasName, aliasPtr);
strcpy(curAlias->aliasInfo.realName, tbuffer);
curAlias->next = adir->alias_entries;
adir->alias_entries = curAlias;
}
/* now read the fs keys, if possible */
adir->keystr = (struct afsconf_keys *) 0;
afsconf_IntGetKeys(adir);
@ -545,6 +583,28 @@ char *arock; {
return 0;
}
/* call aproc(entry, arock, adir) for all cell aliases.
* Proc must return 0, or we'll stop early and return the code it returns
*/
afsconf_CellAliasApply(adir, aproc, arock)
struct afsconf_dir *adir;
int (*aproc)();
char *arock;
{
register struct afsconf_aliasentry *tde;
register afs_int32 code;
LOCK_GLOBAL_MUTEX
for(tde=adir->alias_entries; tde; tde=tde->next) {
code = (*aproc)(&tde->aliasInfo, arock, adir);
if (code) {
UNLOCK_GLOBAL_MUTEX
return code;
}
}
UNLOCK_GLOBAL_MUTEX
return 0;
}
afs_int32 afsconf_SawCell = 0;
afsconf_GetExtendedCellInfo(adir, acellName, aservice, acellInfo, clones)
@ -734,6 +794,7 @@ char *aservice;
char *acellName;
struct afsconf_cell *acellInfo; {
register struct afsconf_entry *tce;
struct afsconf_aliasentry *tcae;
struct afsconf_entry *bestce;
register afs_int32 i;
int tservice;
@ -765,6 +826,15 @@ struct afsconf_cell *acellInfo; {
UNLOCK_GLOBAL_MUTEX
return 0;
}
/* Look through the list of aliases */
for (tcae = adir->alias_entries; tcae; tcae = tcae->next) {
if (strcasecmp(tcae->aliasInfo.aliasName, tcell) == 0) {
tcell = tcae->aliasInfo.realName;
break;
}
}
for(tce=adir->entries;tce;tce=tce->next) {
if (strcasecmp(tce->cellInfo.name, tcell) == 0) {
/* found our cell */
@ -797,7 +867,7 @@ struct afsconf_cell *acellInfo; {
else {
UNLOCK_GLOBAL_MUTEX
#ifdef AFS_AFSDB_ENV
return afsconf_GetAfsdbInfo(acellName, aservice, acellInfo);
return afsconf_GetAfsdbInfo(tcell, aservice, acellInfo);
#else
return AFSCONF_NOTFOUND;
#endif /* AFS_AFSDB_ENV */

View File

@ -69,17 +69,28 @@ struct afsconf_cell {
int timeout; /* Data timeout, if non-zero */
};
struct afsconf_cellalias {
char aliasName[MAXCELLCHARS];
char realName[MAXCELLCHARS];
};
struct afsconf_entry {
struct afsconf_entry *next; /* next guy in afsconf_dir */
struct afsconf_cell cellInfo; /* info for this cell */
};
struct afsconf_aliasentry {
struct afsconf_aliasentry *next;
struct afsconf_cellalias aliasInfo;
};
struct afsconf_dir {
char *name; /* pointer to dir prefix */
char *cellName; /* cell name, if any, we're in */
struct afsconf_entry *entries; /* list of cell entries */
struct afsconf_keys *keystr; /* structure containing keys */
afs_int32 timeRead; /* time stamp of file last read */
struct afsconf_aliasentry *alias_entries; /* cell aliases */
};
extern struct afsconf_dir *afsconf_Open();

View File

@ -40,6 +40,7 @@
#define AFSOP_ADDCELL2 29 /* 2nd add cell protocol interface */
#define AFSOP_AFSDB_HANDLER 30 /* userspace AFSDB lookup handler */
#define AFSOP_SET_DYNROOT 31 /* enable/disable dynroot support */
#define AFSOP_ADDCELLALIAS 32 /* create alias for existing cell */
/* The range 20-30 is reserved for AFS system offsets in the afs_syscall */
#define AFSCALL_PIOCTL 20

View File

@ -177,4 +177,9 @@ struct cm_initparams {
#define VIOC_PREFETCHTAPE _VICEIOCTL(66) /* MR-AFS prefetch from tape */
#define VIOC_RESIDENCY_CMD _VICEIOCTL(67) /* generic MR-AFS cmds */
#define VIOC_STATISTICS _VICEIOCTL(68) /* arla: fetch statistics */
/* Coordinated 'C' pioctl's */
#define VIOC_NEWALIAS _VICEIOCTL2('C', 1) /* create new cell alias */
#define VIOC_GETALIAS _VICEIOCTL2('C', 2) /* get alias info */
#endif /* AFS_VENUS_H */

View File

@ -357,12 +357,17 @@ static void initDirPathArray(void)
"/NoUsrViceEtcThisCellFileOnWindows");
sprintf(dirPathArray[AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID], "%s/%s",
ntClientConfigDirShort, AFSDIR_CELLSERVDB_FILE_NTCLIENT);
strcpy(dirPathArray[AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID],
"/NoCellAliasOnWindows");
#else
pathp = dirPathArray[AFSDIR_CLIENT_THISCELL_FILEPATH_ID];
AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR, AFSDIR_THISCELL_FILE);
pathp = dirPathArray[AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID];
AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR, AFSDIR_CELLSERVDB_FILE);
pathp = dirPathArray[AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID];
AFSDIR_CLIENT_FILEPATH(pathp, AFSDIR_CLIENT_ETC_DIR, AFSDIR_CELLALIAS_FILE);
#endif /* AFS_NT40_ENV */
pathp = dirPathArray[AFSDIR_CLIENT_NETINFO_FILEPATH_ID];

View File

@ -118,6 +118,7 @@ ConstructLocalLogPath(const char *cpath,
/* file names */
#define AFSDIR_THISCELL_FILE "ThisCell"
#define AFSDIR_CELLSERVDB_FILE "CellServDB"
#define AFSDIR_CELLALIAS_FILE "CellAlias"
#define AFSDIR_KEY_FILE "KeyFile"
#define AFSDIR_ULIST_FILE "UserList"
#define AFSDIR_NOAUTH_FILE "NoAuth"
@ -260,6 +261,7 @@ typedef enum afsdir_id {
AFSDIR_SERVER_MIGRATE_DIRPATH_ID,
AFSDIR_SERVER_MIGRATELOG_FILEPATH_ID,
AFSDIR_SERVER_BIN_FILE_DIRPATH_ID,
AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID,
AFSDIR_PATHSTRING_MAX } afsdir_id_t;
/* getDirPath() returns a pointer to a string from an internal array of path strings
@ -331,6 +333,7 @@ const char *getDirPath(afsdir_id_t string_id);
/* client file paths */
#define AFSDIR_CLIENT_THISCELL_FILEPATH getDirPath(AFSDIR_CLIENT_THISCELL_FILEPATH_ID)
#define AFSDIR_CLIENT_CELLSERVDB_FILEPATH getDirPath(AFSDIR_CLIENT_CELLSERVDB_FILEPATH_ID)
#define AFSDIR_CLIENT_CELLALIAS_FILEPATH getDirPath(AFSDIR_CLIENT_CELLALIAS_FILEPATH_ID)
#define AFSDIR_CLIENT_NETINFO_FILEPATH getDirPath(AFSDIR_CLIENT_NETINFO_FILEPATH_ID)
#define AFSDIR_CLIENT_NETRESTRICT_FILEPATH getDirPath(AFSDIR_CLIENT_NETRESTRICT_FILEPATH_ID)

View File

@ -62,8 +62,10 @@ struct ViceIoctl {
*/
#if defined(KERNEL) && !defined(AFS_OSF_ENV) && !defined(AFS_ALPHA_LINUX20_ENV)
#define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl32))
#define _VICEIOCTL2(dev, id) ((unsigned int ) _IOW(dev, id, struct ViceIoctl32))
#else
#define _VICEIOCTL(id) ((unsigned int ) _IOW('V', id, struct ViceIoctl))
#define _VICEIOCTL2(dev, id) ((unsigned int ) _IOW(dev, id, struct ViceIoctl))
#endif
/* Use this macro to define up to 256 vice ioctl's. These ioctl's
@ -72,4 +74,3 @@ struct ViceIoctl {
into the kernel by the normal ioctl parameter passing mechanism.
*/
#define _VALIDVICEIOCTL(com) (com >= _VICEIOCTL(0) && com <= _VICEIOCTL(255))

View File

@ -1863,6 +1863,35 @@ static ListCellsCmd(as)
return 0;
}
static ListAliasesCmd(as)
struct cmd_syndesc *as;
{
afs_int32 code, i;
char *tp, *aliasName, *realName;
struct ViceIoctl blob;
for(i=0;;i++) {
tp = space;
memcpy(tp, &i, sizeof(afs_int32));
blob.out_size = MAXSIZE;
blob.in_size = sizeof(afs_int32);
blob.in = space;
blob.out = space;
code = pioctl(0, VIOC_GETALIAS, &blob, 1);
if (code < 0) {
if (errno == EDOM) break; /* done with the list */
Die(errno, 0);
return 1;
}
tp = space;
aliasName = tp;
tp += strlen(aliasName) + 1;
realName = tp;
printf("Alias %s for cell %s\n", aliasName, realName);
}
return 0;
}
static NewCellCmd(as)
struct cmd_syndesc *as;
{
@ -1964,6 +1993,40 @@ static NewCellCmd(as)
return 0;
}
static NewAliasCmd(as)
struct cmd_syndesc *as;
{
afs_int32 code;
struct ViceIoctl blob;
char *tp;
char *aliasName, *realName;
/* Now setup and do the NEWCELL pioctl call */
aliasName = as->parms[0].items->data;
realName = as->parms[1].items->data;
tp = space;
strcpy(tp, aliasName);
tp += strlen(aliasName) + 1;
strcpy(tp, realName);
tp += strlen(realName) + 1;
blob.in_size = tp - space;
blob.in = space;
blob.out_size = 0;
blob.out = space;
code = pioctl(0, VIOC_NEWALIAS, &blob, 1);
if (code < 0) {
if (errno == EEXIST) {
fprintf(stderr, "%s: cell name `%s' in use by an existing cell.\n",
pn, aliasName);
} else {
Die(errno, 0);
}
return 1;
}
return 0;
}
static WhichCellCmd(as)
struct cmd_syndesc *as;
{
@ -2984,6 +3047,8 @@ defect 3069
ts = cmd_CreateSyntax("listcells", ListCellsCmd, 0, "list configured cells");
cmd_AddParm(ts, "-numeric", CMD_FLAG, CMD_OPTIONAL, "addresses only");
ts = cmd_CreateSyntax("listaliases", ListAliasesCmd, 0, "list configured cell aliases");
ts = cmd_CreateSyntax("setquota", SetQuotaCmd, 0, "set volume quota");
cmd_AddParm(ts, "-path", CMD_SINGLE, CMD_OPTIONAL, "dir/file path");
cmd_AddParm(ts, "-max", CMD_SINGLE, 0, "max quota in kbytes");
@ -2997,6 +3062,10 @@ defect 3069
cmd_AddParm(ts, "-servers", CMD_LIST, CMD_REQUIRED, "primary servers");
cmd_AddParm(ts, "-linkedcell", CMD_SINGLE, CMD_OPTIONAL, "linked cell name");
ts = cmd_CreateSyntax("newalias", NewAliasCmd, 0, "configure new cell alias");
cmd_AddParm(ts, "-alias", CMD_SINGLE, 0, "alias name");
cmd_AddParm(ts, "-name", CMD_SINGLE, 0, "real name of cell");
#ifdef FS_ENABLE_SERVER_DEBUG_PORTS
/*
* Turn this on only if you wish to be able to talk to a server which is listening