Beispiel #1
0
void
InstallUVolumeEntry(struct volume *av, struct uvldbentry *ve, int acell,
		    struct cell *tcell, struct vrequest *areq)
{
    register struct server *ts;
    struct afs_conn *tconn;
    struct cell *cellp;
    register int i, j;
    afs_uint32 serverid;
    afs_int32 mask;
    int k;

    AFS_STATCNT(InstallVolumeEntry);

    /* Determine type of volume we want */
    if ((ve->flags & VLF_RWEXISTS) && (av->volume == ve->volumeId[RWVOL])) {
	mask = VLSF_RWVOL;
    } else if ((ve->flags & VLF_ROEXISTS)
	       && av->volume == ve->volumeId[ROVOL]) {
	mask = VLSF_ROVOL;
	av->states |= VRO;
    } else if ((ve->flags & VLF_BACKEXISTS)
	       && (av->volume == ve->volumeId[BACKVOL])) {
	/* backup always is on the same volume as parent */
	mask = VLSF_RWVOL;
	av->states |= (VRO | VBackup);
    } else {
	mask = 0;		/* Can't find volume in vldb entry */
    }

    /* fill in volume types */
    av->rwVol = ((ve->flags & VLF_RWEXISTS) ? ve->volumeId[RWVOL] : 0);
    av->roVol = ((ve->flags & VLF_ROEXISTS) ? ve->volumeId[ROVOL] : 0);
    av->backVol = ((ve->flags & VLF_BACKEXISTS) ? ve->volumeId[BACKVOL] : 0);

    if (ve->flags & VLF_DFSFILESET)
	av->states |= VForeign;

    cellp = afs_GetCell(acell, 0);

    /* This volume, av, is locked. Zero out the serverHosts[] array 
     * so that if afs_GetServer() decides to replace the server 
     * struct, we don't deadlock trying to afs_ResetVolumeInfo()
     * this volume.
     */
    for (j = 0; j < AFS_MAXHOSTS; j++) {
	av->serverHost[j] = 0;
    }

    /* Gather the list of servers the VLDB says the volume is on
     * and initialize the ve->serverHost[] array. If a server struct
     * is not found, then get the list of addresses for the
     * server, VL_GetAddrsU(), and create a server struct, afs_GetServer().
     */
    for (i = 0, j = 0; i < ve->nServers; i++) {
	if (((ve->serverFlags[i] & mask) == 0)
	    || (ve->serverFlags[i] & VLSF_DONTUSE)) {
	    continue;		/* wrong volume don't use this volume */
	}

	if (!(ve->serverFlags[i] & VLSERVER_FLAG_UUID)) {
	    /* The server has no uuid */
	    serverid = htonl(ve->serverNumber[i].time_low);
	    ts = afs_GetServer(&serverid, 1, acell, cellp->fsport, WRITE_LOCK,
			       (afsUUID *) 0, 0);
	} else {
	    ts = afs_FindServer(0, cellp->fsport, &ve->serverNumber[i], 0);
	    if (ts && (ts->sr_addr_uniquifier == ve->serverUnique[i])
		&& ts->addr) {
		/* uuid, uniquifier, and portal are the same */
	    } else {
		afs_uint32 *addrp, code;
		afs_int32 nentries, unique;
		bulkaddrs addrs;
		ListAddrByAttributes attrs;
		afsUUID uuid;

		memset(&attrs, 0, sizeof(attrs));
		attrs.Mask = VLADDR_UUID;
		attrs.uuid = ve->serverNumber[i];
		memset(&uuid, 0, sizeof(uuid));
		memset(&addrs, 0, sizeof(addrs));
		do {
		    tconn =
			afs_ConnByMHosts(tcell->cellHosts, tcell->vlport,
					 tcell->cellNum, areq, SHARED_LOCK);
		    if (tconn) {
			RX_AFS_GUNLOCK();
			code =
			    VL_GetAddrsU(tconn->id, &attrs, &uuid, &unique,
					 &nentries, &addrs);
			RX_AFS_GLOCK();
		    } else {
			code = -1;
		    }

		    /* Handle corrupt VLDB (defect 7393) */
		    if (code == 0 && nentries == 0)
			code = VL_NOENT;

		} while (afs_Analyze
			 (tconn, code, NULL, areq, -1, SHARED_LOCK, tcell));
		if (code) {
		    /* Better handing of such failures; for now we'll simply retry this call */
		    areq->volumeError = 1;
		    return;
		}

		addrp = addrs.bulkaddrs_val;
		for (k = 0; k < nentries; k++) {
		    addrp[k] = htonl(addrp[k]);
		}
		ts = afs_GetServer(addrp, nentries, acell, cellp->fsport,
				   WRITE_LOCK, &ve->serverNumber[i],
				   ve->serverUnique[i]);
		xdr_free((xdrproc_t) xdr_bulkaddrs, &addrs);
	    }
	}
	av->serverHost[j] = ts;

	/* The cell field could be 0 if the server entry was created
	 * first with the 'fs setserverprefs' call which doesn't set
	 * the cell field. Thus if the afs_GetServer call above
	 * follows later on it will find the server entry thus it will
	 * simply return without setting any fields, so we set the
	 * field ourselves below.
	 */
	if (!ts->cell)
	    ts->cell = cellp;
	afs_PutServer(ts, WRITE_LOCK);
	j++;
    }

