Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6fd20be629b6dceb…
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,
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ed93f0973a307634…
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;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0089201588d65bf1…
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
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=4a4b22e11413ac76…
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;
}
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=07f9889b53eb3314…
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* */