1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-02 01:18:26 +03:00

report: add kernel_discards report field to display thin pool discard used in kernel

Thin pool discard mode set in metadata can be different from the one
actually used if any device underneath does not support that mode. Add
kernel_discard report field to make it possible to see this difference.
This commit is contained in:
Peter Rajnoha 2016-01-14 16:54:12 +01:00
parent 6d09c8c2c4
commit b82d5ee092
8 changed files with 90 additions and 0 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.140 - Version 2.02.140 -
=================================== ===================================
Add kernel_discards report field to display thin pool discard used in kernel.
Correct checking of target presence when driver access is disabled. Correct checking of target presence when driver access is disabled.
Eval poolmetadatasize arg earlier in lvresize. Eval poolmetadatasize arg earlier in lvresize.
Fix vgcfgrestore to respect allocatable attribute of PVs. Fix vgcfgrestore to respect allocatable attribute of PVs.

View File

@ -162,6 +162,45 @@ char *lvseg_discards_dup(struct dm_pool *mem, const struct lv_segment *seg)
return dm_pool_strdup(mem, get_pool_discards_name(seg->discards)); return dm_pool_strdup(mem, get_pool_discards_name(seg->discards));
} }
char *lvseg_kernel_discards_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_with_info_and_seg_status *lvdm)
{
const char *s = "";
char *ret;
if (lvdm->seg_status.type == SEG_STATUS_THIN_POOL)
s = get_pool_discards_name(lvdm->seg_status.thin_pool->discards);
if (!(ret = dm_pool_strdup(mem, s))) {
log_error("lvseg_kernel_discards_dup_with_info_and_seg_status: dm_pool_strdup failed");
return NULL;
}
return ret;
}
char *lvseg_kernel_discards_dup(struct dm_pool *mem, const struct lv_segment *seg)
{
char *ret = NULL;
struct lv_with_info_and_seg_status status = {
.seg_status.type = SEG_STATUS_NONE,
.seg_status.seg = seg
};
if (!lv_is_thin_pool(seg->lv))
return NULL;
if (!(status.seg_status.mem = dm_pool_create("reporter_pool", 1024)))
return_NULL;
if (!(status.info_ok = lv_info_with_seg_status(seg->lv->vg->cmd, seg->lv, seg, 1, &status, 0, 0)))
goto_bad;
ret = lvseg_kernel_discards_dup_with_info_and_seg_status(mem, &status);
bad:
dm_pool_destroy(status.seg_status.mem);
return ret;
}
char *lvseg_cachemode_dup(struct dm_pool *mem, const struct lv_segment *seg) char *lvseg_cachemode_dup(struct dm_pool *mem, const struct lv_segment *seg)
{ {
const char *name = get_cache_mode_name(seg); const char *name = get_cache_mode_name(seg);

View File

@ -95,6 +95,7 @@ char *lvseg_seg_metadata_le_ranges(struct dm_pool *mem, const struct lv_segment
int lv_kernel_major(const struct logical_volume *lv); int lv_kernel_major(const struct logical_volume *lv);
int lv_kernel_minor(const struct logical_volume *lv); int lv_kernel_minor(const struct logical_volume *lv);
uint32_t lv_kernel_read_ahead(const struct logical_volume *lv); uint32_t lv_kernel_read_ahead(const struct logical_volume *lv);
char *lvseg_kernel_discards_dup(struct dm_pool *mem, const struct lv_segment *seg);
/* LV modification functions */ /* LV modification functions */
int lv_set_creation(struct logical_volume *lv, int lv_set_creation(struct logical_volume *lv,
@ -137,4 +138,5 @@ char *lv_host_dup(struct dm_pool *mem, const struct logical_volume *lv);
char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv); char *lv_active_dup(struct dm_pool *mem, const struct logical_volume *lv);
char *lv_profile_dup(struct dm_pool *mem, const struct logical_volume *lv); char *lv_profile_dup(struct dm_pool *mem, const struct logical_volume *lv);
char *lv_lock_args_dup(struct dm_pool *mem, const struct logical_volume *lv); char *lv_lock_args_dup(struct dm_pool *mem, const struct logical_volume *lv);
char *lvseg_kernel_discards_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_with_info_and_seg_status *lvdm);
#endif /* _LVM_LV_H */ #endif /* _LVM_LV_H */

View File

@ -113,6 +113,7 @@ FIELD(LVSSTATUS, lv, NUM, "CacheReadMisses", lvid, 16, cache_read_misses, cache_
FIELD(LVSSTATUS, lv, NUM, "CacheWriteHits", lvid, 16, cache_write_hits, cache_write_hits, "Cache write hits.", 0) FIELD(LVSSTATUS, lv, NUM, "CacheWriteHits", lvid, 16, cache_write_hits, cache_write_hits, "Cache write hits.", 0)
FIELD(LVSSTATUS, lv, NUM, "CacheWriteMisses", lvid, 16, cache_write_misses, cache_write_misses, "Cache write misses.", 0) FIELD(LVSSTATUS, lv, NUM, "CacheWriteMisses", lvid, 16, cache_write_misses, cache_write_misses, "Cache write misses.", 0)
FIELD(LVSSTATUS, lv, STR, "Health", lvid, 15, lvhealthstatus, lv_health_status, "LV health status.", 0) FIELD(LVSSTATUS, lv, STR, "Health", lvid, 15, lvhealthstatus, lv_health_status, "LV health status.", 0)
FIELD(LVSSTATUS, lv, STR, "KDiscards", lvid, 8, kdiscards, kernel_discards, "For thin pools, how discards are handled in kernel.", 0)
FIELD(LABEL, label, STR, "Fmt", type, 3, pvfmt, pv_fmt, "Type of metadata.", 0) FIELD(LABEL, label, STR, "Fmt", type, 3, pvfmt, pv_fmt, "Type of metadata.", 0)
FIELD(LABEL, label, STR, "PV UUID", type, 38, pvuuid, pv_uuid, "Unique identifier.", 0) FIELD(LABEL, label, STR, "PV UUID", type, 38, pvuuid, pv_uuid, "Unique identifier.", 0)

View File

@ -450,6 +450,8 @@ GET_LVSEG_NUM_PROPERTY_FN(thin_id, lvseg->device_id)
#define _thin_id_set prop_not_implemented_set #define _thin_id_set prop_not_implemented_set
GET_LVSEG_STR_PROPERTY_FN(discards, lvseg_discards_dup(lvseg->lv->vg->vgmem, lvseg)) GET_LVSEG_STR_PROPERTY_FN(discards, lvseg_discards_dup(lvseg->lv->vg->vgmem, lvseg))
#define _discards_set prop_not_implemented_set #define _discards_set prop_not_implemented_set
GET_LVSEG_STR_PROPERTY_FN(kernel_discards, lvseg_kernel_discards_dup(lvseg->lv->vg->vgmem, lvseg))
#define _kernel_discards_set prop_not_implemented_set
GET_LVSEG_STR_PROPERTY_FN(cachemode, lvseg_cachemode_dup(lvseg->lv->vg->vgmem, lvseg)) GET_LVSEG_STR_PROPERTY_FN(cachemode, lvseg_cachemode_dup(lvseg->lv->vg->vgmem, lvseg))
#define _cachemode_set prop_not_implemented_set #define _cachemode_set prop_not_implemented_set
GET_LVSEG_NUM_PROPERTY_FN(seg_start, (SECTOR_SIZE * lvseg_start(lvseg))) GET_LVSEG_NUM_PROPERTY_FN(seg_start, (SECTOR_SIZE * lvseg_start(lvseg)))

View File

@ -2221,6 +2221,23 @@ static int _discards_disp(struct dm_report *rh, struct dm_pool *mem,
return _field_set_value(field, "", NULL); return _field_set_value(field, "", NULL);
} }
static int _kdiscards_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
const struct lv_with_info_and_seg_status *lvdm = (const struct lv_with_info_and_seg_status *) data;
const char *discards_str;
if (!(discards_str = lvseg_kernel_discards_dup_with_info_and_seg_status(mem, lvdm)))
return_0;
if (*discards_str)
return _field_set_value(field, discards_str, NULL);
return _field_set_value(field, GET_FIRST_RESERVED_NAME(seg_kernel_discards_undef),
GET_FIELD_RESERVED_VALUE(seg_kernel_discards_undef));
}
static int _cachemode_disp(struct dm_report *rh, struct dm_pool *mem, static int _cachemode_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field, struct dm_report_field *field,
const void *data, void *private) const void *data, void *private)

View File

@ -93,6 +93,7 @@ FIELD_RESERVED_VALUE(NAMED | RANGE | FUZZY | DYNAMIC, lv_time, lv_time_fuzzy, ""
FIELD_RESERVED_VALUE(NOFLAG, cache_policy, cache_policy_undef, "", "", "", "undefined") FIELD_RESERVED_VALUE(NOFLAG, cache_policy, cache_policy_undef, "", "", "", "undefined")
FIELD_RESERVED_VALUE(NOFLAG, seg_monitor, seg_monitor_undef, "", "", "", "undefined") FIELD_RESERVED_VALUE(NOFLAG, seg_monitor, seg_monitor_undef, "", "", "", "undefined")
FIELD_RESERVED_VALUE(NOFLAG, lv_health_status, health_undef, "", "", "", "undefined") FIELD_RESERVED_VALUE(NOFLAG, lv_health_status, health_undef, "", "", "", "undefined")
FIELD_RESERVED_VALUE(NOFLAG, kernel_discards, seg_kernel_discards_undef, "", "", "", "undefined")
/* TODO the following 2 need STR_LIST support for reserved values /* TODO the following 2 need STR_LIST support for reserved values
FIELD_RESERVED_VALUE(cache_settings, cache_settings_default, "", "default", "default") FIELD_RESERVED_VALUE(cache_settings, cache_settings_default, "", "default", "default")
FIELD_RESERVED_VALUE(cache_settings, cache_settings_undef, "", "undefined", "undefined") */ FIELD_RESERVED_VALUE(cache_settings, cache_settings_undef, "", "undefined", "undefined") */

View File

@ -26,15 +26,20 @@ aux have_thin 1 1 0 || skip
aux prepare_pvs 2 64 aux prepare_pvs 2 64
aux extend_filter_LVMTEST
vgcreate $vg -s 64K $(cat DEVICES) vgcreate $vg -s 64K $(cat DEVICES)
# Create named pool only # Create named pool only
lvcreate -l1 --discards ignore -T $vg/pool lvcreate -l1 --discards ignore -T $vg/pool
check lv_field $vg/pool discards "ignore" check lv_field $vg/pool discards "ignore"
check lv_field $vg/pool kernel_discards "ignore"
lvcreate -l1 --discards nopassdown -T $vg/pool1 lvcreate -l1 --discards nopassdown -T $vg/pool1
check lv_field $vg/pool1 discards "nopassdown" check lv_field $vg/pool1 discards "nopassdown"
check lv_field $vg/pool1 kernel_discards "nopassdown"
lvcreate -l1 --discards passdown -T $vg/pool2 lvcreate -l1 --discards passdown -T $vg/pool2
check lv_field $vg/pool2 discards "passdown" check lv_field $vg/pool2 discards "passdown"
check lv_field $vg/pool2 discards "passdown"
lvchange --discards nopassdown $vg/pool2 lvchange --discards nopassdown $vg/pool2
@ -66,3 +71,25 @@ lvchange --discards ignore $vg/pool1
check lv_field $vg/pool1 discards "ignore" check lv_field $vg/pool1 discards "ignore"
vgremove -ff $vg vgremove -ff $vg
# Create thin pool with discards set to "ignore".
# If we create a thin volume which we use for a PV
# which we use to create another thin pool on top
# with discards set to "passdown", the discards value
# in metadata is still "passdown", but because the
# device below does not support it, the kernel value
# of discards actually used will be "nopassdown".
# This is why we have "-o discards" and "-o kernel_discards".
vgcreate -s 1m ${vg}_1 $(cat DEVICES)
lvcreate -l 10 -T ${vg}_1/pool --discards ignore
lvcreate -V 9m -T ${vg}_1/pool -n device_with_ignored_discards
vgcreate -s 1m ${vg}_2 "$DM_DEV_DIR/${vg}_1/device_with_ignored_discards"
lvcreate -l 1 -T ${vg}_2/pool --discards passdown
lvcreate -V 1 -T ${vg}_2/pool
check lv_field ${vg}_1/pool discards "ignore"
check lv_field ${vg}_1/pool kernel_discards "ignore"
check lv_field ${vg}_2/pool discards "passdown"
check lv_field ${vg}_2/pool kernel_discards "nopassdown"
vgremove -ff ${vg}_2
vgremove -ff ${vg}_1