Пример #1
0
/*!
 * Set the primary cell name to the given cell name.
 * \param acellName Cell name.
 * \return 0 for success, < 0 for error.
 */
afs_int32
afs_SetPrimaryCell(char *acellName)
{
    ObtainWriteLock(&afs_xcell, 691);
    if (afs_thiscell)
	afs_osi_FreeStr(afs_thiscell);
    afs_thiscell = afs_strdup(acellName);
    ReleaseWriteLock(&afs_xcell);
    return 0;
}
Пример #2
0
/*!
 * Look up AFSDB for given cell name and create locally.
 * \param acellName Cell name.
 */
void
afs_LookupAFSDB(char *acellName)
{
    int code;
    char *cellName = afs_strdup(acellName);

    code = afs_GetCellHostsAFSDB(cellName);
    afs_Trace2(afs_iclSetp, CM_TRACE_AFSDB, ICL_TYPE_STRING, cellName,
               ICL_TYPE_INT32, code);
    afs_osi_FreeStr(cellName);
}
Пример #3
0
/*!
 * Create new cell alias entry and update dynroot vnode.
 * \param alias
 * \param cell
 * \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;
}
Пример #4
0
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_osi_Alloc(sn * sizeof(afs_int32));
    osi_Assert(a_hosts->serverList_val != NULL);

    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;
}
Пример #5
0
/*!
 * Create a new cell name, optional cell number.
 * \param  name Name of cell.
 * \param cellnum Cellname number.
 * \return Initialized structure.
 */
static struct cell_name *
afs_cellname_new(char *name, afs_int32 cellnum)
{
    struct cell_name *cn;

    if (cellnum == 0)
	cellnum = afs_cellnum_next;

    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 (cellnum >= afs_cellnum_next)
	afs_cellnum_next = cellnum + 1;

    return cn;
}
Пример #6
0
/*
 * Inform dynroot that a new vnode is being created.  Return value
 * is non-zero if this vnode is handled by dynroot, in which case
 * FetchStatus will be filled in.
 */
int
afs_DynrootNewVnode(struct vcache *avc, struct AFSFetchStatus *status)
{
    char *bp, tbuf[CVBS];

    if (_afs_IsDynrootFid(&avc->f.fid)) {
	if (!afs_dynrootEnable)
	    return 0;
	afs_GetDynroot(0, 0, status);
	afs_PutDynroot();
	return 1;
    }

    if (afs_IsDynrootMount(avc)) {
	afs_GetDynrootMount(0, 0, status);
	afs_PutDynroot();
	return 1;
    }

    /*
     * Check if this is an entry under /afs, e.g. /afs/cellname.
     */
    if (avc->f.fid.Cell == afs_dynrootCell
	&& avc->f.fid.Fid.Volume == AFS_DYNROOT_VOLUME) {

	struct cell *c;
	struct cell_alias *ca;
	int namelen, linklen, cellidx, rw;

	memset(status, 0, sizeof(struct AFSFetchStatus));

	status->FileType = SymbolicLink;
	status->LinkCount = 1;
	status->DataVersion = 1;
	status->CallerAccess = PRSFS_LOOKUP | PRSFS_READ;
	status->AnonymousAccess = PRSFS_LOOKUP | PRSFS_READ;
	status->ParentVnode = 1;
	status->ParentUnique = 1;

	if (VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode) == VN_TYPE_SYMLINK) {
	    struct afs_dynSymlink *ts;
	    int index = VNUM_TO_VNID(avc->f.fid.Fid.Vnode);

	    ObtainReadLock(&afs_dynSymlinkLock);
	    ts = afs_dynSymlinkBase;
	    while (ts) {
		if (ts->index == index)
		    break;
		ts = ts->next;
	    }

	    if (ts) {
		linklen = strlen(ts->target);
		avc->linkData = afs_osi_Alloc(linklen + 1);
		strcpy(avc->linkData, ts->target);

		status->Length = linklen;
		status->UnixModeBits = 0755;
	    }
	    ReleaseReadLock(&afs_dynSymlinkLock);

	    return ts ? 1 : 0;
	}

	if (VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode) != VN_TYPE_CELL
	    && VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode) != VN_TYPE_ALIAS
	    && VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode) != VN_TYPE_MOUNT) {
	    afs_warn("dynroot vnode inconsistency, unknown VNTYPE %d\n",
		     VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode));
	    return 0;
	}

	cellidx = VNUM_TO_CIDX(avc->f.fid.Fid.Vnode);
	rw = VNUM_TO_RW(avc->f.fid.Fid.Vnode);

	if (VNUM_TO_VNTYPE(avc->f.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;
	    }

	    /*
	     * linkData needs to contain the name of the cell
	     * we're aliasing for.
	     */
	    realName = ca->cell;
	    if (!realName) {
		afs_warn("dynroot: alias %s missing real cell name\n",
			 ca->alias);
		avc->linkData = afs_strdup("unknown");
		linklen = 7;
	    } else {
		int namelen = strlen(realName);
		linklen = rw + namelen;
		avc->linkData = afs_osi_Alloc(linklen + 1);
		strcpy(avc->linkData, rw ? "." : "");
		afs_strcat(avc->linkData, realName);
	    }

	    status->UnixModeBits = 0755;
	    afs_PutCellAlias(ca);

	} else if (VNUM_TO_VNTYPE(avc->f.fid.Fid.Vnode) == VN_TYPE_MOUNT) {
	    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:volumeid"
	     */
	    namelen = strlen(c->cellName);
	    bp = afs_cv2string(&tbuf[CVBS], avc->f.fid.Fid.Unique);
	    linklen = 2 + namelen + strlen(bp);
	    avc->linkData = afs_osi_Alloc(linklen + 1);
	    strcpy(avc->linkData, "%");
	    afs_strcat(avc->linkData, c->cellName);
	    afs_strcat(avc->linkData, ":");
	    afs_strcat(avc->linkData, bp);

	    status->UnixModeBits = 0644;
	    status->ParentVnode = AFS_DYNROOT_MOUNT_VNODE;
	    afs_PutCell(c, READ_LOCK);

	} 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"
	     */
	    namelen = strlen(c->cellName);
	    linklen = 1 + namelen + 10;
	    avc->linkData = afs_osi_Alloc(linklen + 1);
	    strcpy(avc->linkData, rw ? "%" : "#");
	    afs_strcat(avc->linkData, c->cellName);
	    afs_strcat(avc->linkData, ":root.cell");

	    status->UnixModeBits = 0644;
	    afs_PutCell(c, READ_LOCK);
	}

	status->Length = linklen;
	return 1;
    }

    return 0;
}
Пример #7
0
/*!
 * 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 fsport File server port.
 * \param vlport Volume server port.
 * \param timeout Cell timeout value, 0 means static AFSDB entry.
 * \return
 */
