From 5619c629f6c75f6d91d36748ce6f1bfc39f2acc3 Mon Sep 17 00:00:00 2001 From: Milan Broz Date: Mon, 7 Apr 2008 10:23:47 +0000 Subject: [PATCH] Add detection of clustered mirror log capability. Currently only check for kernel module presence. --- WHATS_NEW | 1 + lib/activate/activate.c | 29 ++++++++++++++++++----------- lib/activate/activate.h | 4 ++++ lib/activate/dev_manager.c | 2 +- lib/error/errseg.c | 3 ++- lib/metadata/mirror.c | 2 +- lib/metadata/segtype.h | 3 ++- lib/mirror/mirrored.c | 13 ++++++++++++- lib/snapshot/snapshot.c | 3 ++- lib/striped/striped.c | 3 ++- lib/zero/zero.c | 3 ++- tools/lvconvert.c | 2 +- tools/lvcreate.c | 2 +- tools/pvmove.c | 34 +++++++++++++++++++++++++--------- 14 files changed, 74 insertions(+), 30 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index c2cad9f33..0727392c6 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.34 - =================================== + Add detection of clustered mirror log capability. Add check to vg_commit() ensuring VG lock held before writing new VG metadata. Add validation of LV name to pvmove -n. Make clvmd refresh the context correctly when lvm.conf is updated. diff --git a/lib/activate/activate.c b/lib/activate/activate.c index 21b125422..7b959cdd1 100644 --- a/lib/activate/activate.c +++ b/lib/activate/activate.c @@ -391,12 +391,26 @@ int target_version(const char *target_name, uint32_t *maj, return r; } +int module_present(const char *target_name) +{ + int ret = 0; +#ifdef MODPROBE_CMD + char module[128]; + + if (dm_snprintf(module, sizeof(module), "dm-%s", target_name) < 0) { + log_error("module_present module name too long: %s", + target_name); + return 0; + } + + ret = exec_cmd(MODPROBE_CMD, module, "", ""); +#endif + return ret; +} + int target_present(const char *target_name, int use_modprobe) { uint32_t maj, min, patchlevel; -#ifdef MODPROBE_CMD - char module[128]; -#endif if (!activation()) return 0; @@ -406,14 +420,7 @@ int target_present(const char *target_name, int use_modprobe) if (target_version(target_name, &maj, &min, &patchlevel)) return 1; - if (dm_snprintf(module, sizeof(module), "dm-%s", target_name) - < 0) { - log_error("target_present module name too long: %s", - target_name); - return 0; - } - - if (!exec_cmd(MODPROBE_CMD, module, "", "")) + if (!module_present(target_name)) return_0; } #endif diff --git a/lib/activate/activate.h b/lib/activate/activate.h index fe5676a21..ec68251f1 100644 --- a/lib/activate/activate.h +++ b/lib/activate/activate.h @@ -30,6 +30,9 @@ struct lvinfo { uint32_t read_ahead; }; +/* target attribute flags */ +#define MIRROR_LOG_CLUSTERED 0x00000001U + void set_activation(int activation); int activation(void); @@ -37,6 +40,7 @@ int driver_version(char *version, size_t size); int library_version(char *version, size_t size); int lvm1_present(struct cmd_context *cmd); +int module_present(const char *target_name); int target_present(const char *target_name, int use_modprobe); int target_version(const char *target_name, uint32_t *maj, uint32_t *min, uint32_t *patchlevel); diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index 0e3844d22..e53452bdc 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -823,7 +823,7 @@ static int _add_segment_to_dtree(struct dev_manager *dm, layer ? "-" : "", layer ? : ""); if (seg_present->segtype->ops->target_present && - !seg_present->segtype->ops->target_present(seg_present)) { + !seg_present->segtype->ops->target_present(seg_present, NULL)) { log_error("Can't expand LV %s: %s target support missing " "from kernel?", seg->lv->name, seg_present->segtype->name); return 0; diff --git a/lib/error/errseg.c b/lib/error/errseg.c index df9c5523c..bb560ff25 100644 --- a/lib/error/errseg.c +++ b/lib/error/errseg.c @@ -51,7 +51,8 @@ static int _errseg_add_target_line(struct dev_manager *dm __attribute((unused)), return dm_tree_node_add_error_target(node, len); } -static int _errseg_target_present(const struct lv_segment *seg __attribute((unused))) +static int _errseg_target_present(const struct lv_segment *seg __attribute((unused)), + unsigned *attributes __attribute((unused))) { static int _errseg_checked = 0; static int _errseg_present = 0; diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c index 282f4e1fc..f97dac1b4 100644 --- a/lib/metadata/mirror.c +++ b/lib/metadata/mirror.c @@ -1300,7 +1300,7 @@ int add_mirror_log(struct cmd_context *cmd, return_0; if (activation() && segtype->ops->target_present && - !segtype->ops->target_present(NULL)) { + !segtype->ops->target_present(NULL, NULL)) { log_error("%s: Required device-mapper target(s) not " "detected in your kernel", segtype->name); return 0; diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h index db060ac2a..91542928d 100644 --- a/lib/metadata/segtype.h +++ b/lib/metadata/segtype.h @@ -78,7 +78,8 @@ struct segtype_handler { struct lv_segment *seg, char *params, uint64_t *total_numerator, uint64_t *total_denominator, float *percent); - int (*target_present) (const struct lv_segment *seg); + int (*target_present) (const struct lv_segment *seg, + unsigned *attributes); int (*modules_needed) (struct dm_pool *mem, const struct lv_segment *seg, struct list *modules); diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c index 48577e3de..64bcd3048 100644 --- a/lib/mirror/mirrored.c +++ b/lib/mirror/mirrored.c @@ -33,6 +33,7 @@ #endif static int _block_on_error_available = 0; +static unsigned _mirror_attributes = 0; enum { MIRR_DISABLED, @@ -343,7 +344,8 @@ static int _mirrored_add_target_line(struct dev_manager *dm, struct dm_pool *mem return add_areas_line(dm, seg, node, start_area, area_count); } -static int _mirrored_target_present(const struct lv_segment *seg __attribute((unused))) +static int _mirrored_target_present(const struct lv_segment *seg __attribute((unused)), + unsigned *attributes) { static int _mirrored_checked = 0; static int _mirrored_present = 0; @@ -369,6 +371,15 @@ static int _mirrored_target_present(const struct lv_segment *seg __attribute((un _block_on_error_available = 1; } + /* + * Check only for modules if atttributes requested and no previous check. + * FIXME: need better check + */ + if (attributes) { + if (!_mirror_attributes && module_present("cmirror")) + _mirror_attributes |= MIRROR_LOG_CLUSTERED; + *attributes = _mirror_attributes; + } _mirrored_checked = 1; return _mirrored_present; diff --git a/lib/snapshot/snapshot.c b/lib/snapshot/snapshot.c index cb166f90c..6437970c7 100644 --- a/lib/snapshot/snapshot.c +++ b/lib/snapshot/snapshot.c @@ -114,7 +114,8 @@ static int _snap_target_percent(void **target_state __attribute((unused)), return 1; } -static int _snap_target_present(const struct lv_segment *seg __attribute((unused))) +static int _snap_target_present(const struct lv_segment *seg __attribute((unused)), + unsigned *attributes __attribute((unused))) { static int _snap_checked = 0; static int _snap_present = 0; diff --git a/lib/striped/striped.c b/lib/striped/striped.c index a7fea1775..1e4f3c65b 100644 --- a/lib/striped/striped.c +++ b/lib/striped/striped.c @@ -175,7 +175,8 @@ static int _striped_add_target_line(struct dev_manager *dm, return add_areas_line(dm, seg, node, 0u, seg->area_count); } -static int _striped_target_present(const struct lv_segment *seg __attribute((unused))) +static int _striped_target_present(const struct lv_segment *seg __attribute((unused)), + unsigned *attributes __attribute((unused))) { static int _striped_checked = 0; static int _striped_present = 0; diff --git a/lib/zero/zero.c b/lib/zero/zero.c index f6cb1cecd..ca0200a91 100644 --- a/lib/zero/zero.c +++ b/lib/zero/zero.c @@ -50,7 +50,8 @@ static int _zero_add_target_line(struct dev_manager *dm __attribute((unused)), return dm_tree_node_add_zero_target(node, len); } -static int _zero_target_present(const struct lv_segment *seg __attribute((unused))) +static int _zero_target_present(const struct lv_segment *seg __attribute((unused)), + unsigned *attributes __attribute((unused))) { static int _zero_checked = 0; static int _zero_present = 0; diff --git a/tools/lvconvert.c b/tools/lvconvert.c index c0a87d8be..43447e625 100644 --- a/tools/lvconvert.c +++ b/tools/lvconvert.c @@ -219,7 +219,7 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd, } if (activation() && lp->segtype->ops->target_present && - !lp->segtype->ops->target_present(NULL)) { + !lp->segtype->ops->target_present(NULL, NULL)) { log_error("%s: Required device-mapper target(s) not " "detected in your kernel", lp->segtype->name); return 0; diff --git a/tools/lvcreate.c b/tools/lvcreate.c index 5fc2fb619..6011b16b1 100644 --- a/tools/lvcreate.c +++ b/tools/lvcreate.c @@ -420,7 +420,7 @@ static int _lvcreate_params(struct lvcreate_params *lp, struct cmd_context *cmd, } if (activation() && lp->segtype->ops->target_present && - !lp->segtype->ops->target_present(NULL)) { + !lp->segtype->ops->target_present(NULL, NULL)) { log_error("%s: Required device-mapper target(s) not " "detected in your kernel", lp->segtype->name); return 0; diff --git a/tools/pvmove.c b/tools/pvmove.c index a138d0248..7a14a8d4f 100644 --- a/tools/pvmove.c +++ b/tools/pvmove.c @@ -17,6 +17,30 @@ #include "polldaemon.h" #include "display.h" +static int pvmove_target_present(struct cmd_context *cmd, int clustered) +{ + const struct segment_type *segtype; + unsigned attr = 0; + + if (!(segtype = get_segtype_from_string(cmd, "mirror"))) + return_0; + + if (activation() && segtype->ops->target_present && + !segtype->ops->target_present(NULL, clustered ? &attr : NULL)) { + log_error("%s: Required device-mapper target(s) not " + "detected in your kernel", segtype->name); + return 0; + } + + if (clustered && !(attr & MIRROR_LOG_CLUSTERED)) { + log_error("%s: Required device-mapper clustered log " + "module not detected in your kernel", segtype->name); + return 0; + } + + return 1; +} + /* Allow /dev/vgname/lvname, vgname/lvname or lvname */ static const char *_extract_lvname(struct cmd_context *cmd, const char *vgname, const char *arg) @@ -540,17 +564,9 @@ int pvmove(struct cmd_context *cmd, int argc, char **argv) char *pv_name = NULL; char *colon; int ret; - const struct segment_type *segtype; - if (!(segtype = get_segtype_from_string(cmd, "mirror"))) - return_0; - - if (activation() && segtype->ops->target_present && - !segtype->ops->target_present(NULL)) { - log_error("%s: Required device-mapper target(s) not " - "detected in your kernel", segtype->name); + if (!pvmove_target_present(cmd, 0)) return 0; - } if (argc) { pv_name = argv[0];