diff --git a/WHATS_NEW b/WHATS_NEW index d70be1e07..0e8a55604 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,5 +1,6 @@ Version 2.02.89 - ================================== + Add activation/use_linear_target enabled by default. Use gcc warning options only with .c to .o compilation. Move y/n prompts to stderr and repeat if response has both 'n' and 'y'. Replace the unit testing framework with CUnit (--enable-testing). diff --git a/doc/example.conf.in b/doc/example.conf.in index 2dd18089c..72005e989 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -490,6 +490,11 @@ activation { # or snapshotted volumes is likely to result in data corruption. missing_stripe_filler = "error" + # The linear target is an optimised version of the striped target + # that only handles a single stripe. Set this to 0 to disable this + # optimisation and always use the striped target. + use_linear_target = 1 + # How much stack (in KB) to reserve for use while devices suspended # Prior to version 2.02.89 this used to be set to 256KB reserved_stack = 64 diff --git a/lib/activate/activate.h b/lib/activate/activate.h index d2e13a535..283c1d21c 100644 --- a/lib/activate/activate.h +++ b/lib/activate/activate.h @@ -128,6 +128,10 @@ int target_register_events(struct cmd_context *cmd, const char *dso, struct logi int evmask __attribute__((unused)), int set, int timeout); #endif +int add_linear_area_to_dtree(struct dm_tree_node *node, uint64_t size, + uint32_t extent_size, int use_linear_target, + const char *vgname, const char *lvname); + /* * Returns 1 if PV has a dependency tree that uses anything in VG. */ diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index a89d681ee..86269d55b 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -441,6 +441,42 @@ bad: return r; } +int add_linear_area_to_dtree(struct dm_tree_node *node, uint64_t size, uint32_t extent_size, int use_linear_target, const char *vgname, const char *lvname) +{ + uint32_t page_size; + + /* + * Use striped or linear target? + */ + if (!use_linear_target) { + page_size = lvm_getpagesize() >> SECTOR_SHIFT; + + /* + * We'll use the extent size as the stripe size. + * Extent size and page size are always powers of 2. + * The striped target requires that the stripe size is + * divisible by the page size. + */ + if (extent_size >= page_size) { + /* Use striped target */ + if (!dm_tree_node_add_striped_target(node, size, extent_size)) + return_0; + return 1; + } else + /* Some exotic cases are unsupported by striped. */ + log_warn("WARNING: Using linear target for %s/%s: Striped requires extent size (%" PRIu32 " sectors) >= page size (%" PRIu32 ").", + vgname, lvname, extent_size, page_size); + } + + /* + * Use linear target. + */ + if (!dm_tree_node_add_linear_target(node, size)) + return_0; + + return 1; +} + static percent_range_t _combine_percent(percent_t a, percent_t b, uint32_t numerator, uint32_t denominator) { diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c index 8b6ad3b63..0bbbc3585 100644 --- a/lib/commands/toolcontext.c +++ b/lib/commands/toolcontext.c @@ -333,6 +333,10 @@ static int _process_config(struct cmd_context *cmd) cmd->default_settings.udev_fallback = 1; #endif + cmd->use_linear_target = find_config_tree_int(cmd, + "activation/use_linear_target", + DEFAULT_USE_LINEAR_TARGET); + cmd->stripe_filler = find_config_tree_str(cmd, "activation/missing_stripe_filler", DEFAULT_STRIPE_FILLER); diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h index e66a14b75..143a9a0e6 100644 --- a/lib/commands/toolcontext.h +++ b/lib/commands/toolcontext.h @@ -81,6 +81,7 @@ struct cmd_context { unsigned is_long_lived:1; /* Optimises persistent_filter handling */ unsigned handles_missing_pvs:1; unsigned handles_unknown_segments:1; + unsigned use_linear_target:1; unsigned partial_activation:1; unsigned si_unit_consistency:1; unsigned metadata_read_only:1; diff --git a/lib/config/defaults.h b/lib/config/defaults.h index 9b91aea51..27acf8abd 100644 --- a/lib/config/defaults.h +++ b/lib/config/defaults.h @@ -127,6 +127,7 @@ # define DEFAULT_ACTIVATION 0 #endif +#define DEFAULT_USE_LINEAR_TARGET 1 #define DEFAULT_STRIPE_FILLER "error" #define DEFAULT_MIRROR_REGION_SIZE 512 /* KB */ #define DEFAULT_INTERVAL 15 diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c index 4e16a5cfd..e80fee6da 100644 --- a/lib/mirror/mirrored.c +++ b/lib/mirror/mirrored.c @@ -427,7 +427,9 @@ static int _mirrored_add_target_line(struct dev_manager *dm, struct dm_pool *mem } if (mirror_status != MIRR_RUNNING) { - if (!dm_tree_node_add_linear_target(node, len)) + if (!add_linear_area_to_dtree(node, len, seg->lv->vg->extent_size, + cmd->use_linear_target, + seg->lv->vg->name, seg->lv->name)) return_0; goto done; } diff --git a/lib/replicator/replicator.c b/lib/replicator/replicator.c index f6428fdaf..1d3132b90 100644 --- a/lib/replicator/replicator.c +++ b/lib/replicator/replicator.c @@ -625,7 +625,9 @@ static int _replicator_dev_add_target_line(struct dev_manager *dm, /* Create passive linear mapping */ log_very_verbose("Inactive replicator %s using %s.", seg->lv->name, seg->lv->rdevice->lv->name); - if (!dm_tree_node_add_linear_target(node, seg->lv->size)) + if (!add_linear_area_to_dtree(node, seg->lv->size, seg->lv->vg->extent_size, + dm->cmd->use_linear_target, + seg->lv->vg->name, seg->lv_name)) return_0; if (!(rdev_dlid = build_dm_uuid(mem, seg->lv->rdevice->lv->lvid.s, NULL))) return_0; diff --git a/lib/striped/striped.c b/lib/striped/striped.c index 14d05baab..3b0846780 100644 --- a/lib/striped/striped.c +++ b/lib/striped/striped.c @@ -174,7 +174,9 @@ static int _striped_add_target_line(struct dev_manager *dm, return 0; } if (seg->area_count == 1) { - if (!dm_tree_node_add_linear_target(node, len)) + if (!add_linear_area_to_dtree(node, len, seg->lv->vg->extent_size, + cmd->use_linear_target, + seg->lv->vg->name, seg->lv->name)) return_0; } else if (!dm_tree_node_add_striped_target(node, len, seg->stripe_size)) diff --git a/lib/thin/thin.c b/lib/thin/thin.c index 4a40d2743..d19f497a6 100644 --- a/lib/thin/thin.c +++ b/lib/thin/thin.c @@ -230,7 +230,9 @@ static int _thin_pool_add_target_line(struct dev_manager *dm, return 0; } - if (!dm_tree_node_add_linear_target(node, len) || + if (!add_linear_area_to_dtree(node, len, seg->lv->vg->extent_size, + cmd->use_linear_target, + seg->lv->vg->name, seg->lv->name) || !dm_tree_node_add_target_area(node, NULL, pool_dlid, 0)) return_0;