diff --git a/WHATS_NEW b/WHATS_NEW index ca3cf1120..9bbe92844 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,7 @@ Version 2.02.02 - ==================================== + Set block_on_error parameter if available. + Add target_version. Add details to format1 'Invalid LV in extent map' error message. Fix lvscan snapshot full display. Bring lvdisplay man page example into line. diff --git a/lib/activate/activate.c b/lib/activate/activate.c index 3bb3a3f98..d7de8ea04 100644 --- a/lib/activate/activate.c +++ b/lib/activate/activate.c @@ -76,6 +76,11 @@ int driver_version(char *version, size_t size) { return 0; } +int target_version(const char *target_name, uint32_t *maj, + uint32_t *min, uint32_t *patchlevel) +{ + return 0; +} int target_present(const char *target_name) { return 0; @@ -278,7 +283,8 @@ int driver_version(char *version, size_t size) return dm_driver_version(version, size); } -static int _target_present(const char *target_name) +int target_version(const char *target_name, uint32_t *maj, + uint32_t *min, uint32_t *patchlevel) { int r = 0; struct dm_task *dmt; @@ -301,6 +307,9 @@ static int _target_present(const char *target_name) if (!strcmp(target_name, target->name)) { r = 1; + *maj = target->version[0]; + *min = target->version[1]; + *patchlevel = target->version[2]; goto out; } @@ -315,6 +324,7 @@ static int _target_present(const char *target_name) int target_present(const char *target_name, int use_modprobe) { + uint32_t maj, min, patchlevel; #ifdef MODPROBE_CMD char module[128]; #endif @@ -324,7 +334,7 @@ int target_present(const char *target_name, int use_modprobe) #ifdef MODPROBE_CMD if (use_modprobe) { - if (_target_present(target_name)) + if (target_version(target_name, &maj, &min, &patchlevel)) return 1; if (lvm_snprintf(module, sizeof(module), "dm-%s", target_name) @@ -339,7 +349,7 @@ int target_present(const char *target_name, int use_modprobe) } #endif - return _target_present(target_name); + return target_version(target_name, &maj, &min, &patchlevel); } /* @@ -580,7 +590,7 @@ static int _register_dev(struct cmd_context *cmd, struct logical_volume *lv, if (do_reg) { if (seg->segtype->ops->target_register_events) reg = seg->segtype->ops->target_register_events; - } else if(seg->setype->ops->target_unregister_events) + } else if (seg->segtype->ops->target_unregister_events) reg = seg->segtype->ops->target_unregister_events; if (reg) diff --git a/lib/activate/activate.h b/lib/activate/activate.h index c05f667da..0a62c322a 100644 --- a/lib/activate/activate.h +++ b/lib/activate/activate.h @@ -37,6 +37,8 @@ int library_version(char *version, size_t size); int lvm1_present(struct cmd_context *cmd); 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); void activation_exit(void); diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c index a45f95bef..5f539bc07 100644 --- a/lib/mirror/mirrored.c +++ b/lib/mirror/mirrored.c @@ -27,6 +27,8 @@ #include "activate.h" #include "libdevmapper-event.h" +static int _block_on_error_available = 0; + enum { MIRR_DISABLED, MIRR_RUNNING, @@ -239,12 +241,10 @@ static int _add_log(struct dev_manager *dm, struct lv_segment *seg, return 0; } - /* FIXME Only if the kernel supports this - if (!(seg->status & PVMOVE)) + if (_block_on_error_available && !(seg->status & PVMOVE)) log_flags |= DM_BLOCK_ON_ERROR; - */ - return dm_tree_node_add_mirror_target_log(node, region_size, clustered, log_flags, log_dlid, area_count); + return dm_tree_node_add_mirror_target_log(node, region_size, clustered, log_dlid, area_count, log_flags); } static int _add_target_line(struct dev_manager *dm, struct dm_pool *mem, @@ -322,10 +322,27 @@ static int _target_present(void) { static int checked = 0; static int present = 0; + uint32_t maj, min, patchlevel; + unsigned maj2, min2; + char vsn[80]; - if (!checked) + if (!checked) { present = target_present("mirror", 1); + /* + * block_on_error available with mirror target >= 1.1 + * or with 1.0 in RHEL4U3 driver >= 4.5 + */ + + if (target_version("mirror", &maj, &min, &patchlevel) && + maj == 1 && + (min >= 1 || + (min == 0 && driver_version(vsn, sizeof(vsn)) && + sscanf(vsn, "%u.%u", &maj2, &min2) == 2 && + maj2 >= 4 && min2 >= 5))) /* RHEL4U3 */ + _block_on_error_available = 1; + } + checked = 1; return present;