afs_int32
afs_NewCell(char *acellName, afs_int32 * acellHosts, int aflags,
	    char *linkedcname, u_short fsport, u_short vlport, int timeout)
{
    struct cell *tc, *tcl = 0;
    afs_int32 i, newc = 0, code = 0;

    AFS_STATCNT(afs_NewCell);

    ObtainWriteLock(&afs_xcell, 103);

    tc = afs_FindCellByName_nl(acellName, READ_LOCK);
    if (tc) {
	aflags &= ~CNoSUID;
    } else {
	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));
	AFS_RWLOCK_INIT(&tc->lock, "cell lock");
	newc = 1;
	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 = EEXIST;		/* This code is checked for in afs_LookupAFSDB */
	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; i < AFS_MAXCELLHOSTS; i++) {
	if (!tc->cellHosts[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;
	}
	tcl = afs_FindCellByName_nl(linkedcname, READ_LOCK);
	if (!tcl) {
	    code = ENOENT;
	    goto bad;
	}
	if (tcl->lcellp) {	/* XXX Overwriting if one existed before! XXX */
	    tcl->lcellp->lcellp = (struct cell *)0;
	    tcl->lcellp->states &= ~CLinkedCell;
	}
	tc->lcellp = tcl;
	tcl->lcellp = tc;
    }
    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.*/
	struct server *ts;
	afs_uint32 temp = acellHosts[i];
	if (!temp)
	    break;
	ts = afs_GetServer(&temp, 1, 0, tc->vlport, WRITE_LOCK, NULL, 0);
	ts->cell = tc;
	ts->flags &= ~SRVR_ISGONE;
	/* Set the server as a host of the new cell. */
	tc->cellHosts[i] = ts;
	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;

	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);
    if (!(aflags & CHush))
	afs_DynrootInvalidate();
    return 0;

  bad:
    if (newc) {
	afs_osi_FreeStr(tc->cellName);
	afs_osi_Free(tc, sizeof(struct cell));
    }
    ReleaseWriteLock(&tc->lock);
    ReleaseWriteLock(&afs_xcell);
    return code;
}