From cdb8a859c412a8ec94b6fe59be428fe8a2ddabe1 Mon Sep 17 00:00:00 2001 From: Nickolai Zeldovich Date: Thu, 6 Mar 2003 15:25:35 +0000 Subject: [PATCH] STABLE12-new-and-maybe-improved-cell-code-20020822 This is mostly a rewrite of src/afs/afs_cell.c, and associated changes to other things. Features of the new cell code: * Persistent name-to-cell-number mapping across reboots, to ensure the cell numbers in the dcache are meaningful. Stored in the new cache file, /usr/vice/cache/CellInfo. * Allow cmdebug to query the cell number to cell name mapping. * Allow clients to have an empty CellServDB as long as AFSDB is enabled and ThisCell has AFSDB records. * The home cell retains the setuid bit even if looked up via AFSDB. * Dynroot gets its own cell, rather than piggybacking on cell 1. * Cell 1 is no longer special; cell numbers are now semi-opaque. * Convert cell traversal code to using GetCellByIndex rather than directly poking at CellLRU / afs_xcell. * Separate cells from aliases, which shouldn't have been the same in the first place. * Cleaner code (IMHO). ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== correct a code block so patch is correct (cherry picked from commit 629d0806549d5b9cff9cd6f8eae50cf11c3e85ac) --- src/afs/IRIX/osi_vfsops.c | 9 +- src/afs/VNOPS/afs_vnop_lookup.c | 34 +- src/afs/afs.h | 41 +- src/afs/afs_analyze.c | 8 +- src/afs/afs_call.c | 120 ++-- src/afs/afs_callback.c | 85 ++- src/afs/afs_cell.c | 1200 ++++++++++++++++++------------- src/afs/afs_daemons.c | 90 +-- src/afs/afs_dcache.c | 22 +- src/afs/afs_dynroot.c | 253 ++++--- src/afs/afs_init.c | 77 +- src/afs/afs_osi_vget.c | 39 +- src/afs/afs_pioctl.c | 156 ++-- src/afs/afs_prototypes.h | 31 +- src/afs/afs_server.c | 89 +-- src/afs/afs_stats.h | 2 + src/afs/afs_vcache.c | 12 +- src/afs/afs_volume.c | 20 +- src/afsd/afsd.c | 217 +++--- src/config/afs_args.h | 3 + src/fsint/afscbint.xg | 6 + src/fsprobe/fsprobe_callback.c | 9 + src/venus/cmdebug.c | 61 +- src/venus/kdump.c | 80 ++- src/vol/vnode.c | 2 +- src/xstat/xstat_fs_callback.c | 10 + 26 files changed, 1594 insertions(+), 1082 deletions(-) diff --git a/src/afs/IRIX/osi_vfsops.c b/src/afs/IRIX/osi_vfsops.c index e93fe01bbe..87c15cfdf7 100644 --- a/src/afs/IRIX/osi_vfsops.c +++ b/src/afs/IRIX/osi_vfsops.c @@ -518,7 +518,6 @@ afs_vget(OSI_VFS_DECL(afsp), vnode_t **avcp, struct fid *fidp) { struct VenusFid vfid; struct vrequest treq; - extern struct cell *afs_GetCellByIndex(); register struct cell *tcell; register afs_int32 code = 0; afs_int32 ret; @@ -537,13 +536,13 @@ 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, 0 /* !refresh */); + tcell = afs_GetCellByIndex(afid2->af_cell, READ_LOCK); if (!tcell) { code = ENOENT; goto out; - } - vfid.Cell = tcell->cell; - afs_PutCell(tcell, WRITE_LOCK); + } + vfid.Cell = tcell->cellNum; + afs_PutCell(tcell, READ_LOCK); vfid.Fid.Volume = afid2->af_volid; vfid.Fid.Vnode = afid2->af_vno; vfid.Fid.Unique = afid2->af_uniq; diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index 67faf8bf08..50fe768f1c 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -137,10 +137,10 @@ EvalMountPoint(avc, advc, avolpp, areq) } if (!tcell) return ENODEV; - mtptCell = tcell->cell; /* The cell for the mountpoint */ + mtptCell = tcell->cellNum; /* The cell for the mountpoint */ if (tcell->lcellp) { - hac = 1; /* has associated cell */ - assocCell = tcell->lcellp->cell; /* The associated cell */ + hac = 1; /* has associated cell */ + assocCell = tcell->lcellp->cellNum; /* The associated cell */ } afs_PutCell(tcell, READ_LOCK); @@ -255,6 +255,9 @@ void afs_InitFakeStat(state) struct afs_fakestat_state *state; { + if (!afs_fakestat_enable) + return; + state->valid = 1; state->did_eval = 0; state->need_release = 0; @@ -275,11 +278,13 @@ int afs_EvalFakeStat_int(struct vcache **avcp, struct afs_fakestat_state *state, struct volume *tvolp = NULL; int code = 0; + if (!afs_fakestat_enable) + return 0; + osi_Assert(state->valid == 1); osi_Assert(state->did_eval == 0); state->did_eval = 1; - if (!afs_fakestat_enable) - return 0; + tvc = *avcp; if (tvc->mvstat != 1) return 0; @@ -396,6 +401,9 @@ void afs_PutFakeStat(state) struct afs_fakestat_state *state; { + if (!afs_fakestat_enable) + return; + osi_Assert(state->valid == 1); if (state->need_release) afs_PutVCache(state->root_vp, 0); @@ -1313,20 +1321,14 @@ afs_lookup(adp, aname, avcp, acred) afs_PutDCache(tdc); if (code == ENOENT && afs_IsDynroot(adp) && dynrootRetry) { - struct cell *tcell; - ReleaseReadLock(&adp->lock); dynrootRetry = 0; - if (*tname == '.') - tcell = afs_GetCellByName(tname + 1, READ_LOCK); + if (tname[0] == '.') + afs_LookupAFSDB(tname + 1); else - tcell = afs_GetCellByName(tname, READ_LOCK); - if (tcell) { - afs_PutCell(tcell, READ_LOCK); - afs_RefreshDynroot(); - if (tname != aname && tname) osi_FreeLargeSpace(tname); - goto redo; - } + afs_LookupAFSDB(tname); + if (tname && tname != aname) osi_FreeLargeSpace(tname); + goto redo; } else { ReleaseReadLock(&adp->lock); } diff --git a/src/afs/afs.h b/src/afs/afs.h index d3ff50343b..8f93de5c4f 100644 --- a/src/afs/afs.h +++ b/src/afs/afs.h @@ -181,29 +181,43 @@ struct afs_cbr { struct AFSFid fid; }; - -#define LOCALCELL 1 /* local cell's number is always 1 */ +/* cellinfo file magic number */ +#define AFS_CELLINFO_MAGIC 0xf32817cd /* cell flags */ -#define CPrimary 1 /* on if this is the primary cell */ -#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 */ +#define CNoSUID 0x02 /* disable suid bit for this cell */ +#define CLinkedCell4 0x04 /* reserved for ADDCELL2 pioctl */ +#define CNoAFSDB 0x08 /* never bother trying AFSDB */ +#define CHasVolRef 0x10 /* volumes were referenced */ +#define CLinkedCell 0x20 /* has a linked cell in lcellp */ struct cell { - struct afs_q lruq; /* lru q next and prev */ - afs_int32 cell; /* unique id assigned by venus */ + struct afs_q lruq; /* lru q next and prev */ char *cellName; /* char string name of cell */ - struct server *cellHosts[MAXCELLHOSTS]; /* volume *location* hosts for this cell */ + afs_int32 cellIndex; /* sequence number */ + afs_int32 cellNum; /* semi-permanent cell number */ + struct server *cellHosts[MAXCELLHOSTS]; /* volume *location* hosts */ struct cell *lcellp; /* Associated linked cell */ u_short fsport; /* file server port */ u_short vlport; /* volume server port */ short states; /* state flags */ - short cellIndex; /* relative index number per cell */ - short realcellIndex; /* as above but ignoring aliases */ time_t timeout; /* data expire time, if non-zero */ - char *realName; /* who this cell is an alias for */ + struct cell_name *cnamep; /* pointer to our cell_name */ + afs_rwlock_t lock; /* protects cell data */ +}; + +struct cell_name { + struct cell_name *next; + afs_int32 cellnum; + char *cellname; + char used; +}; + +struct cell_alias { + struct cell_alias *next; + afs_int32 index; + char *alias; + char *cell; }; #define afs_PutCell(cellp, locktype) @@ -992,7 +1006,6 @@ extern struct volume *afs_GetVolumeByName(); extern struct conn *afs_Conn(); extern struct conn *afs_ConnByHost(); extern struct conn *afs_ConnByMHosts(); -extern afs_int32 afs_NewCell(); extern struct dcache *afs_GetDCache(); extern struct dcache *afs_FindDCache(); extern struct dcache *afs_NewDCache(); diff --git a/src/afs/afs_analyze.c b/src/afs/afs_analyze.c index 90540117bf..06f7d4c790 100644 --- a/src/afs/afs_analyze.c +++ b/src/afs/afs_analyze.c @@ -179,7 +179,7 @@ static int VLDB_Same (afid, areq) do { VSleep(2); /* Better safe than sorry. */ tconn = afs_ConnByMHosts(tcell->cellHosts, tcell->vlport, - tcell->cell, &treq, SHARED_LOCK); + tcell->cellNum, &treq, SHARED_LOCK); if (tconn) { if (tconn->srvr->server->flags & SNO_LHOSTS) { type = 0; @@ -392,8 +392,8 @@ int afs_Analyze(aconn, acode, afid, areq, op, locktype, cellp) if (aerrP) (aerrP->err_Network)++; if (hm_retry_int && !(areq->flags & O_NONBLOCK) && /* "hard" mount */ - ((afid && afid->Cell == LOCALCELL) || - (cellp && cellp->cell == LOCALCELL))) { + ((afid && afs_IsPrimaryCellNum(afid->Cell)) || + (cellp && afs_IsPrimaryCell(cellp)))) { if (!afid) { afs_warnuser("afs: hard-mount waiting for a vlserver to return to service\n"); VSleep(hm_retry_int); @@ -492,7 +492,7 @@ int afs_Analyze(aconn, acode, afid, areq, op, locktype, cellp) if (aerrP) (aerrP->err_Protection)++; - tu = afs_FindUser(areq->uid, tsp->cell->cell, READ_LOCK); + tu = afs_FindUser(areq->uid, tsp->cell->cellNum, READ_LOCK); if (tu) { if ((acode == VICETOKENDEAD) || (acode == RXKADEXPIRED)) afs_warnuser("afs: Tokens for user of AFS id %d for cell %s have expired\n", diff --git a/src/afs/afs_call.c b/src/afs/afs_call.c index 47bee60c3e..2fd484bf65 100644 --- a/src/afs/afs_call.c +++ b/src/afs/afs_call.c @@ -83,6 +83,7 @@ static int afs_CacheInit_Done = 0; static int afs_Go_Done = 0; extern struct interfaceAddr afs_cb_interface; static int afs_RX_Running = 0; +static int afs_InitSetup_done = 0; static int Afscall_icl(long opcode, long p1, long p2, long p3, long p4, long *retval); @@ -99,6 +100,9 @@ static int afs_InitSetup(int preallocs) extern void afs_InitStats(); int code; + if (afs_InitSetup_done) + return; + #ifndef AFS_NOSTATS /* * Set up all the AFS statistics variables. This should be done @@ -121,6 +125,9 @@ static int afs_InitSetup(int preallocs) /* resource init creates the services */ afs_ResourceInit(preallocs); + afs_InitSetup_done = 1; + afs_osi_Wakeup(&afs_InitSetup_done); + return code; } #if defined(AFS_LINUX24_ENV) && defined(COMPLETION_H_EXISTS) @@ -294,6 +301,11 @@ afs_syscall_call(parm, parm2, parm3, parm4, parm5, parm6) long parm, parm2, parm3, parm4, parm5, parm6; { afs_int32 code = 0; +#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 */ AFS_STATCNT(afs_syscall_call); #ifdef AFS_SUN5_ENV @@ -377,21 +389,11 @@ long parm, parm2, parm3, parm4, parm5, parm6; #endif else if (parm == AFSOP_START_AFS) { /* afs daemon */ - afs_int32 temp; - if (AFS_Running) goto out; AFS_Running = 1; while (afs_initState < AFSOP_START_AFS) afs_osi_Sleep(&afs_initState); -#if defined(AFS_SUN_ENV) || defined(AFS_SGI_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) - temp = AFS_MINBUFFERS; /* Should fix this soon */ -#else - temp = ((afs_bufferpages * NBPG)>>11); /* number of 2k buffers we could get from all of the buffer space */ - temp = temp>>2; /* don't take more than 25% (our magic parameter) */ - if (temp < AFS_MINBUFFERS) temp = AFS_MINBUFFERS; /* although we really should have this many */ -#endif - DInit(temp); afs_initState = AFSOP_START_BKG; afs_osi_Wakeup(&afs_initState); afs_osi_Invisible(); @@ -452,13 +454,31 @@ long parm, parm2, parm3, parm4, parm5, parm6; } #endif #endif + else if (parm == AFSOP_BASIC_INIT) { + afs_int32 temp; + + while (!afs_InitSetup_done) + afs_osi_Sleep(&afs_InitSetup_done); + +#if defined(AFS_SUN_ENV) || defined(AFS_SGI_ENV) || defined(AFS_HPUX_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) + temp = AFS_MINBUFFERS; /* Should fix this soon */ +#else + /* number of 2k buffers we could get from all of the buffer space */ + temp = ((afs_bufferpages * NBPG)>>11); + temp = temp>>2; /* don't take more than 25% (our magic parameter) */ + if (temp < AFS_MINBUFFERS) + temp = AFS_MINBUFFERS; /* though we really should have this many */ +#endif + DInit(temp); + afs_rootFid.Fid.Volume = 0; + code = 0; + } else if (parm == AFSOP_ADDCELL) { /* add a cell. Parameter 2 is 8 hosts (in net order), parm 3 is the null-terminated name. Parameter 4 is the length of the name, including the null. Parm 5 is the home cell flag (0x1 bit) and the nosuid flag (0x2 bit) */ struct afsop_cell tcell; - while (afs_initState < AFSOP_START_BKG) afs_osi_Sleep(&afs_initState); AFS_COPYIN((char *)parm2, (char *)tcell.hosts, sizeof(tcell.hosts), code); if (!code) { if (parm4 > sizeof(tcell.cellName)) @@ -467,18 +487,13 @@ long parm, parm2, parm3, parm4, parm5, parm6; AFS_COPYIN((char *)parm3, tcell.cellName, parm4, code); if (!code) afs_NewCell(tcell.cellName, tcell.hosts, parm5, - (char *)0, (u_short)0, (u_short)0, (int)0); + NULL, 0, 0, 0); } } } else if (parm == AFSOP_ADDCELL2) { struct afsop_cell tcell; char *tbuffer = osi_AllocSmallSpace(AFS_SMALLOCSIZ), *lcnamep = 0; char *tbuffer1 = osi_AllocSmallSpace(AFS_SMALLOCSIZ), *cnamep = 0; -#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 */ int cflags = parm4; /* wait for basic init */ @@ -497,7 +512,7 @@ long parm, parm2, parm3, parm4, parm5, parm6; } if (!code) afs_NewCell(tbuffer1, tcell.hosts, cflags, - lcnamep, (u_short)0, (u_short)0, (int)0); + lcnamep, 0, 0, 0); } } osi_FreeSmallSpace(tbuffer); @@ -509,34 +524,33 @@ long parm, parm2, parm3, parm4, parm5, parm6; * 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 */ + if (!code) afs_NewCellAlias(aliasName, cellName); osi_FreeSmallSpace(aliasName); osi_FreeSmallSpace(cellName); } + else if (parm == AFSOP_SET_THISCELL) { + /* + * Call arguments: + * parm2 is the primary cell name + */ + char *cell = osi_AllocSmallSpace(AFS_SMALLOCSIZ); + + AFS_COPYINSTR((char *) parm2, cell, AFS_SMALLOCSIZ, &bufferSize, code); + if (!code) + afs_SetPrimaryCell(cell); + osi_FreeSmallSpace(cell); + } else if (parm == AFSOP_CACHEINIT) { struct afs_cacheParams cparms; if (afs_CacheInit_Done) goto out; - /* wait for basic init */ - while (afs_initState < AFSOP_START_BKG) afs_osi_Sleep(&afs_initState); AFS_COPYIN((char *)parm2, (caddr_t) &cparms, sizeof(cparms), code); if (code) { #if defined(AFS_SUN5_ENV) || defined(AFS_OSF_ENV) || defined (AFS_SGI64_ENV) || defined(AFS_LINUX20_ENV) || defined(AFS_DARWIN_ENV) || defined(AFS_FBSD_ENV) @@ -585,12 +599,6 @@ long parm, parm2, parm3, parm4, parm5, parm6; code = afs_InitCacheFile((char *) 0, ainode); } else if (parm == AFSOP_ROOTVOLUME) { -#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 */ - /* wait for basic init */ while (afs_initState < AFSOP_START_BKG) afs_osi_Sleep(&afs_initState); @@ -600,29 +608,31 @@ long parm, parm2, parm3, parm4, parm5, parm6; } else code = 0; } - else if (parm == AFSOP_CACHEFILE || parm == AFSOP_CACHEINFO || - parm == AFSOP_VOLUMEINFO || parm == AFSOP_AFSLOG) { + else if (parm == AFSOP_CACHEFILE || + parm == AFSOP_CACHEINFO || + parm == AFSOP_VOLUMEINFO || + parm == AFSOP_AFSLOG || + parm == AFSOP_CELLINFO) { char *tbuffer = osi_AllocSmallSpace(AFS_SMALLOCSIZ); -#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 */ - /* wait for basic init */ - while (afs_initState < AFSOP_START_BKG) afs_osi_Sleep(&afs_initState); code = 0; - AFS_COPYINSTR((char *)parm2, tbuffer, AFS_SMALLOCSIZ, &bufferSize, code); + AFS_COPYINSTR((char *) parm2, tbuffer, AFS_SMALLOCSIZ, + &bufferSize, code); if (code) { osi_FreeSmallSpace(tbuffer); goto out; } if (!code) { - tbuffer[AFS_SMALLOCSIZ-1] = 0; /* null-terminate the name */ - /* we now have the cache dir copied in. Call the cache init routines */ - if (parm == AFSOP_CACHEFILE) code = afs_InitCacheFile(tbuffer, 0); - else if (parm == AFSOP_CACHEINFO) code = afs_InitCacheInfo(tbuffer); - else if (parm == AFSOP_VOLUMEINFO) code = afs_InitVolumeInfo(tbuffer); + tbuffer[AFS_SMALLOCSIZ-1] = '\0'; /* null-terminate the name */ + /* We have the cache dir copied in. Call the cache init routine */ + if (parm == AFSOP_CACHEFILE) + code = afs_InitCacheFile(tbuffer, 0); + else if (parm == AFSOP_CACHEINFO) + code = afs_InitCacheInfo(tbuffer); + else if (parm == AFSOP_VOLUMEINFO) + code = afs_InitVolumeInfo(tbuffer); + else if (parm == AFSOP_CELLINFO) + code = afs_InitCellInfo(tbuffer); } osi_FreeSmallSpace(tbuffer); } @@ -827,7 +837,7 @@ long parm, parm2, parm3, parm4, parm5, parm6; AFS_COPYIN((afs_int32 *)parm2, cellname, cellLen, code); AFS_COPYIN((afs_int32 *)parm3, kmsg, kmsgLen, code); if (!code) { - code = afs_AfsdbHandler(cellname, cellLen, kmsg); + code = afs_AFSDBHandler(cellname, cellLen, kmsg); if (*cellname == 1) *cellname = 0; if (code == -2) { /* Shutting down? */ *cellname = 1; @@ -1451,7 +1461,7 @@ afs_shutdown() } #ifdef AFS_AFSDB_ENV afs_warn("AFSDB... "); - afs_StopAfsdb(); + afs_StopAFSDB(); while (afs_termState == AFSOP_STOP_AFSDB) afs_osi_Sleep(&afs_termState); #endif diff --git a/src/afs/afs_callback.c b/src/afs/afs_callback.c index fe6ccf79c2..55639ea606 100644 --- a/src/afs/afs_callback.c +++ b/src/afs/afs_callback.c @@ -1137,7 +1137,7 @@ int SRXAFSCB_GetCellServDB( #endif /* RX_ENABLE_LOCKS */ AFS_STATCNT(SRXAFSCB_GetCellServDB); - tcell = afs_GetCellByIndex(a_index, READ_LOCK, 0); + tcell = afs_GetCellByIndex(a_index, READ_LOCK); if (!tcell) { i = 0; @@ -1203,7 +1203,6 @@ int SRXAFSCB_GetLocalCell( { int plen; struct cell *tcell; - struct afs_q *cq, *tq; char *t_name, *p_name = NULL; #ifdef RX_ENABLE_LOCKS @@ -1214,27 +1213,16 @@ int SRXAFSCB_GetLocalCell( /* Search the list for the primary cell. Cell number 1 is only * the primary cell is when no other cell is explicitly marked as * the primary cell. */ - ObtainReadLock(&afs_xcell); - - for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { - tq = QNext(cq); - tcell = QTOC(cq); - if (tcell->states & CPrimary) { - p_name = tcell->cellName; - break; - } - if (tcell->cell == 1) { - p_name = tcell->cellName; - } - } - + tcell = afs_GetPrimaryCell(READ_LOCK); + if (tcell) + p_name = tcell->cellName; if (p_name) plen = strlen(p_name); else plen = 0; t_name = (char *)afs_osi_Alloc(plen+1); if (t_name == NULL) { - ReleaseReadLock(&afs_xcell); + if (tcell) afs_PutCell(tcell, READ_LOCK); #ifdef RX_ENABLE_LOCKS AFS_GUNLOCK(); #endif /* RX_ENABLE_LOCKS */ @@ -1245,13 +1233,12 @@ int SRXAFSCB_GetLocalCell( if (p_name) memcpy(t_name, p_name, plen); - ReleaseReadLock(&afs_xcell); - #ifdef RX_ENABLE_LOCKS AFS_GUNLOCK(); #endif /* RX_ENABLE_LOCKS */ *a_name = t_name; + if (tcell) afs_PutCell(tcell, READ_LOCK); return 0; } @@ -1369,3 +1356,63 @@ int SRXAFSCB_GetCacheConfig( return 0; } + +/*------------------------------------------------------------------------ + * EXPORTED SRXAFSCB_GetCellByNum + * + * Description: + * Routine to get information about a cell specified by its + * cell number (returned by GetCE/GetCE64). + * + * Arguments: + * a_call : Ptr to Rx call on which this request came in. + * a_cellnum : Input cell number + * a_name : Output cell name (one zero byte when no such cell). + * a_hosts : Output cell database servers in host byte order. + * + * Returns: + * 0 on success + * + * Environment: + * Nothing interesting. + * + * Side Effects: + * As advertised. + *------------------------------------------------------------------------*/ + +int SRXAFSCB_GetCellByNum(struct rx_call *a_call, afs_int32 a_cellnum, + char **a_name, serverList *a_hosts) +{ + afs_int32 i, sn; + struct cell *tcell; + + RX_AFS_GLOCK(); + AFS_STATCNT(SRXAFSCB_GetCellByNum); + + a_hosts->serverList_val = 0; + a_hosts->serverList_len = 0; + + tcell = afs_GetCellStale(a_cellnum, READ_LOCK); + if (!tcell) { + *a_name = afs_strdup(""); + RX_AFS_GUNLOCK(); + return 0; + } + + ObtainReadLock(&tcell->lock); + *a_name = afs_strdup(tcell->cellName); + + for (sn = 0; sn < AFSMAXCELLHOSTS && tcell->cellHosts[sn]; sn++) + ; + a_hosts->serverList_len = sn; + a_hosts->serverList_val = (afs_int32 *) afs_osi_Alloc(sn*sizeof(afs_int32)); + + for (i = 0; i < sn; i++) + a_hosts->serverList_val[i] = ntohl(tcell->cellHosts[i]->addr->sa_ip); + ReleaseReadLock(&tcell->lock); + afs_PutCell(tcell, READ_LOCK); + + RX_AFS_GUNLOCK(); + return 0; +} + diff --git a/src/afs/afs_cell.c b/src/afs/afs_cell.c index e00e6548e5..8f2ee0ecd2 100644 --- a/src/afs/afs_cell.c +++ b/src/afs/afs_cell.c @@ -11,523 +11,674 @@ * Implements: */ #include -#include "../afs/param.h" +#include "afs/param.h" RCSID("$Header$"); -#include "../afs/stds.h" -#include "../afs/sysincludes.h" /* Standard vendor system headers */ - -#if !defined(UKERNEL) -#include -#include - -#ifdef AFS_SGI62_ENV -#include "../h/hashing.h" -#endif -#if !defined(AFS_HPUX110_ENV) && !defined(AFS_LINUX20_ENV) && !defined(AFS_DARWIN60_ENV) -#include -#endif /* ! ASF_HPUX110_ENV */ -#endif /* !defined(UKERNEL) */ - -#include "../afs/afsincludes.h" /* Afs-based standard headers */ -#include "../afs/afs_stats.h" /* afs statistics */ - -#if defined(AFS_SUN56_ENV) -#include -#include -#if defined(AFS_SUN58_ENV) -#include -#endif -#include -#endif - -/* Exported variables */ -afs_rwlock_t afs_xcell; /* allocation lock for cells */ -struct afs_q CellLRU; -afs_int32 afs_cellindex=0; -afs_int32 afs_realcellindex=0; -afs_uint32 afs_nextCellNum = 0x100; +#include "afs/stds.h" +#include "afs/sysincludes.h" /* Standard vendor system headers */ +#include "afsincludes.h" /* Afs-based standard headers */ +#include "afs/afs_stats.h" /* afs statistics */ +#include "afs/afs_osi.h" /* 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; - -/* 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_GetCellByName2(); - -int afs_strcasecmp(s1, s2) - register char *s1, *s2; -{ - while (*s1 && *s2) { - register char c1, c2; - - c1 = *s1++; - c2 = *s2++; - if (c1 >= 'A' && c1 <= 'Z') c1 += 0x20; - if (c2 >= 'A' && c2 <= 'Z') c2 += 0x20; - if (c1 != c2) - return c1-c2; - } - - return *s1 - *s2; -} +afs_rwlock_t afs_xcell; /* Export for cmdebug peeking at locks */ +/* + * AFSDB implementation: + * + * afs_StopAFSDB: terminate the AFSDB handler, used on shutdown + * afs_AFSDBHandler: entry point for user-space AFSDB request handler + * afs_GetCellHostsAFSDB: query the AFSDB handler and wait for response + * afs_LookupAFSDB: look up AFSDB for given cell name and create locally + */ #ifdef AFS_AFSDB_ENV -void afs_StopAfsdb() +static afs_rwlock_t afsdb_client_lock; /* Serializes client requests */ +static char afsdb_handler_running; /* Protected by GLOCK */ +static char afsdb_handler_shutdown; /* Protected by GLOCK */ + +static struct { + afs_rwlock_t lock; + char pending; + char complete; + char *cellname; + afs_int32 *cellhosts; + int *timeout; + char **realname; +} afsdb_req; + +void afs_StopAFSDB() { - if (afs_AfsdbHandlerPresent) { - afs_osi_Wakeup(&afs_AfsdbHandlerWait); + if (afsdb_handler_running) { + afs_osi_Wakeup(&afsdb_req); } else { - afs_AfsdbHandlerShutdown = 1; + afsdb_handler_shutdown = 1; afs_termState = AFSOP_STOP_RXEVENT; } } -int afs_AfsdbHandler(acellName, acellNameLen, kernelMsg) - char *acellName; - int acellNameLen; - afs_int32 *kernelMsg; +int afs_AFSDBHandler(char *acellName, int acellNameLen, afs_int32 *kernelMsg) { - /* afs_syscall_call() has already grabbed the global lock */ + if (afsdb_handler_shutdown) return -2; + afsdb_handler_running = 1; - if (afs_AfsdbHandlerShutdown) return -2; - afs_AfsdbHandlerPresent = 1; - - if (afs_AfsdbHandler_ReqPending) { + ObtainSharedLock(&afsdb_req.lock, 683); + if (afsdb_req.pending) { int i, hostCount; + UpgradeSToWLock(&afsdb_req.lock, 684); hostCount = kernelMsg[0]; - *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); + *afsdb_req.timeout = kernelMsg[1]; + if (*afsdb_req.timeout) *afsdb_req.timeout += osi_Time(); + *afsdb_req.realname = afs_strdup(acellName); for (i=0; i= hostCount) - afs_AfsdbHandler_CellHosts[i] = 0; + afsdb_req.cellhosts[i] = 0; else - afs_AfsdbHandler_CellHosts[i] = kernelMsg[2+i]; + afsdb_req.cellhosts[i] = kernelMsg[2+i]; } /* Request completed, wake up the relevant thread */ - afs_AfsdbHandler_ReqPending = 0; - afs_AfsdbHandler_Completed = 1; - afs_osi_Wakeup(&afs_AfsdbLookupWait); + afsdb_req.pending = 0; + afsdb_req.complete = 1; + afs_osi_Wakeup(&afsdb_req); + ConvertWToSLock(&afsdb_req.lock); } + ConvertSToRLock(&afsdb_req.lock); /* Wait for a request */ - while (afs_AfsdbHandler_ReqPending == 0 && afs_termState != AFSOP_STOP_AFSDB) - afs_osi_Sleep(&afs_AfsdbHandlerWait); + while (afsdb_req.pending == 0 && afs_termState != AFSOP_STOP_AFSDB) { + ReleaseReadLock(&afsdb_req.lock); + afs_osi_Sleep(&afsdb_req); + ObtainReadLock(&afsdb_req.lock); + } /* Check if we're shutting down */ if (afs_termState == AFSOP_STOP_AFSDB) { + ReleaseReadLock(&afsdb_req.lock); + /* Inform anyone waiting for us that we're going away */ - afs_AfsdbHandlerShutdown = 1; - afs_AfsdbHandlerPresent = 0; - afs_osi_Wakeup(&afs_AfsdbLookupWait); + afsdb_handler_shutdown = 1; + afsdb_handler_running = 0; + afs_osi_Wakeup(&afsdb_req); afs_termState = AFSOP_STOP_RXEVENT; afs_osi_Wakeup(&afs_termState); return -2; } - /* Copy the requested cell name into the request buffer */ - strncpy(acellName, afs_AfsdbHandler_CellName, acellNameLen); - /* Return the lookup request to userspace */ + strncpy(acellName, afsdb_req.cellname, acellNameLen); + ReleaseReadLock(&afsdb_req.lock); return 0; } + +static int afs_GetCellHostsAFSDB(char *acellName, afs_int32 *acellHosts, + int *timeout, char **realName) +{ + AFS_ASSERT_GLOCK(); + if (!afsdb_handler_running) return ENOENT; + + ObtainWriteLock(&afsdb_client_lock, 685); + ObtainWriteLock(&afsdb_req.lock, 686); + + *acellHosts = 0; + afsdb_req.cellname = acellName; + afsdb_req.cellhosts = acellHosts; + afsdb_req.timeout = timeout; + afsdb_req.realname = realName; + + afsdb_req.complete = 0; + afsdb_req.pending = 1; + afs_osi_Wakeup(&afsdb_req); + ConvertWToRLock(&afsdb_req.lock); + + while (afsdb_handler_running && !afsdb_req.complete) { + ReleaseReadLock(&afsdb_req.lock); + afs_osi_Sleep(&afsdb_req); + ObtainReadLock(&afsdb_req.lock); + }; + ReleaseReadLock(&afsdb_req.lock); + ReleaseWriteLock(&afsdb_client_lock); + + if (*acellHosts) + return 0; + else + return ENOENT; +} #endif - -int afs_GetCellHostsFromDns(acellName, acellHosts, timeout, realName) - char *acellName; - afs_int32 *acellHosts; - int *timeout; - char **realName; +void afs_LookupAFSDB(char *acellName) { #ifdef AFS_AFSDB_ENV - char grab_glock = 0; - - if (!afs_AfsdbHandlerPresent) return ENOENT; - - /* Initialize host list to empty in case the handler is gone */ - *acellHosts = 0; - - if (!ISAFS_GLOCK()) { - grab_glock = 1; - AFS_GLOCK(); - } - - /* Wait until the AFSDB handler is available, and grab it */ - while (afs_AfsdbHandlerInuse) - afs_osi_Sleep(&afs_AfsdbLookupWait); - afs_AfsdbHandlerInuse = 1; - - /* Set up parameters for the handler */ - 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; - afs_AfsdbHandler_ReqPending = 1; - afs_osi_Wakeup(&afs_AfsdbHandlerWait); - - /* Wait for the handler to get back to us with the reply */ - while (afs_AfsdbHandlerPresent && !afs_AfsdbHandler_Completed) - afs_osi_Sleep(&afs_AfsdbLookupWait); - - /* Release the AFSDB handler and wake up others waiting for it */ - afs_AfsdbHandlerInuse = 0; - afs_osi_Wakeup(&afs_AfsdbLookupWait); - - if (grab_glock) AFS_GUNLOCK(); - - if (*acellHosts) return 0; - return ENOENT; -#else - return ENOENT; -#endif -} - - -void afs_RefreshCell(ac) - register struct cell *ac; -{ afs_int32 cellHosts[MAXCELLHOSTS]; char *realName = NULL; - struct cell *tc; - int timeout; + int code, timeout; + + code = afs_GetCellHostsAFSDB(acellName, cellHosts, &timeout, &realName); + if (code) goto done; + code = afs_NewCell(realName, cellHosts, CNoSUID, NULL, 0, 0, timeout); + if (code) goto done; - /* Don't need to do anything if no timeout or it's not expired */ - if (!ac->timeout || ac->timeout > osi_Time()) return; - - if (afs_GetCellHostsFromDns(ac->cellName, cellHosts, &timeout, &realName)) - /* In case of lookup failure, keep old data */ - goto done; - - /* Refresh the DB servers for the real cell; other values stay the same. */ - afs_NewCell(realName, cellHosts, 0, (char *) 0, 0, 0, timeout, (char *) 0); - - /* If this is an alias, update the alias entry too */ - if (afs_strcasecmp(ac->cellName, realName)) { - /* - * Look up the entry we just updated, to compensate for - * uppercase-vs-lowercase lossage with DNS. - */ - tc = afs_GetCellByName2(realName, READ_LOCK, 0 /* no AFSDB */); - - if (tc) { - afs_NewCell(ac->cellName, 0, CAlias, (char *) 0, 0, 0, - timeout, tc->cellName); - afs_PutCell(tc, READ_LOCK); - } - } + /* If we found an alias, create it */ + if (afs_strcasecmp(acellName, realName)) + afs_NewCellAlias(acellName, realName); done: if (realName) - afs_osi_Free(realName, strlen(realName) + 1); + afs_osi_FreeStr(realName); +#endif } +/* + * Cell name-to-ID mapping + * + * afs_cellname_new: create a new cell name, optional cell number + * afs_cellname_lookup_id: look up a cell name + * afs_cellname_lookup_name: look up a cell number + * afs_cellname_ref: note that this cell name was referenced somewhere + * afs_cellname_init: load the list of cells from given inode + * afs_cellname_write: write in-kernel list of cells to disk + */ -struct cell *afs_GetCellByName_Dns(acellName, locktype) - register char *acellName; - afs_int32 locktype; +struct cell_name *afs_cellname_head; /* Export for kdump */ +static ino_t afs_cellname_inode; +static int afs_cellname_inode_set; +static int afs_cellname_dirty; +static afs_int32 afs_cellnum_next; + +static struct cell_name *afs_cellname_new(char *name, afs_int32 cellnum) { - afs_int32 cellHosts[MAXCELLHOSTS]; - char *realName = NULL; - struct cell *tc; - int timeout; + struct cell_name *cn; - if (afs_GetCellHostsFromDns(acellName, cellHosts, &timeout, &realName)) - goto bad; - if (afs_NewCell(realName, cellHosts, CNoSUID, (char *) 0, 0, 0, - timeout, (char *) 0)) - goto bad; + if (cellnum == 0) + cellnum = afs_cellnum_next; - /* If this is an alias, create an entry for it too */ - if (afs_strcasecmp(acellName, realName)) { - /* - * Look up the entry we just updated, to compensate for - * uppercase-vs-lowercase lossage with DNS. - */ - tc = afs_GetCellByName2(realName, READ_LOCK, 0 /* no AFSDB */); - if (!tc) - goto bad; + cn = (struct cell_name *) afs_osi_Alloc(sizeof(*cn)); + cn->next = afs_cellname_head; + cn->cellnum = cellnum; + cn->cellname = afs_strdup(name); + cn->used = 0; + afs_cellname_head = cn; - if (afs_NewCell(acellName, 0, CAlias, (char *) 0, 0, 0, - timeout, tc->cellName)) { - afs_PutCell(tc, READ_LOCK); - goto bad; + if (cellnum >= afs_cellnum_next) + afs_cellnum_next = cellnum + 1; + + return cn; +} + +static struct cell_name *afs_cellname_lookup_id(afs_int32 cellnum) +{ + struct cell_name *cn; + + for (cn = afs_cellname_head; cn; cn = cn->next) + if (cn->cellnum == cellnum) + return cn; + + return NULL; +} + +static struct cell_name *afs_cellname_lookup_name(char *name) +{ + struct cell_name *cn; + + for (cn = afs_cellname_head; cn; cn = cn->next) + if (strcmp(cn->cellname, name) == 0) + return cn; + + return NULL; +} + +static void afs_cellname_ref(struct cell_name *cn) +{ + if (!cn->used) { + cn->used = 1; + afs_cellname_dirty = 1; + } +} + +int afs_cellname_init(ino_t inode, int lookupcode) +{ + struct osi_file *tfile; + int cc, off = 0; + + ObtainWriteLock(&afs_xcell, 692); + + afs_cellnum_next = 1; + afs_cellname_dirty = 0; + + if (cacheDiskType == AFS_FCACHE_TYPE_MEM) { + ReleaseWriteLock(&afs_xcell); + return 0; + } + if (lookupcode) { + ReleaseWriteLock(&afs_xcell); + return lookupcode; + } + + tfile = osi_UFSOpen(inode); + if (!tfile) { + ReleaseWriteLock(&afs_xcell); + return EIO; + } + + afs_cellname_inode = inode; + afs_cellname_inode_set = 1; + + while (1) { + afs_int32 cellnum, clen, magic; + struct cell_name *cn; + char *cellname; + + cc = afs_osi_Read(tfile, off, &magic, sizeof(magic)); + if (cc != sizeof(magic)) + break; + if (magic != AFS_CELLINFO_MAGIC) + break; + off += cc; + + cc = afs_osi_Read(tfile, off, &cellnum, sizeof(cellnum)); + if (cc != sizeof(cellnum)) + break; + off += cc; + + cc = afs_osi_Read(tfile, off, &clen, sizeof(clen)); + if (cc != sizeof(clen)) + break; + off += cc; + + cellname = afs_osi_Alloc(clen + 1); + if (!cellname) + break; + + cc = afs_osi_Read(tfile, off, cellname, clen); + if (cc != clen) { + afs_osi_Free(cellname, clen + 1); + break; + } + off += cc; + cellname[clen] = '\0'; + + if (afs_cellname_lookup_name(cellname) || + afs_cellname_lookup_id(cellnum)) { + afs_osi_Free(cellname, clen + 1); + break; } + cn = afs_cellname_new(cellname, cellnum); + afs_osi_Free(cellname, clen + 1); + } + + osi_UFSClose(tfile); + ReleaseWriteLock(&afs_xcell); + return 0; +} + +int afs_cellname_write() +{ + struct osi_file *tfile; + struct cell_name *cn; + int off; + + if (!afs_cellname_dirty || !afs_cellname_inode_set) + return 0; + if (afs_initState != 300) + return 0; + + ObtainWriteLock(&afs_xcell, 693); + afs_cellname_dirty = 0; + off = 0; + tfile = osi_UFSOpen(afs_cellname_inode); + if (!tfile) { + ReleaseWriteLock(&afs_xcell); + return EIO; + } + + for (cn = afs_cellname_head; cn; cn = cn->next) { + afs_int32 magic, cellnum, clen; + int cc; + + if (!cn->used) + continue; + + magic = AFS_CELLINFO_MAGIC; + cc = afs_osi_Write(tfile, off, &magic, sizeof(magic)); + if (cc != sizeof(magic)) + break; + off += cc; + + cellnum = cn->cellnum; + cc = afs_osi_Write(tfile, off, &cellnum, sizeof(cellnum)); + if (cc != sizeof(cellnum)) + break; + off += cc; + + clen = strlen(cn->cellname); + cc = afs_osi_Write(tfile, off, &clen, sizeof(clen)); + if (cc != sizeof(clen)) + break; + off += cc; + + cc = afs_osi_Write(tfile, off, cn->cellname, clen); + if (cc != clen) + break; + off += clen; + } + + osi_UFSClose(tfile); + ReleaseWriteLock(&afs_xcell); + return 0; +} + +/* + * Cell alias implementation + * + * afs_FindCellAlias: look up cell alias by alias name + * afs_GetCellAlias: get cell alias by index (starting at 0) + * afs_PutCellAlias: put back a cell alias returned by Find or Get + * afs_NewCellAlias: create new cell alias entry + */ + +struct cell_alias *afs_cellalias_head; /* Export for kdump */ +static afs_int32 afs_cellalias_index; +static int afs_CellOrAliasExists_nl(char *aname); /* Forward declaration */ + +static struct cell_alias *afs_FindCellAlias(char *alias) +{ + struct cell_alias *tc; + + for (tc = afs_cellalias_head; tc != NULL; tc = tc->next) + if (!strcmp(alias, tc->alias)) + break; + return tc; +} + +struct cell_alias *afs_GetCellAlias(int index) +{ + struct cell_alias *tc; + + ObtainReadLock(&afs_xcell); + for (tc = afs_cellalias_head; tc != NULL; tc = tc->next) + if (tc->index == index) + break; + ReleaseReadLock(&afs_xcell); + + return tc; +} + +void afs_PutCellAlias(struct cell_alias *a) +{ + return; +} + +afs_int32 afs_NewCellAlias(char *alias, char *cell) +{ + struct cell_alias *tc; + + ObtainSharedLock(&afs_xcell, 681); + if (afs_CellOrAliasExists_nl(alias)) { + ReleaseSharedLock(&afs_xcell); + return EEXIST; + } + + UpgradeSToWLock(&afs_xcell, 682); + tc = (struct cell_alias *) afs_osi_Alloc(sizeof(struct cell_alias)); + tc->alias = afs_strdup(alias); + tc->cell = afs_strdup(cell); + tc->next = afs_cellalias_head; + tc->index = afs_cellalias_index++; + afs_cellalias_head = tc; + ReleaseWriteLock(&afs_xcell); + + afs_DynrootInvalidate(); + return 0; +} + +/* + * Actual cell list implementation + * + * afs_UpdateCellLRU: bump given cell up to the front of the LRU queue + * afs_RefreshCell: look up cell information in AFSDB if timeout expired + * + * afs_TraverseCells: execute a callback for each existing cell + * afs_TraverseCells_nl: same as above except without locking afs_xcell + * afs_choose_cell_by_{name,num,index}: useful traversal callbacks + * + * afs_FindCellByName: return a cell with a given name, if it exists + * afs_FindCellByName_nl: same as above, without locking afs_xcell + * afs_GetCellByName: same as FindCellByName but tries AFSDB if not found + * afs_GetCell: return a cell with a given cell number + * afs_GetCellStale: same as GetCell, but does not try to refresh the data + * afs_GetCellByIndex: return a cell with a given index number (starting at 0) + * + * afs_GetPrimaryCell: return the primary cell, if any + * afs_IsPrimaryCell: returns true iff the given cell is the primary cell + * afs_IsPrimaryCellNum: returns afs_IsPrimaryCell(afs_GetCell(cellnum)) + * afs_SetPrimaryCell: set the primary cell name to the given cell name + * + * afs_NewCell: create or update a cell entry + */ + +struct afs_q CellLRU; /* Export for kdump */ +static char *afs_thiscell; +static afs_int32 afs_cellindex; + +static void afs_UpdateCellLRU(struct cell *c) +{ + ObtainWriteLock(&afs_xcell, 100); + QRemove(&c->lruq); + QAdd(&CellLRU, &c->lruq); + ReleaseWriteLock(&afs_xcell); +} + +static void afs_RefreshCell(struct cell *ac) +{ + if (ac->states & CNoAFSDB) + return; + if (!ac->cellHosts[0] || (ac->timeout && ac->timeout <= osi_Time())) + afs_LookupAFSDB(ac->cellName); +} + +static void *afs_TraverseCells_nl(void *(*cb)(struct cell *, void *), void *arg) +{ + struct afs_q *cq, *tq; + struct cell *tc; + void *ret = NULL; + + for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { + tc = QTOC(cq); tq = QNext(cq); + ret = cb(tc, arg); + if (ret) break; + } + + return ret; +} + +void *afs_TraverseCells(void *(*cb)(struct cell *, void *), void *arg) +{ + void *ret; + + ObtainReadLock(&afs_xcell); + ret = afs_TraverseCells_nl(cb, arg); + ReleaseReadLock(&afs_xcell); + + return ret; +} + +static void *afs_choose_cell_by_name(struct cell *cell, void *arg) +{ + return strcmp(cell->cellName, (char *) arg) ? NULL : cell; +} + +static void *afs_choose_cell_by_num(struct cell *cell, void *arg) +{ + return (cell->cellNum == *((afs_int32 *) arg)) ? cell : NULL; +} + +static void *afs_choose_cell_by_index(struct cell *cell, void *arg) +{ + return (cell->cellIndex == *((afs_int32 *) arg)) ? cell : NULL; +} + +static struct cell *afs_FindCellByName_nl(char *acellName, afs_int32 locktype) +{ + return afs_TraverseCells_nl(&afs_choose_cell_by_name, acellName); +} + +static struct cell *afs_FindCellByName(char *acellName, afs_int32 locktype) +{ + return afs_TraverseCells(&afs_choose_cell_by_name, acellName); +} + +struct cell *afs_GetCellByName(char *acellName, afs_int32 locktype) +{ + struct cell *tc; + + tc = afs_FindCellByName(acellName, locktype); + if (!tc) { + afs_LookupAFSDB(acellName); + tc = afs_FindCellByName(acellName, locktype); + } + if (tc) { + afs_cellname_ref(tc->cnamep); + afs_UpdateCellLRU(tc); + afs_RefreshCell(tc); + } + + return tc; +} + +struct cell *afs_GetCell(afs_int32 cellnum, afs_int32 locktype) +{ + struct cell *tc; + struct cell_name *cn; + + tc = afs_GetCellStale(cellnum, locktype); + if (tc) { + afs_RefreshCell(tc); + } else { + ObtainReadLock(&afs_xcell); + cn = afs_cellname_lookup_id(cellnum); + ReleaseReadLock(&afs_xcell); + if (cn) + tc = afs_GetCellByName(cn->cellname, locktype); + } + return tc; +} + +struct cell *afs_GetCellStale(afs_int32 cellnum, afs_int32 locktype) +{ + struct cell *tc; + + tc = afs_TraverseCells(&afs_choose_cell_by_num, &cellnum); + if (tc) { + afs_cellname_ref(tc->cnamep); + afs_UpdateCellLRU(tc); + } + return tc; +} + +struct cell *afs_GetCellByIndex(afs_int32 index, afs_int32 locktype) +{ + struct cell *tc; + + tc = afs_TraverseCells(&afs_choose_cell_by_index, &index); + if (tc) + afs_UpdateCellLRU(tc); + return tc; +} + +struct cell *afs_GetPrimaryCell(afs_int32 locktype) +{ + return afs_GetCellByName(afs_thiscell, locktype); +} + +int afs_IsPrimaryCell(struct cell *cell) +{ + return strcmp(cell->cellName, afs_thiscell) ? 0 : 1; +} + +int afs_IsPrimaryCellNum(afs_int32 cellnum) +{ + struct cell *tc; + int primary = 0; + + tc = afs_GetCellStale(cellnum, READ_LOCK); + if (tc) { + primary = afs_IsPrimaryCell(tc); afs_PutCell(tc, READ_LOCK); } - if (realName) - afs_osi_Free(realName, strlen(realName) + 1); - return afs_GetCellByName2(acellName, locktype, 0); - -bad: - if (realName) - afs_osi_Free(realName, strlen(realName) + 1); - return (struct cell *) 0; + return primary; } - -struct cell *afs_GetCellByName2(acellName, locktype, trydns) - register char *acellName; - afs_int32 locktype; - char trydns; +afs_int32 afs_SetPrimaryCell(char *acellName) { - 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); - if (!afs_strcasecmp(tc->cellName, acellName)) { - QRemove(&tc->lruq); - QAdd(&CellLRU, &tc->lruq); - ReleaseWriteLock(&afs_xcell); - afs_RefreshCell(tc); - if ((tc->states & CAlias) && (didAlias == 0)) { - acellName = tc->realName; - if (!acellName) return (struct cell *) 0; - didAlias = 1; - goto retry; - } - return tc; - } - } + ObtainWriteLock(&afs_xcell, 691); + if (afs_thiscell) + afs_osi_FreeStr(afs_thiscell); + afs_thiscell = afs_strdup(acellName); ReleaseWriteLock(&afs_xcell); - return trydns ? afs_GetCellByName_Dns(acellName, locktype) - : (struct cell *) 0; - -} /*afs_GetCellByName2*/ - - -struct cell *afs_GetCellByName(acellName, locktype) - register char *acellName; - afs_int32 locktype; -{ - return afs_GetCellByName2(acellName, locktype, 1); - -} /*afs_GetCellByName*/ - -static struct cell *afs_GetCellInternal(acell, locktype, holdxcell) - register afs_int32 acell; - afs_int32 locktype; - int holdxcell; -{ - register struct cell *tc; - register struct afs_q *cq, *tq; - - AFS_STATCNT(afs_GetCell); - if (acell == 1 && afs_rootcell) return afs_rootcell; - if (holdxcell) - ObtainWriteLock(&afs_xcell,101); - for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { - tc = QTOC(cq); tq = QNext(cq); - if (tc->cell == acell) { - QRemove(&tc->lruq); - QAdd(&CellLRU, &tc->lruq); - if (holdxcell) - ReleaseWriteLock(&afs_xcell); - afs_RefreshCell(tc); - return tc; - } - } - if (holdxcell) - ReleaseWriteLock(&afs_xcell); - return (struct cell *) 0; - -} /*afs_GetCell*/ - -struct cell *afs_GetCell(acell, locktype) - register afs_int32 acell; - afs_int32 locktype; -{ - return afs_GetCellInternal(acell, locktype, 1); + return 0; } -/* This is only to be called if the caller is already holding afs_xcell */ -struct cell *afs_GetCellNoLock(acell, locktype) - register afs_int32 acell; - afs_int32 locktype; +afs_int32 afs_NewCell(char *acellName, afs_int32 *acellHosts, int aflags, + char *linkedcname, u_short fsport, u_short vlport, int timeout) { - return afs_GetCellInternal(acell, locktype, 0); -} - -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; - - AFS_STATCNT(afs_GetCellByIndex); - ObtainWriteLock(&afs_xcell,102); - for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { - tc = QTOC(cq); tq = QNext(cq); - if (tc->cellIndex == cellindex) { - QRemove(&tc->lruq); - QAdd(&CellLRU, &tc->lruq); - ReleaseWriteLock(&afs_xcell); - if (refresh) afs_RefreshCell(tc); - return tc; - } - } - ReleaseWriteLock(&afs_xcell); - return (struct cell *) 0; - -} /*afs_GetCellByIndex*/ - - -struct cell *afs_GetRealCellByIndex(cellindex, locktype, refresh) - register afs_int32 cellindex; - afs_int32 locktype; - afs_int32 refresh; -{ - register struct cell *tc; - register struct afs_q *cq, *tq; - - AFS_STATCNT(afs_GetCellByIndex); - ObtainWriteLock(&afs_xcell,102); - for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { - tc = QTOC(cq); tq = QNext(cq); - if (tc->realcellIndex == cellindex) { - QRemove(&tc->lruq); - QAdd(&CellLRU, &tc->lruq); - ReleaseWriteLock(&afs_xcell); - if (refresh) afs_RefreshCell(tc); - return tc; - } - } - ReleaseWriteLock(&afs_xcell); - return (struct cell *) 0; -} /*afs_GetRealCellByIndex*/ - - -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; + struct cell *tc, *tcl=0; + afs_int32 i, newc=0, code=0; AFS_STATCNT(afs_NewCell); - if (!(aflags & CAlias) && *acellHosts == 0) - /* need >= one host to gen cell # */ - return EINVAL; - ObtainWriteLock(&afs_xcell,103); + ObtainWriteLock(&afs_xcell, 103); - /* Find the cell and mark its servers as not down but gone */ - for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { - tc = QTOC(cq); tq = QNext(cq); - if (afs_strcasecmp(tc->cellName, acellName) == 0) { - /* if the cell we've found has the correct name but no timeout, - * and we're called with a non-zero timeout, bail out: never - * override static configuration entries with AFSDB ones. */ - if (timeout && !tc->timeout) { - ReleaseWriteLock(&afs_xcell); - return 0; - } - /* we don't want to keep pinging old vlservers which were down, - * since they don't matter any more. It's easier to do this than - * to remove the server from its various hash tables. */ - for (i=0; icellHosts[i]) break; - tc->cellHosts[i]->flags &= ~SRVR_ISDOWN; - tc->cellHosts[i]->flags |= SRVR_ISGONE; - } - break; - } - } - - if (cq != &CellLRU) { + tc = afs_FindCellByName_nl(acellName, READ_LOCK); + if (tc) { aflags &= ~CNoSUID; - } - else { + } 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); - tc->cellIndex = afs_cellindex++; - if (aflags & CPrimary) { - extern int afs_rootCellIndex; - tc->cell = 1; /* primary cell is always 1 */ - afs_rootcell = tc; - afs_rootCellIndex = tc->cellIndex; - } else { - tc->cell = afs_nextCellNum++; - } - tc->states = 0; - tc->lcellp = (struct cell *)0; - tc->fsport = (fsport ? fsport : AFS_FSPORT); - tc->vlport = (vlport ? vlport : AFS_VLPORT); - afs_stats_cmperf.numCellsVisible++; - newc++; - if (!(aflags & CAlias)) { - tc->realcellIndex = afs_realcellindex++; - } else { - tc->realcellIndex = -1; - } + memset((char *) tc, 0, sizeof(*tc)); + tc->cellName = afs_strdup(acellName); + tc->fsport = AFS_FSPORT; + tc->vlport = AFS_VLPORT; + RWLOCK_INIT(&tc->lock, "cell lock"); + newc = 1; + if (afs_thiscell && !strcmp(acellName, afs_thiscell)) + aflags &= ~CNoSUID; } + ObtainWriteLock(&tc->lock, 688); + + /* If the cell we've found has the correct name but no timeout, + * and we're called with a non-zero timeout, bail out: never + * override static configuration entries with AFSDB ones. + * One exception: if the original cell entry had no servers, + * it must get servers from AFSDB. + */ + if (timeout && !tc->timeout && tc->cellHosts[0]) { + code = EINVAL; + goto bad; + } + + /* we don't want to keep pinging old vlservers which were down, + * since they don't matter any more. It's easier to do this than + * to remove the server from its various hash tables. */ + for (i=0; icellHosts[i]) break; + tc->cellHosts[i]->flags &= ~SRVR_ISDOWN; + tc->cellHosts[i]->flags |= SRVR_ISGONE; + } + + if (fsport) tc->fsport = fsport; + if (vlport) tc->vlport = vlport; if (aflags & CLinkedCell) { if (!linkedcname) { code = EINVAL; goto bad; } - for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { - tcl = QTOC(cq); tq = QNext(cq); - if (!afs_strcasecmp(tcl->cellName, linkedcname)) { - break; - } - tcl = 0; - } + tcl = afs_FindCellByName_nl(linkedcname, READ_LOCK); if (!tcl) { code = ENOENT; goto bad; @@ -542,71 +693,154 @@ 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)) { - tc->states &= ~CAlias; - tc->realcellIndex = afs_realcellindex++; - } - memset((char *)tc->cellHosts, 0, sizeof(tc->cellHosts)); - if (aflags & CAlias) { - if (!aliasFor) { - code = EINVAL; - goto bad; - } - 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; - } - for (i=0; ivlport, WRITE_LOCK, (afsUUID *)0, 0); - ts->cell = tc; + ts = afs_GetServer(&temp, 1, 0, tc->vlport, WRITE_LOCK, NULL, 0); + ts->cell = tc; ts->flags &= ~SRVR_ISGONE; tc->cellHosts[i] = ts; afs_PutServer(ts, WRITE_LOCK); } afs_SortServers(tc->cellHosts, MAXCELLHOSTS); /* randomize servers */ -done: + + if (newc) { + struct cell_name *cn; + + cn = afs_cellname_lookup_name(acellName); + if (!cn) + cn = afs_cellname_new(acellName, 0); + + tc->cnamep = cn; + tc->cellNum = cn->cellnum; + tc->cellIndex = afs_cellindex++; + afs_stats_cmperf.numCellsVisible++; + QAdd(&CellLRU, &tc->lruq); + } + + ReleaseWriteLock(&tc->lock); ReleaseWriteLock(&afs_xcell); + afs_PutCell(tc, 0); + afs_DynrootInvalidate(); return 0; + bad: if (newc) { - QRemove(&tc->lruq); - afs_osi_Free(tc->cellName, strlen(tc->cellName)+1); - afs_osi_Free((char *)tc, sizeof(struct cell)); + afs_osi_FreeStr(tc->cellName); + afs_osi_Free(tc, sizeof(struct cell)); } + ReleaseWriteLock(&tc->lock); ReleaseWriteLock(&afs_xcell); return code; - -} /*afs_NewCell*/ - -afs_RemoveCellEntry(struct server *srvp) -{ - struct cell *tc; - afs_int32 j, k; - - tc = srvp->cell; - if (!tc) return; - - /* Remove the server structure from the cell list - if there */ - ObtainWriteLock(&afs_xcell,200); - for (j=k=0; jcellHosts[j]) break; - if (tc->cellHosts[j] != srvp) { - tc->cellHosts[k++] = tc->cellHosts[j]; - } - } - if (k == 0) { - /* What do we do if we remove the last one? */ - } - for (; kcellHosts[k] = 0; - } - ReleaseWriteLock(&afs_xcell); } +/* + * Miscellaneous stuff + * + * afs_CellInit: perform whatever initialization is necessary + * shutdown_cell: called on shutdown, should deallocate memory, etc + * afs_RemoveCellEntry: remove a server from a cell's server list + * afs_CellOrAliasExists: check if the given name exists as a cell or alias + * afs_CellOrAliasExists_nl: same as above without locking afs_xcell + * afs_CellNumValid: check if a cell number is valid (also set the used flag) + */ + +void afs_CellInit() +{ + RWLOCK_INIT(&afs_xcell, "afs_xcell"); +#ifdef AFS_AFSDB_ENV + RWLOCK_INIT(&afsdb_req.lock, "afsdb_req.lock"); +#endif + QInit(&CellLRU); + + afs_cellindex = 0; + afs_cellalias_index = 0; +} + +void shutdown_cell() +{ + struct afs_q *cq, *tq; + struct cell *tc; + + RWLOCK_INIT(&afs_xcell, "afs_xcell"); + + for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { + tc = QTOC(cq); tq = QNext(cq); + if (tc->cellName) afs_osi_FreeStr(tc->cellName); + afs_osi_Free(tc, sizeof(struct cell)); + } + QInit(&CellLRU); +} + +void afs_RemoveCellEntry(struct server *srvp) +{ + struct cell *tc; + afs_int32 j, k; + + tc = srvp->cell; + if (!tc) return; + + /* Remove the server structure from the cell list - if there */ + ObtainWriteLock(&tc->lock, 200); + for (j=k=0; jcellHosts[j]) break; + if (tc->cellHosts[j] != srvp) { + tc->cellHosts[k++] = tc->cellHosts[j]; + } + } + if (k == 0) { + /* What do we do if we remove the last one? */ + } + for (; kcellHosts[k] = 0; + } + ReleaseWriteLock(&tc->lock); +} + +static int afs_CellOrAliasExists_nl(char *aname) +{ + struct cell *c; + struct cell_alias *ca; + + c = afs_FindCellByName_nl(aname, READ_LOCK); + if (c) { + afs_PutCell(c, READ_LOCK); + return 1; + } + + ca = afs_FindCellAlias(aname); + if (ca) { + afs_PutCellAlias(ca); + return 1; + } + + return 0; +} + +int afs_CellOrAliasExists(char *aname) +{ + int ret; + + ObtainReadLock(&afs_xcell); + ret = afs_CellOrAliasExists_nl(aname); + ReleaseReadLock(&afs_xcell); + + return ret; +} + +int afs_CellNumValid(afs_int32 cellnum) +{ + struct cell_name *cn; + + ObtainReadLock(&afs_xcell); + cn = afs_cellname_lookup_id(cellnum); + ReleaseReadLock(&afs_xcell); + if (cn) { + cn->used = 1; + return 1; + } else { + return 0; + } +} diff --git a/src/afs/afs_daemons.c b/src/afs/afs_daemons.c index 5f0d4ea096..89cc498777 100644 --- a/src/afs/afs_daemons.c +++ b/src/afs/afs_daemons.c @@ -265,57 +265,67 @@ void afs_Daemon() { } } -afs_CheckRootVolume () { +int afs_CheckRootVolume (void) { char rootVolName[32]; - register struct volume *tvp; + struct volume *tvp; int usingDynroot = afs_GetDynrootEnable(); + int localcell; AFS_STATCNT(afs_CheckRootVolume); if (*afs_rootVolumeName == 0) { strcpy(rootVolName, "root.afs"); - } - else { + } else { strcpy(rootVolName, afs_rootVolumeName); } - if (usingDynroot) { - afs_GetDynrootFid(&afs_rootFid); - tvp = afs_GetVolume(&afs_rootFid, (struct vrequest *) 0, READ_LOCK); - } else { - tvp = afs_GetVolumeByName(rootVolName, LOCALCELL, 1, (struct vrequest *) 0, READ_LOCK); - } - if (!tvp) { - char buf[128]; - int len = strlen(rootVolName); - if ((len < 9) || strcmp(&rootVolName[len - 9], ".readonly")) { - strcpy(buf, rootVolName); - afs_strcat(buf, ".readonly"); - tvp = afs_GetVolumeByName(buf, LOCALCELL, 1, (struct vrequest *) 0, READ_LOCK); - } + if (!usingDynroot) { + struct cell *lc = afs_GetPrimaryCell(READ_LOCK); + + if (!lc) + return ENOENT; + localcell = lc->cellNum; + afs_PutCell(lc, READ_LOCK); + } + + if (usingDynroot) { + afs_GetDynrootFid(&afs_rootFid); + tvp = afs_GetVolume(&afs_rootFid, NULL, READ_LOCK); + } else { + tvp = afs_GetVolumeByName(rootVolName, localcell, 1, NULL, READ_LOCK); + } + if (!tvp && !usingDynroot) { + char buf[128]; + int len = strlen(rootVolName); + + if ((len < 9) || strcmp(&rootVolName[len - 9], ".readonly")) { + strcpy(buf, rootVolName); + afs_strcat(buf, ".readonly"); + tvp = afs_GetVolumeByName(buf, localcell, 1, NULL, READ_LOCK); + } } if (tvp) { - if (!usingDynroot) { - int volid = (tvp->roVol? tvp->roVol : tvp->volume); - afs_rootFid.Cell = LOCALCELL; - if (afs_rootFid.Fid.Volume && afs_rootFid.Fid.Volume != volid - && afs_globalVp) { - /* If we had a root fid before and it changed location we reset - * the afs_globalVp so that it will be reevaluated. - * Just decrement the reference count. This only occurs during - * initial cell setup and can panic the machine if we set the - * count to zero and fs checkv is executed when the current - * directory is /afs. - */ - AFS_FAST_RELE(afs_globalVp); - afs_globalVp = 0; - } - afs_rootFid.Fid.Volume = volid; - afs_rootFid.Fid.Vnode = 1; - afs_rootFid.Fid.Unique = 1; - } - afs_initState = 300; /* won */ - afs_osi_Wakeup(&afs_initState); - afs_PutVolume(tvp, READ_LOCK); + if (!usingDynroot) { + int volid = (tvp->roVol? tvp->roVol : tvp->volume); + afs_rootFid.Cell = localcell; + if (afs_rootFid.Fid.Volume && afs_rootFid.Fid.Volume != volid + && afs_globalVp) { + /* If we had a root fid before and it changed location we reset + * the afs_globalVp so that it will be reevaluated. + * Just decrement the reference count. This only occurs during + * initial cell setup and can panic the machine if we set the + * count to zero and fs checkv is executed when the current + * directory is /afs. + */ + AFS_FAST_RELE(afs_globalVp); + afs_globalVp = 0; + } + afs_rootFid.Fid.Volume = volid; + afs_rootFid.Fid.Vnode = 1; + afs_rootFid.Fid.Unique = 1; + } + afs_initState = 300; /* won */ + afs_osi_Wakeup(&afs_initState); + afs_PutVolume(tvp, READ_LOCK); } #ifdef AFS_DEC_ENV /* This is to make sure that we update the root gnode */ diff --git a/src/afs/afs_dcache.c b/src/afs/afs_dcache.c index 51fbf981e3..df908d2bfa 100644 --- a/src/afs/afs_dcache.c +++ b/src/afs/afs_dcache.c @@ -2128,7 +2128,7 @@ done: /* * See if this was a reference to a file in the local cell. */ - if (avc->fid.Cell == LOCALCELL) + if (afs_IsPrimaryCellNum(avc->fid.Cell)) afs_stats_cmperf.dlocalAccesses++; else afs_stats_cmperf.dremoteAccesses++; @@ -2297,6 +2297,7 @@ struct dcache *afs_UFSGetDSlot(aslot, tmpdc) register afs_int32 code; register struct dcache *tdc; + int entryok; AFS_STATCNT(afs_UFSGetDSlot); if (CheckLock(&afs_xdcache) != -1) osi_Panic("getdslot nolock"); @@ -2345,9 +2346,16 @@ struct dcache *afs_UFSGetDSlot(aslot, tmpdc) /* * Seek to the aslot'th entry and read it in. */ - code = afs_osi_Read(afs_cacheInodep, sizeof(struct fcache) * aslot + sizeof(struct afs_fheader), - (char *)(&tdc->f), sizeof(struct fcache)); - if (code != sizeof(struct fcache)) { + code = afs_osi_Read(afs_cacheInodep, sizeof(struct fcache) * aslot + + sizeof(struct afs_fheader), + (char *)(&tdc->f), sizeof(struct fcache)); + entryok = 1; + if (code != sizeof(struct fcache)) + entryok = 0; + if (!afs_CellNumValid(tdc->f.fid.Cell)) + entryok = 0; + + if (!entryok) { tdc->f.fid.Cell = 0; tdc->f.fid.Fid.Volume = 0; tdc->f.chunk = -1; @@ -2406,8 +2414,10 @@ afs_WriteDCache(adc, atime) /* * Seek to the right dcache slot and write the in-memory image out to disk. */ - code = afs_osi_Write(afs_cacheInodep, sizeof(struct fcache) * adc->index + sizeof(struct afs_fheader), - (char *)(&adc->f), sizeof(struct fcache)); + afs_cellname_write(); + code = afs_osi_Write(afs_cacheInodep, sizeof(struct fcache) * adc->index + + sizeof(struct afs_fheader), + (char *)(&adc->f), sizeof(struct fcache)); if (code != sizeof(struct fcache)) return EIO; return 0; diff --git a/src/afs/afs_dynroot.c b/src/afs/afs_dynroot.c index 107b3a8bd3..7241166258 100644 --- a/src/afs/afs_dynroot.c +++ b/src/afs/afs_dynroot.c @@ -14,7 +14,7 @@ * afs_IsDynrootFid * afs_GetDynrootFid * afs_IsDynroot - * afs_RefreshDynroot + * afs_DynrootInvalidate * afs_GetDynroot * afs_PutDynroot * afs_DynrootNewVnode @@ -38,7 +38,7 @@ #include "../afs/prs_fs.h" #include "../afs/dir.h" -#define AFS_DYNROOT_CELL 1 +#define AFS_DYNROOT_CELLNAME "dynroot" #define AFS_DYNROOT_VOLUME 1 #define AFS_DYNROOT_VNODE 1 #define AFS_DYNROOT_UNIQUE 1 @@ -48,7 +48,8 @@ * 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 VN_TYPE_ALIAS 0x02 /* Corresponds to a struct cell_alias */ +#define VN_TYPE_SYMLINK 0x03 /* User-created symlink in /afs */ #define VNUM_TO_VNTYPE(vnum) ((vnum) >> 24) #define VNUM_TO_VNID(vnum) ((vnum) & 0x00ffffff) @@ -59,15 +60,19 @@ #define VNUM_FROM_CIDX_RW(cidx, rw) \ VNUM_FROM_TYPEID(VN_TYPE_CELL, \ ((cidx) << 2 | (rw) << 1)) +#define VNUM_FROM_CAIDX_RW(caidx, rw) \ + VNUM_FROM_TYPEID(VN_TYPE_ALIAS, \ + ((caidx) << 2 | (rw) << 1)) static int afs_dynrootEnable = 0; +static int afs_dynrootCell = 0; static afs_rwlock_t afs_dynrootDirLock; /* Start of variables protected by afs_dynrootDirLock */ static char *afs_dynrootDir = NULL; static int afs_dynrootDirLen; static int afs_dynrootDirLinkcnt; -static int afs_dynrootCellCount; +static int afs_dynrootDirVersion; static int afs_dynrootVersion = 1; static int afs_dynrootVersionHigh = 1; /* End of variables protected by afs_dynrootDirLock */ @@ -89,6 +94,30 @@ static int afs_dynSymlinkIndex = 0; extern afs_int32 afs_cellindex; extern afs_rwlock_t afs_xvcache; +/* + * Set up a cell for dynroot if it's not there yet. + */ +static int afs_dynrootCellInit() +{ + if (afs_dynrootEnable && !afs_dynrootCell) { + afs_int32 cellHosts[MAXCELLHOSTS]; + struct cell *tc; + int code; + + memset(cellHosts, 0, sizeof(cellHosts)); + code = afs_NewCell(AFS_DYNROOT_CELLNAME, cellHosts, CNoSUID | CNoAFSDB, + NULL, 0, 0, 0); + if (code) + return code; + tc = afs_GetCellByName(AFS_DYNROOT_CELLNAME, READ_LOCK); + if (!tc) + return ENODEV; + afs_dynrootCell = tc->cellNum; + afs_PutCell(tc, READ_LOCK); + } + return 0; +} + /* * Returns non-zero iff fid corresponds to the top of the dynroot volume. */ @@ -97,7 +126,7 @@ afs_IsDynrootFid(struct VenusFid *fid) { return (afs_dynrootEnable && - fid->Cell == AFS_DYNROOT_CELL && + fid->Cell == afs_dynrootCell && fid->Fid.Volume == AFS_DYNROOT_VOLUME && fid->Fid.Vnode == AFS_DYNROOT_VNODE && fid->Fid.Unique == AFS_DYNROOT_UNIQUE); @@ -109,7 +138,7 @@ afs_IsDynrootFid(struct VenusFid *fid) void afs_GetDynrootFid(struct VenusFid *fid) { - fid->Cell = AFS_DYNROOT_CELL; + fid->Cell = afs_dynrootCell; fid->Fid.Volume = AFS_DYNROOT_VOLUME; fid->Fid.Vnode = AFS_DYNROOT_VNODE; fid->Fid.Unique = AFS_DYNROOT_UNIQUE; @@ -213,32 +242,61 @@ afs_dynroot_addDirEnt(dirHeader, curPageP, curChunkP, name, vnode) *curChunkP = curChunk; } +/* + * Invalidate the /afs vnode for dynroot; called when the underlying + * directory has changed and needs to be re-read. + */ +void afs_DynrootInvalidate(void) +{ + afs_int32 retry; + struct vcache *tvc; + struct VenusFid tfid; + + if (!afs_dynrootEnable) + return; + + ObtainWriteLock(&afs_dynrootDirLock, 687); + afs_dynrootVersion++; + afs_dynrootVersionHigh = osi_Time(); + ReleaseWriteLock(&afs_dynrootDirLock); + + afs_GetDynrootFid(&tfid); + do { + retry = 0; + ObtainReadLock(&afs_xvcache); + tvc = afs_FindVCache(&tfid, 0, 0, &retry, 0); + ReleaseReadLock(&afs_xvcache); + } while (retry); + if (tvc) { + tvc->states &= ~(CStatd | CUnique); + osi_dnlc_purgedp(tvc); + afs_PutVCache(tvc); + } +} + /* * Regenerates the dynroot contents from the current list of * cells. Useful when the list of cells has changed due to * an AFSDB lookup, for instance. */ -void -afs_RefreshDynroot() +static void afs_RebuildDynroot(void) { int cellidx, maxcellidx, i; + int aliasidx, maxaliasidx; struct cell *c; + struct cell_alias *ca; int curChunk, curPage; int dirSize, sizeOfCurEntry, dotLen; char *newDir, *dotCell; struct DirHeader *dirHeader; - struct PageHeader *pageHeader; struct DirEntry *dirEntry; - int doFlush = 0; int linkCount = 0; struct afs_dynSymlink *ts; - int newCellCount; + int newVersion; - /* - * Save afs_cellindex here, in case it changes between the - * two loops. - */ - maxcellidx = afs_cellindex; + ObtainReadLock(&afs_dynrootDirLock); + newVersion = afs_dynrootVersion; + ReleaseReadLock(&afs_dynrootDirLock); /* * Compute the amount of space we need for the fake dir @@ -249,9 +307,10 @@ afs_RefreshDynroot() /* Reserve space for "." and ".." */ curChunk += 2; - for (cellidx = 0; cellidx < maxcellidx; cellidx++) { - c = afs_GetCellByIndex(cellidx, READ_LOCK, 0 /* don't refresh */); - if (!c) continue; + for (cellidx = 0; ; cellidx++) { + c = afs_GetCellByIndex(cellidx, READ_LOCK); + if (!c) break; + if (c->cellNum == afs_dynrootCell) continue; sizeOfCurEntry = afs_dir_NameBlobs(c->cellName); if (curChunk + sizeOfCurEntry > EPP) { @@ -274,6 +333,32 @@ afs_RefreshDynroot() afs_osi_Free(dotCell, dotLen); afs_PutCell(c, READ_LOCK); } + maxcellidx = cellidx; + + for (aliasidx = 0; ; aliasidx++) { + ca = afs_GetCellAlias(aliasidx); + if (!ca) break; + + sizeOfCurEntry = afs_dir_NameBlobs(ca->alias); + if (curChunk + sizeOfCurEntry > EPP) { + curPage++; + curChunk = 1; + } + curChunk += sizeOfCurEntry; + + dotCell = afs_osi_Alloc(strlen(ca->alias) + 2); + strcpy(dotCell, "."); + strcat(dotCell, ca->alias); + sizeOfCurEntry = afs_dir_NameBlobs(dotCell); + if (curChunk + sizeOfCurEntry > EPP) { + curPage++; + curChunk = 1; + } + curChunk += sizeOfCurEntry; + + afs_PutCellAlias(ca); + } + maxaliasidx = aliasidx; ObtainReadLock(&afs_dynSymlinkLock); ts = afs_dynSymlinkBase; @@ -317,8 +402,9 @@ afs_RefreshDynroot() linkCount += 2; for (cellidx = 0; cellidx < maxcellidx; cellidx++) { - c = afs_GetCellByIndex(cellidx, READ_LOCK, 0 /* don't refresh */); + c = afs_GetCellByIndex(cellidx, READ_LOCK); if (!c) continue; + if (c->cellNum == afs_dynrootCell) continue; dotLen = strlen(c->cellName) + 2; dotCell = afs_osi_Alloc(dotLen); @@ -329,12 +415,26 @@ afs_RefreshDynroot() afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, dotCell, VNUM_FROM_CIDX_RW(cellidx, 1)); - if (!(c->states & CAlias)) linkCount += 2; + linkCount += 2; afs_osi_Free(dotCell, dotLen); afs_PutCell(c, READ_LOCK); } + for (aliasidx = 0; aliasidx < maxaliasidx; aliasidx++) { + ca = afs_GetCellAlias(aliasidx); + if (!ca) continue; + + dotCell = afs_osi_Alloc(strlen(ca->alias) + 2); + strcpy(dotCell, "."); + strcat(dotCell, ca->alias); + afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, + ca->alias, VNUM_FROM_CAIDX_RW(aliasidx, 0)); + afs_dynroot_addDirEnt(dirHeader, &curPage, &curChunk, + dotCell, VNUM_FROM_CAIDX_RW(aliasidx, 1)); + afs_PutCellAlias(ca); + } + ts = afs_dynSymlinkBase; while (ts) { int vnum = VNUM_FROM_TYPEID(VN_TYPE_SYMLINK, ts->index); @@ -343,7 +443,6 @@ afs_RefreshDynroot() ts = ts->next; } - newCellCount = maxcellidx + afs_dynSymlinkIndex; ReleaseReadLock(&afs_dynSymlinkLock); ObtainWriteLock(&afs_dynrootDirLock, 549); @@ -351,51 +450,21 @@ afs_RefreshDynroot() afs_dynrootDir = newDir; afs_dynrootDirLen = dirSize; afs_dynrootDirLinkcnt = linkCount; - if (afs_dynrootCellCount != newCellCount) { - /* - * New cells/symlinks added -- bump data version, invalidate vcache. - */ - afs_dynrootCellCount = newCellCount; - afs_dynrootVersion++; - afs_dynrootVersionHigh = osi_Time(); - doFlush = 1; - } + afs_dynrootVersion = newVersion; ReleaseWriteLock(&afs_dynrootDirLock); - - if (doFlush) { - afs_int32 retry; - struct vcache *tvc; - struct VenusFid tfid; - - afs_GetDynrootFid(&tfid); - do { - retry = 0; - ObtainReadLock(&afs_xvcache); - tvc = afs_FindVCache(&tfid, 0, 0, &retry, 0); - ReleaseReadLock(&afs_xvcache); - } while (retry); - if (tvc) { - tvc->states &= ~(CStatd | CUnique); - osi_dnlc_purgedp(tvc); - afs_PutVCache(tvc); - } - } } /* * Returns a pointer to the base of the dynroot directory in memory, * length thereof, and a FetchStatus. */ -void -afs_GetDynroot(dynrootDir, dynrootLen, status) - char **dynrootDir; - int *dynrootLen; - struct AFSFetchStatus *status; +void afs_GetDynroot(char **dynrootDir, int *dynrootLen, + struct AFSFetchStatus *status) { ObtainReadLock(&afs_dynrootDirLock); - if (!afs_dynrootDir) { + if (!afs_dynrootDir || afs_dynrootDirVersion != afs_dynrootVersion) { ReleaseReadLock(&afs_dynrootDirLock); - afs_RefreshDynroot(); + afs_RebuildDynroot(); ObtainReadLock(&afs_dynrootDirLock); } @@ -447,10 +516,11 @@ afs_DynrootNewVnode(avc, status) /* * Check if this is an entry under /afs, e.g. /afs/cellname. */ - if (avc->fid.Cell == AFS_DYNROOT_CELL && + if (avc->fid.Cell == afs_dynrootCell && avc->fid.Fid.Volume == AFS_DYNROOT_VOLUME) { struct cell *c; + struct cell_alias *ca; int namelen, linklen, cellidx, rw; memset(status, 0, sizeof(struct AFSFetchStatus)); @@ -487,7 +557,8 @@ afs_DynrootNewVnode(avc, status) return ts ? 1 : 0; } - if (VNUM_TO_VNTYPE(avc->fid.Fid.Vnode) != VN_TYPE_CELL) { + if (VNUM_TO_VNTYPE(avc->fid.Fid.Vnode) != VN_TYPE_CELL && + VNUM_TO_VNTYPE(avc->fid.Fid.Vnode) != VN_TYPE_ALIAS) { afs_warn("dynroot vnode inconsistency, unknown VNTYPE %d\n", VNUM_TO_VNTYPE(avc->fid.Fid.Vnode)); return 0; @@ -496,26 +567,26 @@ afs_DynrootNewVnode(avc, status) 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; - } + if (VNUM_TO_VNTYPE(avc->fid.Fid.Vnode) == VN_TYPE_ALIAS) { + char *realName; + + ca = afs_GetCellAlias(cellidx); + if (!ca) { + afs_warn("dynroot vnode inconsistency, can't find alias %d\n", + cellidx); + return 0; + } - if (c->states & CAlias) { /* * linkData needs to contain the name of the cell * we're aliasing for. */ - char *realName = c->realName; - + realName = ca->cell; if (!realName) { afs_warn("dynroot: alias %s missing real cell name\n", - c->cellName); + ca->alias); + avc->linkData = afs_strdup("unknown"); linklen = 7; - avc->linkData = afs_osi_Alloc(linklen + 1); - strcpy(avc->linkData, "unknown"); } else { int namelen = strlen(realName); linklen = rw + namelen; @@ -525,7 +596,15 @@ afs_DynrootNewVnode(avc, status) } status->UnixModeBits = 0755; + afs_PutCellAlias(ca); } else { + c = afs_GetCellByIndex(cellidx, READ_LOCK); + if (!c) { + afs_warn("dynroot vnode inconsistency, can't find cell %d\n", + cellidx); + return 0; + } + /* * linkData needs to contain "#cell:root.cell" or "%cell:root.cell" */ @@ -537,10 +616,10 @@ afs_DynrootNewVnode(avc, status) strcat(avc->linkData, ":root.cell"); status->UnixModeBits = 0644; + afs_PutCell(c, READ_LOCK); } status->Length = linklen; - afs_PutCell(c, READ_LOCK); return 1; } @@ -555,7 +634,7 @@ afs_SetDynrootEnable(enable) int enable; { afs_dynrootEnable = enable; - return 0; + return afs_dynrootCellInit(); } /* @@ -571,14 +650,11 @@ afs_GetDynrootEnable() * Remove a temporary symlink entry from /afs. */ int -afs_DynrootVOPRemove(avc, acred, aname) - struct vcache *avc; - struct AFS_UCRED *acred; - char *aname; +afs_DynrootVOPRemove(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) @@ -601,18 +677,14 @@ afs_DynrootVOPRemove(avc, acred, aname) } ReleaseWriteLock(&afs_dynSymlinkLock); if (found) { - afs_RefreshDynroot(); + afs_DynrootInvalidate(); 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); + if (afs_CellOrAliasExists(aname)) return EROFS; - } else { + else return ENOENT; - } } /* @@ -626,17 +698,12 @@ afs_DynrootVOPSymlink(avc, acred, aname, atargetName) 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; - } + if (afs_CellOrAliasExists(aname)) + return EEXIST; /* Check if it's already a symlink */ ObtainWriteLock(&afs_dynSymlinkLock, 91); @@ -660,6 +727,6 @@ afs_DynrootVOPSymlink(avc, acred, aname, atargetName) afs_dynSymlinkBase = tps; ReleaseWriteLock(&afs_dynSymlinkLock); - afs_RefreshDynroot(); + afs_DynrootInvalidate(); return 0; } diff --git a/src/afs/afs_init.c b/src/afs/afs_init.c index 7f830f2459..5c64eb051f 100644 --- a/src/afs/afs_init.c +++ b/src/afs/afs_init.c @@ -312,36 +312,50 @@ afs_ComputeCacheParms() * WARNING: Data will be written to this file over time by AFS. */ -afs_InitVolumeInfo(afile) - register char *afile; - -{ /*afs_InitVolumeInfo*/ - +static int LookupInodeByPath(char *filename, ino_t *inode) +{ afs_int32 code; - struct osi_file *tfile; - struct vnode *filevp; - struct fcache fce; - - AFS_STATCNT(afs_InitVolumeInfo); + #ifdef AFS_LINUX22_ENV - { - struct dentry *dp; - code = gop_lookupname(afile, AFS_UIOSYS, 0, (struct vnode **) 0, &dp); - if (code) return ENOENT; - fce.inode = volumeInode = dp->d_inode->i_ino; - dput(dp); - } + struct dentry *dp; + code = gop_lookupname(filename, AFS_UIOSYS, 0, NULL, &dp); + if (code) return code; + *inode = dp->d_inode->i_ino; + dput(dp); #else - code = gop_lookupname(afile, AFS_UIOSYS, 0, (struct vnode **) 0, &filevp); - if (code) return ENOENT; - fce.inode = volumeInode = afs_vnodeToInumber(filevp); + struct vnode *filevp; + code = gop_lookupname(filename, AFS_UIOSYS, 0, NULL, &filevp); + if (code) return code; + *inode = afs_vnodeToInumber(filevp); #ifdef AFS_DEC_ENV grele(filevp); #else AFS_RELE((struct vnode *)filevp); #endif #endif /* AFS_LINUX22_ENV */ - tfile = afs_CFileOpen(fce.inode); + + return 0; + } + +int afs_InitCellInfo(char *afile) +{ + ino_t inode; + int code; + + code = LookupInodeByPath(afile, &inode); + return afs_cellname_init(inode, code); +} + +int afs_InitVolumeInfo(char *afile) +{ + int code; + struct osi_file *tfile; + struct vnode *filevp; + + AFS_STATCNT(afs_InitVolumeInfo); + code = LookupInodeByPath(afile, &volumeInode); + if (code) return code; + tfile = afs_CFileOpen(volumeInode); afs_CFileTruncate(tfile, 0); afs_CFileClose(tfile); return 0; @@ -521,7 +535,6 @@ afs_ResourceInit(preallocs) AFS_STATCNT(afs_ResourceInit); RWLOCK_INIT(&afs_xuser, "afs_xuser"); RWLOCK_INIT(&afs_xvolume, "afs_xvolume"); - RWLOCK_INIT(&afs_xcell, "afs_xcell"); RWLOCK_INIT(&afs_xserver, "afs_xserver"); RWLOCK_INIT(&afs_xsrvAddr, "afs_xsrvAddr"); RWLOCK_INIT(&afs_icl_lock, "afs_icl_lock"); @@ -533,6 +546,7 @@ afs_ResourceInit(preallocs) LOCK_INIT(&osi_flplock, "osi_flplock"); RWLOCK_INIT(&afs_xconn, "afs_xconn"); + afs_CellInit(); afs_InitCBQueue(1); /* initialize callback queues */ if (afs_resourceinit_flag == 0) { @@ -544,7 +558,6 @@ afs_ResourceInit(preallocs) afs_sysname = afs_sysnamelist[0]; strcpy(afs_sysname, SYS_NAME); afs_sysnamecount = 1; - QInit(&CellLRU); #if defined(AFS_AIX32_ENV) || defined(AFS_HPUX_ENV) { extern afs_int32 afs_preallocs; @@ -750,19 +763,6 @@ void shutdown_AFS() AFS_STATCNT(shutdown_AFS); if (afs_cold_shutdown) { afs_resourceinit_flag = 0; - /* - * Free Cells table allocations - */ - { - struct cell *tc; - register struct afs_q *cq, *tq; - for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { - tc = QTOC(cq); tq = QNext(cq); - if (tc->cellName) - afs_osi_Free(tc->cellName, strlen(tc->cellName)+1); - afs_osi_Free(tc, sizeof(struct cell)); - } - } /* * Free Volumes table allocations */ @@ -859,19 +859,16 @@ void shutdown_AFS() afs_sysname = 0; afs_sysnamecount = 0; afs_marinerHost = 0; - QInit(&CellLRU); afs_setTimeHost = (struct server *)0; afs_volCounter = 1; afs_waitForever = afs_waitForeverCount = 0; - afs_cellindex = 0; - afs_nextCellNum = 0x100; afs_FVIndex = -1; afs_server = (struct rx_service *)0; RWLOCK_INIT(&afs_xconn, "afs_xconn"); memset((char *)&afs_rootFid, 0, sizeof(struct VenusFid)); RWLOCK_INIT(&afs_xuser, "afs_xuser"); RWLOCK_INIT(&afs_xvolume, "afs_xvolume"), RWLOCK_INIT(&afs_xcell, "afs_xcell"); - RWLOCK_INIT(&afs_xserver, "afs_xserver"), LOCK_INIT(&afs_puttofileLock, "afs_puttofileLock"); + shutdown_cell(); } } /*shutdown_AFS*/ diff --git a/src/afs/afs_osi_vget.c b/src/afs/afs_osi_vget.c index 873f24ffbd..301ac5f7aa 100644 --- a/src/afs/afs_osi_vget.c +++ b/src/afs/afs_osi_vget.c @@ -22,8 +22,6 @@ RCSID("$Header$"); -extern int afs_NFSRootOnly; -int afs_rootCellIndex = 0; #if !defined(AFS_LINUX20_ENV) /* This is the common part of the vget VFS call. */ int afs_osi_vget(struct vcache **avcpp, struct fid *afidp, @@ -31,7 +29,6 @@ int afs_osi_vget(struct vcache **avcpp, struct fid *afidp, { struct VenusFid vfid; struct SmallFid Sfid; - extern struct cell *afs_GetCellByIndex(); register struct cell *tcell; struct vrequest treq; register afs_int32 code = 0, cellindex; @@ -41,31 +38,19 @@ int afs_osi_vget(struct vcache **avcpp, struct fid *afidp, #ifdef AFS_OSF_ENV Sfid.Vnode = afidp->fid_reserved; #endif - if (afs_NFSRootOnly && - Sfid.Volume == afs_rootFid.Fid.Volume && - Sfid.Vnode == afs_rootFid.Fid.Vnode && - (Sfid.CellAndUnique & 0xffffff) == - (afs_rootFid.Fid.Unique & 0xffffff) && - ((Sfid.CellAndUnique >> 24) & 0xff) == afs_rootCellIndex) { - vfid = afs_rootFid; - } - else { - /* Need to extract fid from SmallFid. Will need a wild card option for - * finding the right vcache entry. - */ - struct cell *tcell; - cellindex = (Sfid.CellAndUnique >> 24) & 0xff; - tcell = afs_GetCellByIndex(cellindex, READ_LOCK, 0 /* don't refresh */); - if (!tcell) { - return ENOENT; - } - vfid.Cell = tcell->cell; - afs_PutCell(tcell, WRITE_LOCK); - vfid.Fid.Volume = Sfid.Volume; - vfid.Fid.Vnode = Sfid.Vnode; - vfid.Fid.Unique = Sfid.CellAndUnique & 0xffffff; - } + /* Need to extract fid from SmallFid. Will need a wild card option for + * finding the right vcache entry. + */ + cellindex = (Sfid.CellAndUnique >> 24) & 0xff; + tcell = afs_GetCellByIndex(cellindex, READ_LOCK); + if (!tcell) + return ENOENT; + vfid.Cell = tcell->cellNum; + afs_PutCell(tcell, WRITE_LOCK); + vfid.Fid.Volume = Sfid.Volume; + vfid.Fid.Vnode = Sfid.Vnode; + vfid.Fid.Unique = Sfid.CellAndUnique & 0xffffff; /* First attempt to find in cache using wildcard. If that fails, * try the usual route to try to get the vcache from the server. diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index 3bae148639..1b8912454d 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -1327,39 +1327,29 @@ static PGCPAGs(avc, afun, areq, ain, aout, ainSize, aoutSize, acred) return 0; } - static PGetWSCell(avc, afun, areq, ain, aout, ainSize, aoutSize) - struct vcache *avc; - int afun; - struct vrequest *areq; - register char *ain; - char *aout; - afs_int32 ainSize; - afs_int32 *aoutSize; /* set this */ { - register struct cell *tcell=0, *cellOne=0; - register struct afs_q *cq, *tq; +static PGetWSCell(avc, afun, areq, ain, aout, ainSize, aoutSize) + struct vcache *avc; + int afun; + struct vrequest *areq; + register char *ain; + char *aout; + afs_int32 ainSize; + afs_int32 *aoutSize; /* set this */ +{ + struct cell *tcell = NULL; AFS_STATCNT(PGetWSCell); if ( !afs_resourceinit_flag ) /* afs deamons havn't started yet */ return EIO; /* Inappropriate ioctl for device */ - ObtainReadLock(&afs_xcell); - cellOne = (struct cell *) 0; - - for (cq = CellLRU.next; cq != &CellLRU; cq = tq) { - tcell = QTOC(cq); tq = QNext(cq); - if (tcell->states & CPrimary) break; - if (tcell->cell == 1) cellOne = tcell; - tcell = 0; - } - ReleaseReadLock(&afs_xcell); - if (!tcell) { /* no primary cell, use cell #1 */ - if (!cellOne) return ESRCH; - tcell = cellOne; - } + tcell = afs_GetPrimaryCell(READ_LOCK); + if (!tcell) /* no primary cell? */ + return ESRCH; strcpy(aout, tcell->cellName); *aoutSize = strlen(aout) + 1; + afs_PutCell(tcell, READ_LOCK); return 0; - } +} static PGetUserCell(avc, afun, areq, ain, aout, ainSize, aoutSize) struct vcache *avc; @@ -1454,20 +1444,15 @@ static PGCPAGs(avc, afun, areq, ain, aout, ainSize, aoutSize, acred) set_parent_pag = 1; } tcell = afs_GetCellByName(ain, READ_LOCK); - if (tcell) { - i = tcell->cell; - } - else { - goto nocell; - } - } - else { - /* default to cell 1, primary id */ - flag = 1; /* primary id */ - i = 1; /* cell number */ - tcell = afs_GetCell(1, READ_LOCK); if (!tcell) goto nocell; } + else { + /* default to primary cell, primary id */ + flag = 1; /* primary id */ + tcell = afs_GetPrimaryCell(READ_LOCK); + if (!tcell) goto nocell; + } + i = tcell->cellNum; afs_PutCell(tcell, READ_LOCK); if (set_parent_pag) { int pag; @@ -1818,7 +1803,7 @@ static PGetTokens(avc, afun, areq, ain, aout, ainSize, aoutSize) } } else { - if (tu->uid == areq->uid && tu->cell == 1) break; + if (tu->uid == areq->uid && afs_IsPrimaryCellNum(tu->cell)) break; } } if (tu) { @@ -2003,7 +1988,7 @@ static PCheckServers(avc, afun, areq, ain, aout, ainSize, aoutSize, acred) else cellp = (struct cell *) 0; if (!cellp && (temp & 2)) { /* use local cell */ - cellp = afs_GetCell(1, READ_LOCK); + cellp = afs_GetPrimaryCell(READ_LOCK); } if (!(temp & 1)) { /* if not fast, call server checker routine */ afs_CheckServers(1, cellp); /* check down servers */ @@ -2342,7 +2327,7 @@ static PNewCell(avc, afun, areq, ain, aout, ainSize, aoutSize, acred) } linkedstate |= CNoSUID; /* setuid is disabled by default for fs newcell */ - code = afs_NewCell(newcell, cellHosts, linkedstate, linkedcell, fsport, vlport, (int)0, (char *) 0); + code = afs_NewCell(newcell, cellHosts, linkedstate, linkedcell, fsport, vlport, (int)0); return code; } @@ -2357,11 +2342,9 @@ static PNewAlias(avc, afun, areq, ain, aout, ainSize, aoutSize, 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 */ @@ -2373,22 +2356,7 @@ static PNewAlias(avc, afun, areq, ain, aout, ainSize, aoutSize, acred) 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); + code = afs_NewCellAlias(aliasName, realName); *aoutSize = 0; return code; } @@ -2404,7 +2372,6 @@ static PListCells(avc, afun, areq, ain, aout, ainSize, aoutSize) register struct cell *tcell=0; register afs_int32 i; register char *cp, *tp = ain; - register struct afs_q *cq, *tq; AFS_STATCNT(PListCells); if ( !afs_resourceinit_flag ) /* afs deamons havn't started yet */ @@ -2412,7 +2379,7 @@ static PListCells(avc, afun, areq, ain, aout, ainSize, aoutSize) memcpy((char *)&whichCell, tp, sizeof(afs_int32)); tp += sizeof(afs_int32); - tcell = afs_GetRealCellByIndex(whichCell, READ_LOCK, 0); + tcell = afs_GetCellByIndex(whichCell, READ_LOCK); if (tcell) { cp = aout; memset(cp, 0, MAXCELLHOSTS * sizeof(afs_int32)); @@ -2425,6 +2392,7 @@ static PListCells(avc, afun, areq, ain, aout, ainSize, aoutSize) strcpy(cp, tcell->cellName); cp += strlen(tcell->cellName)+1; *aoutSize = cp - aout; + afs_PutCell(tcell, READ_LOCK); } if (tcell) return 0; else return EDOM; @@ -2439,9 +2407,8 @@ static PListAliases(avc, afun, areq, ain, aout, ainSize, aoutSize) afs_int32 *aoutSize; /* set this */ { afs_int32 whichAlias; - register struct cell *tcell=0; + register struct cell_alias *tcalias=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 */ @@ -2451,27 +2418,17 @@ static PListAliases(avc, afun, areq, ain, aout, ainSize, aoutSize) 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) { + tcalias = afs_GetCellAlias(whichAlias); + if (tcalias) { cp = aout; - strcpy(cp, tcell->cellName); - cp += strlen(tcell->cellName)+1; - strcpy(cp, tcell->realName); - cp += strlen(tcell->realName)+1; + strcpy(cp, tcalias->alias); + cp += strlen(tcalias->alias)+1; + strcpy(cp, tcalias->cell); + cp += strlen(tcalias->cell)+1; *aoutSize = cp - aout; + afs_PutCellAlias(tcalias); } - ReleaseReadLock(&afs_xcell); - if (tcell) return 0; + if (tcalias) return 0; else return EDOM; } @@ -2956,10 +2913,22 @@ register struct AFS_UCRED *acred; * fine. Should consider special-casing the local cell for large n. * Likewise for PSetSPrefs. */ -static void ReSortCells(s,l, vlonly) - int s; /* number of ids in array l[] -- NOT index of last id */ - afs_int32 l[]; /* array of cell ids which have volumes that need to be sorted */ - int vlonly; /* sort vl servers or file servers?*/ +static void *ReSortCells_cb(struct cell *cell, void *arg) +{ + afs_int32 *p = (afs_int32 *) arg; + afs_int32 *l = p + 1; + int i, s = p[0]; + + for (i=0; icellNum) { + ObtainWriteLock(&cell->lock, 690); + afs_SortServers(cell->cellHosts, MAXCELLHOSTS); + ReleaseWriteLock(&cell->lock); + } + } +} + +static void ReSortCells(int s, afs_int32 *l, int vlonly) { extern struct volume *afs_volumes[NVOLS]; /* volume hash table */ @@ -2968,15 +2937,12 @@ static void ReSortCells(s,l, vlonly) register int k; if (vlonly) { - struct cell *tcell; - ObtainWriteLock(&afs_xcell,300); - for(k=0;kcellHosts, MAXCELLHOSTS); - afs_PutCell(tcell, WRITE_LOCK); - } - ReleaseWriteLock(&afs_xcell); + afs_int32 *p; + p = (afs_int32 *) afs_osi_Alloc(sizeof(afs_int32) * (s+1)); + p[0] = s; + memcpy(p+1, l, s * sizeof(afs_int32)); + afs_TraverseCells(&ReSortCells_cb, p); + afs_osi_Free(p, sizeof(afs_int32) * (s+1)); return; } @@ -3038,10 +3004,10 @@ static int afs_setsprefs(sp, num, vlonly) if (srvr->cell) { /* if we don't know yet what cell it's in, this is moot */ - for (j=touchedSize-1; j>=0 && touched[j] != srvr->cell->cell; j--) + for (j=touchedSize-1; j>=0 && touched[j] != srvr->cell->cellNum; j--) /* is it in our list of touched cells ? */ ; if (j < 0) { /* no, it's not */ - touched[touchedSize++] = srvr->cell->cell; + touched[touchedSize++] = srvr->cell->cellNum; if (touchedSize >= 32) { /* watch for ovrflow */ ReleaseReadLock(&afs_xserver); ReSortCells(touchedSize, touched, vlonly); diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 2bbfc9eb8c..52162ece77 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -18,9 +18,32 @@ extern int afs_Analyze(struct conn *aconn, afs_int32 acode, struct VenusFid *afi struct cell *cellp); /* afs_cell.c */ -extern struct cell *afs_GetRealCellByIndex(register afs_int32 cellindex, - afs_int32 locktype, - afs_int32 refresh); +extern afs_rwlock_t afs_xcell; +extern void afs_CellInit(void); +extern void shutdown_cell(void); +extern int afs_cellname_init(ino_t inode, int lookupcode); +extern int afs_cellname_write(); +extern afs_int32 afs_NewCell(char *acellName, afs_int32 *acellHosts, + int aflags, char *linkedcname, u_short fsport, + u_short vlport, int timeout); +extern afs_int32 afs_SetPrimaryCell(char *acellName); +extern struct cell *afs_GetCell(afs_int32 acell, afs_int32 locktype); +extern struct cell *afs_GetCellStale(afs_int32 acell, afs_int32 locktype); +extern struct cell *afs_GetCellByIndex(afs_int32 cellidx, afs_int32 locktype); +extern struct cell *afs_GetCellByName(char *acellName, afs_int32 locktype); +extern struct cell *afs_GetPrimaryCell(afs_int32 locktype); +extern int afs_IsPrimaryCellNum(afs_int32 cellnum); +extern int afs_IsPrimaryCell(struct cell *cell); +extern void *afs_TraverseCells(void *(*cb)(struct cell *, void *), void *arg); +extern int afs_CellOrAliasExists(char *aname); +extern int afs_CellNumValid(afs_int32 cellnum); +extern afs_int32 afs_NewCellAlias(char *alias, char *cell); +extern struct cell_alias *afs_GetCellAlias(int index); +extern int afs_AFSDBHandler(char *acellName, int acellNameLen, + afs_int32 *kernelMsg); +extern void afs_LookupAFSDB(char *acellName); +extern void afs_StopAFSDB(void); +extern void afs_RemoveCellEntry(struct server *srvp); /* afs_conn.c */ extern struct conn *afs_ConnBySA(struct srvAddr *sap, unsigned short aport, @@ -28,6 +51,7 @@ extern struct conn *afs_ConnBySA(struct srvAddr *sap, unsigned short aport, int force_if_down, afs_int32 create, afs_int32 locktype); /* afs_dcache.c */ +extern int cacheDiskType; extern void afs_dcacheInit(int afiles, int ablocks, int aDentries, int achunk, int aflags); @@ -84,6 +108,7 @@ extern void afs_GCPAGs_perproc_func(AFS_PROC *pproc); /* afs_util.c */ extern char *afs_cv2string(char *ttp, afs_uint32 aval); +extern int afs_strcasecmp(char *s1, char *s2); extern char *afs_strchr(char *s, int c); extern void print_internet_address(char *preamble, struct srvAddr *sa, char *postamble, int flag); diff --git a/src/afs/afs_server.c b/src/afs/afs_server.c index b8019a46a3..785891dac3 100644 --- a/src/afs/afs_server.c +++ b/src/afs/afs_server.c @@ -90,6 +90,26 @@ int afs_totalSrvAddrs = 0; +static struct afs_stats_SrvUpDownInfo * +GetUpDownStats(struct server *srv) +{ + struct afs_stats_SrvUpDownInfo *upDownP; + u_short fsport = AFS_FSPORT; + + if (srv->cell) + fsport = srv->cell->fsport; + + if (srv->addr->sa_portal == fsport) + upDownP = afs_stats_cmperf.fs_UpDown; + else + upDownP = afs_stats_cmperf.vl_UpDown; + + if (srv->cell && afs_IsPrimaryCell(srv->cell)) + return &upDownP[AFS_STATS_UPDOWN_IDX_SAME_CELL]; + else + return &upDownP[AFS_STATS_UPDOWN_IDX_DIFF_CELL]; +} + /*------------------------------------------------------------------------ * afs_MarkServerUpOrDown @@ -165,16 +185,7 @@ void afs_MarkServerUpOrDown(struct srvAddr *sa, int a_isDown) currTimeP = &currTime; osi_GetuTime(currTimeP); - if (sa->sa_portal == AFS_FSPORT) { - upDownP = (a_serverP->cell->cell == 1) ? - &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) : - &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]); - } /*File Server record*/ - else { - upDownP = (a_serverP->cell->cell == 1) ? - &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) : - &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]); - } /*VL Server record*/ + upDownP = GetUpDownStats(a_serverP); if (a_isDown) { /* @@ -295,7 +306,7 @@ static void CheckVLServer(sa, areq) return; /* can't do much */ tc = afs_ConnByHost(aserver, aserver->cell->vlport, - aserver->cell->cell, areq, 1, SHARED_LOCK); + aserver->cell->cellNum, areq, 1, SHARED_LOCK); if (!tc) return; rx_SetConnDeadTime(tc->id, 3); @@ -429,17 +440,7 @@ void afs_CountServers() * in the appropriate places. */ srvRecordAge = currTime.tv_sec - currSrvP->activationTime; - if (currSrvP->addr->sa_portal == AFS_FSPORT) { - upDownP = (currSrvP->cell->cell == 1) ? - &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]): - &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]); - } /*File Server record*/ - else { - upDownP = (currSrvP->cell->cell == 1) ? - &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]): - &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]); - } /*VL Server record*/ - + upDownP = GetUpDownStats(currSrvP); upDownP->sumOfRecordAges += srvRecordAge; if ((upDownP->ageOfYoungestRecord == 0) || (srvRecordAge < upDownP->ageOfYoungestRecord)) @@ -568,8 +569,8 @@ void afs_CheckServers(adown, acellp) continue; /* have just been added by setsprefs */ /* get a connection, even if host is down; bumps conn ref count */ - tu = afs_GetUser(treq.uid, ts->cell->cell, SHARED_LOCK); - tc = afs_ConnBySA(sa, ts->cell->fsport, ts->cell->cell, tu, + tu = afs_GetUser(treq.uid, ts->cell->cellNum, SHARED_LOCK); + tc = afs_ConnBySA(sa, ts->cell->fsport, ts->cell->cellNum, tu, 1/*force*/, 1/*create*/, SHARED_LOCK); afs_PutUser(tu, SHARED_LOCK); if (!tc) continue; @@ -602,12 +603,9 @@ void afs_CheckServers(adown, acellp) */ if (code == 0 && start == end && afs_setTime != 0 && (tc->srvr->server == afs_setTimeHost || - /* - * Sync only to a server in the local cell: cell(id)==1 - * or CPrimary. - */ + /* Sync only to a server in the local cell */ (afs_setTimeHost == (struct server *)0 && - (ts->cell->cell == 1 || (ts->cell->states&CPrimary))))) { + afs_IsPrimaryCell(ts->cell)))) { char msgbuf[90]; /* strlen("afs: setting clock...") + slop */ /* set the time */ @@ -1605,16 +1603,8 @@ struct server *afs_GetServer(afs_uint32 *aserverp, afs_int32 nservers, /* With the introduction of this new record, we need to adjust the * proper individual & global server up/down info. */ - if (aport == fsport) { /* File Server record */ - upDownP = (acell == 1) ? - &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) : - &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]); - } else { /* VL Server record */ - upDownP = (acell == 1) ? - &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) : - &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]); - } - (upDownP->numTtlRecords) += srvcount; + upDownP = GetUpDownStats(newts); + upDownP->numTtlRecords += srvcount; afs_stats_cmperf.srvRecords += srvcount; if (afs_stats_cmperf.srvRecords > afs_stats_cmperf.srvRecordsHWM) afs_stats_cmperf.srvRecordsHWM = afs_stats_cmperf.srvRecords; @@ -1642,21 +1632,12 @@ void afs_ActivateServer(sap) currTimeP = &currTime; osi_GetuTime(currTimeP); aserver->activationTime = currTime.tv_sec; - if (sap->sa_portal == AFS_FSPORT) { - upDownP = (aserver->cell->cell == 1) ? - &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) : - &(afs_stats_cmperf.fs_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]); - } /*File Server record*/ - else { - upDownP = (aserver->cell->cell == 1) ? - &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_SAME_CELL]) : - &(afs_stats_cmperf.vl_UpDown[AFS_STATS_UPDOWN_IDX_DIFF_CELL]); - } /*VL Server record*/ - if (aserver->flags & SRVR_ISDOWN) - (upDownP->numDownRecords)++; - else { - (upDownP->numUpRecords)++; - (upDownP->numRecordsNeverDown)++; + upDownP = GetUpDownStats(aserver); + if (aserver->flags & SRVR_ISDOWN) { + upDownP->numDownRecords++; + } else { + upDownP->numUpRecords++; + upDownP->numRecordsNeverDown++; } } } diff --git a/src/afs/afs_stats.h b/src/afs/afs_stats.h index d595c0c203..39dfcd0d03 100644 --- a/src/afs/afs_stats.h +++ b/src/afs/afs_stats.h @@ -637,6 +637,8 @@ struct afs_CMCallStats { afs_int32 C_SRXAFSCB_GetLocalCell; /* afs_callback.c*/ afs_int32 C_afs_MarshallCacheConfig; /* afs_callback.c*/ afs_int32 C_SRXAFSCB_GetCacheConfig; /* afs_callback.c*/ + afs_int32 C_SRXAFSCB_GetCE64; /* afs_callback.c*/ + afs_int32 C_SRXAFSCB_GetCellByNum; /* afs_callback.c*/ }; struct afs_CMMeanStats { diff --git a/src/afs/afs_vcache.c b/src/afs/afs_vcache.c index 4dce21619c..f91daeb61d 100644 --- a/src/afs/afs_vcache.c +++ b/src/afs/afs_vcache.c @@ -374,7 +374,7 @@ afs_int32 afs_FlushVCBs (afs_int32 lockit) callBacks[0].CallBackType = CB_EXCLUSIVE; for (safety3 = 0; safety3 < MAXHOSTS*2; safety3++) { tc = afs_ConnByHost(tsp, tsp->cell->fsport, - tsp->cell->cell, &treq, 0, + tsp->cell->cellNum, &treq, 0, SHARED_LOCK); if (tc) { XSTATS_START_TIME(AFS_STATS_FS_RPCIDX_GIVEUPCALLBACKS); @@ -632,9 +632,7 @@ restart: * entries locked. */ -afs_RemoveVCB(afid) - register struct VenusFid *afid; - +afs_RemoveVCB(struct VenusFid *afid) { /*afs_RemoveVCB*/ register int i, j; @@ -648,7 +646,7 @@ afs_RemoveVCB(afid) for(i=0;inext) { /* if cell is known, and is wrong, then skip this server */ - if (tsp->cell && tsp->cell->cell != afid->Cell) continue; + if (tsp->cell && tsp->cell->cellNum != afid->Cell) continue; /* * Otherwise, iterate through file IDs we're sending to the @@ -2530,7 +2528,7 @@ struct vcache *afs_FindVCache(struct VenusFid *afid, afs_int32 lockit, if (flag & DO_STATS) { if (tvc) afs_stats_cmperf.vcacheHits++; else afs_stats_cmperf.vcacheMisses++; - if (afid->Cell == LOCALCELL) + if (afs_IsPrimaryCellNum(afid->Cell)) afs_stats_cmperf.vlocalAccesses++; else afs_stats_cmperf.vremoteAccesses++; @@ -2672,7 +2670,7 @@ afs_int32 afs_NFSFindVCache(avcp, afid, lockit) if (tvc) afs_stats_cmperf.vcacheHits++; else afs_stats_cmperf.vcacheMisses++; - if (afid->Cell == LOCALCELL) + if (afs_IsPrimaryCellNum(afid->Cell)) afs_stats_cmperf.vlocalAccesses++; else afs_stats_cmperf.vremoteAccesses++; diff --git a/src/afs/afs_volume.c b/src/afs/afs_volume.c index d75eb16960..89d1e35cd6 100644 --- a/src/afs/afs_volume.c +++ b/src/afs/afs_volume.c @@ -112,7 +112,7 @@ struct volume *afs_UFSGetVolSlot() { register struct volume *tv, **lv; - register char *tfile; + struct osi_file *tfile; register afs_int32 i, code; afs_int32 bestTime; struct volume *bestVp, **bestLp; @@ -461,7 +461,7 @@ static struct volume *afs_SetupVolume(volid, aname, ve, tcell, agood, type, areq ObtainWriteLock(&afs_xvolume,108); i = VHash(volid); for (tv = afs_volumes[i]; tv; tv=tv->next) { - if (tv->volume == volid && tv->cell == tcell->cell) { + if (tv->volume == volid && tv->cell == tcell->cellNum) { break; } } @@ -470,14 +470,14 @@ static struct volume *afs_SetupVolume(volid, aname, ve, tcell, agood, type, areq tv = afs_GetVolSlot(); memset((char *)tv, 0, sizeof(struct volume)); - tv->cell = tcell->cell; + tv->cell = tcell->cellNum; RWLOCK_INIT(&tv->lock, "volume lock"); tv->next = afs_volumes[i]; /* thread into list */ afs_volumes[i] = tv; tv->volume = volid; for (j=fvTable[FVHash(tv->cell,volid)]; j!=0; j=tf->next) { if (afs_FVIndex != j) { - char *tfile; + struct osi_file *tfile; tfile = osi_UFSOpen(volumeInode); err = afs_osi_Read(tfile, sizeof(struct fvolume) * j, &staticFVolume, sizeof(struct fvolume)); if (err != sizeof(struct fvolume)) @@ -506,12 +506,12 @@ static struct volume *afs_SetupVolume(volid, aname, ve, tcell, agood, type, areq ReleaseWriteLock(&afs_xvolume); ObtainWriteLock(&tv->lock,111); if (type == 2) { - InstallUVolumeEntry(tv, uve, tcell->cell, tcell, areq); + InstallUVolumeEntry(tv, uve, tcell->cellNum, tcell, areq); } else if (type == 1) - InstallNVolumeEntry(tv, nve, tcell->cell); + InstallNVolumeEntry(tv, nve, tcell->cellNum); else - InstallVolumeEntry(tv, ove, tcell->cell); + InstallVolumeEntry(tv, ove, tcell->cellNum); if (agood) { if (!tv->name) { tv->name = afs_osi_Alloc(strlen(aname) + 1); @@ -573,7 +573,7 @@ static struct volume *afs_NewDynrootVolume(struct VenusFid *fid) { tve.volumeId[ROVOL] = fid->Fid.Volume; tve.flags = VLF_ROEXISTS; - tv = afs_SetupVolume(0, bp, &tve, tcell, 0, 0, 0); + tv = afs_SetupVolume(0, bp, (char *) &tve, tcell, 0, 0, 0); afs_PutCell(tcell, READ_LOCK); return tv; } @@ -614,7 +614,7 @@ static struct volume *afs_NewVolumeByName(char *aname, afs_int32 acell, int agoo afs_InitReq(&treq, &afs_osi_cred); /* *must* be unauth for vldb */ do { tconn = afs_ConnByMHosts(tcell->cellHosts, tcell->vlport, - tcell->cell, &treq, SHARED_LOCK); + tcell->cellNum, &treq, SHARED_LOCK); if (tconn) { if (tconn->srvr->server->flags & SNO_LHOSTS) { type = 0; @@ -947,7 +947,7 @@ void InstallUVolumeEntry(struct volume *av, struct uvldbentry *ve, memset((char *)&addrs, 0, sizeof(addrs)); do { tconn = afs_ConnByMHosts(tcell->cellHosts, tcell->vlport, - tcell->cell, areq, SHARED_LOCK); + tcell->cellNum, areq, SHARED_LOCK); if (tconn) { #ifdef RX_ENABLE_LOCKS AFS_GUNLOCK(); diff --git a/src/afsd/afsd.c b/src/afsd/afsd.c index d2921d5329..7d9aa5c964 100644 --- a/src/afsd/afsd.c +++ b/src/afsd/afsd.c @@ -170,6 +170,7 @@ void set_staticaddrs(void); #define AFSLOGFILE "AFSLog" #define DCACHEFILE "CacheItems" #define VOLINFOFILE "VolumeItems" +#define CELLINFOFILE "CellItems" #define MAXIPADDRS 1024 @@ -211,6 +212,7 @@ char cacheBaseDir[1024]; /*Where the workstation AFS cache lives*/ char confDir[1024]; /*Where the workstation AFS configuration lives*/ char fullpn_DCacheFile[1024]; /*Full pathname of DCACHEFILE*/ char fullpn_VolInfoFile[1024]; /*Full pathname of VOLINFOFILE*/ +char fullpn_CellInfoFile[1024]; /*Full pathanem of CELLINFOFILE*/ char fullpn_AFSLogFile[1024]; /*Full pathname of AFSLOGFILE*/ char fullpn_CacheInfo[1024]; /*Full pathname of CACHEINFO*/ char fullpn_VFile[1024]; /*Full pathname of data cache files*/ @@ -224,7 +226,6 @@ char cacheMountDir[1024]; /*Mount directory for AFS*/ char rootVolume[64] = "root.afs"; /*AFS root volume name*/ afs_int32 cacheSetTime = 1; /*Keep checking time to avoid drift?*/ afs_int32 isHomeCell; /*Is current cell info for the home cell?*/ -afs_int32 lookingForHomeCell; /*Are we still looking for the home cell?*/ int createAndTrunc = O_CREAT | O_TRUNC; /*Create & truncate on open*/ int ownerRWmode = 0600; /*Read/write OK by owner*/ static int filesSet = 0; /*True if number of files explicitly set*/ @@ -270,10 +271,11 @@ int *dir_for_V = NULL; /* Array: dir of each cache file. */ AFSD_INO_T *inode_for_V; /* Array of inodes for desired * cache files */ -int missing_DCacheFile = 1; /*Is the DCACHEFILE missing?*/ -int missing_VolInfoFile = 1; /*Is the VOLINFOFILE missing?*/ -int afsd_rmtsys = 0; /* Default: don't support rmtsys */ -struct afs_cacheParams cparams; /* params passed to cache manager */ +int missing_DCacheFile = 1; /*Is the DCACHEFILE missing?*/ +int missing_VolInfoFile = 1; /*Is the VOLINFOFILE missing?*/ +int missing_CellInfoFile = 1; /*Is the CELLINFOFILE missing?*/ +int afsd_rmtsys = 0; /* Default: don't support rmtsys */ +struct afs_cacheParams cparams; /* params passed to cache manager */ static int HandleMTab(); @@ -626,6 +628,16 @@ int CreateCacheFile(fname, statp) return(0); } +static void CreateFileIfMissing(char *fullpn, int missing) +{ + if (missing) { + if (afsd_verbose) + printf("CreateFileIfMissing: Creating '%s'\n", fullpn); + if (CreateCacheFile(fullpn, NULL)) + printf("CreateFileIfMissing: Can't create '%s'\n", fullpn); + } +} + /*----------------------------------------------------------------------------- * SweepAFSCache * @@ -802,6 +814,12 @@ static int doSweepAFSCache(vFilesFound,directory,dirNum,maxDir) */ missing_VolInfoFile = 0; } + else if (dirNum < 0 && strcmp(currp->d_name, CELLINFOFILE) == 0) { + /* + * Found the file holding the cell info. + */ + missing_CellInfoFile = 0; + } else if ((strcmp(currp->d_name, ".") == 0) || (strcmp(currp->d_name, "..") == 0) || #ifdef AFS_DECOSF_ENV @@ -842,25 +860,12 @@ static int doSweepAFSCache(vFilesFound,directory,dirNum,maxDir) if (dirNum < 0) { - /* + /* * Create all the cache files that are missing. */ - if (missing_DCacheFile) { - if (afsd_verbose) - printf("%s: Creating '%s'\n", - rn, fullpn_DCacheFile); - if (CreateCacheFile(fullpn_DCacheFile, NULL)) - printf("%s: Can't create '%s'\n", - rn, fullpn_DCacheFile); - } - if (missing_VolInfoFile) { - if (afsd_verbose) - printf("%s: Creating '%s'\n", - rn, fullpn_VolInfoFile); - if (CreateCacheFile(fullpn_VolInfoFile, NULL)) - printf("%s: Can't create '%s'\n", - rn, fullpn_VolInfoFile); - } + CreateFileIfMissing(fullpn_DCacheFile, missing_DCacheFile); + CreateFileIfMissing(fullpn_VolInfoFile, missing_VolInfoFile); + CreateFileIfMissing(fullpn_CellInfoFile, missing_CellInfoFile); /* ADJUST CACHE FILES */ @@ -1035,19 +1040,14 @@ register struct afsconf_cell *aci; char *arock; struct afsconf_dir *adir; { register int isHomeCell; - register int i; - afs_int32 cellFlags; + register int i, code; + afs_int32 cellFlags = 0; afs_int32 hosts[MAXHOSTSPERCELL]; /* figure out if this is the home cell */ isHomeCell = (strcmp(aci->name, LclCellName) == 0); - if (isHomeCell) { - lookingForHomeCell = 0; - cellFlags = 1; /* home cell, suid is ok */ - } - else { + if (!isHomeCell) cellFlags = 2; /* not home, suid is forbidden */ - } /* build address list */ for(i=0;iname, /* cell name */ cellFlags, /* is this the home cell? */ aci->linkedCell); /* Linked cell, if any */ + if (code) + printf("Adding cell '%s': error %d\n", aci->name, code); return 0; } @@ -1472,8 +1474,9 @@ mainproc(as, arock) /* * Set up all the pathnames we'll need for later. */ - sprintf(fullpn_DCacheFile, "%s/%s", cacheBaseDir, DCACHEFILE); - sprintf(fullpn_VolInfoFile, "%s/%s", cacheBaseDir, VOLINFOFILE); + sprintf(fullpn_DCacheFile, "%s/%s", cacheBaseDir, DCACHEFILE); + sprintf(fullpn_VolInfoFile, "%s/%s", cacheBaseDir, VOLINFOFILE); + sprintf(fullpn_CellInfoFile, "%s/%s", cacheBaseDir, CELLINFOFILE); sprintf(fullpn_VFile, "%s/", cacheBaseDir); vFilePtr = fullpn_VFile + strlen(fullpn_VFile); @@ -1572,6 +1575,83 @@ mainproc(as, arock) } #endif + code = call_syscall(AFSOP_BASIC_INIT, 1); + if (code) + printf("%s: Error %d in basic initialization.\n", rn, code); + + /* + * Tell the kernel some basic information about the workstation's cache. + */ + if (afsd_verbose) + printf("%s: Calling AFSOP_CACHEINIT: %d stat cache entries, %d optimum cache files, %d blocks in the cache, flags = 0x%x, dcache entries %d\n", + rn, cacheStatEntries, cacheFiles, cacheBlocks, cacheFlags, + dCacheSize); + memset(&cparams, '\0', sizeof(cparams)); + cparams.cacheScaches = cacheStatEntries; + cparams.cacheFiles = cacheFiles; + cparams.cacheBlocks = cacheBlocks; + cparams.cacheDcaches = dCacheSize; + cparams.cacheVolumes = vCacheSize; + cparams.chunkSize = chunkSize; + cparams.setTimeFlag = cacheSetTime; + cparams.memCacheFlag = cacheFlags; +#ifdef notdef + cparams.inodes = inodes; +#endif + call_syscall(AFSOP_CACHEINIT, &cparams); + if (afsd_CloseSynch) + call_syscall(AFSOP_CLOSEWAIT); + + /* + * Sweep the workstation AFS cache directory, remembering the inodes of + * valid files and deleting extraneous files. Keep sweeping until we + * have the right number of data cache files or we've swept too many + * times. + * + * This also creates files in the cache directory like VolumeItems and + * CellItems, and thus must be ran before those are sent to the kernel. + */ + if (afsd_verbose) + printf("%s: Sweeping workstation's AFS cache directory.\n", + rn); + cacheIteration = 0; + /* Memory-cache based system doesn't need any of this */ + if(!(cacheFlags & AFSCALL_INIT_MEMCACHE)) { + do { + cacheIteration++; + if (SweepAFSCache(&vFilesFound)) { + printf("%s: Error on sweep %d of workstation AFS cache \ + directory.\n", rn, cacheIteration); + exit(1); + } + if (afsd_verbose) + printf("%s: %d out of %d data cache files found in sweep %d.\n", + rn, vFilesFound, cacheFiles, cacheIteration); + } while ((vFilesFound < cacheFiles) && + (cacheIteration < MAX_CACHE_LOOPS)); + } else if(afsd_verbose) + printf("%s: Using memory cache, not swept\n", rn); + + /* + * Pass the kernel the name of the workstation cache file holding the + * dcache entries. + */ + if (afsd_debug) + printf("%s: Calling AFSOP_CACHEINFO: dcache file is '%s'\n", + rn, fullpn_DCacheFile); + /* once again, meaningless for a memory-based cache. */ + if(!(cacheFlags & AFSCALL_INIT_MEMCACHE)) + call_syscall(AFSOP_CACHEINFO, fullpn_DCacheFile); + + /* + * Pass the kernel the name of the workstation cache file holding the + * cell information. + */ + if (afsd_debug) + printf("%s: Calling AFSOP_CELLINFO: cell info file is '%s'\n", + rn, fullpn_CellInfoFile); + call_syscall(AFSOP_CELLINFO, fullpn_CellInfoFile); + if (enable_dynroot) { if (afsd_verbose) printf("%s: Enabling dynroot support in kernel.\n", rn); @@ -1646,19 +1726,13 @@ mainproc(as, arock) /* * Tell the kernel about each cell in the configuration. */ - 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 - * has been parsed, there's something wrong. + * Set the primary cell name. */ - if (lookingForHomeCell) { - printf("%s: Can't find information for home cell '%s' in cell database!\n", - rn, LclCellName); - } + call_syscall(AFSOP_SET_THISCELL, LclCellName); /* * If the root volume has been explicitly set, tell the kernel. @@ -1670,67 +1744,6 @@ mainproc(as, arock) call_syscall(AFSOP_ROOTVOLUME, rootVolume); } - /* - * Tell the kernel some basic information about the workstation's cache. - */ - if (afsd_verbose) - printf("%s: Calling AFSOP_CACHEINIT: %d stat cache entries, %d optimum cache files, %d blocks in the cache, flags = 0x%x, dcache entries %d\n", - rn, cacheStatEntries, cacheFiles, cacheBlocks, cacheFlags, - dCacheSize); - memset(&cparams, '\0', sizeof(cparams)); - cparams.cacheScaches = cacheStatEntries; - cparams.cacheFiles = cacheFiles; - cparams.cacheBlocks = cacheBlocks; - cparams.cacheDcaches = dCacheSize; - cparams.cacheVolumes = vCacheSize; - cparams.chunkSize = chunkSize; - cparams.setTimeFlag = cacheSetTime; - cparams.memCacheFlag = cacheFlags; -#ifdef notdef - cparams.inodes = inodes; -#endif - call_syscall(AFSOP_CACHEINIT, &cparams); - if (afsd_CloseSynch) - call_syscall(AFSOP_CLOSEWAIT); - - /* - * Sweep the workstation AFS cache directory, remembering the inodes of - * valid files and deleting extraneous files. Keep sweeping until we - * have the right number of data cache files or we've swept too many - * times. - */ - if (afsd_verbose) - printf("%s: Sweeping workstation's AFS cache directory.\n", - rn); - cacheIteration = 0; - /* Memory-cache based system doesn't need any of this */ - if(!(cacheFlags & AFSCALL_INIT_MEMCACHE)) { - do { - cacheIteration++; - if (SweepAFSCache(&vFilesFound)) { - printf("%s: Error on sweep %d of workstation AFS cache \ - directory.\n", rn, cacheIteration); - exit(1); - } - if (afsd_verbose) - printf("%s: %d out of %d data cache files found in sweep %d.\n", - rn, vFilesFound, cacheFiles, cacheIteration); - } while ((vFilesFound < cacheFiles) && - (cacheIteration < MAX_CACHE_LOOPS)); - } else if(afsd_verbose) - printf("%s: Using memory cache, not swept\n", rn); - - /* - * Pass the kernel the name of the workstation cache file holding the - * dcache entries. - */ - if (afsd_debug) - printf("%s: Calling AFSOP_CACHEINFO: dcache file is '%s'\n", - rn, fullpn_DCacheFile); - /* once again, meaningless for a memory-based cache. */ - if(!(cacheFlags & AFSCALL_INIT_MEMCACHE)) - call_syscall(AFSOP_CACHEINFO, fullpn_DCacheFile); - /* * Pass the kernel the name of the workstation cache file holding the * volume information. diff --git a/src/config/afs_args.h b/src/config/afs_args.h index ab8d095eed..688fa68d64 100644 --- a/src/config/afs_args.h +++ b/src/config/afs_args.h @@ -42,6 +42,9 @@ #define AFSOP_SET_DYNROOT 31 /* enable/disable dynroot support */ #define AFSOP_ADDCELLALIAS 32 /* create alias for existing cell */ #define AFSOP_SET_FAKESTAT 33 /* enable/disable fakestat support */ +#define AFSOP_CELLINFO 34 /* set the cellinfo file name */ +#define AFSOP_SET_THISCELL 35 /* set the primary cell */ +#define AFSOP_BASIC_INIT 36 /* used to be part of START_AFS */ /* The range 20-30 is reserved for AFS system offsets in the afs_syscall */ #define AFSCALL_PIOCTL 20 diff --git a/src/fsint/afscbint.xg b/src/fsint/afscbint.xg index a8ce0c1532..c1bae1c50a 100644 --- a/src/fsint/afscbint.xg +++ b/src/fsint/afscbint.xg @@ -96,3 +96,9 @@ proc GetCacheConfig( OUT cacheConfig *config ) = 218; +proc GetCellByNum( + IN afs_int32 cellNumber, + OUT string cellName, + OUT serverList *cellHosts +) = 65537; + diff --git a/src/fsprobe/fsprobe_callback.c b/src/fsprobe/fsprobe_callback.c index 6157643a51..630fccd9c9 100644 --- a/src/fsprobe/fsprobe_callback.c +++ b/src/fsprobe/fsprobe_callback.c @@ -646,6 +646,15 @@ int SRXAFSCB_GetCellServDB( return RXGEN_OPCODE; } +afs_int32 SRXAFSCB_GetCellByNum( + struct rx_call *a_call, + afs_int32 a_cellnum, + char **a_name, + serverList *a_hosts) +{ + return RXGEN_OPCODE; +} + /*------------------------------------------------------------------------ * EXPORTED SRXAFSCB_GetLocalCell * diff --git a/src/venus/cmdebug.c b/src/venus/cmdebug.c index 182f5a418f..a37a9f59bc 100644 --- a/src/venus/cmdebug.c +++ b/src/venus/cmdebug.c @@ -89,12 +89,55 @@ register struct rx_connection *aconn; { return 0; } -static PrintCacheEntries(aconn, aint32) -int aint32; -register struct rx_connection *aconn; { +struct cell_cache { + afs_int32 cellnum; + char *cellname; + struct cell_cache *next; +}; + +static char *GetCellName(struct rx_connection *aconn, afs_int32 cellnum) +{ + static int no_getcellbynum; + static struct cell_cache *cache; + struct cell_cache *tcp; + int code; + char *cellname; + serverList sl; + + if (no_getcellbynum) + return NULL; + + for (tcp = cache; tcp; tcp = tcp->next) + if (tcp->cellnum == cellnum) + return tcp->cellname; + + cellname = NULL; + sl.serverList_len = 0; + sl.serverList_val = NULL; + code = RXAFSCB_GetCellByNum(aconn, cellnum, &cellname, &sl); + if (code) { + if (code == RXGEN_OPCODE) + no_getcellbynum = 1; + return NULL; + } + + if (sl.serverList_val) + free (sl.serverList_val); + tcp = malloc(sizeof(struct cell_cache)); + tcp->next = cache; + tcp->cellnum = cellnum; + tcp->cellname = cellname; + cache = tcp; + + return cellname; +} + +static PrintCacheEntries(struct rx_connection *aconn, int aint32) +{ register int i; register afs_int32 code; struct AFSDBCacheEntry centry; + char *cellname; for(i=0;i<10000;i++) { code = RXAFSCB_GetCE(aconn, i, ¢ry); @@ -115,8 +158,16 @@ register struct rx_connection *aconn; { if (!aint32 && !IsLocked(¢ry.lock)) continue; /* otherwise print this entry */ - printf("** Cache entry @ 0x%08x for %d.%d.%d.%d\n", centry.addr, centry.cell, - centry.netFid.Volume, centry.netFid.Vnode, centry.netFid.Unique); + printf("** Cache entry @ 0x%08x for %d.%d.%d.%d", centry.addr, + centry.cell, centry.netFid.Volume, centry.netFid.Vnode, + centry.netFid.Unique); + + cellname = GetCellName(aconn, centry.cell); + if (cellname) + printf(" [%s]\n", cellname); + else + printf("\n"); + if (IsLocked(¢ry.lock)) { printf(" locks: "); PrintLock(¢ry.lock); diff --git a/src/venus/kdump.c b/src/venus/kdump.c index 91e7a4d8d0..debfd8c21c 100644 --- a/src/venus/kdump.c +++ b/src/venus/kdump.c @@ -1053,6 +1053,8 @@ kdump() if (Dcells || Dall) { print_cells(1); /* Handle the afs_cells structures */ + print_cellaliases(1); + print_cellnames(1); } if (Dusers || Dall) { @@ -1170,6 +1172,7 @@ kdump() #if !defined(AFS_DARWIN_ENV) && !defined(AFS_FBSD_ENV) int Sum_cellnames=0, Sum_userstp=0, Sum_volnames=0, Sum_exps=0, Sum_nfssysnames=0; int Sum_vcachemvids=0, Sum_vcachelinkData=0, Sum_vcacheacc=0, Sum_vcachelocks=0; +int Sum_cellaliases=0, Sum_cellname_names=0; int print_cells(pnt) int pnt; @@ -1193,6 +1196,64 @@ int pnt; j++; } if (pnt) printf("... found %d 'afs_cells' entries\n", j); + + return j; +} + +int print_cellaliases(int pnt) +{ + off_t symoff; + struct cell_alias *ca, cae; + long j = 0; + + if (pnt) printf("\n\nPrinting cell_alias list...\n"); + findsym( "afs_cellalias_head", &symoff); + kread(kmem, symoff, (char *) &ca, sizeof ca); + while (ca) { + char alias[100], cell[100]; + + kread(kmem, (off_t) ca, (char *) &cae, sizeof cae); + kread(kmem, (off_t) cae.alias, alias, (KDUMP_SIZE_T)40); + alias[40] = '\0'; + Sum_cellaliases += strlen(alias) + 1; + kread(kmem, (off_t) cae.cell, cell, (KDUMP_SIZE_T)40); + cell[40] = '\0'; + Sum_cellaliases += strlen(cell) + 1; + if (pnt) + printf("%x: alias=%s cell=%s index=%d\n", + ca, alias, cell, cae.index); + ca = cae.next; + j++; + } + if (pnt) printf("... found %d 'cell_alias' entries\n", j); + + return j; +} + +int print_cellnames(int pnt) +{ + off_t symoff; + struct cell_name *cn, cne; + long j = 0; + + if (pnt) printf("\n\nPrinting cell_name list...\n"); + findsym( "afs_cellname_head", &symoff); + kread(kmem, symoff, (char *) &cn, sizeof cn); + while (cn) { + char cellname[100]; + + kread(kmem, (off_t) cn, (char *) &cne, sizeof cne); + kread(kmem, (off_t) cne.cellname, cellname, (KDUMP_SIZE_T)40); + cellname[40] = '\0'; + Sum_cellname_names += strlen(cellname) + 1; + if (pnt) + printf("%x: cellnum=%d cellname=%s used=%d\n", + cn, cne.cellnum, cellname, cne.used); + cn = cne.next; + j++; + } + if (pnt) printf("... found %d 'cell_name' entries\n", j); + return j; } @@ -1761,6 +1822,18 @@ int pnt; T += j; printf("%20s:\t%8d bytes\t[%d cells/%d bytes each + %d bytes for cell names]\n", "Cell package", j, i, sizeof(struct cell), Sum_cellnames); + Sum_cellaliases=0; + i = print_cellaliases(0); + j = (i * sizeof(struct cell_alias)) + Sum_cellaliases; + T += j; + printf("%20s:\t%8d bytes\t[%d cell_aliases/%d bytes each + %d bytes for cell names]\n", "Cell package", j, i, sizeof(struct cell_alias), Sum_cellaliases); + + Sum_cellname_names=0; + i = print_cellnames(0); + j = (i * sizeof(struct cell_name)) + Sum_cellname_names; + T += j; + printf("%20s:\t%8d bytes\t[%d cell_names/%d bytes each + %d bytes for cell name strings]\n", "Cell package", j, i, sizeof(struct cell_name), Sum_cellname_names); + Sum_userstp=0; i = print_users(0); j = (i * sizeof(struct unixuser)) + Sum_userstp; @@ -2268,9 +2341,10 @@ void print_cell(kmem, clep, ptr, pnt) cellName[40] = 0; Sum_cellnames += strlen(cellName)+1; if (pnt) { - printf("%lx: cell=%s, cellname=%s, states=%x, cindex=%d fsport=%d vlport=%d\n", ptr, - PrintIPAddr(clep->cell), cellName, clep->states, clep->cellIndex, - clep->fsport, clep->vlport); + printf("%lx: cellname=%s, states=%x, cnum=%d, cindex=%d fsport=%d vlport=%d timeout=%d cnamep=%x\n", ptr, + cellName, clep->states, clep->cellNum, clep->cellIndex, + clep->fsport, clep->vlport, clep->timeout, clep->cnamep); + #ifdef AFS33 if (clep->lcellp) printf("\tlinked cellp %lx\n", clep->lcellp); diff --git a/src/vol/vnode.c b/src/vol/vnode.c index e9ec600b83..72186326d1 100644 --- a/src/vol/vnode.c +++ b/src/vol/vnode.c @@ -55,7 +55,7 @@ RCSID("$Header$"); #include #endif /* AFS_NT40_ENV */ #include - +#include struct VnodeClassInfo VnodeClassInfo[nVNODECLASSES]; diff --git a/src/xstat/xstat_fs_callback.c b/src/xstat/xstat_fs_callback.c index e5e2356ce4..ec137f5ce4 100644 --- a/src/xstat/xstat_fs_callback.c +++ b/src/xstat/xstat_fs_callback.c @@ -652,6 +652,16 @@ int SRXAFSCB_GetCellServDB( } +afs_int32 SRXAFSCB_GetCellByNum( + struct rx_call *a_call, + afs_int32 a_cellnum, + char **a_name, + serverList *a_hosts) +{ + return RXGEN_OPCODE; +} + + /*------------------------------------------------------------------------ * EXPORTED SRXAFSCB_GetLocalCell *