Revise use of the vinum_conf variables drives_used, subdisks_used,

plexes_used and volumes_used.  Now these fields are only informative,
and the <object>_allocated count is used for searches, etc.  This also
required checking the object state before doing things with the
presumed object.

Problems-reported-by: Kiril Mitev <kiril@ideaglobal.com>

vinum_scandisk: increment drive use count when we find a good one.
This commit is contained in:
Greg Lehey 1999-03-30 05:00:19 +00:00
parent c22d0bffee
commit 18bf283fec
1 changed files with 85 additions and 75 deletions

View File

@ -236,12 +236,15 @@ remove_drive(int driveno)
struct drive *drive = &vinum_conf.drive[driveno]; struct drive *drive = &vinum_conf.drive[driveno];
long long int nomagic = VINUM_NOMAGIC; /* no magic number */ long long int nomagic = VINUM_NOMAGIC; /* no magic number */
write_drive(drive, /* obliterate the magic, but leave a hint */ if (drive->state > drive_referenced) { /* real drive */
(char *) &nomagic, if (drive->state == drive_up)
8, write_drive(drive, /* obliterate the magic, but leave a hint */
VINUM_LABEL_OFFSET); (char *) &nomagic,
free_drive(drive); /* close it and free resources */ 8,
save_config(); /* and save the updated configuration */ VINUM_LABEL_OFFSET);
free_drive(drive); /* close it and free resources */
save_config(); /* and save the updated configuration */
}
} }
/* /*
@ -596,11 +599,11 @@ format_config(char *config, int len)
bzero(config, len); bzero(config, len);
/* First, the volume configuration */ /* First, the volume configuration */
for (i = 0; i < vinum_conf.volumes_used; i++) { for (i = 0; i < vinum_conf.volumes_allocated; i++) {
struct volume *vol; struct volume *vol;
vol = &vinum_conf.volume[i]; vol = &vinum_conf.volume[i];
if ((vol->state != volume_unallocated) if ((vol->state > volume_uninit)
&& (vol->name[0] != '\0')) { /* paranoia */ && (vol->name[0] != '\0')) { /* paranoia */
if (vol->preferred_plex >= 0) /* preferences, */ if (vol->preferred_plex >= 0) /* preferences, */
sprintf(s, sprintf(s,
@ -624,11 +627,11 @@ format_config(char *config, int len)
} }
/* Then the plex configuration */ /* Then the plex configuration */
for (i = 0; i < vinum_conf.plexes_used; i++) { for (i = 0; i < vinum_conf.plexes_allocated; i++) {
struct plex *plex; struct plex *plex;
plex = &vinum_conf.plex[i]; plex = &vinum_conf.plex[i];
if ((plex->state != plex_unallocated) if ((plex->state != plex_referenced)
&& (plex->name[0] != '\0')) { /* paranoia */ && (plex->name[0] != '\0')) { /* paranoia */
sprintf(s, "plex name %s state %s org %s ", sprintf(s, "plex name %s state %s org %s ",
plex->name, plex->name,
@ -658,9 +661,11 @@ format_config(char *config, int len)
} }
/* And finally the subdisk configuration */ /* And finally the subdisk configuration */
for (i = 0; i < vinum_conf.subdisks_used; i++) { for (i = 0; i < vinum_conf.subdisks_allocated; i++) {
struct sd *sd = &vinum_conf.sd[i]; /* XXX */ struct sd *sd;
if ((sd->state != sd_unallocated)
sd = &SD[i];
if ((sd->state != sd_referenced)
&& (sd->name[0] != '\0')) { /* paranoia */ && (sd->name[0] != '\0')) { /* paranoia */
sprintf(s, sprintf(s,
"sd name %s drive %s plex %s state %s len ", "sd name %s drive %s plex %s state %s len ",
@ -724,72 +729,74 @@ daemon_save_config(void)
format_config(config, MAXCONFIG); format_config(config, MAXCONFIG);
error = 0; /* no errors yet */ error = 0; /* no errors yet */
for (driveno = 0; driveno < vinum_conf.drives_used; driveno++) { for (driveno = 0; driveno < vinum_conf.drives_allocated; driveno++) {
drive = &vinum_conf.drive[driveno]; /* point to drive */ drive = &vinum_conf.drive[driveno]; /* point to drive */
lockdrive(drive); /* don't let it change */ if (drive->state > drive_referenced) {
lockdrive(drive); /* don't let it change */
/* /*
* First, do some drive consistency checks. Some * First, do some drive consistency checks. Some
* of these are kludges, others require a process * of these are kludges, others require a process
* context and couldn't be done before * context and couldn't be done before
*/ */
if ((drive->devicename[0] == '\0') /* XXX we keep getting these nameless drives */ if ((drive->devicename[0] == '\0') /* XXX we keep getting these nameless drives */
||(drive->label.name[0] == '\0')) { /* XXX we keep getting these nameless drives */ ||(drive->label.name[0] == '\0')) { /* XXX we keep getting these nameless drives */
unlockdrive(drive); unlockdrive(drive);
log(LOG_WARNING, log(LOG_WARNING,
"Removing incomplete drive, index %d\n", "Removing incomplete drive, index %d\n",
driveno); driveno);
if (drive->vp) /* how can it be open without a name? */ if (drive->vp) /* how can it be open without a name? */
close_drive(drive); close_drive(drive);
free_drive(drive); /* get rid of it */ free_drive(drive); /* get rid of it */
break; break;
} }
if ((drive->vp == NULL) /* drive not open */ if ((drive->vp == NULL) /* drive not open */
&&(drive->state > drive_down)) { /* and it thinks it's not down */ &&(drive->state > drive_down)) { /* and it thinks it's not down */
unlockdrive(drive); unlockdrive(drive);
set_drive_state(driveno, drive_down, setstate_force); /* tell it what's what */ set_drive_state(driveno, drive_down, setstate_force); /* tell it what's what */
} }
if ((drive->state == drive_down) /* it's down */ if ((drive->state == drive_down) /* it's down */
&&(drive->vp != NULL)) { /* but open, */ &&(drive->vp != NULL)) { /* but open, */
unlockdrive(drive); unlockdrive(drive);
close_drive(drive); /* close it */ close_drive(drive); /* close it */
} else if (drive->state > drive_down) { } else if (drive->state > drive_down) {
getmicrotime(&drive->label.last_update); /* time of last update is now */ getmicrotime(&drive->label.last_update); /* time of last update is now */
bcopy((char *) &drive->label, /* and the label info from the drive structure */ bcopy((char *) &drive->label, /* and the label info from the drive structure */
(char *) &vhdr->label, (char *) &vhdr->label,
sizeof(vhdr->label)); sizeof(vhdr->label));
if ((drive->state != drive_unallocated) if ((drive->state != drive_unallocated)
&& (drive->state != drive_referenced)) { /* and it's a real drive */ && (drive->state != drive_referenced)) { /* and it's a real drive */
wlabel_on = 1; /* enable writing the label */ wlabel_on = 1; /* enable writing the label */
error = VOP_IOCTL(drive->vp, /* make the label writeable */ error = VOP_IOCTL(drive->vp, /* make the label writeable */
DIOCWLABEL,
(caddr_t) & wlabel_on,
FWRITE,
NOCRED,
curproc);
if (error == 0)
error = write_drive(drive, (char *) vhdr, VINUMHEADERLEN, VINUM_LABEL_OFFSET);
if (error == 0)
error = write_drive(drive, config, MAXCONFIG, VINUM_CONFIG_OFFSET); /* first config copy */
if (error == 0)
error = write_drive(drive, config, MAXCONFIG, VINUM_CONFIG_OFFSET + MAXCONFIG); /* second copy */
wlabel_on = 0; /* enable writing the label */
if (error == 0)
VOP_IOCTL(drive->vp, /* make the label non-writeable again */
DIOCWLABEL, DIOCWLABEL,
(caddr_t) & wlabel_on, (caddr_t) & wlabel_on,
FWRITE, FWRITE,
NOCRED, NOCRED,
curproc); curproc);
unlockdrive(drive); if (error == 0)
if (error) { error = write_drive(drive, (char *) vhdr, VINUMHEADERLEN, VINUM_LABEL_OFFSET);
log(LOG_ERR, if (error == 0)
"vinum: Can't write config to %s, error %d\n", error = write_drive(drive, config, MAXCONFIG, VINUM_CONFIG_OFFSET); /* first config copy */
drive->devicename, if (error == 0)
error); error = write_drive(drive, config, MAXCONFIG, VINUM_CONFIG_OFFSET + MAXCONFIG); /* second copy */
set_drive_state(drive->driveno, drive_down, setstate_force); wlabel_on = 0; /* enable writing the label */
} else if (error == 0)
written_config = 1; /* we've written it on at least one drive */ VOP_IOCTL(drive->vp, /* make the label non-writeable again */
DIOCWLABEL,
(caddr_t) & wlabel_on,
FWRITE,
NOCRED,
curproc);
unlockdrive(drive);
if (error) {
log(LOG_ERR,
"vinum: Can't write config to %s, error %d\n",
drive->devicename,
error);
set_drive_state(drive->driveno, drive_down, setstate_force);
} else
written_config = 1; /* we've written it on at least one drive */
}
} }
} }
} }
@ -870,12 +877,14 @@ write_volume_label(int volno)
if (lp == 0) if (lp == 0)
return ENOMEM; return ENOMEM;
if ((unsigned) (volno) >= (unsigned) vinum_conf.volumes_used) /* invalid volume */ if ((unsigned) (volno) >= (unsigned) vinum_conf.volumes_allocated) /* invalid volume */
return ENOENT; return ENOENT;
vol = &VOL[volno]; /* volume in question */ vol = &VOL[volno]; /* volume in question */
if (vol->state == volume_unallocated) /* nothing there */ if (vol->state <= volume_uninit) /* nothing there */
return ENOENT; return ENXIO;
else if (vol->state < volume_up) /* not accessible */
return EIO; /* I/O error */
get_volume_label(vol, lp); /* get the label */ get_volume_label(vol, lp); /* get the label */
@ -1011,6 +1020,7 @@ vinum_scandisk(char *drivename[], int drives)
* data on the drive * data on the drive
*/ */
else { else {
vinum_conf.drives_used++; /* another drive in use */
/* Parse the configuration, and add it to the global configuration */ /* Parse the configuration, and add it to the global configuration */
for (cptr = config_text; *cptr != '\0';) { /* love this style(9) */ for (cptr = config_text; *cptr != '\0';) { /* love this style(9) */
volatile int parse_status; /* return value from parse_config */ volatile int parse_status; /* return value from parse_config */