diff options
| author | haad <haad@NetBSD.org> | 2008-12-21 00:59:39 +0000 |
|---|---|---|
| committer | haad <haad@NetBSD.org> | 2008-12-21 00:59:39 +0000 |
| commit | cca8fb31f911820f397b9d96a25bdf445dcaa28b (patch) | |
| tree | 2a241827f48fd6b8d163de6d5f6d4c7bd4388c30 /sys/dev | |
| parent | 38805eb14c9a24414515ec80d28fc16ff67c9c41 (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.h | 3 | ||||
| -rw-r--r-- | sys/dev/dm/dm_target.c | 19 | ||||
| -rw-r--r-- | sys/dev/dm/dm_target_error.c | 60 | ||||
| -rw-r--r-- | sys/dev/dm/dm_target_snapshot.c | 80 | ||||
| -rw-r--r-- | sys/dev/dm/dm_target_zero.c | 59 |
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. |
