master - activation: lv_info_with_seg_status API change
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6fd20be629b6dc...
Commit: 6fd20be629b6dceb96702c5f875a2e612e6f465d
Parent: ed93f0973a307634d1266aeab5c0d2bbceab086e
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Dec 5 14:31:25 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Dec 5 17:09:47 2016 +0100
activation: lv_info_with_seg_status API change
Drop LV from passed API arg - it's always segment being checked.
Also use_layer is now in full control of lv_info_with_seg_status().
It decides which device needs to be checked to get 'the most info'.
TODO: future version should be able to expose status from
---
WHATS_NEW | 1 +
lib/activate/activate.c | 47 +++++++++++++----------------------------------
lib/activate/activate.h | 16 +++++-----------
lib/metadata/lv.c | 6 +++---
tools/reporter.c | 18 ++++++++----------
5 files changed, 30 insertions(+), 58 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 2b0e822..a097477 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Simplify internal lv_info_with_seg_status API.
Decide which status is needed in one place for lv_info_with_seg_status.
Fix matching of LV segment when checking for it info status.
Report log_warn when status cannot be parsed.
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 1b1f7e4..afdf518 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -741,32 +741,24 @@ int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
}
/*
- * Returns 1 if lv_seg_status structure populated,
- * else 0 on failure or if device not active locally.
- */
-int lv_status(struct cmd_context *cmd, const struct lv_segment *lv_seg,
- int use_layer, struct lv_seg_status *lv_seg_status)
-{
- if (!activation())
- return 0;
-
- return _lv_info(cmd, lv_seg->lv, use_layer, NULL, lv_seg, lv_seg_status, 0, 0);
-}
-
-/*
- * Returns 1 if lv_with_info_and_seg_status structure populated,
+ * Returns 1 if lv_with_info_and_seg_status info structure populated,
* else 0 on failure or if device not active locally.
*
* When seg_status parsing had troubles it will set type to SEG_STATUS_UNKNOWN.
*
- * This is the same as calling lv_info and lv_status,
- * but* it's done in one go with one ioctl if possible! ]
+ * Using usually one ioctl to obtain info and status.
+ * More complex segment do collect info from one device,
+ * but status from another device.
+ *
+ * TODO: further improve with more statuses (i.e. snapshot's origin/merge)
*/
-int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume *lv,
- const struct lv_segment *lv_seg, int use_layer,
+int lv_info_with_seg_status(struct cmd_context *cmd,
+ const struct lv_segment *lv_seg,
struct lv_with_info_and_seg_status *status,
int with_open_count, int with_read_ahead)
{
+ const struct logical_volume *lv = status->lv = lv_seg->lv;
+
if (!activation())
return 0;
@@ -774,23 +766,10 @@ int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume
/* INFO is not set as cache-pool cannot be active.
* STATUS is collected from cache LV */
lv_seg = get_only_segment_using_this_lv(lv);
- (void) _lv_info(cmd, lv_seg->lv, use_layer, NULL, lv_seg, &status->seg_status, 0, 0);
+ (void) _lv_info(cmd, lv_seg->lv, 0, NULL, lv_seg, &status->seg_status, 0, 0);
return 1;
}
- /* By default, take the first LV segment to report status for. */
- if (!lv_seg)
- lv_seg = first_seg(lv);
-
- if (lv != lv_seg->lv)
- /*
- * If the info is requested for an LV and segment
- * status for segment that belong to another LV,
- * we need to acquire info and status separately!
- */
- return _lv_info(cmd, lv, use_layer, &status->info, NULL, NULL, with_open_count, with_read_ahead) &&
- _lv_info(cmd, lv_seg->lv, use_layer, NULL, lv_seg, &status->seg_status, 0, 0);
-
if (lv_is_thin_pool(lv)) {
/* Always collect status for '-tpool' */
if (_lv_info(cmd, lv, 1, &status->info, lv_seg, &status->seg_status, 0, 0) &&
@@ -824,7 +803,7 @@ int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume
* When merge is in progress, query merging origin LV instead.
* COW volume is already mapped as error target in this case.
*/
- lv = origin_from_cow(lv);
+ status->lv = lv = origin_from_cow(lv);
lv_seg = first_seg(lv);
log_debug_activation("Snapshot merge is in progress, querying status of %s instead.",
display_lvname(lv));
@@ -833,7 +812,7 @@ int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume
lv_seg = find_snapshot(lv);
}
- return _lv_info(cmd, lv, use_layer, &status->info, lv_seg, &status->seg_status,
+ return _lv_info(cmd, lv, 0, &status->info, lv_seg, &status->seg_status,
with_open_count, with_read_ahead);
}
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index 3922d78..db8d997 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -54,11 +54,12 @@ struct lv_seg_status {
};
struct lv_with_info_and_seg_status {
- const struct logical_volume *lv; /* input */
int info_ok;
+ const struct logical_volume *lv; /* output */
struct lvinfo info; /* output */
int seg_part_of_lv; /* output */
- struct lv_seg_status seg_status; /* input/output, see lv_seg_status */
+ struct lv_seg_status seg_status; /* output, see lv_seg_status */
+ /* TODO: add extra status for snapshot origin */
};
struct lv_activate_opts {
@@ -133,21 +134,14 @@ int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
struct lvinfo *info, int with_open_count, int with_read_ahead);
/*
- * Returns 1 if lv_seg_status structure has been populated,
- * else 0 on failure or if device not active locally.
- */
-int lv_status(struct cmd_context *cmd, const struct lv_segment *lv_seg,
- int use_layer, struct lv_seg_status *lv_seg_status);
-
-/*
* Returns 1 if lv_info_and_seg_status structure has been populated,
* else 0 on failure or if device not active locally.
*
* lv_info_with_seg_status is the same as calling lv_info and then lv_status,
* but this fn tries to do that with one ioctl if possible.
*/
-int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume *lv,
- const struct lv_segment *lv_seg, int use_layer,
+int lv_info_with_seg_status(struct cmd_context *cmd,
+ const struct lv_segment *lv_seg,
struct lv_with_info_and_seg_status *status,
int with_open_count, int with_read_ahead);
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index eb5066a..087b564 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -255,7 +255,7 @@ char *lvseg_kernel_discards_dup(struct dm_pool *mem, const struct lv_segment *se
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)))
+ if (!(status.info_ok = lv_info_with_seg_status(seg->lv->vg->cmd, seg, &status, 0, 0)))
goto_bad;
ret = lvseg_kernel_discards_dup_with_info_and_seg_status(mem, &status);
@@ -407,7 +407,7 @@ dm_percent_t lvseg_percent_with_info_and_seg_status(const struct lv_with_info_an
/* TODO: expose highest mapped sector */
p = DM_PERCENT_INVALID;
else {
- seg = first_seg(lvdm->lv);
+ seg = lvdm->seg_status.seg;
/* Pool allocates whole chunk so round-up to nearest one */
csize = first_seg(seg->pool_lv)->chunk_size;
csize = ((seg->lv->size + csize - 1) / csize) * csize;
@@ -1318,7 +1318,7 @@ char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
if (!(status.seg_status.mem = dm_pool_create("reporter_pool", 1024)))
return_0;
- if (!(status.info_ok = lv_info_with_seg_status(lv->vg->cmd, lv, first_seg(lv), 1, &status, 1, 1)))
+ if (!(status.info_ok = lv_info_with_seg_status(lv->vg->cmd, first_seg(lv), &status, 1, 1)))
goto_bad;
ret = lv_attr_dup_with_info_and_seg_status(mem, &status);
diff --git a/tools/reporter.c b/tools/reporter.c
index 0a9ca34..fc87c06 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -88,14 +88,13 @@ static int _vgs_single(struct cmd_context *cmd __attribute__((unused)),
}
static int _do_info_and_status(struct cmd_context *cmd,
- const struct logical_volume *lv,
const struct lv_segment *lv_seg,
struct lv_with_info_and_seg_status *status,
int do_info, int do_status)
{
- status->lv = lv;
+ status->lv = lv_seg->lv;
- if (lv_is_historical(lv))
+ if (lv_is_historical(lv_seg->lv))
return 1;
if (do_status) {
@@ -104,13 +103,12 @@ static int _do_info_and_status(struct cmd_context *cmd,
if (do_info)
/* both info and status */
- status->info_ok = lv_info_with_seg_status(cmd, lv, lv_seg, 0, status, 1, 1);
+ status->info_ok = lv_info_with_seg_status(cmd, lv_seg, status, 1, 1);
else
- /* status only */
- status->info_ok = lv_info_with_seg_status(cmd, lv, lv_seg, 0, status, 0, 0);
+ status->info_ok = lv_info_with_seg_status(cmd, lv_seg, status, 0, 0);
} else if (do_info)
/* info only */
- status->info_ok = lv_info(cmd, lv, 0, &status->info, 1, 1);
+ status->info_ok = lv_info(cmd, status->lv, 0, &status->info, 1, 1);
return 1;
}
@@ -126,7 +124,7 @@ static int _do_lvs_with_info_and_status_single(struct cmd_context *cmd,
};
int r = ECMD_FAILED;
- if (!_do_info_and_status(cmd, lv, NULL, &status, do_info, do_status))
+ if (!_do_info_and_status(cmd, first_seg(lv), &status, do_info, do_status))
goto_out;
if (!report_object(sh ? : handle->custom_handle, sh != NULL,
@@ -176,7 +174,7 @@ static int _do_segs_with_info_and_status_single(struct cmd_context *cmd,
};
int r = ECMD_FAILED;
- if (!_do_info_and_status(cmd, seg->lv, seg, &status, do_info, do_status))
+ if (!_do_info_and_status(cmd, seg, &status, do_info, do_status))
goto_out;
if (!report_object(sh ? : handle->custom_handle, sh != NULL,
@@ -302,7 +300,7 @@ static int _do_pvsegs_sub_single(struct cmd_context *cmd,
.lv = &_free_logical_volume
};
- if (seg && !_do_info_and_status(cmd, seg->lv, seg, &status, do_info, do_status))
+ if (seg && !_do_info_and_status(cmd, seg, &status, do_info, do_status))
goto_out;
if (!report_object(sh ? : handle->custom_handle, sh != NULL,
7 years, 4 months
master - activation: lv_info_with_seg_status unify status selection
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ed93f0973a3076...
Commit: ed93f0973a307634d1266aeab5c0d2bbceab086e
Parent: 0089201588d65bf131d3fadd1cf5be67a562c4b1
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Dec 5 10:20:42 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Dec 5 17:09:13 2016 +0100
activation: lv_info_with_seg_status unify status selection
Start moving selection of status taken for a LV into a single place.
The logic for showing info & status has been spread over multiple
places and were doing too complex decision going agains each other.
Unify selection of status of origin & cow scanned device.
TODO: in future we want to grab status for LV and layered LV and have
both statuses present for display - i.e. when 'old snapshot'
of thinLV is takes and there is ongoing merge - at some moment
we are not capable to show all needed info.
---
WHATS_NEW | 1 +
lib/activate/activate.c | 82 ++++++++++++++++++++++++++++++--------------
lib/activate/dev_manager.c | 56 +++++++++++++++--------------
tools/reporter.c | 41 +++-------------------
4 files changed, 91 insertions(+), 89 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 0f5ed02..2b0e822 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Decide which status is needed in one place for lv_info_with_seg_status.
Fix matching of LV segment when checking for it info status.
Report log_warn when status cannot be parsed.
Test segment type before accessing segment members when checking status.
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index efb8912..1b1f7e4 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -688,32 +688,6 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv,
if (seg_status) {
/* TODO: for now it's mess with seg_status */
seg_status->seg = seg;
- if (lv_is_merging_cow(lv)) {
- if (lv_has_target_type(cmd->mem, origin_from_cow(lv), NULL, TARGET_NAME_SNAPSHOT_MERGE)) {
- /*
- * When the snapshot-merge has not yet started, query COW LVs as is.
- * When merge is in progress, query merging origin LV instead.
- * COW volume is already mapped as error target in this case.
- */
- lv = origin_from_cow(lv);
- seg_status->seg = first_seg(lv);
- log_debug_activation("Snapshot merge is in progress, querying status of %s instead.",
- display_lvname(lv));
- }
- } else if (!use_layer && lv_is_origin(lv) && !lv_is_external_origin(lv)) {
- /*
- * Query status for 'layered' (-real) device most of the time,
- * only when snapshot merge started, query its progress.
- * TODO: single LV may need couple status to be exposed at once....
- * but this needs more logical background
- */
- if (!lv_is_merging_origin(lv) ||
- !lv_has_target_type(cmd->mem, origin_from_cow(lv), NULL, TARGET_NAME_SNAPSHOT_MERGE))
- use_layer = 1;
- } else if (lv_is_cow(lv)) {
- /* Hadle fictional lvm2 snapshot and query snapshotX volume */
- seg_status->seg = find_snapshot(lv);
- }
}
if (!dev_manager_info(cmd, lv,
@@ -783,6 +757,8 @@ int lv_status(struct cmd_context *cmd, const struct lv_segment *lv_seg,
* Returns 1 if lv_with_info_and_seg_status structure populated,
* else 0 on failure or if device not active locally.
*
+ * When seg_status parsing had troubles it will set type to SEG_STATUS_UNKNOWN.
+ *
* This is the same as calling lv_info and lv_status,
* but* it's done in one go with one ioctl if possible! ]
*/
@@ -794,6 +770,18 @@ int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume
if (!activation())
return 0;
+ if (lv_is_used_cache_pool(lv)) {
+ /* INFO is not set as cache-pool cannot be active.
+ * STATUS is collected from cache LV */
+ lv_seg = get_only_segment_using_this_lv(lv);
+ (void) _lv_info(cmd, lv_seg->lv, use_layer, NULL, lv_seg, &status->seg_status, 0, 0);
+ return 1;
+ }
+
+ /* By default, take the first LV segment to report status for. */
+ if (!lv_seg)
+ lv_seg = first_seg(lv);
+
if (lv != lv_seg->lv)
/*
* If the info is requested for an LV and segment
@@ -803,6 +791,48 @@ int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume
return _lv_info(cmd, lv, use_layer, &status->info, NULL, NULL, with_open_count, with_read_ahead) &&
_lv_info(cmd, lv_seg->lv, use_layer, NULL, lv_seg, &status->seg_status, 0, 0);
+ if (lv_is_thin_pool(lv)) {
+ /* Always collect status for '-tpool' */
+ if (_lv_info(cmd, lv, 1, &status->info, lv_seg, &status->seg_status, 0, 0) &&
+ (status->seg_status.type == SEG_STATUS_THIN_POOL)) {
+ /* There is -tpool device, but query 'active' state of 'fake' thin-pool */
+ if (!_lv_info(cmd, lv, 0, NULL, NULL, NULL, 0, 0) &&
+ !status->seg_status.thin_pool->needs_check)
+ status->info.exists = 0; /* So pool LV is not active */
+ }
+ return 1;
+ } else if (lv_is_origin(lv) &&
+ (!lv_is_merging_origin(lv) ||
+ !lv_has_target_type(cmd->mem, lv, NULL, TARGET_NAME_SNAPSHOT_MERGE))) {
+ /* Query segment status for 'layered' (-real) device most of the time,
+ * only for merging snapshot, query its progress.
+ * TODO: single LV may need couple status to be exposed at once....
+ * but this needs more logical background
+ */
+ /* Show INFO for actual origin */
+ if (!_lv_info(cmd, lv, 0, &status->info, NULL, NULL, with_open_count, with_read_ahead))
+ return_0;
+
+ if (status->info.exists)
+ /* Grab STATUS from layered -real */
+ (void) _lv_info(cmd, lv, 1, NULL, lv_seg, &status->seg_status, 0, 0);
+ return 1;
+ } else if (lv_is_cow(lv)) {
+ if (lv_is_merging_cow(lv) &&
+ lv_has_target_type(cmd->mem, origin_from_cow(lv), NULL, TARGET_NAME_SNAPSHOT_MERGE)) {
+ /*
+ * When merge is in progress, query merging origin LV instead.
+ * COW volume is already mapped as error target in this case.
+ */
+ lv = origin_from_cow(lv);
+ lv_seg = first_seg(lv);
+ log_debug_activation("Snapshot merge is in progress, querying status of %s instead.",
+ display_lvname(lv));
+ } else
+ /* Hadle fictional lvm2 snapshot and query snapshotX volume */
+ lv_seg = find_snapshot(lv);
+ }
+
return _lv_info(cmd, lv, use_layer, &status->info, lv_seg, &status->seg_status,
with_open_count, with_read_ahead);
}
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 56c6d1d..a72d5a9 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -124,42 +124,41 @@ static int _get_segment_status_from_target_params(const char *target_name,
const char *params,
struct lv_seg_status *seg_status)
{
- struct segment_type *segtype;
+ const struct lv_segment *seg = seg_status->seg;
+ const struct segment_type *segtype = seg->segtype;
seg_status->type = SEG_STATUS_UNKNOWN; /* Parsing failed */
+ /* Switch to snapshot segtype status logic for merging origin */
+ /* This is 'dynamic' decision, both states are valid */
+ if (lv_is_merging_origin(seg->lv)) {
+ if (!strcmp(target_name, TARGET_NAME_SNAPSHOT_ORIGIN)) {
+ seg_status->type = SEG_STATUS_NONE;
+ return 1; /* Merge has not yet started */
+ }
+ if (!strcmp(target_name, TARGET_NAME_SNAPSHOT_MERGE) &&
+ !(segtype = get_segtype_from_string(seg->lv->vg->cmd, TARGET_NAME_SNAPSHOT)))
+ return_0;
+ /* Merging, parse 'snapshot' status of merge progress */
+ }
+
if (!params) {
log_warn("WARNING: Cannot find matching %s segment for %s.",
- seg_status->seg->segtype->name,
- display_lvname(seg_status->seg->lv));
+ segtype->name, display_lvname(seg_status->seg->lv));
return 0;
}
- /*
- * TODO: Add support for other segment types too!
- * The segment to report status for must be properly
- * selected for all the other types - mainly make sure
- * linear/striped, old snapshots and raids have proper
- * segment selected for status!
- */
- if (!strcmp(target_name, TARGET_NAME_SNAPSHOT_MERGE) &&
- lv_is_merging_origin(seg_status->seg->lv)) {
- /* Snapshot merge has started, check snapshot status */
- if (!(segtype = get_segtype_from_string(seg_status->seg->lv->vg->cmd, TARGET_NAME_SNAPSHOT)))
- return_0;
- } else {
- if (!(segtype = get_segtype_from_string(seg_status->seg->lv->vg->cmd, target_name)))
- return_0;
-
- /* Validate segtype from DM table and lvm2 metadata */
- if (segtype != seg_status->seg->segtype) {
- log_warn("WARNING: segment type %s found does not match "
- "expected segment type %s.",
- segtype->name, seg_status->seg->segtype->name);
- return 0;
- }
+ /* Validate target_name segtype from DM table with lvm2 metadata segtype */
+ if (strcmp(segtype->name, target_name) &&
+ /* If kernel's type isn't an exact match is it compatible? */
+ (!segtype->ops->target_status_compatible ||
+ !segtype->ops->target_status_compatible(target_name))) {
+ log_warn(INTERNAL_ERROR "WARNING: Segment type %s found does not match expected type %s for %s.",
+ target_name, segtype->name, display_lvname(seg_status->seg->lv));
+ return 0;
}
+ /* TODO: move into segtype method */
if (segtype_is_cache(segtype)) {
if (!dm_get_status_cache(seg_status->mem, params, &(seg_status->cache)))
return_0;
@@ -181,7 +180,10 @@ static int _get_segment_status_from_target_params(const char *target_name,
return_0;
seg_status->type = SEG_STATUS_SNAPSHOT;
} else
- /* Status not supported */
+ /*
+ * TODO: Add support for other segment types too!
+ * Status not supported
+ */
seg_status->type = SEG_STATUS_NONE;
return 1;
diff --git a/tools/reporter.c b/tools/reporter.c
index b7a2f39..0a9ca34 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -87,32 +87,12 @@ static int _vgs_single(struct cmd_context *cmd __attribute__((unused)),
return ECMD_PROCESSED;
}
-static void _choose_lv_segment_for_status_report(const struct logical_volume *lv, const struct lv_segment **lv_seg)
-{
- if (lv_is_used_cache_pool(lv)) {
- /* For a used cache pool, choose cache volume segment */
- *lv_seg = get_only_segment_using_this_lv(lv);
- return;
- }
-
- /*
- * By default, take the first LV segment to report status for.
- * If there's any other specific segment that needs to be
- * reported instead for the LV, choose it here and assign it
- * to lvdm->seg_status->seg. This is the segment whose
- * status line will be used for report exactly.
- */
- *lv_seg = first_seg(lv);
-}
-
static int _do_info_and_status(struct cmd_context *cmd,
const struct logical_volume *lv,
const struct lv_segment *lv_seg,
struct lv_with_info_and_seg_status *status,
int do_info, int do_status)
{
- unsigned use_layer = lv_is_thin_pool(lv) ? 1 : 0;
-
status->lv = lv;
if (lv_is_historical(lv))
@@ -121,27 +101,16 @@ static int _do_info_and_status(struct cmd_context *cmd,
if (do_status) {
if (!(status->seg_status.mem = dm_pool_create("reporter_pool", 1024)))
return_0;
- if (!lv_seg || seg_is_used_cache_pool(lv_seg))
- _choose_lv_segment_for_status_report(lv, &lv_seg);
- if (do_info) {
+ if (do_info)
/* both info and status */
- status->info_ok = lv_info_with_seg_status(cmd, lv, lv_seg, use_layer, status, 1, 1);
- /* for inactive thin-pools reset lv info struct */
- if (use_layer && status->info_ok &&
- !lv_info(cmd, lv, 0, NULL, 0, 0))
- memset(&status->info, 0, sizeof(status->info));
- /* for inactive cache reset lvinfo for its struct for cache-pool */
- if (lv_is_used_cache_pool(lv) && !status->info_ok) {
- memset(&status->info, 0, sizeof(status->info));
- status->info_ok = 1;
- }
- } else
+ status->info_ok = lv_info_with_seg_status(cmd, lv, lv_seg, 0, status, 1, 1);
+ else
/* status only */
- status->info_ok = lv_status(cmd, lv_seg, use_layer, &status->seg_status);
+ status->info_ok = lv_info_with_seg_status(cmd, lv, lv_seg, 0, status, 0, 0);
} else if (do_info)
/* info only */
- status->info_ok = lv_info(cmd, lv, use_layer, &status->info, 1, 1);
+ status->info_ok = lv_info(cmd, lv, 0, &status->info, 1, 1);
return 1;
}
7 years, 4 months
master - cleanup: swap test order
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0089201588d65b...
Commit: 0089201588d65bf131d3fadd1cf5be67a562c4b1
Parent: 5ba2d58d28ace811c33e7e66b777fcca3f42149e
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Nov 30 13:43:43 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Dec 5 17:05:23 2016 +0100
cleanup: swap test order
Check for lv != lvseg->lv.
Make the logic of following patches look better and easier to read.
---
lib/activate/activate.c | 22 +++++++++++-----------
1 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 8fc45b7..efb8912 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -794,17 +794,17 @@ int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume
if (!activation())
return 0;
- if (lv == lv_seg->lv)
- return _lv_info(cmd, lv, use_layer, &status->info, lv_seg, &status->seg_status,
- with_open_count, with_read_ahead);
+ if (lv != lv_seg->lv)
+ /*
+ * If the info is requested for an LV and segment
+ * status for segment that belong to another LV,
+ * we need to acquire info and status separately!
+ */
+ return _lv_info(cmd, lv, use_layer, &status->info, NULL, NULL, with_open_count, with_read_ahead) &&
+ _lv_info(cmd, lv_seg->lv, use_layer, NULL, lv_seg, &status->seg_status, 0, 0);
- /*
- * If the info is requested for an LV and segment
- * status for segment that belong to another LV,
- * we need to acquire info and status separately!
- */
- return _lv_info(cmd, lv, use_layer, &status->info, NULL, NULL, with_open_count, with_read_ahead) &&
- _lv_info(cmd, lv_seg->lv, use_layer, NULL, lv_seg, &status->seg_status, 0, 0);
+ return _lv_info(cmd, lv, use_layer, &status->info, lv_seg, &status->seg_status,
+ with_open_count, with_read_ahead);
}
#define OPEN_COUNT_CHECK_RETRIES 25
7 years, 4 months
master - activation: improve error handling for status reading
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=5ba2d58d28ace8...
Commit: 5ba2d58d28ace811c33e7e66b777fcca3f42149e
Parent: 4a4b22e11413ac76164fbdd9b3c353151c8dde70
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Dec 1 10:37:03 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Dec 5 17:05:17 2016 +0100
activation: improve error handling for status reading
When lvm2 wants to see a status, it needs to validate,
segment for status reading is matching whan lvm2 expects in
metadata.
Also ensure status failure will not cause '0' from info reading
when actual info was collected properly.
Failure in 'status' reading is considered to be
a 'log_warn()' event only.
---
WHATS_NEW | 1 +
lib/activate/dev_manager.c | 28 +++++++++++++++-------------
2 files changed, 16 insertions(+), 13 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 3aedebb..0f5ed02 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Fix matching of LV segment when checking for it info status.
Report log_warn when status cannot be parsed.
Test segment type before accessing segment members when checking status.
Implement compatible target function for stripe segment.
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 8ace08c..56c6d1d 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -203,9 +203,8 @@ static int _info_run(info_type_t type, const char *name, const char *dlid,
struct dm_task *dmt;
int dmtask;
void *target = NULL;
- uint64_t target_start, target_length;
- char *target_name, *target_params, *params_to_process = NULL;
- uint32_t extent_size;
+ uint64_t target_start, target_length, start, length;
+ char *target_name, *target_params;
int with_flush = 1; /* TODO: arg for _info_run */
switch (type) {
@@ -240,21 +239,24 @@ static int _info_run(info_type_t type, const char *name, const char *dlid,
} else if (read_ahead)
*read_ahead = DM_READ_AHEAD_NONE;
- if (type == STATUS) {
- extent_size = seg_status->seg->lv->vg->extent_size;
+ /* Query status only for active device */
+ if ((type == STATUS) && dminfo->exists) {
+ start = length = seg_status->seg->lv->vg->extent_size;
+ start *= seg_status->seg->le;
+ length *= seg_status->seg->len;
+
do {
target = dm_get_next_target(dmt, target, &target_start,
&target_length, &target_name, &target_params);
- if (((uint64_t) seg_status->seg->le * extent_size == target_start) &&
- ((uint64_t) seg_status->seg->len * extent_size == target_length)) {
- params_to_process = target_params;
- break;
- }
+
+ if ((start == target_start) && (length == target_length))
+ break; /* Keep target_params when matching segment is found */
+
+ target_params = NULL; /* Marking this target_params unusable */
} while (target);
- if (params_to_process &&
- !_get_segment_status_from_target_params(target_name, params_to_process, seg_status))
- goto_out;
+ if (!_get_segment_status_from_target_params(target_name, target_params, seg_status))
+ stack;
}
r = 1;
7 years, 4 months
master - activation: status check switch to warn
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4a4b22e11413ac...
Commit: 4a4b22e11413ac76164fbdd9b3c353151c8dde70
Parent: 325c2c5687e42afd2c8611e4cefd73f4fb7fb6ed
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Dec 2 13:57:52 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Dec 5 17:04:24 2016 +0100
activation: status check switch to warn
When we can't parse status, switch to warning as this is not
considered an errornous case. LVS is not supposed to return
error status code when device is not what it's been expected to
be - but it should be WARNING a user there is something unexpected.
---
WHATS_NEW | 1 +
lib/activate/dev_manager.c | 29 +++++++++++++++--------------
2 files changed, 16 insertions(+), 14 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index fbf4f61..3aedebb 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Report log_warn when status cannot be parsed.
Test segment type before accessing segment members when checking status.
Implement compatible target function for stripe segment.
Use status info to report merge failed and snapshot invalid lvs fields.
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index b8b1235..8ace08c 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -126,7 +126,14 @@ static int _get_segment_status_from_target_params(const char *target_name,
{
struct segment_type *segtype;
- seg_status->type = SEG_STATUS_UNKNOWN;
+ seg_status->type = SEG_STATUS_UNKNOWN; /* Parsing failed */
+
+ if (!params) {
+ log_warn("WARNING: Cannot find matching %s segment for %s.",
+ seg_status->seg->segtype->name,
+ display_lvname(seg_status->seg->lv));
+ return 0;
+ }
/*
* TODO: Add support for other segment types too!
@@ -141,19 +148,14 @@ static int _get_segment_status_from_target_params(const char *target_name,
if (!(segtype = get_segtype_from_string(seg_status->seg->lv->vg->cmd, TARGET_NAME_SNAPSHOT)))
return_0;
} else {
- if (strcmp(target_name, TARGET_NAME_CACHE) &&
- strcmp(target_name, TARGET_NAME_SNAPSHOT) &&
- strcmp(target_name, TARGET_NAME_THIN_POOL) &&
- strcmp(target_name, TARGET_NAME_THIN))
- return 1; /* TODO: Do not know how to handle yet */
-
if (!(segtype = get_segtype_from_string(seg_status->seg->lv->vg->cmd, target_name)))
return_0;
+ /* Validate segtype from DM table and lvm2 metadata */
if (segtype != seg_status->seg->segtype) {
- log_error(INTERNAL_ERROR "_get_segment_status_from_target_params: "
- "segment type %s found does not match expected segment type %s",
- segtype->name, seg_status->seg->segtype->name);
+ log_warn("WARNING: segment type %s found does not match "
+ "expected segment type %s.",
+ segtype->name, seg_status->seg->segtype->name);
return 0;
}
}
@@ -178,10 +180,9 @@ static int _get_segment_status_from_target_params(const char *target_name,
if (!dm_get_status_snapshot(seg_status->mem, params, &seg_status->snapshot))
return_0;
seg_status->type = SEG_STATUS_SNAPSHOT;
- } else {
- log_error(INTERNAL_ERROR "Unsupported segment type %s.", segtype->name);
- return 0;
- }
+ } else
+ /* Status not supported */
+ seg_status->type = SEG_STATUS_NONE;
return 1;
}
7 years, 4 months
master - lv: always check status type
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=325c2c5687e42a...
Commit: 325c2c5687e42afd2c8611e4cefd73f4fb7fb6ed
Parent: 6a450952add6bc389537aec23fc727ef6e156671
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Dec 1 10:43:55 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Dec 5 17:03:38 2016 +0100
lv: always check status type
Always validate status type has an expected value,
before accessing status struct members.
---
WHATS_NEW | 1 +
lib/metadata/lv.c | 33 ++++++++++++++++-----------------
lib/report/report.c | 12 ++++++++----
3 files changed, 25 insertions(+), 21 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 541e3ec..fbf4f61 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Test segment type before accessing segment members when checking status.
Implement compatible target function for stripe segment.
Use status info to report merge failed and snapshot invalid lvs fields.
diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c
index 14370bb..eb5066a 100644
--- a/lib/metadata/lv.c
+++ b/lib/metadata/lv.c
@@ -1184,7 +1184,8 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
if (lv_is_historical(lv)) {
repstr[4] = 'h';
repstr[5] = '-';
- } else if (!activation() || !lvdm->info_ok) {
+ } else if (!activation() || !lvdm->info_ok ||
+ (lvdm->seg_status.type == SEG_STATUS_UNKNOWN)) {
repstr[4] = 'X'; /* Unknown */
repstr[5] = 'X'; /* Unknown */
} else if (lvdm->info.exists) {
@@ -1216,8 +1217,10 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
/* 'c' when cache/thin-pool is active with needs_check flag
* 'C' for suspend */
if ((lv_is_thin_pool(lv) &&
+ (lvdm->seg_status.type == SEG_STATUS_THIN_POOL) &&
lvdm->seg_status.thin_pool->needs_check) ||
(lv_is_cache(lv) &&
+ (lvdm->seg_status.type == SEG_STATUS_CACHE) &&
lvdm->seg_status.cache->needs_check))
repstr[4] = lvdm->info.suspended ? 'C' : 'c';
@@ -1259,6 +1262,10 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
repstr[7] = '-';
repstr[8] = '-';
+ /* TODO: also convert raid health
+ * lv_is_raid_type() is to wide
+ * NOTE: snapshot origin is 'mostly' showing it's layered status
+ */
if (lv_is_partial(lv))
repstr[8] = 'p';
else if (lv_is_raid_type(lv)) {
@@ -1272,31 +1279,23 @@ char *lv_attr_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_
repstr[8] = 'm'; /* RAID has 'm'ismatches */
} else if (lv->status & LV_WRITEMOSTLY)
repstr[8] = 'w'; /* sub-LV has 'w'ritemostly */
- } else if (lv_is_cache(lv) &&
- (lvdm->seg_status.type != SEG_STATUS_NONE)) {
- if (lvdm->seg_status.type == SEG_STATUS_UNKNOWN)
- repstr[8] = 'X'; /* Unknown */
- else if (lvdm->seg_status.cache->fail)
+ } else if (lvdm->seg_status.type == SEG_STATUS_CACHE) {
+ if (lvdm->seg_status.cache->fail)
repstr[8] = 'F';
else if (lvdm->seg_status.cache->read_only)
repstr[8] = 'M';
- } else if (lv_is_thin_pool(lv) &&
- (lvdm->seg_status.type != SEG_STATUS_NONE)) {
- if (lvdm->seg_status.type == SEG_STATUS_UNKNOWN)
- repstr[8] = 'X'; /* Unknown */
- else if (lvdm->seg_status.thin_pool->fail)
+ } else if (lvdm->seg_status.type == SEG_STATUS_THIN_POOL) {
+ if (lvdm->seg_status.thin_pool->fail)
repstr[8] = 'F';
else if (lvdm->seg_status.thin_pool->out_of_data_space)
repstr[8] = 'D';
else if (lvdm->seg_status.thin_pool->read_only)
repstr[8] = 'M';
- } else if (lv_is_thin_volume(lv) &&
- (lvdm->seg_status.type != SEG_STATUS_NONE)) {
- if (lvdm->seg_status.type == SEG_STATUS_UNKNOWN)
- repstr[8] = 'X'; /* Unknown */
- else if (lvdm->seg_status.thin->fail)
+ } else if (lvdm->seg_status.type == SEG_STATUS_THIN) {
+ if (lvdm->seg_status.thin->fail)
repstr[8] = 'F';
- }
+ } else if (lvdm->seg_status.type == SEG_STATUS_UNKNOWN)
+ repstr[8] = 'X'; /* Unknown */
if (lv->status & LV_ACTIVATION_SKIP)
repstr[9] = 'k';
diff --git a/lib/report/report.c b/lib/report/report.c
index 358ae94..702befb 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -2936,12 +2936,16 @@ static int _metadatapercent_disp(struct dm_report *rh,
const void *data, void *private)
{
const struct lv_with_info_and_seg_status *lvdm = (const struct lv_with_info_and_seg_status *) data;
- dm_percent_t percent = DM_PERCENT_INVALID;
+ dm_percent_t percent;
- if (lv_is_thin_pool(lvdm->lv) ||
- lv_is_cache(lvdm->lv) ||
- lv_is_used_cache_pool(lvdm->lv))
+ switch (lvdm->seg_status.type) {
+ case SEG_STATUS_CACHE:
+ case SEG_STATUS_THIN_POOL:
percent = lvseg_percent_with_info_and_seg_status(lvdm, PERCENT_GET_METADATA);
+ break;
+ default:
+ percent = DM_PERCENT_INVALID;
+ }
return dm_report_field_percent(rh, field, &percent);
}
7 years, 4 months
master - striped: implement compatible target name
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6a450952add6bc...
Commit: 6a450952add6bc389537aec23fc727ef6e156671
Parent: 254f73e3efe27e55637e8d3c23abf607564650d7
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Dec 1 16:09:53 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Dec 5 17:02:01 2016 +0100
striped: implement compatible target name
Linear is handled by striped target.
---
WHATS_NEW | 1 +
lib/striped/striped.c | 6 ++++++
2 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 82222d7..541e3ec 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Implement compatible target function for stripe segment.
Use status info to report merge failed and snapshot invalid lvs fields.
Version 2.02.168 - 30th November 2016
diff --git a/lib/striped/striped.c b/lib/striped/striped.c
index 7d19786..e1de9c9 100644
--- a/lib/striped/striped.c
+++ b/lib/striped/striped.c
@@ -159,6 +159,11 @@ static int _striped_merge_segments(struct lv_segment *seg1, struct lv_segment *s
}
#ifdef DEVMAPPER_SUPPORT
+static int _striped_target_status_compatible(const char *type)
+{
+ return (strcmp(type, TARGET_NAME_LINEAR) == 0);
+}
+
static int _striped_add_target_line(struct dev_manager *dm,
struct dm_pool *mem __attribute__((unused)),
struct cmd_context *cmd __attribute__((unused)),
@@ -218,6 +223,7 @@ static struct segtype_handler _striped_ops = {
.text_export = _striped_text_export,
.merge_segments = _striped_merge_segments,
#ifdef DEVMAPPER_SUPPORT
+ .target_status_compatible = _striped_target_status_compatible,
.add_target_line = _striped_add_target_line,
.target_present = _striped_target_present,
#endif
7 years, 4 months
master - snapshot: reporting uses statusinfo
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=254f73e3efe27e...
Commit: 254f73e3efe27e55637e8d3c23abf607564650d7
Parent: 07f9889b53eb3314e3ca816ffbeb72d087e9282a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Dec 1 17:58:06 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Dec 5 17:01:15 2016 +0100
snapshot: reporting uses statusinfo
Convert lvs -o lv_merge_failed,lv_snapshot_invalid to use
lv_info_and_status function.
This makes it equal to attr value showing this info
(as they were different since they were derived from
different data set and different logic as well).
Also saves couple extra ioctl that were needed to obtain this info.
---
WHATS_NEW | 1 +
lib/report/columns.h | 4 ++--
lib/report/report.c | 20 ++++++++------------
3 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 3e551ec..82222d7 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Use status info to report merge failed and snapshot invalid lvs fields.
Version 2.02.168 - 30th November 2016
=====================================
diff --git a/lib/report/columns.h b/lib/report/columns.h
index ffc92c0..6d9b851 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -60,8 +60,6 @@ FIELD(LVS, lv, BIN, "Converting", lvid, 0, lvconverting, lv_converting, "Set if
FIELD(LVS, lv, STR, "AllocPol", lvid, 10, lvallocationpolicy, lv_allocation_policy, "LV allocation policy.", 0)
FIELD(LVS, lv, BIN, "AllocLock", lvid, 10, lvallocationlocked, lv_allocation_locked, "Set if LV is locked against allocation changes.", 0)
FIELD(LVS, lv, BIN, "FixMin", lvid, 10, lvfixedminor, lv_fixed_minor, "Set if LV has fixed minor number assigned.", 0)
-FIELD(LVS, lv, BIN, "MergeFailed", lvid, 15, lvmergefailed, lv_merge_failed, "Set if snapshot merge failed.", 0)
-FIELD(LVS, lv, BIN, "SnapInvalid", lvid, 15, lvsnapshotinvalid, lv_snapshot_invalid, "Set if snapshot LV is invalid.", 0)
FIELD(LVS, lv, BIN, "SkipAct", lvid, 15, lvskipactivation, lv_skip_activation, "Set if LV is skipped on activation.", 0)
FIELD(LVS, lv, STR, "WhenFull", lvid, 15, lvwhenfull, lv_when_full, "For thin pools, behavior when full.", 0)
FIELD(LVS, lv, STR, "Active", lvid, 0, lvactive, lv_active, "Active state of the LV.", 0)
@@ -145,6 +143,8 @@ FIELD(LVSSTATUS, lv, STR, "KCachePolicy", lvid, 18, kernel_cache_policy, kernel_
FIELD(LVSSTATUS, lv, STR, "Health", lvid, 15, lvhealthstatus, lv_health_status, "LV health status.", 0)
FIELD(LVSSTATUS, lv, STR, "KDiscards", lvid, 0, kdiscards, kernel_discards, "For thin pools, how discards are handled in kernel.", 0)
FIELD(LVSSTATUS, lv, BIN, "CheckNeeded", lvid, 15, lvcheckneeded, lv_check_needed, "For thin pools and cache volumes, whether metadata check is needed.", 0)
+FIELD(LVSSTATUS, lv, BIN, "MergeFailed", lvid, 15, lvmergefailed, lv_merge_failed, "Set if snapshot merge failed.", 0)
+FIELD(LVSSTATUS, lv, BIN, "SnapInvalid", lvid, 15, lvsnapshotinvalid, lv_snapshot_invalid, "Set if snapshot LV is invalid.", 0)
/*
* End of LVSSTATUS type fields
*/
diff --git a/lib/report/report.c b/lib/report/report.c
index 1ca4dfb..358ae94 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -3363,30 +3363,26 @@ static int _lvmergefailed_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
- const struct logical_volume *lv = (const struct logical_volume *) data;
- dm_percent_t snap_percent;
- int merge_failed;
+ const struct lv_with_info_and_seg_status *lvdm = (const struct lv_with_info_and_seg_status *) data;
- if (!lv_is_cow(lv) || !lv_snapshot_percent(lv, &snap_percent))
+ if (lvdm->seg_status.type != SEG_STATUS_SNAPSHOT)
return _binary_undef_disp(rh, mem, field, private);
- merge_failed = snap_percent == LVM_PERCENT_MERGE_FAILED;
- return _binary_disp(rh, mem, field, merge_failed, GET_FIRST_RESERVED_NAME(lv_merge_failed_y), private);
+ return _binary_disp(rh, mem, field, lvdm->seg_status.snapshot->merge_failed,
+ GET_FIRST_RESERVED_NAME(lv_merge_failed_y), private);
}
static int _lvsnapshotinvalid_disp(struct dm_report *rh, struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
{
- const struct logical_volume *lv = (const struct logical_volume *) data;
- dm_percent_t snap_percent;
- int snap_invalid;
+ const struct lv_with_info_and_seg_status *lvdm = (const struct lv_with_info_and_seg_status *) data;
- if (!lv_is_cow(lv))
+ if (lvdm->seg_status.type != SEG_STATUS_SNAPSHOT)
return _binary_undef_disp(rh, mem, field, private);
- snap_invalid = !lv_snapshot_percent(lv, &snap_percent) || snap_percent == DM_PERCENT_INVALID;
- return _binary_disp(rh, mem, field, snap_invalid, GET_FIRST_RESERVED_NAME(lv_snapshot_invalid_y), private);
+ return _binary_disp(rh, mem, field, lvdm->seg_status.snapshot->invalid,
+ GET_FIRST_RESERVED_NAME(lv_snapshot_invalid_y), private);
}
static int _lvsuspended_disp(struct dm_report *rh, struct dm_pool *mem,
7 years, 4 months
master - report: order fields by type for field defintions in columns.h
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=07f9889b53eb33...
Commit: 07f9889b53eb3314e3ca816ffbeb72d087e9282a
Parent: bb5eb324e3d503bf6dd8923531f63d3e1933ff0d
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Dec 1 14:39:21 2016 +0100
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Dec 1 14:55:29 2016 +0100
report: order fields by type for field defintions in columns.h
When displaying <reporting_command> -o help, we'd like to have fields
grouped nicely, not starting having groups interleaved as it was before.
The code that displays the help output for fields takes the order as
written in columns.h file - this caused output like:
$ lvs -o help
Logical Volume Fields
---------------------
...field list...
Logical Volume Device Info and Status Combined Fields
-----------------------------------------------------
...field list...
Logical Volume Fields
---------------------
...field list...
Logical Volume Device Status Fields
-----------------------------------
...field list...
Logical Volume Fields
---------------------
...field list...
Instead, let's have it without groups interleaved which may be
a bit confusing, so:
Logical Volume Fields
---------------------
...field list...
Logical Volume Device Status Fields
-----------------------------------
...field list...
Logical Volume Device Info and Status Combined Fields
-----------------------------------------------------
...field list...
..and so on.
---
lib/report/columns.h | 77 ++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 71 insertions(+), 6 deletions(-)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 212f9ed..ffc92c0 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -21,9 +21,19 @@
* determines the order the entries appear in this file.
*
* When adding new entries take care to use the existing style.
+ *
+ * Do not interleave fields from different report types - for example,
+ * if you have a field of type "LVS" add it in between "LVS type fields"
+ * and "End of LVS type fields" comment. If you interleaved fields of
+ * different types here in this file, they would end up interleaved in
+ * the <reporting_command> -o help output too which may be confusing
+ * for users.
+ *
* Displayed fields names normally have a type prefix and use underscores.
+ *
* Field-specific internal functions names normally match the displayed
* field names but without underscores.
+ *
* Help text ends with a full stop.
*/
@@ -32,13 +42,15 @@
*/
/* *INDENT-OFF* */
+/*
+ * LVS type fields
+ */
FIELD(LVS, lv, STR, "LV UUID", lvid, 38, lvuuid, lv_uuid, "Unique identifier.", 0)
FIELD(LVS, lv, STR, "LV", lvid, 4, lvname, lv_name, "Name. LVs created for internal use are enclosed in brackets.", 0)
FIELD(LVS, lv, STR, "LV", lvid, 4, lvfullname, lv_full_name, "Full name of LV including its VG, namely VG/LV.", 0)
FIELD(LVS, lv, STR, "Path", lvid, 0, lvpath, lv_path, "Full pathname for LV. Blank for internal LVs.", 0)
FIELD(LVS, lv, STR, "DMPath", lvid, 0, lvdmpath, lv_dm_path, "Internal device-mapper pathname for LV (in /dev/mapper directory).", 0)
FIELD(LVS, lv, STR, "Parent", lvid, 0, lvparent, lv_parent, "For LVs that are components of another LV, the parent LV.", 0)
-FIELD(LVSINFOSTATUS, lv, STR, "Attr", lvid, 0, lvstatus, lv_attr, "Various attributes - see man page.", 0)
FIELD(LVS, lv, STR_LIST, "Layout", lvid, 10, lvlayout, lv_layout, "LV layout.", 0)
FIELD(LVS, lv, STR_LIST, "Role", lvid, 10, lvrole, lv_role, "LV role.", 0)
FIELD(LVS, lv, BIN, "InitImgSync", lvid, 10, lvinitialimagesync, lv_initial_image_sync, "Set if mirror/RAID images underwent initial resynchronization.", 0)
@@ -69,11 +81,6 @@ FIELD(LVS, lv, STR_LIST, "Ancestors", lvid, 0, lvancestors, lv_ancestors, "LV an
FIELD(LVS, lv, STR_LIST, "FAncestors", lvid, 0, lvfullancestors, lv_full_ancestors, "LV ancestors including stored history of the ancestry chain.", 0)
FIELD(LVS, lv, STR_LIST, "Descendants", lvid, 0, lvdescendants, lv_descendants, "LV descendants ignoring any stored history of the ancestry chain.", 0)
FIELD(LVS, lv, STR_LIST, "FDescendants", lvid, 0, lvfulldescendants, lv_full_descendants, "LV descendants including stored history of the ancestry chain.", 0)
-FIELD(LVSSTATUS, lv, PCT, "Data%", lvid, 6, datapercent, data_percent, "For snapshot, cache and thin pools and volumes, the percentage full if LV is active.", 0)
-FIELD(LVSSTATUS, lv, PCT, "Snap%", lvid, 6, snpercent, snap_percent, "For snapshots, the percentage full if LV is active.", 0)
-FIELD(LVSSTATUS, lv, PCT, "Meta%", lvid, 6, metadatapercent, metadata_percent, "For cache and thin pools, the percentage of metadata full if LV is active.", 0)
-FIELD(LVSSTATUS, lv, PCT, "Cpy%Sync", lvid, 0, copypercent, copy_percent, "For Cache, RAID, mirrors and pvmove, current percentage in-sync.", 0)
-FIELD(LVSSTATUS, lv, PCT, "Cpy%Sync", lvid, 0, copypercent, sync_percent, "For Cache, RAID, mirrors and pvmove, current percentage in-sync.", 0)
FIELD(LVS, lv, NUM, "Mismatches", lvid, 0, raidmismatchcount, raid_mismatch_count, "For RAID, number of mismatches found or repaired.", 0)
FIELD(LVS, lv, STR, "SyncAction", lvid, 0, raidsyncaction, raid_sync_action, "For RAID, the current synchronization action being performed.", 0)
FIELD(LVS, lv, NUM, "WBehind", lvid, 0, raidwritebehind, raid_write_behind, "For RAID1, the number of outstanding writes allowed to writemostly devices.", 0)
@@ -99,7 +106,13 @@ FIELD(LVS, lv, TIM, "RTime", lvid, 26, lvtimeremoved, lv_time_removed, "Removal
FIELD(LVS, lv, STR, "Host", lvid, 10, lvhost, lv_host, "Creation host of the LV, if known.", 0)
FIELD(LVS, lv, STR_LIST, "Modules", lvid, 0, modules, lv_modules, "Kernel device-mapper modules required for this LV.", 0)
FIELD(LVS, lv, BIN, "Historical", lvid, 0, lvhistorical, lv_historical, "Set if the LV is historical.", 0)
+/*
+ * End of LVS type fields
+ */
+/*
+ * LVSINFO type fields
+ */
FIELD(LVSINFO, lv, SNUM, "KMaj", lvid, 0, lvkmaj, lv_kernel_major, "Currently assigned major number or -1 if LV is not active.", 0)
FIELD(LVSINFO, lv, SNUM, "KMin", lvid, 0, lvkmin, lv_kernel_minor, "Currently assigned minor number or -1 if LV is not active.", 0)
FIELD(LVSINFO, lv, SIZ, "KRahead", lvid, 0, lvkreadahead, lv_kernel_read_ahead, "Currently-in-use read ahead setting in current units.", 0)
@@ -108,7 +121,18 @@ FIELD(LVSINFO, lv, BIN, "Suspended", lvid, 10, lvsuspended, lv_suspended, "Set i
FIELD(LVSINFO, lv, BIN, "LiveTable", lvid, 20, lvlivetable, lv_live_table, "Set if LV has live table present.", 0)
FIELD(LVSINFO, lv, BIN, "InactiveTable", lvid, 20, lvinactivetable, lv_inactive_table, "Set if LV has inactive table present.", 0)
FIELD(LVSINFO, lv, BIN, "DevOpen", lvid, 10, lvdeviceopen, lv_device_open, "Set if LV device is open.", 0)
+/*
+ * End of LVSINFO type fields
+ */
+/*
+ * LVSSTATUS type fields
+ */
+FIELD(LVSSTATUS, lv, PCT, "Data%", lvid, 6, datapercent, data_percent, "For snapshot, cache and thin pools and volumes, the percentage full if LV is active.", 0)
+FIELD(LVSSTATUS, lv, PCT, "Snap%", lvid, 6, snpercent, snap_percent, "For snapshots, the percentage full if LV is active.", 0)
+FIELD(LVSSTATUS, lv, PCT, "Meta%", lvid, 6, metadatapercent, metadata_percent, "For cache and thin pools, the percentage of metadata full if LV is active.", 0)
+FIELD(LVSSTATUS, lv, PCT, "Cpy%Sync", lvid, 0, copypercent, copy_percent, "For Cache, RAID, mirrors and pvmove, current percentage in-sync.", 0)
+FIELD(LVSSTATUS, lv, PCT, "Cpy%Sync", lvid, 0, copypercent, sync_percent, "For Cache, RAID, mirrors and pvmove, current percentage in-sync.", 0)
FIELD(LVSSTATUS, lv, NUM, "CacheTotalBlocks", lvid, 0, cache_total_blocks, cache_total_blocks, "Total cache blocks.", 0)
FIELD(LVSSTATUS, lv, NUM, "CacheUsedBlocks", lvid, 16, cache_used_blocks, cache_used_blocks, "Used cache blocks.", 0)
FIELD(LVSSTATUS, lv, NUM, "CacheDirtyBlocks", lvid, 0, cache_dirty_blocks, cache_dirty_blocks, "Dirty cache blocks.", 0)
@@ -121,7 +145,21 @@ FIELD(LVSSTATUS, lv, STR, "KCachePolicy", lvid, 18, kernel_cache_policy, kernel_
FIELD(LVSSTATUS, lv, STR, "Health", lvid, 15, lvhealthstatus, lv_health_status, "LV health status.", 0)
FIELD(LVSSTATUS, lv, STR, "KDiscards", lvid, 0, kdiscards, kernel_discards, "For thin pools, how discards are handled in kernel.", 0)
FIELD(LVSSTATUS, lv, BIN, "CheckNeeded", lvid, 15, lvcheckneeded, lv_check_needed, "For thin pools and cache volumes, whether metadata check is needed.", 0)
+/*
+ * End of LVSSTATUS type fields
+ */
+/*
+ * LVSINFOSTATUS type fields
+ */
+FIELD(LVSINFOSTATUS, lv, STR, "Attr", lvid, 0, lvstatus, lv_attr, "Various attributes - see man page.", 0)
+/*
+ * End of LVSINFOSTATUS type fields
+ */
+
+/*
+ * LABEL type fields
+ */
FIELD(LABEL, label, STR, "Fmt", type, 0, pvfmt, pv_fmt, "Type of metadata.", 0)
FIELD(LABEL, label, STR, "PV UUID", type, 38, pvuuid, pv_uuid, "Unique identifier.", 0)
FIELD(LABEL, label, SIZ, "DevSize", dev, 0, devsize, dev_size, "Size of underlying device in current units.", 0)
@@ -131,7 +169,13 @@ FIELD(LABEL, label, STR, "Min", dev, 0, devminor, pv_minor, "Device minor number
FIELD(LABEL, label, SIZ, "PMdaFree", type, 9, pvmdafree, pv_mda_free, "Free metadata area space on this device in current units.", 0)
FIELD(LABEL, label, SIZ, "PMdaSize", type, 9, pvmdasize, pv_mda_size, "Size of smallest metadata area on this device in current units.", 0)
FIELD(LABEL, label, NUM, "PExtVsn", type, 0, pvextvsn, pv_ext_vsn, "PV header extension version.", 0)
+/*
+ * End of LABEL type fields
+ */
+/*
+ * PVS type fields
+ */
FIELD(PVS, pv, NUM, "1st PE", pe_start, 7, size64, pe_start, "Offset to the start of data on the underlying device.", 0)
FIELD(PVS, pv, SIZ, "PSize", id, 0, pvsize, pv_size, "Size of PV in current units.", 0)
FIELD(PVS, pv, SIZ, "PFree", id, 0, pvfree, pv_free, "Total amount of unallocated space in current units.", 0)
@@ -149,7 +193,13 @@ FIELD(PVS, pv, SIZ, "BA Start", ba_start, 0, size64, pv_ba_start, "Offset to the
FIELD(PVS, pv, SIZ, "BA Size", ba_size, 0, size64, pv_ba_size, "Size of PV Bootloader Area in current units.", 0)
FIELD(PVS, pv, BIN, "PInUse", id, 0, pvinuse, pv_in_use, "Set if PV is used.", 0)
FIELD(PVS, pv, BIN, "Duplicate", id, 0, pvduplicate, pv_duplicate, "Set if PV is an unchosen duplicate.", 0)
+/*
+ * End of PVS type fields
+ */
+/*
+ * VGS type fields
+ */
FIELD(VGS, vg, STR, "Fmt", cmd, 0, vgfmt, vg_fmt, "Type of metadata.", 0)
FIELD(VGS, vg, STR, "VG UUID", id, 38, uuid, vg_uuid, "Unique identifier.", 0)
FIELD(VGS, vg, STR, "VG", name, 0, string, vg_name, "Name.", 0)
@@ -183,7 +233,13 @@ FIELD(VGS, vg, NUM, "#VMdaUse", cmd, 0, vgmdasused, vg_mda_used_count, "Number o
FIELD(VGS, vg, SIZ, "VMdaFree", cmd, 9, vgmdafree, vg_mda_free, "Free metadata area space for this VG in current units.", 0)
FIELD(VGS, vg, SIZ, "VMdaSize", cmd, 9, vgmdasize, vg_mda_size, "Size of smallest metadata area for this VG in current units.", 0)
FIELD(VGS, vg, NUM, "#VMdaCps", cmd, 0, vgmdacopies, vg_mda_copies, "Target number of in use metadata areas in the VG.", 1)
+/*
+ * End of VGS type fields
+ */
+/*
+ * SEGS type fields
+ */
FIELD(SEGS, seg, STR, "Type", list, 0, segtype, segtype, "Type of LV segment.", 0)
FIELD(SEGS, seg, NUM, "#Str", area_count, 0, uint32, stripes, "Number of stripes or mirror legs.", 0)
FIELD(SEGS, seg, SIZ, "Stripe", stripe_size, 0, size32, stripe_size, "For stripes, amount of data placed on one device before switching to the next.", 0)
@@ -208,7 +264,16 @@ FIELD(SEGS, seg, STR_LIST, "Metadata Devs", list, 0, metadatadevices, metadata_d
FIELD(SEGS, seg, STR, "Monitor", list, 0, segmonitor, seg_monitor, "Dmeventd monitoring status of the segment.", 0)
FIELD(SEGS, seg, STR, "CachePolicy", list, 0, cache_policy, cache_policy, "The cache policy (cached segments only).", 0)
FIELD(SEGS, seg, STR_LIST, "CacheSettings", list, 0, cache_settings, cache_settings, "Cache settings/parameters (cached segments only).", 0)
+/*
+ * End of SEGS type fields
+ */
+/*
+ * PVSEGS type fields
+ */
FIELD(PVSEGS, pvseg, NUM, "Start", pe, 0, uint32, pvseg_start, "Physical Extent number of start of segment.", 0)
FIELD(PVSEGS, pvseg, NUM, "SSize", len, 0, uint32, pvseg_size, "Number of extents in segment.", 0)
+/*
+ * End of PVSEGS type fields
+ */
/* *INDENT-ON* */
7 years, 4 months