diff options
Diffstat (limited to 'sys/dev/vinum')
-rw-r--r-- | sys/dev/vinum/vinum.c | 82 | ||||
-rw-r--r-- | sys/dev/vinum/vinumhdr.h | 1 | ||||
-rw-r--r-- | sys/dev/vinum/vinumio.c | 29 |
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; |