diff options
author | Peter Rajnoha <prajnoha@redhat.com> | 2015-05-07 10:29:24 +0200 |
---|---|---|
committer | Peter Rajnoha <prajnoha@redhat.com> | 2015-05-08 09:57:08 +0200 |
commit | 73bcbb5b7c31885f39b273b8f883992acb296598 (patch) | |
tree | 8ead845a207d33b0f0b8aac172ae1bbec408083f | |
parent | bfbdd3bff08bb3f7740e1c388e81f3e70e88a745 (diff) | |
download | lvm2-dev-prajnoha-full-ancestors-descendants.tar.gz |
report: add ancestors_full and descendants_full reporting fieldsdev-prajnoha-full-ancestors-descendants
In contrast to ancestors and descendants fields, the *_full counterparts
also count with indirect origins in case thin snapshot LV was removed
from the middle of the snapshot chain.
-rw-r--r-- | lib/report/columns.h | 2 | ||||
-rw-r--r-- | lib/report/properties.c | 4 | ||||
-rw-r--r-- | lib/report/report.c | 85 |
3 files changed, 83 insertions, 8 deletions
diff --git a/lib/report/columns.h b/lib/report/columns.h index 06282c5b4..27dd8ca2e 100644 --- a/lib/report/columns.h +++ b/lib/report/columns.h @@ -65,7 +65,9 @@ FIELD(LVS, lv, NUM, "#Seg", lvid, 4, lvsegcount, seg_count, "Number of segments FIELD(LVS, lv, STR, "Origin", lvid, 6, origin, origin, "For snapshots, the origin device of this LV.", 0) FIELD(LVS, lv, SIZ, "OSize", lvid, 5, originsize, origin_size, "For snapshots, the size of the origin device of this LV.", 0) FIELD(LVS, lv, STR_LIST, "Ancestors", lvid, 12, lvancestors, lv_ancestors, "Ancestors of this LV.", 0) +FIELD(LVS, lv, STR_LIST, "FAncestors", lvid, 12, lvancestorsfull, lv_ancestors_full, "Full list of ancestors of this LV.", 0) FIELD(LVS, lv, STR_LIST, "Descendants", lvid, 12, lvdescendants, lv_descendants, "Descendants of this LV.", 0) +FIELD(LVS, lv, STR_LIST, "FDescendants", lvid, 12, lvdescendantsfull, lv_descendants_full, "Full list of descendants of this LV.", 0) FIELD(LVS, lv, PCT, "Data%", lvid, 6, datapercent, data_percent, "For snapshot and thin pools and volumes, the percentage full if LV is active.", 0) FIELD(LVS, lv, PCT, "Snap%", lvid, 6, snpercent, snap_percent, "For snapshots, the percentage full if LV is active.", 0) FIELD(LVS, lv, PCT, "Meta%", lvid, 6, metadatapercent, metadata_percent, "For thin pools, the percentage of metadata full if LV is active.", 0) diff --git a/lib/report/properties.c b/lib/report/properties.c index b0a91a7da..98df71823 100644 --- a/lib/report/properties.c +++ b/lib/report/properties.c @@ -302,8 +302,12 @@ GET_LV_NUM_PROPERTY_FN(origin_size, (SECTOR_SIZE * lv_origin_size(lv))) #define _origin_size_set prop_not_implemented_set #define _lv_ancestors_set prop_not_implemented_set #define _lv_ancestors_get prop_not_implemented_get +#define _lv_ancestors_full_set prop_not_implemented_set +#define _lv_ancestors_full_get prop_not_implemented_get #define _lv_descendants_set prop_not_implemented_set #define _lv_descendants_get prop_not_implemented_get +#define _lv_descendants_full_set prop_not_implemented_set +#define _lv_descendants_full_get prop_not_implemented_get GET_LV_NUM_PROPERTY_FN(snap_percent, _snap_percent(lv)) #define _snap_percent_set prop_not_implemented_set GET_LV_NUM_PROPERTY_FN(copy_percent, _copy_percent(lv)) diff --git a/lib/report/report.c b/lib/report/report.c index a1076690a..bd3f51a94 100644 --- a/lib/report/report.c +++ b/lib/report/report.c @@ -634,25 +634,33 @@ static int _origin_disp(struct dm_report *rh, struct dm_pool *mem, } static int _find_ancestors(struct _str_list_append_baton *ancestors, - struct logical_volume *lv) + struct logical_volume *lv, int full) { struct logical_volume *ancestor_lv = NULL; struct lv_segment *seg; + struct dm_str_list *strl; if (lv_is_cow(lv)) { ancestor_lv = origin_from_cow(lv); - } else if (lv_is_thin_volume(lv)) { + } else if (lv_is_thin_volume(lv)) { seg = first_seg(lv); if (seg->origin) ancestor_lv = seg->origin; else if (seg->external_lv) ancestor_lv = seg->external_lv; + else if (full) { + dm_list_iterate_items(strl, &seg->lv->removed_ancestor_lv_names) + if (!_str_list_append(strl->str, ancestors)) + return_0; + if (seg->indirect_origin) + ancestor_lv = seg->indirect_origin; + } } if (ancestor_lv) { if (!_str_list_append(ancestor_lv->name, ancestors)) return_0; - if (!_find_ancestors(ancestors, ancestor_lv)) + if (!_find_ancestors(ancestors, ancestor_lv, full)) return_0; } @@ -670,7 +678,7 @@ static int _lvancestors_disp(struct dm_report *rh, struct dm_pool *mem, if (!(ancestors.result = str_list_create(mem))) return_0; - if (!_find_ancestors(&ancestors, lv)) { + if (!_find_ancestors(&ancestors, lv, 0)) { dm_pool_free(ancestors.mem, ancestors.result); return_0; } @@ -678,19 +686,39 @@ static int _lvancestors_disp(struct dm_report *rh, struct dm_pool *mem, return _field_set_string_list(rh, field, ancestors.result, private, 0); } +static int _lvancestorsfull_disp(struct dm_report *rh, struct dm_pool *mem, + struct dm_report_field *field, + const void *data, void *private) +{ + struct logical_volume *lv = (struct logical_volume *) data; + struct _str_list_append_baton ancestors_full; + + ancestors_full.mem = mem; + if (!(ancestors_full.result = str_list_create(mem))) + return_0; + + if (!_find_ancestors(&ancestors_full, lv, 1)) { + dm_pool_free(ancestors_full.mem, ancestors_full.result); + return_0; + } + + return _field_set_string_list(rh, field, ancestors_full.result, private, 0); +} + static int _find_descendants(struct _str_list_append_baton *descendants, - struct logical_volume *lv) + struct logical_volume *lv, int full) { struct logical_volume *descendant_lv = NULL; const struct seg_list *sl; struct lv_segment *seg; + struct dm_str_list *strl; if (lv_is_origin(lv)) { dm_list_iterate_items_gen(seg, &lv->snapshot_segs, origin_list) { if ((descendant_lv = seg->cow)) { if (!_str_list_append(descendant_lv->name, descendants)) return_0; - if (!_find_descendants(descendants, descendant_lv)) + if (!_find_descendants(descendants, descendant_lv, full)) return_0; } } @@ -703,12 +731,34 @@ static int _find_descendants(struct _str_list_append_baton *descendants, } if (descendant_lv) { + dm_list_iterate_items(strl, &descendant_lv->removed_ancestor_lv_names) + if (!_str_list_append(strl->str, descendants)) + return_0; if (!_str_list_append(descendant_lv->name, descendants)) return_0; - if (!_find_descendants(descendants, descendant_lv)) + if (!_find_descendants(descendants, descendant_lv, full)) return_0; } } + + if (full) { + descendant_lv = NULL; + dm_list_iterate_items(sl, &lv->indirect_segs_using_this_lv) { + seg = first_seg(sl->seg->lv); + if (seg->indirect_origin == lv) + descendant_lv = sl->seg->lv; + + if (descendant_lv) { + dm_list_iterate_items(strl, &descendant_lv->removed_ancestor_lv_names) + if (!_str_list_append(strl->str, descendants)) + return_0; + if (!_str_list_append(descendant_lv->name, descendants)) + return_0; + if (!_find_descendants(descendants, descendant_lv, full)) + return_0; + } + } + } } return 1; @@ -725,7 +775,7 @@ static int _lvdescendants_disp(struct dm_report *rh, struct dm_pool *mem, if (!(descendants.result = str_list_create(mem))) return_0; - if (!_find_descendants(&descendants, lv)) { + if (!_find_descendants(&descendants, lv, 0)) { dm_pool_free(descendants.mem, descendants.result); return_0; } @@ -733,6 +783,25 @@ static int _lvdescendants_disp(struct dm_report *rh, struct dm_pool *mem, return _field_set_string_list(rh, field, descendants.result, private, 0); } +static int _lvdescendantsfull_disp(struct dm_report *rh, struct dm_pool *mem, + struct dm_report_field *field, + const void *data, void *private) +{ + struct logical_volume *lv = (struct logical_volume *) data; + struct _str_list_append_baton descendants_full; + + descendants_full.mem = mem; + if (!(descendants_full.result = str_list_create(mem))) + return_0; + + if (!_find_descendants(&descendants_full, lv, 1)) { + dm_pool_free(descendants_full.mem, descendants_full.result); + return_0; + } + + return _field_set_string_list(rh, field, descendants_full.result, private, 0); +} + static int _movepv_disp(struct dm_report *rh, struct dm_pool *mem __attribute__((unused)), struct dm_report_field *field, const void *data, void *private __attribute__((unused))) |