aboutsummaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/vinum/vinumconfig.c8
-rw-r--r--sys/dev/vinum/vinumio.c99
2 files changed, 83 insertions, 24 deletions
diff --git a/sys/dev/vinum/vinumconfig.c b/sys/dev/vinum/vinumconfig.c
index c7abaf8202715..885201af7c06b 100644
--- a/sys/dev/vinum/vinumconfig.c
+++ b/sys/dev/vinum/vinumconfig.c
@@ -505,7 +505,7 @@ find_drive(const char *name, int create)
/*
* Find a drive given its device name.
* devname must be valid.
- * Otherwise the same as find_drive above
+ * Otherwise the same as find_drive above.
*/
int
find_drive_by_name(const char *devname, int create)
@@ -1599,10 +1599,6 @@ parse_config(char *cptr, struct keywordset *keyset, int update)
return 0;
switch (get_keyword(token[0], keyset)) { /* decide what to do */
- case kw_read: /* read config from a specified drive */
- status = vinum_scandisk(&token[1], tokens - 1); /* read the config from disk */
- break;
-
case kw_drive:
config_drive(update);
break;
@@ -1644,8 +1640,6 @@ parse_user_config(char *cptr, struct keywordset *keyset)
ioctl_reply = (struct _ioctl_reply *) cptr;
status = parse_config(cptr, keyset, 0);
- if (status == ENOENT) /* from scandisk, but it can't tell us */
- strcpy(ioctl_reply->msg, "no drives found");
ioctl_reply = NULL; /* don't do this again */
return status;
}
diff --git a/sys/dev/vinum/vinumio.c b/sys/dev/vinum/vinumio.c
index 7a10a89b1b0af..3b31f6e26283a 100644
--- a/sys/dev/vinum/vinumio.c
+++ b/sys/dev/vinum/vinumio.c
@@ -726,9 +726,18 @@ write_volume_label(int volno)
return error;
}
-/* Look at all disks on the system for vinum slices. */
+/*
+ * Seach disks on system for vinum slices and add
+ * them to the configuuration if they're not
+ * there already. devicename is a blank-separate
+ * list of device names. If not provided, use
+ * sysctl to get a list of all disks on the
+ * system.
+ *
+ * Return an error indication.
+ */
int
-vinum_scandisk(char *devicename[], int drives)
+vinum_scandisk(char *devicename)
{
struct drive *volatile drive;
volatile int driveno;
@@ -741,37 +750,85 @@ vinum_scandisk(char *devicename[], int drives)
char *eptr; /* end pointer into config information */
char *config_line; /* copy the config line to */
volatile int status;
- int *volatile drivelist; /* list of drive indices */
-#define DRIVENAMELEN 64
-#define DRIVEPARTS 35 /* max partitions per drive, excluding c */
- char partname[DRIVENAMELEN]; /* for creating partition names */
+ int *drivelist; /* list of drive indices */
+ char *partname; /* for creating partition names */
+ char *cp; /* pointer to start of disk name */
+ char *ep; /* and to first char after name */
+ char *np; /* name pointer in naem we build */
+ size_t alloclen;
+ int malloced;
+ int partnamelen; /* length of partition name */
+ int drives;
+
+ malloced = 0; /* devicename not malloced */
+ if (devicename == NULL) { /* no devices specified, */
+ /* get a list of all disks in the system */
+ /* Get size of disk list */
+ error = kernel_sysctlbyname(&thread0, "kern.disks", NULL,
+ NULL, NULL, 0, &alloclen);
+ if (error) {
+ log(LOG_ERR, "vinum: can't get disk list: %d\n", error);
+ return EINVAL;
+ }
+ devicename = Malloc(alloclen);
+ if (devicename == NULL) {
+ printf("vinum: can't allocate memory for drive list");
+ return ENOMEM;
+ } else
+ malloced = 1;
+ /* Now det the list of disks */
+ kernel_sysctlbyname(&thread0, "kern.disks", devicename,
+ &alloclen, NULL, 0, NULL);
+ }
+ printf("vinum_scandisk: devicename is %s\n", devicename); /* XXX */
status = 0; /* success indication */
vinum_conf.flags |= VF_READING_CONFIG; /* reading config from disk */
-
+ partname = Malloc(MAXPATHLEN); /* extract name of disk here */
+ if (partname == NULL) {
+ printf("vinum_scandisk: can't allocate memory for drive name");
+ return ENOMEM;
+ }
gooddrives = 0; /* number of usable drives found */
firstdrive = vinum_conf.drives_used; /* the first drive */
firsttime = vinum_conf.drives_used == 0; /* are we a virgin? */
/* allocate a drive pointer list */
- drivelist = (int *) Malloc(drives * DRIVEPARTS * sizeof(int));
+ drives = 256; /* should be enough for most cases */
+ drivelist = (int *) Malloc(drives * sizeof(int));
CHECKALLOC(drivelist, "Can't allocate memory");
/* Open all drives and find which was modified most recently */
- for (driveno = 0; driveno < drives; driveno++) {
+ for (cp = devicename; *cp; cp = ep) {
char part; /* UNIX partition */
int slice;
int founddrive; /* flag when we find a vinum drive */
+ while (*cp == ' ')
+ cp++; /* find start of name */
+ if (*cp == '\0') /* done, */
+ break;
+ ep = cp;
+ while (*ep && (*ep != ' ')) /* find end of name */
+ ep++;
+
+ np = partname; /* start building up a name here */
+ if (*cp != '/') { /* name doesn't start with /, */
+ strcpy(np, "/dev/"); /* assume /dev */
+ np += strlen("/dev/");
+ }
+ memcpy(np, cp, ep - cp); /* put in name */
+ np += ep - cp; /* and point past */
+
+ partnamelen = MAXPATHLEN + np - partname; /* remaining length in partition name */
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],
+ snprintf(np,
+ partnamelen,
+ "s%d%c",
slice,
part);
drive = check_drive(partname); /* try to open it */
@@ -783,6 +840,8 @@ vinum_scandisk(char *devicename[], int drives)
"vinum: already read config from %s\n", /* say so */
drive->label.name);
else {
+ if (gooddrives == drives) /* ran out of entries */
+ EXPAND(drivelist, int, drives, drives); /* double the size */
drivelist[gooddrives] = drive->driveno; /* keep the drive index */
drive->flags &= ~VF_NEWBORN; /* which is no longer newly born */
gooddrives++;
@@ -793,10 +852,9 @@ vinum_scandisk(char *devicename[], int drives)
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],
+ snprintf(np,
+ partnamelen,
+ "%c",
part);
drive = check_drive(partname); /* try to open it */
if ((drive->lasterror != 0) /* didn't work, */
@@ -807,6 +865,8 @@ vinum_scandisk(char *devicename[], int drives)
"vinum: already read config from %s\n", /* say so */
drive->label.name);
else {
+ if (gooddrives == drives) /* ran out of entries */
+ EXPAND(drivelist, int, drives, drives); /* double the size */
drivelist[gooddrives] = drive->driveno; /* keep the drive index */
drive->flags &= ~VF_NEWBORN; /* which is no longer newly born */
gooddrives++;
@@ -814,12 +874,15 @@ vinum_scandisk(char *devicename[], int drives)
}
}
}
+ Free(partname);
if (gooddrives == 0) {
if (firsttime)
log(LOG_WARNING, "vinum: no drives found\n");
else
log(LOG_INFO, "vinum: no additional drives found\n");
+ if (malloced)
+ Free(devicename);
return ENOENT;
}
/*
@@ -901,6 +964,8 @@ vinum_scandisk(char *devicename[], int drives)
printf("vinum: couldn't read configuration");
else
updateconfig(VF_READING_CONFIG); /* update from disk config */
+ if (malloced)
+ Free(devicename);
return status;
}