⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vinumconfig.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    CHECKALLOC(plex->sdnos, "vinum: Can't allocate plex subdisk table");    bzero(plex->sdnos, (sizeof(int) * INITIAL_SUBDISKS_IN_PLEX)); /* do we need this? */    plex->flags |= VF_NEWBORN;				    /* newly born plex */    plex->subdisks = 0;					    /* no subdisks in use */    plex->subdisks_allocated = INITIAL_SUBDISKS_IN_PLEX;    /* and we have space for this many */    plex->organization = plex_disorg;			    /* and it's not organized */    plex->volno = -1;					    /* no volume yet */    return plexno;					    /* return the index */}/* * Find the named plex in vinum_conf.plex * * If create != 0, create an entry if it doesn't exist * return index in vinum_conf.plex */int find_plex(const char *name, int create){    int plexno;    struct plex *plex;    for (plexno = 0; plexno < vinum_conf.plexes_allocated; plexno++) {	if (strcmp(PLEX[plexno].name, name) == 0)	    /* found it */	    return plexno;    }    /* the plex isn't in the list.  Add it if he wants */    if (create == 0)					    /* don't want to create */	return -1;					    /* give up */    /* Allocate one and insert the name */    plexno = get_empty_plex();    plex = &PLEX[plexno];				    /* point to it */    bcopy(name, plex->name, min(sizeof(plex->name), strlen(name))); /* put in its name */    return plexno;					    /* return the pointer */}/* * Free an allocated plex entry * and its associated memory areas */void free_plex(int plexno){    struct plex *plex;    plex = &PLEX[plexno];    if (plex->sdnos)	Free(plex->sdnos);    if (plex->lock)	Free(plex->lock);    bzero(plex, sizeof(struct plex));			    /* and clear it out */    plex->state = plex_unallocated;}/* Find an empty volume in the volume table */int get_empty_volume(void){    int volno;    struct volume *vol;    /* first see if we have one which has been deallocated */    for (volno = 0; volno < vinum_conf.volumes_allocated; volno++) {	if (VOL[volno].state == volume_unallocated)	    /* bingo */	    break;    }    if (volno >= vinum_conf.volumes_allocated)	EXPAND(VOL, struct volume, vinum_conf.volumes_allocated, INITIAL_VOLUMES);    /* Now initialize fields */    vol = &VOL[volno];    bzero(vol, sizeof(struct volume));    vol->flags |= VF_NEWBORN | VF_CREATED;		    /* newly born volume */    vol->preferred_plex = ROUND_ROBIN_READPOL;		    /* round robin */    return volno;					    /* return the index */}/* * Find the named volume in vinum_conf.volume. * * If create != 0, create an entry if it doesn't exist * return the index in vinum_conf */int find_volume(const char *name, int create){    int volno;    struct volume *vol;    for (volno = 0; volno < vinum_conf.volumes_allocated; volno++) {	if (strcmp(VOL[volno].name, name) == 0)		    /* found it */	    return volno;    }    /* the volume isn't in the list.  Add it if he wants */    if (create == 0)					    /* don't want to create */	return -1;					    /* give up */    /* Allocate one and insert the name */    volno = get_empty_volume();    vol = &VOL[volno];    bcopy(name, vol->name, min(sizeof(vol->name), strlen(name))); /* put in its name */    vol->blocksize = DEV_BSIZE;				    /* block size of this volume */    return volno;					    /* return the pointer */}/* * Free an allocated volume entry * and its associated memory areas */void free_volume(int volno){    struct volume *vol;    vol = &VOL[volno];    bzero(vol, sizeof(struct volume));			    /* and clear it out */    vol->state = volume_unallocated;}/* * Handle a drive definition.  We store the information in the global variable * drive, so we don't need to allocate. * * If we find an error, print a message and return */void config_drive(int update){    enum drive_label_info partition_status;		    /* info about the partition */    int parameter;    int driveno;					    /* index of drive in vinum_conf */    struct drive *drive;				    /* and pointer to it */    if (tokens < 2)					    /* not enough tokens */	throw_rude_remark(EINVAL, "Drive has no name\n");    driveno = find_drive(token[1], 1);			    /* allocate a drive to initialize */    drive = &DRIVE[driveno];				    /* and get a pointer */    if (update && ((drive->flags & VF_NEWBORN) == 0))	    /* this drive exists already */	return;						    /* don't do anything */    drive->flags &= ~VF_NEWBORN;			    /* no longer newly born */    if (drive->state != drive_referenced) {		    /* we already know this drive */	/*	 * XXX Check which definition is more up-to-date.  Give	 * preference for the definition on its own drive	 */	return;						    /* XXX */    }    for (parameter = 2; parameter < tokens; parameter++) {  /* look at the other tokens */	switch (get_keyword(token[parameter], &keyword_set)) {	case kw_device:	    parameter++;	    if (drive->devicename[0] == '/') {		    /* we know this drive... */		if (strcmp(drive->devicename, token[parameter])) /* different name */		    close_drive(drive);			    /* close it if it's open */		else					    /* no change */		    break;	    }	    /* open the device and get the configuration */	    bcopy(token[parameter],			    /* insert device information */		drive->devicename,		min(sizeof(drive->devicename),		    strlen(token[parameter])));	    partition_status = read_drive_label(drive, 1);	    switch (partition_status) {	    case DL_CANT_OPEN:				    /* not our kind */		close_drive(drive);		if (drive->lasterror == EFTYPE)		    /* wrong kind of partition */		    throw_rude_remark(drive->lasterror,			"Drive %s has invalid partition type",			drive->label.name);		else					    /* I/O error of some kind */		    throw_rude_remark(drive->lasterror,			"Can't initialize drive %s",			drive->label.name);		break;	    case DL_WRONG_DRIVE:			    /* valid drive, not the name we expected */		if (vinum_conf.flags & VF_FORCECONFIG) {    /* but we'll accept that */		    bcopy(token[1], drive->label.name, sizeof(drive->label.name));		    break;		}		close_drive(drive);		/*		 * There's a potential race condition here:		 * the rude remark refers to a field in an		 * unallocated drive, which potentially could		 * be reused.  This works because we're the only		 * thread accessing the config at the moment.		 */		drive->state = drive_unallocated;	    /* throw it away completely */		throw_rude_remark(drive->lasterror,		    "Incorrect drive name %s specified for drive %s",		    token[1],		    drive->label.name);		break;	    case DL_DELETED_LABEL:			    /* it was a drive, but we deleted it */		break;	    case DL_NOT_OURS:				    /* nothing to do with the rest */	    case DL_OURS:		break;	    }	    /*	     * read_drive_label overwrites the device name.	     * If we get here, we can have the drive,	     * so put it back again	     */	    bcopy(token[parameter],		drive->devicename,		min(sizeof(drive->devicename),		    strlen(token[parameter])));	    break;	case kw_state:	    checkdiskconfig(token[++parameter]);	    /* must be reading from disk */	    drive->state = DriveState(token[parameter]);    /* set the state */	    break;	default:	    close_drive(drive);	    throw_rude_remark(EINVAL,		"Drive %s, invalid keyword: %s",		token[1],		token[parameter]);	}    }    if (drive->devicename[0] != '/') {	drive->state = drive_unallocated;		    /* deallocate the drive */	throw_rude_remark(EINVAL, "No device name for %s", drive->label.name);    }    vinum_conf.drives_used++;				    /* passed all hurdles: one more in use */}/* * Handle a subdisk definition.  We store the information in the global variable * sd, so we don't need to allocate. * * If we find an error, print a message and return */void config_subdisk(int update){    int parameter;    int sdno;						    /* index of sd in vinum_conf */    struct sd *sd;					    /* and pointer to it */    u_int64_t size;    int detached = 0;					    /* set to 1 if this is a detached subdisk */    int sdindex = -1;					    /* index in plexes subdisk table */    enum sdstate state = sd_unallocated;		    /* state to set, if specified */    int autosize = 0;					    /* set if we autosize in give_sd_to_drive */    int namedsdno;					    /* index of another with this name */    sdno = get_empty_sd();				    /* allocate an SD to initialize */    sd = &SD[sdno];					    /* and get a pointer */    sd->sectors = -1;					    /* to distinguish from 0 */    for (parameter = 1; parameter < tokens; parameter++) {  /* look at the other tokens */	switch (get_keyword(token[parameter], &keyword_set)) {	    /*	     * If we have a 'name' parameter, it must	     * come first, because we're too lazy to tidy	     * up dangling refs if it comes later.	     */	case kw_name:	    namedsdno = find_subdisk(token[++parameter], 0); /* find an existing sd with this name */	    if (namedsdno >= 0) {			    /* got one */		if (SD[namedsdno].state == sd_referenced) { /* we've been told about this one */		    if (parameter > 2)			throw_rude_remark(EINVAL,			    "sd %s: name parameter must come first\n", /* no go */			    token[parameter]);		    else {			int i;			struct plex *plex;		    /* for tidying up dangling references */			*sd = SD[namedsdno];		    /* copy from the referenced one */			SD[namedsdno].state = sd_unallocated; /* and deallocate the referenced one */			plex = &PLEX[sd->plexno];	    /* now take a look at our plex */			for (i = 0; i < plex->subdisks; i++) { /* look for the pointer */			    if (plex->sdnos[i] == namedsdno) /* pointing to the old subdisk */				plex->sdnos[i] = sdno;	    /* bend it to point here */			}		    }		}		if (update)				    /* are we updating? */		    return;				    /* that's OK, nothing more to do */		else		    throw_rude_remark(EINVAL, "Duplicate subdisk %s", token[parameter]);	    } else		bcopy(token[parameter],		    sd->name,		    min(sizeof(sd->name), strlen(token[parameter])));	    break;	case kw_detached:	    detached = 1;	    break;	case kw_plexoffset:	    size = sizespec(token[++parameter]);	    if ((size == -1)				    /* unallocated */	    &&(vinum_conf.flags & VF_READING_CONFIG))	    /* reading from disk */		break;					    /* invalid sd; just ignore it */	    if ((size % DEV_BSIZE) != 0)		throw_rude_remark(EINVAL, "sd %s, bad plex offset alignment: %lld", sd->name, size);	    else		sd->plexoffset = size / DEV_BSIZE;	    break;	case kw_driveoffset:	    size = sizespec(token[++parameter]);	    if ((size == -1)				    /* unallocated */	    &&(vinum_conf.flags & VF_READING_CONFIG))	    /* reading from disk */		break;					    /* invalid sd; just ignore it */	    if ((size % DEV_BSIZE) != 0)		throw_rude_remark(EINVAL, "sd %s, bad drive offset alignment: %lld", sd->name, size);	    else		sd->driveoffset = size / DEV_BSIZE;	    break;	case kw_len:	    if (get_keyword(token[++parameter], &keyword_set) == kw_max) /* select maximum size from drive */		size = 0;				    /* this is how we say it :-) */	    else		size = sizespec(token[parameter]);	    if ((size % DEV_BSIZE) != 0)		throw_rude_remark(EINVAL, "sd %s, length %d not multiple of sector size", sd->name, size);	    else		sd->sectors = size / DEV_BSIZE;	    /*	     * We have a problem with autosizing: we need to	     * give the drive to the plex before we give it	     * to the drive, in order to be clean if we give	     * up in the middle, but at this time the size hasn't	     * been set.  Note that we have to fix up after	     * giving the subdisk to the drive.	     */	    if (size == 0)		autosize = 1;				    /* note that we're autosizing */	    break;	case kw_drive:	    sd->driveno = find_drive(token[++parameter], 1); /* insert drive information */	    break;	case kw_plex:	    sd->plexno = find_plex(token[++parameter], 1);  /* insert plex information */	    break;	    /*	     * Set the state.  We can't do this directly,	     * because give_sd_to_plex may change it	     */	case kw_state:	    checkdiskconfig(token[++parameter]);	    /* must be reading from disk */	    state = SdState(token[parameter]);		    /* set the state */	    break;	default:	    throw_rude_remark(EINVAL, "sd %s, invalid keyword: %s", sd->name, token[parameter]);	}    }    /* Check we have a drive name */    if (sd->driveno < 0) {				    /* didn't specify a drive */	sd->driveno = current_drive;			    /* set to the current drive */	if (sd->driveno < 0)				    /* no current drive? */	    throw_rude_remark(EINVAL, "Subdisk %s is not associated with a drive", sd->name);    }    /*     * This is tacky.  If something goes wrong     * with the checks, we may end up losing drive     * space.  FIXME.     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -