Exemplo n.º 1
0
/*
 * Called whenever an array is shutdown
 */
static void 
rf_UnconfigureArray()
{
	int     rc;

	RF_LOCK_MUTEX(configureMutex);
	if (--configureCount == 0) {	/* if no active configurations, shut
					 * everything down */
		isconfigged = 0;

		rc = rf_ShutdownList(&globalShutdown);
		if (rc) {
			RF_ERRORMSG1("RAIDFRAME: unable to do global shutdown, rc=%d\n", rc);
		}
		rf_shutdown_threadid();

		/*
	         * We must wait until now, because the AllocList module
	         * uses the DebugMem module.
	         */
		if (rf_memDebug)
			rf_print_unfreed();
	}
	RF_UNLOCK_MUTEX(configureMutex);
}
Exemplo n.º 2
0
static void
set_debug_option(char *name, long val)
{
	RF_DebugName_t *p;

	for (p = rf_debugNames; p->name; p++) {
		if (!strcmp(p->name, name)) {
			*(p->ptr) = val;
			printf("[Set debug variable %s to %ld]\n", name, val);
			return;
		}
	}
	RF_ERRORMSG1("Unknown debug string \"%s\"\n", name);
}
Exemplo n.º 3
0
/****************************************************************************************
 *
 * initialize the disks comprising the array
 *
 * We want the spare disks to have regular row,col numbers so that we can easily
 * substitue a spare for a failed disk.  But, the driver code assumes throughout
 * that the array contains numRow by numCol _non-spare_ disks, so it's not clear
 * how to fit in the spares.  This is an unfortunate holdover from raidSim.  The
 * quick and dirty fix is to make row zero bigger than the rest, and put all the
 * spares in it.  This probably needs to get changed eventually.
 *
 ***************************************************************************************/
