WHATS_NEW | 7 +++++++ lib/activate/activate.c | 14 +++----------- lib/metadata/pv_manip.c | 2 +- lib/metadata/thin_manip.c | 39 ++++++++++++++++++++++++++++++++++----- man/Makefile.in | 3 +++ scripts/clvmd_init_red_hat.in | 2 +- test/shell/listings.sh | 5 +++++ test/shell/lvcreate-thin.sh | 16 ++++++++++++++++ tools/toollib.c | 6 +++--- 12 files changed, 78 insertions(+), 23 deletions(-) diff --git a/WHATS_NEW b/WHATS_NEW index 780050d..d90cd94 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,3 +1,10 @@ +Version 2.02.114 - +===================================== + Fix regression when parsing /dev/mapper dir (2.02.112). + Fix missing rounding to 64KB when estimating optimal thin pool chunk size. + Fix typo in clvmd initscript causing CLVMD_STOP_TIMEOUT variable to be ignored. + Fix size in pvresize "Resizing to ..." verbose msg to show proper result size. + Version 2.02.113 - 24th November 2014 ===================================== Add --cachepolicy and --cachesettings options to lvchange. diff --git a/lib/activate/activate.c b/lib/activate/activate.c index 60dba1b..dd0a4f9 100644 --- a/lib/activate/activate.c +++ b/lib/activate/activate.c @@ -719,16 +719,12 @@ int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume struct lvinfo *lvinfo, struct lv_seg_status *lv_seg_status, int with_open_count, int with_read_ahead) { - int r = 0; - if (!activation()) return 0; - if (lv == lv_seg->lv) { - r = _lv_info(cmd, lv, use_layer, lvinfo, lv_seg, lv_seg_status, - with_open_count, with_read_ahead); - goto out; - } + if (lv == lv_seg->lv) + return _lv_info(cmd, lv, use_layer, lvinfo, lv_seg, lv_seg_status, + with_open_count, with_read_ahead); /* * If the info is requested for an LV and segment @@ -737,10 +733,6 @@ int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume */ return _lv_info(cmd, lv, use_layer, lvinfo, NULL, NULL, with_open_count, with_read_ahead) && _lv_info(cmd, lv_seg->lv, use_layer, NULL, lv_seg, lv_seg_status, 0, 0); - - r = 1; -out: - return r; } #define OPEN_COUNT_CHECK_RETRIES 25 diff --git a/lib/metadata/pv_manip.c b/lib/metadata/pv_manip.c index 00a7fd5..6499e36 100644 --- a/lib/metadata/pv_manip.c +++ b/lib/metadata/pv_manip.c @@ -650,7 +650,7 @@ int pv_resize_single(struct cmd_context *cmd, } log_verbose("Resizing volume \"%s\" to %" PRIu64 " sectors.", - pv_name, pv_size(pv)); + pv_name, size); if (!pv_resize(pv, vg, size)) goto_out; diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c index b4aec73..e617b3c 100644 --- a/lib/metadata/thin_manip.c +++ b/lib/metadata/thin_manip.c @@ -394,6 +394,33 @@ int update_pool_lv(struct logical_volume *lv, int activate) return ret; } +/* Estimate thin pool chunk size from data and metadata size (in sector units) */ +static size_t _estimate_chunk_size(uint64_t data_size, uint64_t metadata_size, int attr) +{ + /* + * nr_pool_blocks = data_size / metadata_size + * chunk_size = nr_pool_blocks * 64b / sector_size + */ + size_t chunk_size = data_size / (metadata_size * (SECTOR_SIZE / 64)); + + if (attr & THIN_FEATURE_BLOCK_SIZE) { + /* Round up to 64KB */ + chunk_size += DM_THIN_MIN_DATA_BLOCK_SIZE - 1; + chunk_size &= ~(size_t)(DM_THIN_MIN_DATA_BLOCK_SIZE - 1); + } else { + /* Round up to nearest power of 2 */ + chunk_size--; + chunk_size |= chunk_size >> 1; + chunk_size |= chunk_size >> 2; + chunk_size |= chunk_size >> 4; + chunk_size |= chunk_size >> 8; + chunk_size |= chunk_size >> 16; + chunk_size++; + } + + return chunk_size; +} + int update_thin_pool_params(const struct segment_type *segtype, struct volume_group *vg, unsigned attr, int passed_args, @@ -465,18 +492,20 @@ int update_thin_pool_params(const struct segment_type *segtype, display_size(cmd, *chunk_size)); } else if (pool_metadata_size > (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2)) { /* Suggest bigger chunk size */ - estimate_chunk_size = (uint64_t) pool_data_extents * extent_size / - (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2 * (SECTOR_SIZE / UINT64_C(64))); + estimate_chunk_size = + _estimate_chunk_size((uint64_t) pool_data_extents * extent_size, + (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2), attr); log_warn("WARNING: Chunk size is too small for pool, suggested minimum is %s.", - display_size(cmd, UINT64_C(1) << (ffs(estimate_chunk_size) + 1))); + display_size(cmd, estimate_chunk_size)); } /* Round up to extent size silently */ if (pool_metadata_size % extent_size) pool_metadata_size += extent_size - pool_metadata_size % extent_size; } else { - estimate_chunk_size = (uint64_t) pool_data_extents * extent_size / - (pool_metadata_size * (SECTOR_SIZE / UINT64_C(64))); + estimate_chunk_size = + _estimate_chunk_size((uint64_t) pool_data_extents * extent_size, + pool_metadata_size, attr); if (estimate_chunk_size < DM_THIN_MIN_DATA_BLOCK_SIZE) estimate_chunk_size = DM_THIN_MIN_DATA_BLOCK_SIZE; else if (estimate_chunk_size > DM_THIN_MAX_DATA_BLOCK_SIZE) diff --git a/man/Makefile.in b/man/Makefile.in index 40bf7a2..c42f07a 100644 --- a/man/Makefile.in +++ b/man/Makefile.in @@ -92,6 +92,9 @@ man: $(MAN5) $(MAN7) $(MAN8) $(MAN8CLUSTER) $(MAN8SYSTEMD_GENERATORS) $(MAN5) $(MAN7) $(MAN8) $(MAN8DM) $(MAN8CLUSTER): Makefile +Makefile: Makefile.in + @: + %: %.in @case "$@" in \ */*) ;; \ diff --git a/scripts/clvmd_init_red_hat.in b/scripts/clvmd_init_red_hat.in index 86dea4c..8c46c06 100644 --- a/scripts/clvmd_init_red_hat.in +++ b/scripts/clvmd_init_red_hat.in @@ -38,7 +38,7 @@ CLVMDOPTS="-T30" # allow up to $CLVMD_STOP_TIMEOUT seconds to clvmd to complete exit operations # default to 10 seconds -[ -z $CLMVD_STOP_TIMEOUT ] && CLVMD_STOP_TIMEOUT=10 +[ -z $CLVMD_STOP_TIMEOUT ] && CLVMD_STOP_TIMEOUT=10 LOCK_FILE="/var/lock/subsys/$DAEMON" diff --git a/test/shell/listings.sh b/test/shell/listings.sh index fbd4af7..fcf6308 100644 --- a/test/shell/listings.sh +++ b/test/shell/listings.sh @@ -68,6 +68,11 @@ test $(lvs --noheadings $vg | wc -l) -eq 2 test $(lvs -a --noheadings $vg | wc -l) -eq 6 dmsetup ls | grep "$PREFIX" | grep -v "LVMTEST.*pv." +# Check we parse /dev/mapper/vg-lv +lvdisplay "$DM_DEV_DIR/mapper/$vg-$lv3" +# Check we parse /dev/vg/lv +lvdisplay "$DM_DEV_DIR/$vg/$lv3" + lvcreate -l2 -s $vg/$lv3 lvcreate -l1 -s -n inval $vg/$lv3 lvcreate -l4 -I4 -i2 -n stripe $vg diff --git a/test/shell/lvcreate-thin.sh b/test/shell/lvcreate-thin.sh index 0433ac8..2884d53 100644 --- a/test/shell/lvcreate-thin.sh +++ b/test/shell/lvcreate-thin.sh @@ -261,4 +261,20 @@ lvcreate -L10G --chunksize 256 -T $vg/pool1 lvcreate -L60G --chunksize 1024 -T $vg/pool2 check lv_field $vg/pool1_tmeta size "2.50m" check lv_field $vg/pool2_tmeta size "3.75m" +lvremove -ff $vg + +# Block size of multiple 64KB needs >= 1.4 +if aux have_thin 1 4 0 ; then +# Test chunk size is rounded to 64KB boundary +lvcreate -L10G --poolmetadatasize 4M -T $vg/pool +check lv_field $vg/pool chunk_size "192.00k" +fi +# Old thinpool target required rounding to power of 2 +aux lvmconf "global/thin_disabled_features = [ \"block_size\" ]" +lvcreate -L10G --poolmetadatasize 4M -T $vg/pool_old +check lv_field $vg/pool_old chunk_size "256.00k" +lvremove -ff $vg +# reset +#aux lvmconf "global/thin_disabled_features = []" + vgremove -ff $vg diff --git a/tools/toollib.c b/tools/toollib.c index ddf2dcf..6d409a9 100644 --- a/tools/toollib.c +++ b/tools/toollib.c @@ -130,8 +130,8 @@ const char *skip_dev_dir(struct cmd_context *cmd, const char *vg_name, vg_name++; /* Reformat string if /dev/mapper found */ - if (!strncmp(vg_name, dmdir, dmdir_len) && vg_name[dmdir_len + 1] == '/') { - vg_name += devdir_len + 1; + if (!strncmp(vg_name, dmdir, dmdir_len) && vg_name[dmdir_len] == '/') { + vg_name += dmdir_len + 1; while (*vg_name == '/') vg_name++; @@ -1175,7 +1175,7 @@ struct dm_config_tree *get_cachepolicy_params(struct cmd_context *cmd) ok = 1; out: - if (!ok) { + if (!ok && result) { dm_config_destroy(result); result = NULL; }