1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

thin: enforce there is some free space in thin pool metadata

Unconditionally guard there is at least 1/4 of metadata volume
free (<16Mib) or 4MiB - whichever value is smaller.

In case there is not enough free space do not let operation proceed and
recommend thin-pool metadata resize (in case user has not
enabled autoresize, manual 'lvextend --poolmetadatasize' is needed).
This commit is contained in:
Zdenek Kabelac 2016-09-16 21:50:14 +02:00
parent 776d5a25b4
commit c2c2721d00
5 changed files with 43 additions and 2 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.166 -
=====================================
Enforce 4MiB or 25% metadata free space for thin pool operations.
Fix lock-holder device for thin pool with inactive thin volumes.
Use --alloc normal for mirror logs even if the mimages were stricter.
Use O_DIRECT to gather metadata in lvmdump.

View File

@ -4515,6 +4515,7 @@ static int _lvresize_adjust_policy(const struct logical_volume *lv,
{
struct cmd_context *cmd = lv->vg->cmd;
dm_percent_t percent;
dm_percent_t min_threshold;
int policy_threshold, policy_amount;
*amount = *meta_amount = 0;
@ -4562,7 +4563,10 @@ static int _lvresize_adjust_policy(const struct logical_volume *lv,
if (!lv_thin_pool_percent(lv, 1, &percent))
return_0;
*meta_amount = _adjust_amount(percent, policy_threshold, policy_amount);
/* Resize below the minimal usable value */
min_threshold = pool_metadata_min_threshold(first_seg(lv)) / DM_PERCENT_1;
*meta_amount = _adjust_amount(percent, (min_threshold < policy_threshold) ?
min_threshold : policy_threshold, policy_amount);
if (!lv_thin_pool_percent(lv, 0, &percent))
return_0;

View File

@ -501,6 +501,7 @@ int attach_pool_message(struct lv_segment *pool_seg, dm_thin_message_t type,
int lv_is_merging_thin_snapshot(const struct logical_volume *lv);
int pool_has_message(const struct lv_segment *seg,
const struct logical_volume *lv, uint32_t device_id);
int pool_metadata_min_threshold(const struct lv_segment *pool_seg);
int pool_below_threshold(const struct lv_segment *pool_seg);
int pool_check_overprovisioning(const struct logical_volume *lv);
int create_pool(struct logical_volume *lv, const struct segment_type *segtype,

View File

@ -215,9 +215,29 @@ int thin_pool_feature_supported(const struct logical_volume *lv, int feature)
return (attr & feature) ? 1 : 0;
}
int pool_metadata_min_threshold(const struct lv_segment *pool_seg)
{
/*
* Hardcoded minimal requirment for thin pool target.
*
* In the metadata LV there should be minimum from either 4MiB of free space
* or at least 25% of free space, which applies when the size of thin pool's
* metadata is less then 16MiB.
*/
const dm_percent_t meta_min = DM_PERCENT_1 * 25;
dm_percent_t meta_free = dm_make_percent(((4096 * 1024) >> SECTOR_SHIFT),
pool_seg->metadata_lv->size);
if (meta_min < meta_free)
meta_free = meta_min;
return DM_PERCENT_100 - meta_free;
}
int pool_below_threshold(const struct lv_segment *pool_seg)
{
dm_percent_t percent;
dm_percent_t min_threshold = pool_metadata_min_threshold(pool_seg);
dm_percent_t threshold = DM_PERCENT_1 *
find_config_tree_int(pool_seg->lv->vg->cmd, activation_thin_pool_autoextend_threshold_CFG,
lv_config_profile(pool_seg->lv));
@ -226,7 +246,7 @@ int pool_below_threshold(const struct lv_segment *pool_seg)
if (!lv_thin_pool_percent(pool_seg->lv, 0, &percent))
return_0;
if (percent > threshold) {
if (percent > threshold || percent >= DM_PERCENT_100) {
log_debug("Threshold configured for free data space in "
"thin pool %s has been reached (%.2f%% >= %.2f%%).",
display_lvname(pool_seg->lv),
@ -239,6 +259,18 @@ int pool_below_threshold(const struct lv_segment *pool_seg)
if (!lv_thin_pool_percent(pool_seg->lv, 1, &percent))
return_0;
if (percent >= min_threshold) {
log_warn("WARNING: Remaining free space in metadata of thin pool %s "
"is too low (%.2f%% >= %.2f%%). "
"Resize is recommended.",
display_lvname(pool_seg->lv),
dm_percent_to_float(percent),
dm_percent_to_float(min_threshold));
return 0;
}
if (percent > threshold) {
log_debug("Threshold configured for free metadata space in "
"thin pool %s has been reached (%.2f%% > %.2f%%).",

View File

@ -501,6 +501,9 @@ Supported values are in range between 2MiB and 16GiB for thin pool,
and upto 16GiB for cache pool. The minimum value is computed from pool's
data size.
Default value for thin pool is (Pool_LV_size / Pool_LV_chunk_size * 64b).
To work with a thin pool, there should be at least 25% of free space
when the size of metadata is smaller then 16MiB,
or at least 4MiB of free space otherwise.
Default unit is megabytes.
.
.HP