int 
rf_ConfigureDisks(
    RF_ShutdownList_t ** listp,
    RF_Raid_t * raidPtr,
    RF_Config_t * cfgPtr)
{
	RF_RaidDisk_t **disks;
	RF_SectorCount_t min_numblks = (RF_SectorCount_t) 0x7FFFFFFFFFFFLL;
	RF_RowCol_t r, c;
	int     bs, ret;
	unsigned i, count, foundone = 0, numFailuresThisRow;
	RF_DiskOp_t *rdcap_op = NULL, *tur_op = NULL;
	int     num_rows_done, num_cols_done;

	struct proc *proc = 0;
#if !defined(__NetBSD__) && !defined(__OpenBSD__)
	ret = rf_SCSI_AllocReadCapacity(&rdcap_op);
	if (ret)
		goto fail;
	ret = rf_SCSI_AllocTUR(&tur_op);
	if (ret)
		goto fail;
#endif				/* !__NetBSD__ && !__OpenBSD__ */

	num_rows_done = 0;
	num_cols_done = 0;


	RF_CallocAndAdd(disks, raidPtr->numRow, sizeof(RF_RaidDisk_t *), (RF_RaidDisk_t **), raidPtr->cleanupList);
	if (disks == NULL) {
		ret = ENOMEM;
		goto fail;
	}
	raidPtr->Disks = disks;


	proc = raidPtr->proc;	/* Blah XXX */

	/* get space for the device-specific stuff... */
	RF_CallocAndAdd(raidPtr->raid_cinfo, raidPtr->numRow,
	    sizeof(struct raidcinfo *), (struct raidcinfo **),
	    raidPtr->cleanupList);
	if (raidPtr->raid_cinfo == NULL) {
		ret = ENOMEM;
		goto fail;
	}
	for (r = 0; r < raidPtr->numRow; r++) {
		numFailuresThisRow = 0;
		RF_CallocAndAdd(disks[r], raidPtr->numCol + ((r == 0) ? raidPtr->numSpare : 0), sizeof(RF_RaidDisk_t), (RF_RaidDisk_t *), raidPtr->cleanupList);
		if (disks[r] == NULL) {
			ret = ENOMEM;
			goto fail;
		}
		/* get more space for device specific stuff.. */
		RF_CallocAndAdd(raidPtr->raid_cinfo[r],
		    raidPtr->numCol + ((r == 0) ? raidPtr->numSpare : 0),
		    sizeof(struct raidcinfo), (struct raidcinfo *),
		    raidPtr->cleanupList);
		if (raidPtr->raid_cinfo[r] == NULL) {
			ret = ENOMEM;
			goto fail;
		}
		for (c = 0; c < raidPtr->numCol; c++) {
			ret = rf_ConfigureDisk(raidPtr, &cfgPtr->devnames[r][c][0],
			    &disks[r][c], rdcap_op, tur_op,
			    cfgPtr->devs[r][c], r, c);
			if (ret)
				goto fail;
			if (disks[r][c].status != rf_ds_optimal) {
				numFailuresThisRow++;
			} else {
				if (disks[r][c].numBlocks < min_numblks)
					min_numblks = disks[r][c].numBlocks;
				DPRINTF7("Disk at row %d col %d: dev %s numBlocks %ld blockSize %d (%ld MB)\n",
				    r, c, disks[r][c].devname,
				    (long int) disks[r][c].numBlocks,
				    disks[r][c].blockSize,
				    (long int) disks[r][c].numBlocks * disks[r][c].blockSize / 1024 / 1024);
			}
			num_cols_done++;
		}
		/* XXX fix for n-fault tolerant */
		if (numFailuresThisRow > 0)
			raidPtr->status[r] = rf_rs_degraded;
		num_rows_done++;
	}
#if (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(_KERNEL)
	/* we do nothing */
#else
	rf_SCSI_FreeDiskOp(rdcap_op, 1);
	rdcap_op = NULL;
	rf_SCSI_FreeDiskOp(tur_op, 0);
	tur_op = NULL;
#endif
	/* all disks must be the same size & have the same block size, bs must
	 * be a power of 2 */
	bs = 0;
	for (foundone = r = 0; !foundone && r < raidPtr->numRow; r++) {
		for (c = 0; !foundone && c < raidPtr->numCol; c++) {
			if (disks[r][c].status == rf_ds_optimal) {
				bs = disks[r][c].blockSize;
				foundone = 1;
			}
		}
	}
	if (!foundone) {
		RF_ERRORMSG("RAIDFRAME: Did not find any live disks in the array.\n");
		ret = EINVAL;
		goto fail;
	}
	for (count = 0, i = 1; i; i <<= 1)
		if (bs & i)
			count++;
	if (count != 1) {
		RF_ERRORMSG1("Error: block size on disks (%d) must be a power of 2\n", bs);
		ret = EINVAL;
		goto fail;
	}
	for (r = 0; r < raidPtr->numRow; r++) {
		for (c = 0; c < raidPtr->numCol; c++) {
			if (disks[r][c].status == rf_ds_optimal) {
				if (disks[r][c].blockSize != bs) {
					RF_ERRORMSG2("Error: block size of disk at r %d c %d different from disk at r 0 c 0\n", r, c);
					ret = EINVAL;
					goto fail;
				}
				if (disks[r][c].numBlocks != min_numblks) {
					RF_ERRORMSG3("WARNING: truncating disk at r %d c %d to %d blocks\n",
					    r, c, (int) min_numblks);
					disks[r][c].numBlocks = min_numblks;
				}
			}
		}
	}

	raidPtr->sectorsPerDisk = min_numblks;
	raidPtr->logBytesPerSector = ffs(bs) - 1;
	raidPtr->bytesPerSector = bs;
	raidPtr->sectorMask = bs - 1;
	return (0);

fail:

#if (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(_KERNEL)

	for (r = 0; r < raidPtr->numRow; r++) {
		for (c = 0; c < raidPtr->numCol; c++) {
			/* Cleanup.. */
#ifdef DEBUG
			printf("Cleaning up row: %d col: %d\n", r, c);
#endif
			if (raidPtr->raid_cinfo[r][c].ci_vp) {
				(void) vn_close(raidPtr->raid_cinfo[r][c].ci_vp,
				    FREAD | FWRITE, proc->p_ucred, proc);
			}
		}
	}
	/* Space allocated for raid_vpp will get cleaned up at some other
	 * point */
	/* XXX Need more #ifdefs in the above... */

#else

	if (rdcap_op)
		rf_SCSI_FreeDiskOp(rdcap_op, 1);
	if (tur_op)
		rf_SCSI_FreeDiskOp(tur_op, 0);

#endif
	return (ret);
}
Exemplo n.º 4
0
/****************************************************************************************
 * set up the data structures describing the spare disks in the array
 * recall from the above comment that the spare disk descriptors are stored
 * in row zero, which is specially expanded to hold them.
 ***************************************************************************************/
