summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Rajnoha <prajnoha@redhat.com>2015-05-07 10:29:24 +0200
committerPeter Rajnoha <prajnoha@redhat.com>2015-05-08 09:57:08 +0200
commit73bcbb5b7c31885f39b273b8f883992acb296598 (patch)
tree8ead845a207d33b0f0b8aac172ae1bbec408083f
parentbfbdd3bff08bb3f7740e1c388e81f3e70e88a745 (diff)
downloadlvm2-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.h2
-rw-r--r--lib/report/properties.c4
-rw-r--r--lib/report/report.c85
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)))