summaryrefslogtreecommitdiffstats
path: root/sys/dev/vinum
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/vinum')
-rw-r--r--sys/dev/vinum/vinum.c82
-rw-r--r--sys/dev/vinum/vinumhdr.h1
-rw-r--r--sys/dev/vinum/vinumio.c29
3 files changed, 90 insertions, 22 deletions
diff --git a/sys/dev/vinum/vinum.c b/sys/dev/vinum/vinum.c
index ac98a5e..84056ff 100644
--- a/sys/dev/vinum/vinum.c
+++ b/sys/dev/vinum/vinum.c
@@ -66,6 +66,8 @@ STATIC void vinumattach(void *);
STATIC int vinum_modevent(module_t mod, modeventtype_t type, void *unused);
+STATIC void vinum_clone(void *arg, char *name, int namelen, dev_t *dev);
+
struct _vinum_conf vinum_conf; /* configuration information */
dev_t vinum_daemon_dev;
@@ -79,6 +81,10 @@ dev_t vinum_super_dev;
void
vinumattach(void *dummy)
{
+ int i, rv;
+ char *cp, *cp1, *cp2, **drives, *drivep;
+ size_t alloclen;
+
/* modload should prevent multiple loads, so this is worth a panic */
if ((vinum_conf.flags & VF_LOADED) != 0)
panic("vinum: already loaded");
@@ -135,6 +141,63 @@ vinumattach(void *dummy)
bzero(SD, sizeof(struct sd) * INITIAL_SUBDISKS);
vinum_conf.subdisks_allocated = INITIAL_SUBDISKS; /* number of sd slots allocated */
vinum_conf.subdisks_used = 0; /* and number in use */
+
+ EVENTHANDLER_REGISTER(dev_clone, vinum_clone, 0, 1000);
+
+ /*
+ * See if the loader has passed us any of the
+ * autostart options.
+ */
+ cp = drivep = NULL;
+#ifndef VINUM_AUTOSTART
+ if ((cp = getenv("vinum.autostart")) != NULL) {
+ freeenv(cp);
+ cp = NULL;
+#endif
+ rv = kernel_sysctlbyname(&thread0, "kern.disks",
+ NULL, NULL,
+ NULL, 0,
+ &alloclen);
+ if (rv)
+ log(LOG_NOTICE,
+ "sysctlbyname(\"kern.disks\") failed, rv = %d\n",
+ rv);
+ else {
+ drivep = malloc(alloclen, M_TEMP, 0 /* M_WAITOK */);
+ (void)kernel_sysctlbyname(&thread0, "kern.disks",
+ drivep, &alloclen,
+ NULL, 0,
+ NULL);
+ goto start;
+ }
+#ifndef VINUM_AUTOSTART
+ } else
+#endif
+ if ((cp = getenv("vinum.drives")) != NULL) {
+ start:
+ for (cp1 = cp? cp: drivep, i = 0, drives = 0;
+ *cp1 != '\0';
+ i++) {
+ cp2 = cp1;
+ while (*cp1 != '\0' && *cp1 != ',' && *cp1 != ' ')
+ cp1++;
+ if (*cp1 != '\0')
+ *cp1++ = '\0';
+ drives = realloc(drives,
+ (unsigned long)((i + 1) * sizeof(char *)),
+ M_TEMP, 0 /* M_WAITOK */);
+ drives[i] = cp2;
+ }
+ if (i == 0)
+ goto bailout;
+ rv = vinum_scandisk(drives, i);
+ if (rv)
+ log(LOG_NOTICE, "vinum_scandisk() returned %d\n", rv);
+ bailout:
+ freeenv(cp);
+ free(drives, M_TEMP);
+ free(drivep, M_TEMP);
+ }
}
/*
@@ -492,6 +555,25 @@ vinumsize(dev_t dev)
return size;
}
+void
+vinum_clone(void *arg, char *name, int namelen, dev_t *dev)
+{
+ struct volume *vol;
+ int i;
+
+ if (*dev != NODEV)
+ return;
+ if (strncmp(name, "vinum/", sizeof("vinum/") - 1) != 0)
+ return;
+
+ name += sizeof("vinum/") - 1;
+ if ((i = find_volume(name, 0)) == -1)
+ return;
+
+ vol = &VOL[i];
+ *dev = vol->dev;
+}
+
/* Local Variables: */
/* fill-column: 50 */
/* End: */
diff --git a/sys/dev/vinum/vinumhdr.h b/sys/dev/vinum/vinumhdr.h
index 95aa6fe..3fda4f1 100644
--- a/sys/dev/vinum/vinumhdr.h
+++ b/sys/dev/vinum/vinumhdr.h
@@ -49,6 +49,7 @@
#include <sys/conf.h>
#include <sys/mount.h>
#include <sys/vnode.h>
+#include <sys/sysctl.h>
#endif
#include <sys/errno.h>
#include <sys/dkstat.h>
diff --git a/sys/dev/vinum/vinumio.c b/sys/dev/vinum/vinumio.c
index 14284ae..38500d8 100644
--- a/sys/dev/vinum/vinumio.c
+++ b/sys/dev/vinum/vinumio.c
@@ -50,32 +50,21 @@ static int drivecmp(const void *va, const void *vb);
int
open_drive(struct drive *drive, struct thread *td, int verbose)
{
- struct nameidata nd;
struct cdevsw *dsw; /* pointer to cdevsw entry */
- int error;
if (drive->flags & VF_OPEN) /* open already, */
return EBUSY; /* don't do it again */
- NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, drive->devicename,
- curthread);
- error = namei(&nd);
- if (error)
- return (error);
- if (!vn_isdisk(nd.ni_vp, &error)) {
- NDFREE(&nd, 0);
- return (error);
- }
- drive->dev = udev2dev(nd.ni_vp->v_rdev->si_udev, 0);
- NDFREE(&nd, 0);
-
- if (drive->dev == NULL) /* didn't find anything */
- return ENODEV;
+ drive->dev = getdiskbyname(drive->devicename);
+ if (drive->dev == NODEV) /* didn't find anything */
+ return ENOENT;
drive->dev->si_iosize_max = DFLTPHYS;
dsw = devsw(drive->dev);
- if (dsw == NULL)
+ if (dsw == NULL) /* sanity, should not happen */
drive->lasterror = ENOENT;
+ else if ((dsw->d_flags & D_DISK) == 0)
+ drive->lasterror = ENOTBLK;
else
drive->lasterror = (dsw->d_open) (drive->dev, FWRITE | FREAD, 0, NULL);
@@ -145,11 +134,7 @@ set_drive_parms(struct drive *drive)
int
init_drive(struct drive *drive, int verbose)
{
- if (drive->devicename[0] != '/') {
- drive->lasterror = EINVAL;
- log(LOG_ERR, "vinum: Can't open drive without drive name\n");
- return EINVAL;
- }
+
drive->lasterror = open_drive(drive, curthread, verbose); /* open the drive */
if (drive->lasterror)
return drive->lasterror;
OpenPOWER on IntegriCloud