int 
rf_ConfigureSpareDisks(
    RF_ShutdownList_t ** listp,
    RF_Raid_t * raidPtr,
    RF_Config_t * cfgPtr)
{
	char    buf[256];
	int     r, c, i, ret;
	RF_DiskOp_t *rdcap_op = NULL, *tur_op = NULL;
	unsigned bs;
	RF_RaidDisk_t *disks;
	int     num_spares_done;

	struct proc *proc;

#if !defined(__NetBSD__) && !defined(__OpenBSD__)
	ret = rf_SCSI_AllocReadCapacity(&rdcap_op);
	if (ret)
		goto fail;
	ret = rf_SCSI_AllocTUR(&tur_op);
	if (ret)
		goto fail;
#endif				/* !__NetBSD__ && !__OpenBSD__ */

	num_spares_done = 0;

	proc = raidPtr->proc;
	/* The space for the spares should have already been allocated by
	 * ConfigureDisks() */

	disks = &raidPtr->Disks[0][raidPtr->numCol];
	for (i = 0; i < raidPtr->numSpare; i++) {
		ret = rf_ConfigureDisk(raidPtr, &cfgPtr->spare_names[i][0],
		    &disks[i], rdcap_op, tur_op,
		    cfgPtr->spare_devs[i], 0, raidPtr->numCol + i);
		if (ret)
			goto fail;
		if (disks[i].status != rf_ds_optimal) {
			RF_ERRORMSG1("Warning: spare disk %s failed TUR\n", buf);
		} else {
			disks[i].status = rf_ds_spare;	/* change status to
							 * spare */
			DPRINTF6("Spare Disk %d: dev %s numBlocks %ld blockSize %d (%ld MB)\n", i,
			    disks[i].devname,
			    (long int) disks[i].numBlocks, disks[i].blockSize,
			    (long int) disks[i].numBlocks * disks[i].blockSize / 1024 / 1024);
		}
		num_spares_done++;
	}
#if (defined(__NetBSD__) || defined(__OpenBSD__)) && (_KERNEL)

#else
	rf_SCSI_FreeDiskOp(rdcap_op, 1);
	rdcap_op = NULL;
	rf_SCSI_FreeDiskOp(tur_op, 0);
	tur_op = NULL;
#endif

	/* check sizes and block sizes on spare disks */
	bs = 1 << raidPtr->logBytesPerSector;
	for (i = 0; i < raidPtr->numSpare; i++) {
		if (disks[i].blockSize != bs) {
			RF_ERRORMSG3("Block size of %d on spare disk %s is not the same as on other disks (%d)\n", disks[i].blockSize, disks[i].devname, bs);
			ret = EINVAL;
			goto fail;
		}
		if (disks[i].numBlocks < raidPtr->sectorsPerDisk) {
			RF_ERRORMSG3("Spare disk %s (%d blocks) is too small to serve as a spare (need %ld blocks)\n",
			    disks[i].devname, disks[i].blockSize, (long int) raidPtr->sectorsPerDisk);
			ret = EINVAL;
			goto fail;
		} else
			if (disks[i].numBlocks > raidPtr->sectorsPerDisk) {
				RF_ERRORMSG2("Warning: truncating spare disk %s to %ld blocks\n", disks[i].devname, (long int) raidPtr->sectorsPerDisk);

				disks[i].numBlocks = raidPtr->sectorsPerDisk;
			}
	}

	return (0);

fail:
#if (defined(__NetBSD__) || defined(__OpenBSD__)) && defined(_KERNEL)

	/* Release the hold on the main components.  We've failed to allocate
	 * a spare, and since we're failing, we need to free things.. */

	for (r = 0; r < raidPtr->numRow; r++) {
		for (c = 0; c < raidPtr->numCol; c++) {
			/* Cleanup.. */
#ifdef DEBUG
			printf("Cleaning up row: %d col: %d\n", r, c);
#endif
			if (raidPtr->raid_cinfo[r][c].ci_vp) {
				(void) vn_close(raidPtr->raid_cinfo[r][c].ci_vp,
				    FREAD | FWRITE, proc->p_ucred, proc);
			}
		}
	}

	for (i = 0; i < raidPtr->numSpare; i++) {
		/* Cleanup.. */
#ifdef DEBUG
		printf("Cleaning up spare: %d\n", i);
#endif
		if (raidPtr->raid_cinfo[0][raidPtr->numCol + i].ci_vp) {
			(void) vn_close(raidPtr->raid_cinfo[0][raidPtr->numCol + i].ci_vp,
			    FREAD | FWRITE, proc->p_ucred, proc);
		}
	}

#else

	if (rdcap_op)
		rf_SCSI_FreeDiskOp(rdcap_op, 1);
	if (tur_op)
		rf_SCSI_FreeDiskOp(tur_op, 0);

#endif

	return (ret);
}
Exemplo n.º 5
0
/****************************************************************************
 * Set up the data structures describing the spare disks in the array.
 * Recall from the above comment that the spare disk descriptors are stored
 * in row zero, which is specially expanded to hold them.
 ****************************************************************************/
