예제 #1
0
/*
 * Remove a temporary symlink entry from /afs.
 */
int
afs_DynrootVOPRemove(struct vcache *avc, afs_ucred_t *acred, char *aname)
{
    struct afs_dynSymlink **tpps;
    struct afs_dynSymlink *tps;
    int found = 0;

#if defined(AFS_SUN510_ENV)
    if (crgetruid(acred))
#else
    if (afs_cr_uid(acred))
#endif
	return EPERM;

    ObtainWriteLock(&afs_dynSymlinkLock, 97);
    tpps = &afs_dynSymlinkBase;
    while (*tpps) {
	tps = *tpps;
	if (afs_strcasecmp(aname, tps->name) == 0) {
	    afs_osi_Free(tps->name, strlen(tps->name) + 1);
	    afs_osi_Free(tps->target, strlen(tps->target) + 1);
	    *tpps = tps->next;
	    afs_osi_Free(tps, sizeof(*tps));
	    afs_dynSymlinkIndex++;
	    found = 1;
	    break;
	}
	tpps = &(tps->next);
    }
    ReleaseWriteLock(&afs_dynSymlinkLock);
    if (found) {
	afs_DynrootInvalidate();
	return 0;
    }

    if (afs_CellOrAliasExists(aname))
	return EROFS;
    else
	return ENOENT;
}
예제 #2
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;
}
예제 #3
0
/*
 * Create a temporary symlink entry in /afs.
 */
int
afs_DynrootVOPSymlink(struct vcache *avc, afs_ucred_t *acred,
		      char *aname, char *atargetName)
{
    struct afs_dynSymlink *tps;

    if (afs_cr_uid(acred))
	return EPERM;
    if (afs_CellOrAliasExists(aname))
	return EEXIST;

    /* Check if it's already a symlink */
    ObtainWriteLock(&afs_dynSymlinkLock, 91);
    tps = afs_dynSymlinkBase;
    while (tps) {
	if (afs_strcasecmp(aname, tps->name) == 0) {
	    ReleaseWriteLock(&afs_dynSymlinkLock);
	    return EEXIST;
	}
	tps = tps->next;
    }

    /* Doesn't already exist -- go ahead and create it */
    tps = afs_osi_Alloc(sizeof(*tps));
    tps->index = afs_dynSymlinkIndex++;
    tps->next = afs_dynSymlinkBase;
    tps->name = afs_osi_Alloc(strlen(aname) + 1);
    strcpy(tps->name, aname);
    tps->target = afs_osi_Alloc(strlen(atargetName) + 1);
    strcpy(tps->target, atargetName);
    afs_dynSymlinkBase = tps;
    ReleaseWriteLock(&afs_dynSymlinkLock);

    afs_DynrootInvalidate();
    return 0;
}
예제 #4
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;
}