summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorhaad <haad@NetBSD.org>2008-12-21 00:59:39 +0000
committerhaad <haad@NetBSD.org>2008-12-21 00:59:39 +0000
commitcca8fb31f911820f397b9d96a25bdf445dcaa28b (patch)
tree2a241827f48fd6b8d163de6d5f6d4c7bd4388c30 /sys/dev
parent38805eb14c9a24414515ec80d28fc16ff67c9c41 (diff)
Add support for loading dm targets as separate modules. All targets except
linear can be loaded as module. Module is not loaded when there is target with similar name already. Zero and error targets aresimple examples how can be all future targets written to support dynamic loading. Target can't be unloaded until there is at least one user.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/dm/dm.h3
-rw-r--r--sys/dev/dm/dm_target.c19
-rw-r--r--sys/dev/dm/dm_target_error.c60
-rw-r--r--sys/dev/dm/dm_target_snapshot.c80
-rw-r--r--sys/dev/dm/dm_target_zero.c59
5 files changed, 206 insertions, 15 deletions
diff --git a/sys/dev/dm/dm.h b/sys/dev/dm/dm.h
index a7409bcc16f..90016b209b8 100644
--- a/sys/dev/dm/dm.h
+++ b/sys/dev/dm/dm.h
@@ -1,4 +1,4 @@
-/* $NetBSD: dm.h,v 1.3 2008/12/19 16:30:41 haad Exp $ */
+/* $NetBSD: dm.h,v 1.4 2008/12/21 00:59:39 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -253,6 +253,7 @@ int dm_table_load_ioctl(prop_dictionary_t);
int dm_table_status_ioctl(prop_dictionary_t);
/* dm_target.c */
+dm_target_t* dm_target_alloc(const char *);
int dm_target_destroy(void);
int dm_target_insert(dm_target_t *);
prop_array_t dm_target_prop_list(void);
diff --git a/sys/dev/dm/dm_target.c b/sys/dev/dm/dm_target.c
index 01911e258cd..8b302ab1829 100644
--- a/sys/dev/dm/dm_target.c
+++ b/sys/dev/dm/dm_target.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dm_target.c,v 1.3 2008/12/19 16:30:41 haad Exp $ */
+/* $NetBSD: dm_target.c,v 1.4 2008/12/21 00:59:39 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -37,7 +37,6 @@
#include "netbsd-dm.h"
#include "dm.h"
-static dm_target_t* dm_target_alloc(const char *);
static dm_target_t* dm_target_lookup_name(const char *);
TAILQ_HEAD(dm_target_head, dm_target);
@@ -189,6 +188,8 @@ dm_target_destroy(void)
}
mutex_exit(&dm_target_mutex);
+ mutex_destroy(&dm_target_mutex);
+
return 0;
}
@@ -243,7 +244,7 @@ dm_target_prop_list(void)
int
dm_target_init(void)
{
- dm_target_t *dmt,*dmt1,*dmt2,*dmt3,*dmt4,*dmt5,*dmt6;
+ dm_target_t *dmt,*dmt3,*dmt4;
int r;
r = 0;
@@ -251,12 +252,8 @@ dm_target_init(void)
mutex_init(&dm_target_mutex, MUTEX_DEFAULT, IPL_NONE);
dmt = dm_target_alloc("linear");
- dmt1 = dm_target_alloc("zero");
- dmt2 = dm_target_alloc("error");
dmt3 = dm_target_alloc("striped");
dmt4 = dm_target_alloc("mirror");
- dmt5 = dm_target_alloc("snapshot");
- dmt6 = dm_target_alloc("snapshot-origin");
dmt->version[0] = 1;
dmt->version[1] = 0;
@@ -271,7 +268,7 @@ dm_target_init(void)
r = dm_target_insert(dmt);
- dmt1->version[0] = 1;
+/* dmt1->version[0] = 1;
dmt1->version[1] = 0;
dmt1->version[2] = 0;
strlcpy(dmt1->name, "zero", DM_MAX_TYPE_NAME);
@@ -295,7 +292,7 @@ dm_target_init(void)
dmt2->destroy = &dm_target_error_destroy;
dmt2->upcall = &dm_target_error_upcall;
- r = dm_target_insert(dmt2);
+ r = dm_target_insert(dmt2);*/
dmt3->version[0] = 1;
dmt3->version[1] = 0;
@@ -323,7 +320,7 @@ dm_target_init(void)
r = dm_target_insert(dmt4);
- dmt5->version[0] = 1;
+/* dmt5->version[0] = 1;
dmt5->version[1] = 0;
dmt5->version[2] = 5;
strlcpy(dmt5->name, "snapshot", DM_MAX_TYPE_NAME);
@@ -347,7 +344,7 @@ dm_target_init(void)
dmt6->destroy = &dm_target_snapshot_orig_destroy;
dmt6->upcall = &dm_target_snapshot_orig_upcall;
- r = dm_target_insert(dmt6);
+ r = dm_target_insert(dmt6);*/
return r;
}
diff --git a/sys/dev/dm/dm_target_error.c b/sys/dev/dm/dm_target_error.c
index 9bd8bea19eb..ffcaf40c7e2 100644
--- a/sys/dev/dm/dm_target_error.c
+++ b/sys/dev/dm/dm_target_error.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dm_target_error.c,v 1.3 2008/12/19 16:30:41 haad Exp $ */
+/* $NetBSD: dm_target_error.c,v 1.4 2008/12/21 00:59:39 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -39,6 +39,64 @@
#include "dm.h"
+#ifdef DM_TARGET_MODULE
+/*
+ * Every target can be compiled directly to dm driver or as a
+ * separate module this part of target is used for loading targets
+ * to dm driver.
+ * Target can be unloaded from kernel only if there are no users of
+ * it e.g. there are no devices which uses that target.
+ */
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+MODULE(MODULE_CLASS_MISC, dm_target_error, NULL);
+
+static int
+dm_target_error_modcmd(modcmd_t cmd, void *arg)
+{
+ dm_target_t *dmt;
+ int r;
+ dmt = NULL;
+
+ switch (cmd) {
+ case MODULE_CMD_INIT:
+ if ((dmt = dm_target_lookup("error")) != NULL)
+ return EEXIST;
+
+ dmt = dm_target_alloc("error");
+
+ dmt->version[0] = 1;
+ dmt->version[1] = 0;
+ dmt->version[2] = 0;
+ strlcpy(dmt->name, "error", DM_MAX_TYPE_NAME);
+ dmt->init = &dm_target_error_init;
+ dmt->status = &dm_target_error_status;
+ dmt->strategy = &dm_target_error_strategy;
+ dmt->deps = &dm_target_error_deps;
+ dmt->destroy = &dm_target_error_destroy;
+ dmt->upcall = &dm_target_error_upcall;
+
+ r = dm_target_insert(dmt);
+
+ break;
+
+ case MODULE_CMD_FINI:
+ r = dm_target_rem("error");
+ break;
+
+ case MODULE_CMD_STAT:
+ return ENOTTY;
+
+ default:
+ return ENOTTY;
+ }
+
+ return r;
+}
+
+#endif
+
/* Init function called from dm_table_load_ioctl. */
int
dm_target_error_init(dm_dev_t *dmv, void **target_config, char *argv)
diff --git a/sys/dev/dm/dm_target_snapshot.c b/sys/dev/dm/dm_target_snapshot.c
index 725d525ca63..f363f148db9 100644
--- a/sys/dev/dm/dm_target_snapshot.c
+++ b/sys/dev/dm/dm_target_snapshot.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dm_target_snapshot.c,v 1.3 2008/12/19 16:30:41 haad Exp $ */
+/* $NetBSD: dm_target_snapshot.c,v 1.4 2008/12/21 00:59:39 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -72,6 +72,84 @@
#include "dm.h"
+#ifdef DM_TARGET_MODULE
+/*
+ * Every target can be compiled directly to dm driver or as a
+ * separate module this part of target is used for loading targets
+ * to dm driver.
+ * Target can be unloaded from kernel only if there are no users of
+ * it e.g. there are no devices which uses that target.
+ */
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+MODULE(MODULE_CLASS_MISC, dm_target_snapshot, NULL);
+
+static int
+dm_target_snapshot_modcmd(modcmd_t cmd, void *arg)
+{
+ dm_target_t *dmt, *dmt1;
+ int r;
+ dmt = NULL;
+
+ switch (cmd) {
+ case MODULE_CMD_INIT:
+ if (((dmt = dm_target_lookup("snapshot")) != NULL) ||
+ (((dmt = dm_target_lookup("snapshot-origin")) != NULL)))
+ return EEXIST;
+
+ dmt = dm_target_alloc("snapshot");
+ dmt1 = dm_target_alloc("snapshot-origin");
+
+ dmt->version[0] = 1;
+ dmt->version[1] = 0;
+ dmt->version[2] = 5;
+ strlcpy(dmt->name, "snapshot", DM_MAX_TYPE_NAME);
+ dmt->init = &dm_target_snapshot_init;
+ dmt->status = &dm_target_snapshot_status;
+ dmt->strategy = &dm_target_snapshot_strategy;
+ dmt->deps = &dm_target_snapshot_deps;
+ dmt->destroy = &dm_target_snapshot_destroy;
+ dmt->upcall = &dm_target_snapshot_upcall;
+
+ r = dm_target_insert(dmt);
+
+ dmt1->version[0] = 1;
+ dmt1->version[1] = 0;
+ dmt1->version[2] = 5;
+ strlcpy(dmt1->name, "snapshot-origin", DM_MAX_TYPE_NAME);
+ dmt1->init = &dm_target_snapshot_orig_init;
+ dmt1->status = &dm_target_snapshot_orig_status;
+ dmt1->strategy = &dm_target_snapshot_orig_strategy;
+ dmt1->deps = &dm_target_snapshot_orig_deps;
+ dmt1->destroy = &dm_target_snapshot_orig_destroy;
+ dmt1->upcall = &dm_target_snapshot_orig_upcall;
+
+ r = dm_target_insert(dmt1);
+ break;
+
+ case MODULE_CMD_FINI:
+ /*
+ * Try to remove snapshot target if it works remove snap-origin
+ * it is not possible to remove snapshot and do not remove
+ * snap-origin because they are used together.
+ */
+ if ((r = dm_target_rem("snapshot")) == 0)
+ r = dm_target_rem("snapshot-origin");
+ break;
+
+ case MODULE_CMD_STAT:
+ return ENOTTY;
+
+ default:
+ return ENOTTY;
+ }
+
+ return r;
+}
+
+#endif
+
/*
* Init function called from dm_table_load_ioctl.
* argv: /dev/mapper/my_data_org /dev/mapper/tsc_cow_dev p 64
diff --git a/sys/dev/dm/dm_target_zero.c b/sys/dev/dm/dm_target_zero.c
index c323620732c..b752559ca50 100644
--- a/sys/dev/dm/dm_target_zero.c
+++ b/sys/dev/dm/dm_target_zero.c
@@ -1,4 +1,4 @@
-/* $NetBSD: dm_target_zero.c,v 1.3 2008/12/19 16:30:41 haad Exp $ */
+/* $NetBSD: dm_target_zero.c,v 1.4 2008/12/21 00:59:39 haad Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -40,6 +40,63 @@
#include "dm.h"
+#ifdef DM_TARGET_MODULE
+/*
+ * Every target can be compiled directly to dm driver or as a
+ * separate module this part of target is used for loading targets
+ * to dm driver.
+ * Target can be unloaded from kernel only if there are no users of
+ * it e.g. there are no devices which uses that target.
+ */
+#include <sys/kernel.h>
+#include <sys/module.h>
+
+MODULE(MODULE_CLASS_MISC, dm_target_zero, NULL);
+
+static int
+dm_target_zero_modcmd(modcmd_t cmd, void *arg)
+{
+ dm_target_t *dmt;
+ int r;
+ dmt = NULL;
+
+ switch (cmd) {
+ case MODULE_CMD_INIT:
+ if ((dmt = dm_target_lookup("zero")) != NULL)
+ return EEXIST;
+
+ dmt = dm_target_alloc("zero");
+
+ dmt->version[0] = 1;
+ dmt->version[1] = 0;
+ dmt->version[2] = 0;
+ strlcpy(dmt->name, "zero", DM_MAX_TYPE_NAME);
+ dmt->init = &dm_target_zero_init;
+ dmt->status = &dm_target_zero_status;
+ dmt->strategy = &dm_target_zero_strategy;
+ dmt->deps = &dm_target_zero_deps;
+ dmt->destroy = &dm_target_zero_destroy;
+ dmt->upcall = &dm_target_zero_upcall;
+
+ r = dm_target_insert(dmt);
+ break;
+
+ case MODULE_CMD_FINI:
+ r = dm_target_rem("zero");
+ break;
+
+ case MODULE_CMD_STAT:
+ return ENOTTY;
+
+ default:
+ return ENOTTY;
+ }
+
+ return r;
+}
+
+#endif
+
/*
* Zero target init function. This target doesn't need
* target specific config area.