int
rf_ConfigureSpareDisks(RF_ShutdownList_t ** listp, RF_Raid_t * raidPtr,
    RF_Config_t * cfgPtr)
{
	int i, ret;
	unsigned int bs;
	RF_RaidDisk_t *disks;
	int num_spares_done;

	num_spares_done = 0;

	/*
	 * The space for the spares should have already been allocated by
	 * ConfigureDisks().
	 */

	disks = &raidPtr->Disks[0][raidPtr->numCol];
	for (i = 0; i < raidPtr->numSpare; i++) {
		ret = rf_ConfigureDisk(raidPtr, &cfgPtr->spare_names[i][0],
		    &disks[i], 0, raidPtr->numCol + i);
		if (ret)
			goto fail;
		if (disks[i].status != rf_ds_optimal) {
			RF_ERRORMSG1("Warning: spare disk %s failed TUR\n",
			    &cfgPtr->spare_names[i][0]);
		} else {
			/* Change status to spare. */
			disks[i].status = rf_ds_spare;
			DPRINTF6("Spare Disk %d: dev %s numBlocks %ld"
			    " blockSize %d (%ld MB).\n", i, disks[i].devname,
			    (long int) disks[i].numBlocks, disks[i].blockSize,
			    (long int) disks[i].numBlocks *
			    disks[i].blockSize / 1024 / 1024);
		}
		num_spares_done++;
	}

	/* Check sizes and block sizes on spare disks. */
	bs = 1 << raidPtr->logBytesPerSector;
	for (i = 0; i < raidPtr->numSpare; i++) {
		if (disks[i].blockSize != bs) {
			RF_ERRORMSG3("Block size of %d on spare disk %s is"
			    " not the same as on other disks (%d).\n",
			    disks[i].blockSize, disks[i].devname, bs);
			ret = EINVAL;
			goto fail;
		}
		if (disks[i].numBlocks < raidPtr->sectorsPerDisk) {
			RF_ERRORMSG3("Spare disk %s (%llu blocks) is too small"
			    " to serve as a spare (need %llu blocks).\n",
			    disks[i].devname, disks[i].numBlocks,
			    raidPtr->sectorsPerDisk);
			ret = EINVAL;
			goto fail;
		} else
			if (disks[i].numBlocks > raidPtr->sectorsPerDisk) {
				RF_ERRORMSG2("Warning: truncating spare disk"
				    " %s to %llu blocks.\n", disks[i].devname,
				    raidPtr->sectorsPerDisk);

				disks[i].numBlocks = raidPtr->sectorsPerDisk;
			}
	}

	return (0);

fail:

	/*
	 * Release the hold on the main components. We've failed to allocate
	 * a spare, and since we're failing, we need to free things...
	 *
	 * XXX Failing to allocate a spare is *not* that big of a deal...
	 * We *can* survive without it, if need be, esp. if we get hot
	 * adding working.
	 * If we don't fail out here, then we need a way to remove this spare...
	 * That should be easier to do here than if we are "live"...
	 */

	rf_UnconfigureVnodes(raidPtr);

	return (ret);
}
Exemplo n.º 6
0
/****************************************************************************
 *
 * Initialize the disks comprising the array.
 *
 * We want the spare disks to have regular row,col numbers so that we can
 * easily substitue a spare for a failed disk. But, the driver code assumes
 * throughout that the array contains numRow by numCol _non-spare_ disks, so
 * it's not clear how to fit in the spares. This is an unfortunate holdover
 * from raidSim. The quick and dirty fix is to make row zero bigger than the
 * rest, and put all the spares in it. This probably needs to get changed
 * eventually.
 *
 ****************************************************************************/
