diff options
-rw-r--r-- | sbin/mdconfig/mdconfig.c | 36 | ||||
-rw-r--r-- | sys/dev/md/md.c | 39 |
2 files changed, 71 insertions, 4 deletions
diff --git a/sbin/mdconfig/mdconfig.c b/sbin/mdconfig/mdconfig.c index b2ea2bb..079be71 100644 --- a/sbin/mdconfig/mdconfig.c +++ b/sbin/mdconfig/mdconfig.c @@ -18,12 +18,16 @@ #include <err.h> #include <sys/ioctl.h> #include <sys/param.h> +#include <sys/module.h> +#include <sys/linker.h> #include <sys/mdioctl.h> struct md_ioctl mdio; enum {UNSET, ATTACH, DETACH} action = UNSET; +void mdmaybeload(void); + void usage() { @@ -139,6 +143,7 @@ main(int argc, char **argv) } } + mdmaybeload(); fd = open("/dev/mdctl", O_RDWR, 0); if (fd < 0) err(1, "open(/dev/mdctl)"); @@ -156,3 +161,34 @@ main(int argc, char **argv) return (0); } +void +mdmaybeload(void) +{ + struct module_stat mstat; + int fileid, modid; + char *name = "md"; + char *cp; + + /* scan files in kernel */ + mstat.version = sizeof(struct module_stat); + for (fileid = kldnext(0); fileid > 0; fileid = kldnext(fileid)) { + /* scan modules in file */ + for (modid = kldfirstmod(fileid); modid > 0; + modid = modfnext(modid)) { + if (modstat(modid, &mstat) < 0) + continue; + /* strip bus name if present */ + if ((cp = strchr(mstat.name, '/')) != NULL) { + cp++; + } else { + cp = mstat.name; + } + /* already loaded? */ + if (!strcmp(name, cp)) + return; + } + } + /* not present, we should try to load it */ + kldload(name); +} + diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c index 334023a..48ff0b3 100644 --- a/sys/dev/md/md.c +++ b/sys/dev/md/md.c @@ -85,6 +85,8 @@ #include <vm/vm_zone.h> #include <vm/swap_pager.h> +#define MD_MODVER 1 + #ifndef MD_NSECT #define MD_NSECT (10000 * 2) #endif @@ -111,8 +113,10 @@ static u_char mfs_root[MD_ROOT_SIZE*1024] = "MFS Filesystem goes here"; static u_char end_mfs_root[] __unused = "MFS Filesystem had better STOP here"; #endif -static int mdrootready; -static int mdunits; +static int mdrootready; +static int mdunits; +static dev_t status_dev = 0; + #define CDEV_MAJOR 95 @@ -883,10 +887,37 @@ md_drvinit(void *unused) mdunits, name, len, ptr); md_preloaded(ptr, len); } - make_dev(&mdctl_cdevsw, 0xffff00ff, UID_ROOT, GID_WHEEL, 0600, "mdctl"); + status_dev = make_dev(&mdctl_cdevsw, 0xffff00ff, UID_ROOT, GID_WHEEL, 0600, "mdctl"); +} + +static int +md_modevent(module_t mod, int type, void *data) +{ + switch (type) { + case MOD_LOAD: + md_drvinit(NULL); + break; + case MOD_UNLOAD: + if (!LIST_EMPTY(&md_softc_list)) + return EBUSY; + if (status_dev) + destroy_dev(status_dev); + status_dev = 0; + break; + default: + break; + } + return 0; } -SYSINIT(mddev,SI_SUB_DRIVERS,SI_ORDER_MIDDLE+CDEV_MAJOR, md_drvinit,NULL) +static moduledata_t md_mod = { + "md", + md_modevent, + NULL +}; +DECLARE_MODULE(md, md_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE+CDEV_MAJOR); +MODULE_VERSION(md, MD_MODVER); + #ifdef MD_ROOT static void |