mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 06:50:12 +00:00
dynroot-allow-cell-aliases-20011101
allow cell aliases. includes support for non-'V' pioctls
This commit is contained in:
parent
78d9433851
commit
b28927c752
9
NEWS
9
NEWS
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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];
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user