예제 #1
0
파일: partition.c 프로젝트: openafs/openafs
static void
VInitPartition_r(char *path, char *devname, Device dev)
{
    struct DiskPartition64 *dp, *op;

    dp = malloc(sizeof(struct DiskPartition64));
    /* Add it to the end, to preserve order when we print statistics */
    for (op = DiskPartitionList; op; op = op->next) {
	if (!op->next)
	    break;
    }
    if (op)
	op->next = dp;
    else
	DiskPartitionList = dp;
    dp->next = 0;
    dp->name = strdup(path);
    dp->index = volutil_GetPartitionID(path);
#if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV)
    /* Create a lockfile for the partition, of the form /vicepa/Lock/vicepa */
    dp->devName = malloc(2 * strlen(path) + 6);
    strcpy(dp->devName, path);
    strcat(dp->devName, OS_DIRSEP);
    strcat(dp->devName, "Lock");
    mkdir(dp->devName, 0700);
    strcat(dp->devName, path);
    close(afs_open(dp->devName, O_RDWR | O_CREAT, 0600));
    dp->device = dp->index;
#else
    dp->devName = strdup(devname);
    dp->device = dev;
#endif
    dp->lock_fd = INVALID_FD;
    dp->flags = 0;
    dp->f_files = 1;		/* just a default value */
#if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV)
    if (programType == fileServer)
	(void)namei_ViceREADME(VPartitionPath(dp));
#endif
    VSetPartitionDiskUsage_r(dp);
#ifdef AFS_DEMAND_ATTACH_FS
    AddPartitionToTable_r(dp);
    queue_Init(&dp->vol_list.head);
    CV_INIT(&dp->vol_list.cv, "vol list", CV_DEFAULT, 0);
    dp->vol_list.len = 0;
    dp->vol_list.busy = 0;
    {
	char lockpath[MAXPATHLEN+1];
	snprintf(lockpath, MAXPATHLEN, "%s/" AFS_PARTLOCK_FILE, dp->name);
	lockpath[MAXPATHLEN] = '\0';
	VLockFileInit(&dp->headerLockFile, lockpath);

	snprintf(lockpath, MAXPATHLEN, "%s/" AFS_VOLUMELOCK_FILE, dp->name);
	lockpath[MAXPATHLEN] = '\0';
	VLockFileInit(&dp->volLockFile, lockpath);
    }
    VDiskLockInit(&dp->headerLock, &dp->headerLockFile, 1);
#endif /* AFS_DEMAND_ATTACH_FS */
}
예제 #2
0
static struct DiskPartition64 * 
VLookupPartition_r(char * path)
{
    afs_int32 id = volutil_GetPartitionID(path);

    if (id < 0 || id > VOLMAXPARTS)
	return NULL;

    return DiskPartitionTable[id];
}
예제 #3
0
파일: nsubr.c 프로젝트: adeason/openafs
IHandle_t *
GetLinkHandle(char *part, int volid)
{
    int dev;
    Inode ino;
    IHandle_t *lh;

    dev = volutil_GetPartitionID(part);
    ino = namei_MakeSpecIno(volid, VI_LINKTABLE);

    IH_INIT(lh, dev, volid, ino);
    return lh;
}
예제 #4
0
afs_uint32
xfon_voldump(XFILE * X, int flag, char *name)
{
    struct hostent *he;
    struct rx_securityClass *class;
    struct rx_connection *conn;
    struct ktc_principal sname;
    struct ktc_token token;
    struct afsconf_dir *confdir;
    afs_uint32 code, server_addr = 0;
    afs_int32 volid, date, partid = 0;
    int isnum, index;
    char *x, *y;

    /* Parse out the optional date and server location */
    if ((code = rx_Init(0)))
	return code;
    if (!(name = strdup(name)))
	return ENOMEM;
    if ((x = strrchr(name, ','))) {
	*x++ = 0;
	date = atoi(x);
    } else {
	date = 0;
    }
    if ((x = strrchr(name, '@'))) {
	int a, b, c, d;

	*x++ = 0;
	if (!(y = strchr(x, '/'))) {
	    free(name);
	    return VL_BADPARTITION;
	}
	*y++ = 0;
	if (sscanf(x, "%d.%d.%d.%d", &a, &b, &c, &d) == 4 && a >= 0
	    && a <= 255 && b >= 0 && b <= 255 && c >= 0 && c <= 255 && d >= 0
	    && d <= 255) {
	    server_addr = (a << 24) | (b << 16) | (c << 8) | d;
	    server_addr = htonl(server_addr);
	} else {
	    he = gethostbyname(x);
	    if (!he) {
		free(name);
		return VL_BADSERVER;
	    }
	    memcpy(&server_addr, he->h_addr, sizeof(server_addr));
	}
	partid = volutil_GetPartitionID(y);
	if (partid < 0) {
	    free(name);
	    return VL_BADPARTITION;
	}
    }

    /* Get tokens and set up a security object */
    confdir = afsconf_Open(AFSCONF_CLIENTNAME);
    if (!confdir) {
	free(name);
	return AFSCONF_NODB;
    }
    if ((code = afsconf_GetLocalCell(confdir, sname.cell, MAXKTCNAMELEN))) {
	free(name);
	return code;
    }
    afsconf_Close(confdir);
    strcpy(sname.name, "afs");
    sname.instance[0] = 0;
    code = ktc_GetToken(&sname, &token, sizeof(token), 0);
    if (code) {
	class = rxnull_NewClientSecurityObject();
	index = 0;
    } else {
예제 #5
0
/* function called with partition name and volid ID, and which removes all
 * inodes marked with the specified volume ID.  If the volume is a read-only
 * clone, we'll only remove the header inodes, since they're the only inodes
 * marked with that volume ID.  If you want to reclaim all the data, you should
 * nuke the read-write volume ID.
 *
 * Note also that nuking a read-write volume effectively nukes all RO volumes
 * cloned from that RW volume ID, too, since everything except for their
 * indices will be gone.
 */
int
nuke(char *aname, afs_int32 avolid)
{
    /* first process the partition containing this junk */
    struct afs_stat_st tstat;
    struct ilist *ti, *ni, *li=NULL;
    afs_int32 code;
    int i, forceSal;
    char wpath[100];
    char *lastDevComp;
    struct DiskPartition64 *dp;
#ifdef AFS_NAMEI_ENV
    char *path;

    namei_t ufs_name;
#endif /* AFS_NAMEI_ENV */
#ifndef AFS_NAMEI_ENV
    char devName[64];
#endif /* !AFS_NAMEI_ENV */
    IHandle_t *fileH;
    struct ilist *allInodes = 0;

    if (avolid == 0)
	return EINVAL;
    code = afs_stat(aname, &tstat);
    if (code || (dp = VGetPartition(aname, 0)) == NULL) {
	printf("volnuke: partition %s does not exist.\n", aname);
	if (!code) {
	    code = EINVAL;
	}
	return code;
    }
    /* get the device name for the partition */
#if defined(AFS_NAMEI_ENV) && !defined(AFS_NT40_ENV)
    lastDevComp = aname;
#else
#ifdef AFS_NT40_ENV
    lastDevComp = &aname[strlen(aname) - 1];
    *lastDevComp = toupper(*lastDevComp);
#else
    {
	char *tfile = vol_DevName(tstat.st_dev, wpath);
	if (!tfile) {
	    printf("volnuke: can't find %s's device.\n", aname);
	    return 1;
	}
	strcpy(devName, tfile);	/* save this from the static buffer */
    }
    /* aim lastDevComp at the 'foo' of '/dev/foo' */
    lastDevComp = strrchr(devName, OS_DIRSEPC);
    /* either points at slash, or there is no slash; adjust appropriately */
    if (lastDevComp)
	lastDevComp++;
    else
	lastDevComp = devName;
#endif /* AFS_NT40_ENV */
#endif /* AFS_NAMEI_ENV && !AFS_NT40_ENV */

    ObtainWriteLock(&localLock);
    /* OK, we have the mounted on place, aname, the device name (in devName).
     * all we need to do to call ListViceInodes is find the inodes for the
     * volume we're nuking.
     */
    code =
	ListViceInodes(lastDevComp, aname, INVALID_FD, NukeProc, avolid, &forceSal,
		       0, wpath, &allInodes);
    if (code == 0) {
	/* actually do the idecs now */
	for (ti = allInodes; ti; ti = ti->next) {
	    for (i = 0; i < ti->freePtr; i++) {
#ifndef AFS_PTHREAD_ENV
		IOMGR_Poll();	/* keep RPC running */
#endif /* !AFS_PTHREAD_ENV */
		/* idec this inode into oblivion */
#ifdef AFS_NAMEI_ENV
#ifdef AFS_NT40_ENV
		IH_INIT(fileH, (int)(*lastDevComp - 'A'), avolid,
			ti->inode[i]);
#else
		IH_INIT(fileH, (int)volutil_GetPartitionID(aname), avolid,
			ti->inode[i]);
#endif /* AFS_NT40_ENV */
		namei_HandleToName(&ufs_name, fileH);
		path = ufs_name.n_path;
		IH_RELEASE(fileH);
		if (OS_UNLINK(path) < 0) {
		    Log("Nuke: Failed to remove %s\n", path);
		}
#else /* AFS_NAMEI_ENV */
		IH_INIT(fileH, (int)tstat.st_dev, avolid, ti->inode[i]);
		{
		    int j;
		    for (j = 0; j < ti->count[i]; j++) {
			code = IH_DEC(fileH, ti->inode[i], avolid);
		    }
		}
		IH_RELEASE(fileH);
#endif /* AFS_NAMEI_ENV */
	    }
	    ni = ti->next;
	    if (li) free(li);
	    li = ti;
	}
	if (li) free(li);
	code = 0;		/* we really don't care about it except for debugging */
	allInodes = NULL;

	/* at this point, we should try to remove the volume header file itself.
	 * the volume header file is the file named VNNNNN.vol in the UFS file
	 * system, and is a normal file.  As such, it is not stamped with the
	 * volume's ID in its inode, and has to be removed explicitly.
	 */
	code = VDestroyVolumeDiskHeader(dp, avolid, 0);
    } else {
	/* just free things */
	for (ti = allInodes; ti; ti = ni) {
	    ni = ti->next;
	    if (li) free(li);
	    li = ti;
	}
	if (li) free(li);
	allInodes = NULL;
    }
    ReleaseWriteLock(&localLock);
    return code;
}
예제 #6
0
파일: partition.c 프로젝트: openafs/openafs
/* VAttachPartitions() finds the vice partitions on this server. Calls
 * VCheckPartition() to do some basic checks on the partition. If the partition
 * is a valid vice partition, VCheckPartition will add it to the DiskPartition
 * list.
 * Returns the number of errors returned by VCheckPartition. An error in
 * VCheckPartition means that partition is a valid vice partition but the
 * fileserver should not start because of the error found on that partition.
 *
 * AFS_NAMEI_ENV
 * No specific user space file system checks, since we don't know what
 * is being used for vice partitions.
 *
 * Use partition name as devname.
 */
static int
VCheckPartition(char *part, char *devname, int logging)
{
    struct afs_stat_st status;
#if !defined(AFS_LINUX20_ENV) && !defined(AFS_NT40_ENV)
    char AFSIDatPath[MAXPATHLEN];
#endif

    /* Only keep track of "/vicepx" partitions since it can get hairy
     * when NFS mounts are involved.. */
    if (strncmp(part, VICE_PARTITION_PREFIX, VICE_PREFIX_SIZE)) {
	return 0;
    }
    if (volutil_GetPartitionID(part) == -1) {
	Log("Warning: %s is a bad partition name; ignored.\n", part);
	return 0;
    }
    if (afs_stat(part, &status) < 0) {
	Log("VInitVnodes: Couldn't find file system %s; ignored\n", part);
	return 0;
    }
    if (logging) {
	Log("This program is compiled without AFS_NAMEI_ENV, and "
	    "partition %s is mounted with the 'logging' option. "
	    "Using the inode fileserver backend with 'logging' UFS "
	    "partitions causes volume corruption, so please either "
	    "mount the partition without logging, or use the namei "
	    "fileserver backend. Aborting...\n", part);
	return -1;
    }
#ifndef AFS_AIX32_ENV
    if (programType == fileServer) {
	char salvpath[MAXPATHLEN];
	strcpy(salvpath, part);
	strcat(salvpath, "/FORCESALVAGE");
	if (afs_stat(salvpath, &status) == 0) {
	    Log("VInitVnodes: Found %s; aborting\n", salvpath);
	    return -1;
	}
    }
#endif

#if !defined(AFS_LINUX20_ENV) && !defined(AFS_NT40_ENV)
    strcpy(AFSIDatPath, part);
    strcat(AFSIDatPath, "/AFSIDat");
#ifdef AFS_NAMEI_ENV
    if (afs_stat(AFSIDatPath, &status) < 0) {
	DIR *dirp;
	struct dirent *dp;

	dirp = opendir(part);
	opr_Assert(dirp);
	while ((dp = readdir(dirp))) {
	    if (dp->d_name[0] == 'V') {
		Log("This program is compiled with AFS_NAMEI_ENV, but partition %s seems to contain volumes which don't use the namei-interface; aborting\n", part);
		closedir(dirp);
		return -1;
	    }
	}
	closedir(dirp);
    }
#else /* AFS_NAMEI_ENV */
    if (afs_stat(AFSIDatPath, &status) == 0) {
	Log("This program is compiled without AFS_NAMEI_ENV, but partition %s seems to contain volumes which use the namei-interface; aborting\n", part);
	return -1;
    }

#ifdef AFS_SGI_XFS_IOPS_ENV
    if (VerifyXFSInodeSize(part, status.st_fstype) < 0)
	return -1;
#endif
#endif /* AFS_NAMEI_ENV */
#endif /* !AFS_LINUX20_ENV && !AFS_NT40_ENV */

    VInitPartition(part, devname, status.st_dev);

    return 0;
}