int
rf_ConfigureDisks(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
    RF_Config_t *cfgPtr)
{
	RF_RaidDisk_t **disks;
	RF_SectorCount_t min_numblks = (RF_SectorCount_t) 0x7FFFFFFFFFFFLL;
	RF_RowCol_t r, c;
	int bs, ret;
	unsigned i, count, foundone = 0, numFailuresThisRow;
	int force;

	force = cfgPtr->force;

 	ret = rf_AllocDiskStructures(raidPtr, cfgPtr);
 	if (ret)
		goto fail;

 	disks = raidPtr->Disks;

	for (r = 0; r < raidPtr->numRow; r++) {
		numFailuresThisRow = 0;
		for (c = 0; c < raidPtr->numCol; c++) {
			ret = rf_ConfigureDisk(raidPtr,
			    &cfgPtr->devnames[r][c][0], &disks[r][c], r, c);

			if (ret)
				goto fail;

			if (disks[r][c].status == rf_ds_optimal) {
				raidread_component_label(
					 raidPtr->raid_cinfo[r][c].ci_dev,
					 raidPtr->raid_cinfo[r][c].ci_vp,
					 &raidPtr->raid_cinfo[r][c].ci_label);
			}

			if (disks[r][c].status != rf_ds_optimal) {
				numFailuresThisRow++;
			} else {
				if (disks[r][c].numBlocks < min_numblks)
					min_numblks = disks[r][c].numBlocks;
				DPRINTF7("Disk at row %d col %d: dev %s"
				    " numBlocks %ld blockSize %d (%ld MB)\n",
				    r, c, disks[r][c].devname,
				    (long int) disks[r][c].numBlocks,
				    disks[r][c].blockSize,
				    (long int) disks[r][c].numBlocks *
				     disks[r][c].blockSize / 1024 / 1024);
			}
		}
		/* XXX Fix for n-fault tolerant. */
		/*
		 * XXX This should probably check to see how many failures
		 * we can handle for this configuration !
		 */
		if (numFailuresThisRow > 0)
			raidPtr->status[r] = rf_rs_degraded;
	}
	/*
	 * All disks must be the same size & have the same block size, bs must
	 * be a power of 2.
	 */
	bs = 0;
	for (foundone = r = 0; !foundone && r < raidPtr->numRow; r++) {
		for (c = 0; !foundone && c < raidPtr->numCol; c++) {
			if (disks[r][c].status == rf_ds_optimal) {
				bs = disks[r][c].blockSize;
				foundone = 1;
			}
		}
	}
	if (!foundone) {
		RF_ERRORMSG("RAIDFRAME: Did not find any live disks in"
		    " the array.\n");
		ret = EINVAL;
		goto fail;
	}
	for (count = 0, i = 1; i; i <<= 1)
		if (bs & i)
			count++;
	if (count != 1) {
		RF_ERRORMSG1("Error: block size on disks (%d) must be a"
		    " power of 2.\n", bs);
		ret = EINVAL;
		goto fail;
	}

	if (rf_CheckLabels(raidPtr, cfgPtr)) {
		printf("raid%d: There were fatal errors\n", raidPtr->raidid);
		if (force != 0) {
			printf("raid%d: Fatal errors being ignored.\n",
			    raidPtr->raidid);
		} else {
			ret = EINVAL;
			goto fail;
		}
	}

	for (r = 0; r < raidPtr->numRow; r++) {
		for (c = 0; c < raidPtr->numCol; c++) {
			if (disks[r][c].status == rf_ds_optimal) {
				if (disks[r][c].blockSize != bs) {
					RF_ERRORMSG2("Error: block size of"
					    " disk at r %d c %d different from"
					    " disk at r 0 c 0.\n", r, c);
					ret = EINVAL;
					goto fail;
				}
				if (disks[r][c].numBlocks != min_numblks) {
					RF_ERRORMSG3("WARNING: truncating disk"
					    " at r %d c %d to %d blocks.\n",
					    r, c, (int) min_numblks);
					disks[r][c].numBlocks = min_numblks;
				}
			}
		}
	}

	raidPtr->sectorsPerDisk = min_numblks;
	raidPtr->logBytesPerSector = ffs(bs) - 1;
	raidPtr->bytesPerSector = bs;
	raidPtr->sectorMask = bs - 1;
	return (0);

fail:
	rf_UnconfigureVnodes(raidPtr);

	return (ret);
}
Exemplo n.º 7
0
int
rf_add_hot_spare(RF_Raid_t *raidPtr, RF_SingleComponent_t *sparePtr)
{
	RF_RaidDisk_t *disks;
	RF_DiskQueue_t *spareQueues;
	int ret;
	unsigned int bs;
	int spare_number;

#if 0
	printf("Just in rf_add_hot_spare: %d.\n", raidPtr->numSpare);
	printf("Num col: %d.\n", raidPtr->numCol);
#endif
	if (raidPtr->numSpare >= RF_MAXSPARE) {
		RF_ERRORMSG1("Too many spares: %d.\n", raidPtr->numSpare);
		return(EINVAL);
 	}

	RF_LOCK_MUTEX(raidPtr->mutex);

	/* The beginning of the spares... */
	disks = &raidPtr->Disks[0][raidPtr->numCol];

	spare_number = raidPtr->numSpare;

	ret = rf_ConfigureDisk(raidPtr, sparePtr->component_name,
	    &disks[spare_number], 0, raidPtr->numCol + spare_number);

	if (ret)
		goto fail;
	if (disks[spare_number].status != rf_ds_optimal) {
		RF_ERRORMSG1("Warning: spare disk %s failed TUR.\n",
		    sparePtr->component_name);
		ret = EINVAL;
		goto fail;
	} else {
		disks[spare_number].status = rf_ds_spare;
		DPRINTF6("Spare Disk %d: dev %s numBlocks %ld blockSize %d"
		    " (%ld MB).\n", spare_number, disks[spare_number].devname,
		    (long int) disks[spare_number].numBlocks,
		    disks[spare_number].blockSize,
		    (long int) disks[spare_number].numBlocks *
		     disks[spare_number].blockSize / 1024 / 1024);
	}


	/* Check sizes and block sizes on the spare disk. */
	bs = 1 << raidPtr->logBytesPerSector;
	if (disks[spare_number].blockSize != bs) {
		RF_ERRORMSG3("Block size of %d on spare disk %s is not"
		    " the same as on other disks (%d).\n",
		    disks[spare_number].blockSize,
		    disks[spare_number].devname, bs);
		ret = EINVAL;
		goto fail;
	}
	if (disks[spare_number].numBlocks < raidPtr->sectorsPerDisk) {
		RF_ERRORMSG3("Spare disk %s (%llu blocks) is too small to serve"
		    " as a spare (need %llu blocks).\n",
		    disks[spare_number].devname, disks[spare_number].numBlocks,
		    raidPtr->sectorsPerDisk);
		ret = EINVAL;
		goto fail;
	} else {
		if (disks[spare_number].numBlocks >
		    raidPtr->sectorsPerDisk) {
			RF_ERRORMSG2("Warning: truncating spare disk %s to %llu"
			    " blocks.\n", disks[spare_number].devname,
			    raidPtr->sectorsPerDisk);

			disks[spare_number].numBlocks = raidPtr->sectorsPerDisk;
		}
	}

	spareQueues = &raidPtr->Queues[0][raidPtr->numCol];
	ret = rf_ConfigureDiskQueue(raidPtr, &spareQueues[spare_number],
	    0, raidPtr->numCol + spare_number, raidPtr->qType,
	    raidPtr->sectorsPerDisk, raidPtr->Disks[0][raidPtr->numCol +
	     spare_number].dev, raidPtr->maxOutstanding,
	    &raidPtr->shutdownList, raidPtr->cleanupList);


	raidPtr->numSpare++;
	RF_UNLOCK_MUTEX(raidPtr->mutex);
	return (0);

fail:
	RF_UNLOCK_MUTEX(raidPtr->mutex);
	return(ret);
}
Exemplo n.º 8
0
/*****************************************************************************
 *
 * ConfigureLayout
 *
 * Read the configuration file and set up the RAID layout parameters.
 * After reading common params, invokes the layout-specific configuration
 * routine to finish the configuration.
 *
 *****************************************************************************/
