/*
* Copyright 2000, International Business Machines Corporation and others.
* All Rights Reserved.
- *
+ *
* This software has been released under the terms of the IBM Public
* License. For details, see the LICENSE file in the top-level source
* directory or online at http://www.openafs.org/dl/license10.html
#include "afsincludes.h" /* Afs-based standard headers */
#include "afs/afs_stats.h" /* afs statistics */
#include "afs/afs_osi.h"
-#include "afs/afs_md5.h"
+#include "hcrypto/md5.h"
/* Local variables. */
afs_rwlock_t afs_xcell; /* Export for cmdebug peeking at locks */
afs_osi_Wakeup(&afsdb_req);
} else {
afsdb_handler_shutdown = 1;
+#if defined(AFS_SUN5_ENV) || defined(RXK_LISTENER_ENV) || defined(RXK_UPCALL_ENV)
afs_termState = AFSOP_STOP_RXEVENT;
+#else
+ afs_termState = AFSOP_STOP_COMPLETE;
+#endif
afs_osi_Wakeup(&afs_termState);
}
}
}
if (hostCount)
- code = afs_NewCell(acellName, cellHosts, CNoSUID, NULL, 0, 0,
+ code = afs_NewCell(acellName, cellHosts, CNoSUID, NULL, 0, 0,
timeout);
- if (!hostCount || (code && code != EEXIST))
+ if (!hostCount || (code && code != EEXIST))
/* null out the cellname if the lookup failed */
afsdb_req.cellname = NULL;
else
}
-/*!
+/*!
* Look up AFSDB for given cell name and create locally.
- * \param acellName Cell name.
+ * \param acellName Cell name.
*/
void
afs_LookupAFSDB(char *acellName)
char *cellName = afs_strdup(acellName);
code = afs_GetCellHostsAFSDB(cellName);
- afs_Trace2(afs_iclSetp, CM_TRACE_AFSDB, ICL_TYPE_STRING, cellName,
+ afs_Trace2(afs_iclSetp, CM_TRACE_AFSDB, ICL_TYPE_STRING, cellName,
ICL_TYPE_INT32, code);
afs_osi_FreeStr(cellName);
}
if (cellnum == 0)
cellnum = afs_cellnum_next;
- cn = (struct cell_name *)afs_osi_Alloc(sizeof(*cn));
+ cn = afs_osi_Alloc(sizeof(*cn));
+ osi_Assert(cn != NULL);
cn->next = afs_cellname_head;
cn->cellnum = cellnum;
cn->cellname = afs_strdup(name);
/*!
* Look up a cell name by id.
* \param cellnum
- * \return
+ * \return
*/
static struct cell_name *
afs_cellname_lookup_id(afs_int32 cellnum)
/*!
* Look up a cell name.
* \param name Cell name.
- * \return
+ * \return
*/
static struct cell_name *
afs_cellname_lookup_name(char *name)
/*!
* \brief Load the list of cells from given inode.
* \param inode Source inode.
- * \param lookupcode
+ * \param lookupcode
* \return 0 for success. < 0 for error.
*/
int
while (1) {
afs_int32 cellnum, clen, magic;
- struct cell_name *cn;
char *cellname;
cc = afs_osi_Read(tfile, off, &magic, sizeof(magic));
break;
}
- cn = afs_cellname_new(cellname, cellnum);
+ afs_cellname_new(cellname, cellnum);
afs_osi_Free(cellname, clen + 1);
}
/*!
* Look up cell alias by alias name.
- * \param alias
+ * \param alias
* \return Found struct or NULL.
*/
static struct cell_alias *
/*!
* Get cell alias by index (starting at 0).
- * \param index Cell index.
+ * \param index Cell index.
* \return Found struct or null.
*/
struct cell_alias *
/*!
* Put back a cell alias returned by Find or Get.
- * \param a Alias.
- * \return
+ * \param a Alias.
+ * \return
*/
void
afs_PutCellAlias(struct cell_alias *a)
* Create new cell alias entry and update dynroot vnode.
* \param alias
* \param cell
- * \return
+ * \return
*/
afs_int32
afs_NewCellAlias(char *alias, char *cell)
}
UpgradeSToWLock(&afs_xcell, 682);
- tc = (struct cell_alias *)afs_osi_Alloc(sizeof(struct cell_alias));
+ tc = afs_osi_Alloc(sizeof(struct cell_alias));
+ osi_Assert(tc != NULL);
tc->alias = afs_strdup(alias);
tc->cell = afs_strdup(cell);
tc->next = afs_cellalias_head;
*/
struct afs_q CellLRU; /* Export for kdump */
-static char *afs_thiscell;
+static char *afs_thiscell = NULL;
afs_int32 afs_cellindex; /* Export for kdump */
/*!
* Bump given cell up to the front of the LRU queue.
- * \param c Cell to set.
+ * \param c Cell to set.
*/
static void
afs_UpdateCellLRU(struct cell *c)
/*!
* Look up cell information in AFSDB if timeout expired
* \param ac Cell to be refreshed.
- * \return
+ * \return
*/
static void
afs_RefreshCell(struct cell *ac)
afs_LookupAFSDB(ac->cellName);
}
-/*!
+/*!
* Execute a callback for each existing cell, without a lock on afs_xcell.
* Iterate on CellLRU, and execute a callback for each cell until given arguments are met.
* \see afs_TraverseCells
* Execute a callback for each existing cell, with a lock on afs_xcell.
* \see afs_TraverseCells_nl
* \param cb Traversal callback for each cell.
- * \param arg
+ * \param arg
* \return Found data or NULL.
*/
void *
/*!
* Useful traversal callback: Match by name.
- * \param cell
+ * \param cell
* \param arg Cell name (compared with cell->cellName).
* \return Returns found cell or NULL.
*/
/*!
* Useful traversal callback: Match by handle.
- * \param cell
+ * \param cell
* \param arg Cell handle (compared with cell->cellHandle).
* \return Returns found cell or NULL.
*/
/*!
* Useful traversal callback: Match by cell number.
- * \param cell
+ * \param cell
* \param arg Cell number (compared with cell->cellNum).
* \return Returns found cell or NULL.
*/
/*!
* Useful traversal callback: Match by index.
- * \param cell
+ * \param cell
* \param arg Cell index (compared with cell->cellIndex).
* \return Returns found cell or NULL.
*/
* Does not check AFSDB.
* \param acellName Cell name.
* \param locktype Type of lock to be used (not used).
- * \return
+ * \return
*/
static struct cell *
afs_FindCellByName_nl(char *acellName, afs_int32 locktype)
* Does not check AFSDB.
* \param acellName Cell name.
* \param locktype Type of lock to be used.
- * \return
+ * \return
*/
static struct cell *
afs_FindCellByName(char *acellName, afs_int32 locktype)
* Same as FindCellByName but tries AFSDB if not found.
* \param acellName Cell name.
* \param locktype Type of lock to be used.
- * \return
+ * \return
*/
struct cell *
afs_GetCellByName(char *acellName, afs_int32 locktype)
/*!
* Return a cell with a given cell number.
* \param cellnum Cell number.
- * \param locktype Lock to be used.
- * \return
+ * \param locktype Lock to be used.
+ * \return
*/
struct cell *
afs_GetCell(afs_int32 cellnum, afs_int32 locktype)
* Same as GetCell, but does not try to refresh the data.
* \param cellnum Cell number.
* \param locktype What lock should be used.
- * \return
+ * \return
*/
struct cell *
afs_GetCellStale(afs_int32 cellnum, afs_int32 locktype)
* Return a cell with a given index number (starting at 0). Update CellLRU as well.
* \param index
* \param locktype Type of lock used.
- * \return
+ * \return
*/
struct cell *
afs_GetCellByIndex(afs_int32 index, afs_int32 locktype)
* Return a cell with a given handle..
* \param index
* \param locktype Type of lock used.
- * \return
+ * \return
*/
struct cell *
afs_GetCellByHandle(void *handle, afs_int32 locktype)
/*!
* Return primary cell, if any.
* \param locktype Type of lock used.
- * \return
+ * \return
*/
struct cell *
afs_GetPrimaryCell(afs_int32 locktype)
}
/*!
+ * Return number of the primary cell.
+ * \return
+ * Cell number, or 0 if primary cell not found
+ */
+afs_int32
+afs_GetPrimaryCellNum(void)
+{
+ struct cell *cell;
+ afs_int32 cellNum = 0;
+ cell = afs_GetPrimaryCell(READ_LOCK);
+ if (cell) {
+ cellNum = cell->cellNum;
+ afs_PutCell(cell, READ_LOCK);
+ }
+ return cellNum;
+}
+
+/*!
* Returns true if the given cell is the primary cell.
* \param cell
- * \return
+ * \return
*/
int
afs_IsPrimaryCell(struct cell *cell)
/*!
* Returns afs_IsPrimaryCell(afs_GetCell(cellnum)).
- * \param cellnum
- * \return
+ * \param cellnum
+ * \return
*/
int
afs_IsPrimaryCellNum(afs_int32 cellnum)
/*!
* Set the primary cell name to the given cell name.
- * \param acellName Cell name.
+ * \param acellName Cell name.
* \return 0 for success, < 0 for error.
*/
afs_int32
}
/*!
- * Create or update a cell entry.
+ * Create or update a cell entry.
* \param acellName Name of cell.
* \param acellHosts Array of hosts that this cell has.
* \param aflags Cell flags.
- * \param linkedcname
+ * \param linkedcname
* \param fsport File server port.
* \param vlport Volume server port.
* \param timeout Cell timeout value, 0 means static AFSDB entry.
- * \return
+ * \return
*/
afs_int32
afs_NewCell(char *acellName, afs_int32 * acellHosts, int aflags,
{
struct cell *tc, *tcl = 0;
afs_int32 i, newc = 0, code = 0;
+ struct md5 m;
AFS_STATCNT(afs_NewCell);
if (tc) {
aflags &= ~CNoSUID;
} else {
- tc = (struct cell *)afs_osi_Alloc(sizeof(struct cell));
+ tc = afs_osi_Alloc(sizeof(struct cell));
+ osi_Assert(tc != NULL);
memset(tc, 0, sizeof(*tc));
tc->cellName = afs_strdup(acellName);
tc->fsport = AFS_FSPORT;
tc->vlport = AFS_VLPORT;
- AFS_MD5_String(tc->cellHandle, tc->cellName, strlen(tc->cellName));
+ MD5_Init(&m);
+ MD5_Update(&m, tc->cellName, strlen(tc->cellName));
+ MD5_Final(tc->cellHandle, &m);
AFS_RWLOCK_INIT(&tc->lock, "cell lock");
newc = 1;
aflags |= CNoSUID;
}
tc->states |= aflags;
tc->timeout = timeout;
-
+
memset(tc->cellHosts, 0, sizeof(tc->cellHosts));
for (i = 0; i < AFS_MAXCELLHOSTS; i++) {
- /* Get server for each host and link this cell in.*/
+ /* Get server for each host and link this cell in.*/
struct server *ts;
afs_uint32 temp = acellHosts[i];
if (!temp)
break;
- ts = afs_GetServer(&temp, 1, 0, tc->vlport, WRITE_LOCK, NULL, 0);
+ ts = afs_GetServer(&temp, 1, 0, tc->vlport, WRITE_LOCK, NULL, 0, NULL);
ts->cell = tc;
ts->flags &= ~SRVR_ISGONE;
/* Set the server as a host of the new cell. */
afs_PutServer(ts, WRITE_LOCK);
}
afs_SortServers(tc->cellHosts, AFS_MAXCELLHOSTS); /* randomize servers */
-
+
/* New cell: Build and add to LRU cell queue. */
if (newc) {
struct cell_name *cn;
ReleaseWriteLock(&tc->lock);
ReleaseWriteLock(&afs_xcell);
afs_PutCell(tc, 0);
- afs_DynrootInvalidate();
+ if (!(aflags & CHush))
+ afs_DynrootInvalidate();
return 0;
bad:
+ ReleaseWriteLock(&tc->lock);
+
if (newc) {
+ /* If we're a new cell, nobody else can see us, so doing this
+ * after lock release is safe */
afs_osi_FreeStr(tc->cellName);
afs_osi_Free(tc, sizeof(struct cell));
}
- ReleaseWriteLock(&tc->lock);
+
ReleaseWriteLock(&afs_xcell);
return code;
}
void
afs_CellInit(void)
{
+ static char CellInit_done = 0;
+
+ if (CellInit_done)
+ return;
+
+ CellInit_done = 1;
+
AFS_RWLOCK_INIT(&afs_xcell, "afs_xcell");
AFS_RWLOCK_INIT(&afsdb_client_lock, "afsdb_client_lock");
AFS_RWLOCK_INIT(&afsdb_req_lock, "afsdb_req_lock");
struct afs_q *cq, *tq;
struct cell *tc;
+#ifdef AFS_CACHE_VNODE_PATH
+ if (cacheDiskType != AFS_FCACHE_TYPE_MEM) {
+ afs_osi_FreeStr(afs_cellname_inode.ufs);
+ }
+#endif
AFS_RWLOCK_INIT(&afs_xcell, "afs_xcell");
for (cq = CellLRU.next; cq != &CellLRU; cq = tq) {
/*!
* Remove a server from a cell's server list.
* \param srvp Server to be removed.
- * \return
+ * \return
*/
void
afs_RemoveCellEntry(struct server *srvp)
/*!
* Check if the given name exists as a cell or alias. Does not lock afs_xcell.
- * \param aname
- * \return
+ * \param aname
+ * \return
*/
static int
afs_CellOrAliasExists_nl(char *aname)
/*!
* Check if the given name exists as a cell or alias. Locks afs_xcell.
* \param aname
- * \return
+ * \return
*/
int
afs_CellOrAliasExists(char *aname)
/*!
* Check if a cell number is valid (also set the used flag).
- * \param cellnum
+ * \param cellnum
* \return 1 - true, 0 - false
*/
int