Remove code to accept partitions of type 'unused'. From now on, Vinum

will only accept partitions of type 'vinum'.

format_config: Use the new %q format option in kvprintf, thus getting
  rid of some of the filthiest code I've written in a long time.  Also
  remove the lltoa() function.

With-great-thanks-to:	peter

format_config: Accept the fact that a subdisk might not be attached to
  a plex, and save the config correctly.

vinum_scandisk: Scan all slices on a drive with a Microsoft partition
  table.  Only look at the compatibility slice if nothing was found in
  the Microsoft slices.

  This change removes a frequently employed method of shooting
  yourself in the foot: people would decide that the Vinum drives
  belonged on their own slice, and they wouldn't be able to start the
  subsystem after a reboot.  Documentation updates to follow.
This commit is contained in:
Greg Lehey 1999-08-07 08:07:05 +00:00
parent ffb0a6283d
commit 78436bf362

View File

@ -33,7 +33,7 @@
* otherwise) arising in any way out of the use of this software, even if
* advised of the possibility of such damage.
*
* $Id: vinumio.c,v 1.31 1999/06/29 04:08:51 grog Exp $
* $Id: vinumio.c,v 1.25 1999/06/28 02:37:48 grog Exp grog $
*/
#include <dev/vinum/vinumhdr.h>
@ -175,8 +175,7 @@ init_drive(struct drive *drive, int verbose)
drive->state = drive_down; /* don't tell the system about this one at all */
return error;
}
if ((drive->partinfo.part->p_fstype != FS_UNUSED) /* not plain */
&&(drive->partinfo.part->p_fstype != FS_VINUM)) { /* and not Vinum */
if (drive->partinfo.part->p_fstype != FS_VINUM) { /* not Vinum */
drive->lasterror = EFTYPE;
if (verbose)
log(LOG_WARNING,
@ -200,8 +199,8 @@ close_drive(struct drive *drive)
}
/*
* Real drive close code, called with drive already locked. We have
* also checked that the drive is open. No errors.
* Real drive close code, called with drive already locked.
* We have also checked that the drive is open. No errors.
*/
void
close_locked_drive(struct drive *drive)
@ -570,38 +569,17 @@ sappend(char *txt, char *s)
return s - 1;
}
/* Kludge: kernel printf doesn't handle quads correctly XXX */
static char *lltoa(long long l, char *s);
static char *
lltoa(long long l, char *s)
{
if (l < 0) {
*s++ = '-';
l = -l;
}
if (l > 9) {
s = lltoa(l / 10, s);
l %= 10;
}
*s++ = l + '0';
return s;
}
/*
* Format the configuration in text form into the buffer
* at config. Don't go beyond len bytes
* XXX this stinks. Fix soon.
*/
void
format_config(char *config, int len)
{
int i;
int j;
char *s = config;
char *configend = &config[len];
bzero(config, len);
/* First, the volume configuration */
/* First write the volume configuration */
for (i = 0; i < vinum_conf.volumes_allocated; i++) {
struct volume *vol;
@ -609,23 +587,21 @@ format_config(char *config, int len)
if ((vol->state > volume_uninit)
&& (vol->name[0] != '\0')) { /* paranoia */
if (vol->preferred_plex >= 0) /* preferences, */
sprintf(s,
snprintf(s,
configend - s,
"volume %s state %s readpol prefer %s",
vol->name,
volume_state(vol->state),
vinum_conf.plex[vol->preferred_plex].name);
else /* default round-robin */
sprintf(s,
snprintf(s,
configend - s,
"volume %s state %s",
vol->name,
volume_state(vol->state));
while (*s)
s++; /* find the end */
s = sappend("\n", s);
if (s > &config[len - 80]) {
log(LOG_ERR, "vinum: configuration data overflow\n");
return;
}
}
}
@ -636,7 +612,9 @@ format_config(char *config, int len)
plex = &vinum_conf.plex[i];
if ((plex->state != plex_referenced)
&& (plex->name[0] != '\0')) { /* paranoia */
sprintf(s, "plex name %s state %s org %s ",
snprintf(s,
configend - s,
"plex name %s state %s org %s ",
plex->name,
plex_state(plex->state),
plex_org(plex->organization));
@ -644,22 +622,27 @@ format_config(char *config, int len)
s++; /* find the end */
if ((plex->organization == plex_striped)
|| (plex->organization == plex_raid5)) {
sprintf(s, "%db ", (int) plex->stripesize);
snprintf(s,
configend - s,
"%ds ",
(int) plex->stripesize);
while (*s)
s++; /* find the end */
}
if (plex->volno >= 0) /* we have a volume */
sprintf(s, "vol %s ", vinum_conf.volume[plex->volno].name);
snprintf(s,
configend - s,
"vol %s ",
vinum_conf.volume[plex->volno].name);
while (*s)
s++; /* find the end */
for (j = 0; j < plex->subdisks; j++) {
sprintf(s, " sd %s", vinum_conf.sd[plex->sdnos[j]].name);
snprintf(s,
configend - s,
" sd %s",
vinum_conf.sd[plex->sdnos[j]].name);
}
s = sappend("\n", s);
if (s > &config[len - 80]) {
log(LOG_ERR, "vinum: configuration data overflow\n");
return;
}
}
}
@ -670,26 +653,33 @@ format_config(char *config, int len)
sd = &SD[i];
if ((sd->state != sd_referenced)
&& (sd->name[0] != '\0')) { /* paranoia */
sprintf(s,
"sd name %s drive %s plex %s state %s len ",
sd->name,
vinum_conf.drive[sd->driveno].label.name,
vinum_conf.plex[sd->plexno].name,
sd_state(sd->state));
if (sd->plexno >= 0)
snprintf(s,
configend - s,
"sd name %s drive %s plex %s state %s len %qds driveoffset %qds plexoffset %qds\n",
sd->name,
vinum_conf.drive[sd->driveno].label.name,
vinum_conf.plex[sd->plexno].name,
sd_state(sd->state),
sd->sectors,
sd->driveoffset,
sd->plexoffset);
else
snprintf(s,
configend - s,
"sd name %s drive %s state %s len %qds driveoffset %qds detached\n",
sd->name,
vinum_conf.drive[sd->driveno].label.name,
sd_state(sd->state),
sd->sectors,
sd->driveoffset);
while (*s)
s++; /* find the end */
s = lltoa(sd->sectors, s);
s = sappend("b driveoffset ", s);
s = lltoa(sd->driveoffset, s);
s = sappend("b plexoffset ", s);
s = lltoa(sd->plexoffset, s);
s = sappend("b\n", s);
if (s > &config[len - 80]) {
log(LOG_ERR, "vinum: configuration data overflow\n");
return;
}
}
}
if (s > &config[len - 2])
panic("vinum: configuration data overflow");
}
/*
@ -956,28 +946,57 @@ vinum_scandisk(char *devicename[], int drives)
/* Open all drives and find which was modified most recently */
for (driveno = 0; driveno < drives; driveno++) {
char part; /* UNIX partition */
int slice;
int founddrive; /* flag when we find a vinum drive */
for (part = 'a'; part < 'i'; part++)
if (part != 'c') { /* don't do the c partition */
snprintf(partname, /* /dev/sd0a */
DRIVENAMELEN,
"%s%c",
devicename[driveno],
part);
drive = check_drive(partname); /* try to open it */
if ((drive->lasterror != 0) /* didn't work, */
||(drive->state != drive_up))
free_drive(drive); /* get rid of it */
else if (drive->flags & VF_CONFIGURED) /* already read this config, */
log(LOG_WARNING,
"vinum: already read config from %s\n", /* say so */
drive->label.name);
else {
drivelist[gooddrives] = drive->driveno; /* keep the drive index */
drive->flags &= ~VF_NEWBORN; /* which is no longer newly born */
gooddrives++;
founddrive = 0; /* no vinum drive found yet on this spindle */
/* first try the partition table */
for (slice = 1; slice < 5; slice++)
for (part = 'a'; part < 'i'; part++) {
if (part != 'c') { /* don't do the c partition */
snprintf(partname,
DRIVENAMELEN,
"%ss%d%c",
devicename[driveno],
slice,
part);
drive = check_drive(partname); /* try to open it */
if (drive->lasterror != 0) /* didn't work, */
free_drive(drive); /* get rid of it */
else if (drive->flags & VF_CONFIGURED) /* already read this config, */
log(LOG_WARNING,
"vinum: already read config from %s\n", /* say so */
drive->label.name);
else {
drivelist[gooddrives] = drive->driveno; /* keep the drive index */
drive->flags &= ~VF_NEWBORN; /* which is no longer newly born */
gooddrives++;
}
}
}
if (founddrive == 0) { /* didn't find anything, */
for (part = 'a'; part < 'i'; part++) /* try the compatibility partition */
if (part != 'c') { /* don't do the c partition */
snprintf(partname, /* /dev/sd0a */
DRIVENAMELEN,
"%s%c",
devicename[driveno],
part);
drive = check_drive(partname); /* try to open it */
if ((drive->lasterror != 0) /* didn't work, */
||(drive->state != drive_up))
free_drive(drive); /* get rid of it */
else if (drive->flags & VF_CONFIGURED) /* already read this config, */
log(LOG_WARNING,
"vinum: already read config from %s\n", /* say so */
drive->label.name);
else {
drivelist[gooddrives] = drive->driveno; /* keep the drive index */
drive->flags &= ~VF_NEWBORN; /* which is no longer newly born */
gooddrives++;
}
}
}
}
if (gooddrives == 0) {
@ -1003,12 +1022,6 @@ vinum_scandisk(char *devicename[], int drives)
else
log(LOG_INFO, "vinum: updating configuration from %s\n", drive->devicename);
/* XXX Transition until we can get things changed */
if (drive->partinfo.part->p_fstype == FS_UNUSED) /* still set to unused */
log(LOG_WARNING,
"vinum: %s partition type is 'unused', should be 'vinum'\n",
drive->devicename);
/* Read in both copies of the configuration information */
error = read_drive(drive, config_text, MAXCONFIG * 2, VINUM_CONFIG_OFFSET);