int
rf_ConfigureLayout(RF_ShutdownList_t **listp, RF_Raid_t *raidPtr,
    RF_Config_t *cfgPtr)
{
	RF_RaidLayout_t *layoutPtr = &(raidPtr->Layout);
	RF_ParityConfig_t parityConfig;
	RF_LayoutSW_t *p;
	int retval;

	layoutPtr->sectorsPerStripeUnit = cfgPtr->sectPerSU;
	layoutPtr->SUsPerPU = cfgPtr->SUsPerPU;
	layoutPtr->SUsPerRU = cfgPtr->SUsPerRU;
	parityConfig = cfgPtr->parityConfig;

	if (layoutPtr->sectorsPerStripeUnit <= 0) {
		RF_ERRORMSG2("raid%d: Invalid sectorsPerStripeUnit: %d.\n",
		    raidPtr->raidid, (int)layoutPtr->sectorsPerStripeUnit);
		return (EINVAL);
	}

	layoutPtr->stripeUnitsPerDisk = raidPtr->sectorsPerDisk /
	    layoutPtr->sectorsPerStripeUnit;

	p = rf_GetLayout(parityConfig);
	if (p == NULL) {
		RF_ERRORMSG1("Unknown parity configuration '%c'", parityConfig);
		return (EINVAL);
	}
	RF_ASSERT(p->parityConfig == parityConfig);
	layoutPtr->map = p;

	/* Initialize the specific layout. */

	retval = (p->Configure) (listp, raidPtr, cfgPtr);

	if (retval)
		return (retval);

	layoutPtr->dataBytesPerStripe = layoutPtr->dataSectorsPerStripe <<
	    raidPtr->logBytesPerSector;
	raidPtr->sectorsPerDisk = layoutPtr->stripeUnitsPerDisk *
	    layoutPtr->sectorsPerStripeUnit;

	if (rf_forceNumFloatingReconBufs >= 0) {
		raidPtr->numFloatingReconBufs = rf_forceNumFloatingReconBufs;
	} else {
		raidPtr->numFloatingReconBufs =
		    rf_GetDefaultNumFloatingReconBuffers(raidPtr);
	}

	if (rf_forceHeadSepLimit >= 0) {
		raidPtr->headSepLimit = rf_forceHeadSepLimit;
	} else {
		raidPtr->headSepLimit = rf_GetDefaultHeadSepLimit(raidPtr);
	}

#ifdef	RAIDDEBUG
	if (raidPtr->headSepLimit >= 0) {
		printf("RAIDFRAME(%s): Using %ld floating recon bufs"
		    " with head sep limit %ld.\n", layoutPtr->map->configName,
		    (long) raidPtr->numFloatingReconBufs,
		    (long) raidPtr->headSepLimit);
	} else {
		printf("RAIDFRAME(%s): Using %ld floating recon bufs"
		    " with no head sep limit.\n", layoutPtr->map->configName,
		    (long) raidPtr->numFloatingReconBufs);
	}
#endif	/* RAIDDEBUG */

	return (0);
}