summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/mdconfig/mdconfig.c36
-rw-r--r--sys/dev/md/md.c39
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
OpenPOWER on IntegriCloud