    afs_SortServers(av->serverHost, AFS_MAXHOSTS);
}				/*InstallVolumeEntry */
Beispiel #2
0
void
InstallNVolumeEntry(struct volume *av, struct nvldbentry *ve, int acell)
{
    register struct server *ts;
    struct cell *cellp;
    register int i, j;
    afs_int32 mask;
    afs_uint32 temp;

    AFS_STATCNT(InstallVolumeEntry);

    /* Determine type of volume we want */
    if ((ve->flags & VLF_RWEXISTS) && (av->volume == ve->volumeId[RWVOL])) {
	mask = VLSF_RWVOL;
    } else if ((ve->flags & VLF_ROEXISTS)
	       && (av->volume == ve->volumeId[ROVOL])) {
	mask = VLSF_ROVOL;
	av->states |= VRO;
    } else if ((ve->flags & VLF_BACKEXISTS)
	       && (av->volume == ve->volumeId[BACKVOL])) {
	/* backup always is on the same volume as parent */
	mask = VLSF_RWVOL;
	av->states |= (VRO | VBackup);
    } else {
	mask = 0;		/* Can't find volume in vldb entry */
    }

    /* fill in volume types */
    av->rwVol = ((ve->flags & VLF_RWEXISTS) ? ve->volumeId[RWVOL] : 0);
    av->roVol = ((ve->flags & VLF_ROEXISTS) ? ve->volumeId[ROVOL] : 0);
    av->backVol = ((ve->flags & VLF_BACKEXISTS) ? ve->volumeId[BACKVOL] : 0);

    if (ve->flags & VLF_DFSFILESET)
	av->states |= VForeign;

    cellp = afs_GetCell(acell, 0);

    /* This volume, av, is locked. Zero out the serverHosts[] array 
     * so that if afs_GetServer() decides to replace the server 
     * struct, we don't deadlock trying to afs_ResetVolumeInfo()
     * this volume.
     */
    for (j = 0; j < AFS_MAXHOSTS; j++) {
	av->serverHost[j] = 0;
    }

    /* Step through the VLDB entry making sure each server listed is there */
    for (i = 0, j = 0; i < ve->nServers; i++) {
	if (((ve->serverFlags[i] & mask) == 0)
	    || (ve->serverFlags[i] & VLSF_DONTUSE)) {
	    continue;		/* wrong volume or don't use this volume */
	}

	temp = htonl(ve->serverNumber[i]);
	ts = afs_GetServer(&temp, 1, acell, cellp->fsport, WRITE_LOCK,
			   (afsUUID *) 0, 0);
	av->serverHost[j] = ts;
	/*
	 * The cell field could be 0 if the server entry was created
	 * first with the 'fs setserverprefs' call which doesn't set
	 * the cell field. Thus if the afs_GetServer call above
	 * follows later on it will find the server entry thus it will
	 * simply return without setting any fields, so we set the
	 * field ourselves below.
	 */
	if (!ts->cell)
	    ts->cell = cellp;
	afs_PutServer(ts, WRITE_LOCK);
	j++;
    }
    if (j < AFS_MAXHOSTS) {
	av->serverHost[j++] = 0;
    }
    afs_SortServers(av->serverHost, AFS_MAXHOSTS);
}				/*InstallNVolumeEntry */
Beispiel #3
0
void
LockAndInstallNVolumeEntry(struct volume *av, struct nvldbentry *ve, int acell)
{
    struct server *ts;
    struct cell *cellp;
    int i, j;
    afs_int32 mask;
    afs_uint32 temp;
    char types = 0;
    struct server *serverHost[AFS_MAXHOSTS];

    AFS_STATCNT(InstallVolumeEntry);

    memset(serverHost, 0, sizeof(serverHost));

    /* Determine type of volume we want */
    if ((ve->flags & VLF_RWEXISTS) && (av->volume == ve->volumeId[RWVOL])) {
	mask = VLSF_RWVOL;
    } else if ((ve->flags & VLF_ROEXISTS)
	       && (av->volume == ve->volumeId[ROVOL])) {
	mask = VLSF_ROVOL;
	types |= VRO;
    } else if ((ve->flags & VLF_BACKEXISTS)
	       && (av->volume == ve->volumeId[BACKVOL])) {
	/* backup always is on the same volume as parent */
	mask = VLSF_RWVOL;
	types |= (VRO | VBackup);
    } else {
	mask = 0;		/* Can't find volume in vldb entry */
    }

    cellp = afs_GetCell(acell, 0);

    /* Step through the VLDB entry making sure each server listed is there */
    for (i = 0, j = 0; i < ve->nServers; i++) {
	if (((ve->serverFlags[i] & mask) == 0)
	    || (ve->serverFlags[i] & VLSF_DONTUSE)) {
	    continue;		/* wrong volume or don't use this volume */
	}

	temp = htonl(ve->serverNumber[i]);
	ts = afs_GetServer(&temp, 1, acell, cellp->fsport, WRITE_LOCK,
			   (afsUUID *) 0, 0, av);
	serverHost[j] = ts;
	/*
	 * The cell field could be 0 if the server entry was created
	 * first with the 'fs setserverprefs' call which doesn't set
	 * the cell field. Thus if the afs_GetServer call above
	 * follows later on it will find the server entry thus it will
	 * simply return without setting any fields, so we set the
	 * field ourselves below.
	 */
	if (!ts->cell)
	    ts->cell = cellp;
	afs_PutServer(ts, WRITE_LOCK);
	j++;
    }

    ObtainWriteLock(&av->lock, 110);

    memcpy(av->serverHost, serverHost, sizeof(serverHost));

    /* from above */
    av->states |= types;

    /* fill in volume types */
    av->rwVol = ((ve->flags & VLF_RWEXISTS) ? ve->volumeId[RWVOL] : 0);
    av->roVol = ((ve->flags & VLF_ROEXISTS) ? ve->volumeId[ROVOL] : 0);
    av->backVol = ((ve->flags & VLF_BACKEXISTS) ? ve->volumeId[BACKVOL] : 0);

    if (ve->flags & VLF_DFSFILESET)
	av->states |= VForeign;

    afs_SortServers(av->serverHost, AFS_MAXHOSTS);
}				/*InstallNVolumeEntry */