master - lv: more exact check for merging origin
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=95e3dd5fb1297f...
Commit: 95e3dd5fb1297f6b1aa23cbedad1ab3dc14343a7
Parent: 9491ab41cd61501039027fa5d7cfe89f78504132
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Dec 22 21:15:31 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Dec 22 23:37:07 2016 +0100
lv: more exact check for merging origin
Merging origin has 'MERGE_LV' and should also have its merging snapshot.
---
WHATS_NEW | 1 +
lib/metadata/metadata-exported.h | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 6ab385d..8fefe6a 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Checking LV for merging origin requires also it has merged snapshot.
Extend validation of metadata processing.
Enable usage of cached volumes as snapshot origin LV.
Fix displayed lv name when splitting snapshot (2.02.146).
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index aa40c6c..4e05885 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -198,7 +198,7 @@
#define lv_is_partial(lv) (((lv)->status & PARTIAL_LV) ? 1 : 0)
#define lv_is_virtual(lv) (((lv)->status & VIRTUAL) ? 1 : 0)
#define lv_is_merging(lv) (((lv)->status & MERGING) ? 1 : 0)
-#define lv_is_merging_origin(lv) (lv_is_merging(lv))
+#define lv_is_merging_origin(lv) (lv_is_merging(lv) && (lv)->snapshot)
#define lv_is_snapshot(lv) (((lv)->status & SNAPSHOT) ? 1 : 0)
#define lv_is_converting(lv) (((lv)->status & CONVERTING) ? 1 : 0)
#define lv_is_external_origin(lv) (((lv)->external_count > 0) ? 1 : 0)
7 years, 3 months
master - validation: rework segment validation
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=9491ab41cd6150...
Commit: 9491ab41cd61501039027fa5d7cfe89f78504132
Parent: eacff5c189d0cb3c6ac17a8f0af0fe440f12c4b7
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Dec 20 15:59:11 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Dec 22 23:37:07 2016 +0100
validation: rework segment validation
Move individual segment validation to a separate function
executed for 'complete_vg'.
Move some 'extra' validation bits from 'raid' validation to global
segtype validation (so extending existing normal validation)
TODO: still some test are left to be moved.
Reduce some duplication in validation process - there are still
some left thought so still room for improving overal speed.
---
WHATS_NEW | 1 +
lib/metadata/merge.c | 527 ++++++++++++++++++++++----------------------------
2 files changed, 233 insertions(+), 295 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index fa8f5c3..6ab385d 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Extend validation of metadata processing.
Enable usage of cached volumes as snapshot origin LV.
Fix displayed lv name when splitting snapshot (2.02.146).
Warn about command not making metadata backup just once per command.
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
index 947513b..a1c9455 100644
--- a/lib/metadata/merge.c
+++ b/lib/metadata/merge.c
@@ -71,6 +71,13 @@ int lv_merge_segments(struct logical_volume *lv)
if (error_count++ > ERROR_MAX) \
goto out
+#define seg_error(msg) { \
+ log_error("LV %s, segment %u invalid: %s for %s segment.", \
+ seg->lv->name, seg_count, (msg), lvseg_name(seg)); \
+ if ((*error_count)++ > ERROR_MAX) \
+ return; \
+ }
+
/*
* RAID segment property checks.
*
@@ -188,44 +195,10 @@ static void _check_non_raid_seg_members(struct lv_segment *seg, int *error_count
{
if (seg->origin) /* snap and thin */
raid_seg_error("non-zero origin LV");
- if (seg->indirect_origin) /* thin */
- raid_seg_error("non-zero indirect_origin LV");
- if (seg->merge_lv) /* thin */
- raid_seg_error("non-zero merge LV");
if (seg->cow) /* snap */
raid_seg_error("non-zero cow LV");
if (!dm_list_empty(&seg->origin_list)) /* snap */
raid_seg_error("non-zero origin_list");
- if (seg->log_lv)
- raid_seg_error("non-zero log LV");
- if (seg->segtype_private)
- raid_seg_error("non-zero segtype_private");
- /* thin members */
- if (seg->metadata_lv)
- raid_seg_error("non-zero metadata LV");
- if (seg->transaction_id)
- raid_seg_error("non-zero transaction_id");
- if (seg->zero_new_blocks)
- raid_seg_error("non-zero zero_new_blocks");
- if (seg->discards)
- raid_seg_error("non-zero discards");
- if (!dm_list_empty(&seg->thin_messages))
- raid_seg_error("non-zero thin_messages list");
- if (seg->external_lv)
- raid_seg_error("non-zero external LV");
- if (seg->pool_lv)
- raid_seg_error("non-zero pool LV");
- if (seg->device_id)
- raid_seg_error("non-zero device_id");
- /* cache members */
- if (seg->cache_mode)
- raid_seg_error("non-zero cache_mode");
- if (seg->policy_name)
- raid_seg_error("non-zero policy_name");
- if (seg->policy_settings)
- raid_seg_error("non-zero policy_settings");
- if (seg->cleaner_policy)
- raid_seg_error("non-zero cleaner_policy");
/* replicator members (deprecated) */
if (seg->replicator)
raid_seg_error("non-zero replicator");
@@ -249,9 +222,6 @@ static void _check_raid_seg(struct lv_segment *seg, int *error_count)
uint32_t area_len, s;
/* General checks applying to all RAIDs */
- if (!seg_is_raid(seg))
- raid_seg_error("erroneous RAID check");
-
if (!seg->area_count)
raid_seg_error("zero area count");
@@ -276,9 +246,6 @@ static void _check_raid_seg(struct lv_segment *seg, int *error_count)
return;
}
- if (seg->chunk_size)
- raid_seg_error_val("non-zero chunk_size", seg->chunk_size);
-
/* FIXME: should we check any non-RAID segment struct members at all? */
_check_non_raid_seg_members(seg, error_count);
@@ -329,6 +296,167 @@ static void _check_raid_seg(struct lv_segment *seg, int *error_count)
}
/* END: RAID segment property checks. */
+static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg,
+ unsigned seg_count, int *error_count)
+{
+ struct lv_segment *seg2;
+
+ if (lv_is_mirror_image(lv) &&
+ (!(seg2 = find_mirror_seg(seg)) || !seg_is_mirrored(seg2)))
+ seg_error("mirror image is not mirrored");
+
+ if (seg_is_cache(seg)) {
+ if (!lv_is_cache(lv))
+ seg_error("is not flagged as cache LV");
+
+ if (!seg->pool_lv) {
+ seg_error("is missing cache pool LV");
+ } else if (!lv_is_cache_pool(seg->pool_lv))
+ seg_error("is not referencing cache pool LV");
+ } else { /* !cache */
+ if (seg->cleaner_policy)
+ seg_error("sets cleaner_policy");
+ }
+
+ if (seg_is_cache_pool(seg)) {
+ if (!dm_list_empty(&seg->lv->segs_using_this_lv)) {
+ switch (seg->cache_mode) {
+ case CACHE_MODE_WRITETHROUGH:
+ case CACHE_MODE_WRITEBACK:
+ case CACHE_MODE_PASSTHROUGH:
+ break;
+ default:
+ seg_error("has invalid cache's feature flag")
+ }
+ if (!seg->policy_name)
+ seg_error("is missing cache policy name");
+ }
+ } else { /* !cache_pool */
+ if (seg->cache_mode)
+ seg_error("sets cache mode");
+ if (seg->policy_name)
+ seg_error("sets policy name");
+ if (seg->policy_settings)
+ seg_error("sets policy settings");
+ }
+
+ if (!seg_can_error_when_full(seg) && lv_is_error_when_full(lv))
+ seg_error("does not support flag ERROR_WHEN_FULL.");
+
+ if (seg_is_mirrored(seg)) {
+ /* Check mirror log - which is attached to the mirrored seg */
+ if (seg->log_lv) {
+ if (!lv_is_mirror_log(seg->log_lv))
+ seg_error("log LV is not a mirror log");
+
+ if (!(seg2 = first_seg(seg->log_lv)) || (find_mirror_seg(seg2) != seg))
+ seg_error("log LV does not point back to mirror segment");
+ }
+ } else { /* !mirrored */
+ if (seg->log_lv) {
+ if (lv_is_raid_image(lv))
+ seg_error("log LV is not a mirror log or a RAID image");
+ }
+ }
+
+ if (seg_is_raid(seg))
+ _check_raid_seg(seg, error_count);
+
+ if (seg_is_pool(seg)) {
+ if ((seg->area_count != 1) || (seg_type(seg, 0) != AREA_LV)) {
+ seg_error("is missing a pool data LV");
+ } else if (!(seg2 = first_seg(seg_lv(seg, 0))) || (find_pool_seg(seg2) != seg))
+ seg_error("data LV does not refer back to pool LV");
+
+ if (!seg->metadata_lv) {
+ seg_error("is missing a pool metadata LV");
+ } else if (!(seg2 = first_seg(seg->metadata_lv)) || (find_pool_seg(seg2) != seg))
+ seg_error("metadata LV does not refer back to pool LV");
+
+ if (!validate_pool_chunk_size(lv->vg->cmd, seg->segtype, seg->chunk_size))
+ seg_error("has invalid chunk size.");
+ } else { /* !thin_pool && !cache_pool */
+ if (seg->metadata_lv)
+ seg_error("must not have pool metadata LV set");
+ }
+
+ if (seg_is_thin_pool(seg)) {
+ if (!lv_is_thin_pool(lv))
+ seg_error("is not flagged as thin pool LV");
+
+ if (lv_is_thin_volume(lv))
+ seg_error("is a thin volume that must not contain thin pool segment");
+ } else { /* !thin_pool */
+ if (seg->zero_new_blocks)
+ seg_error("sets zero_new_blocks");
+ if (seg->discards)
+ seg_error("sets discards");
+ if (!dm_list_empty(&seg->thin_messages))
+ seg_error("sets thin_messages list");
+ }
+
+ if (seg_is_thin_volume(seg)) {
+ if (!lv_is_thin_volume(lv))
+ seg_error("is not flagged as thin volume LV");
+
+ if (lv_is_thin_pool(lv))
+ seg_error("is a thin pool that must not contain thin volume segment");
+
+ if (!seg->pool_lv) {
+ seg_error("is missing thin pool LV");
+ } else if (!lv_is_thin_pool(seg->pool_lv))
+ seg_error("is not referencing thin pool LV");
+
+ if (seg->device_id > DM_THIN_MAX_DEVICE_ID)
+ seg_error("has too large device id");
+
+ if (seg->external_lv &&
+ !lv_is_external_origin(seg->external_lv))
+ seg_error("external LV is not flagged as a external origin LV");
+
+ if (seg->merge_lv) {
+ if (!lv_is_thin_volume(seg->merge_lv))
+ seg_error("merge LV is not flagged as a thin LV");
+
+ if (!lv_is_merging_origin(seg->merge_lv))
+ seg_error("merge LV is not flagged as merging");
+ }
+ } else { /* !thin */
+ if (seg->device_id)
+ seg_error("sets device_id");
+ if (seg->external_lv)
+ seg_error("sets external LV");
+ if (seg->merge_lv)
+ seg_error("sets merge LV");
+ if (seg->indirect_origin)
+ seg_error("sets indirect_origin LV");
+ }
+
+ /* Some multi-seg vars excluded here */
+ if (!seg_is_cache(seg) &&
+ !seg_is_thin_volume(seg)) {
+ if (seg->pool_lv)
+ seg_error("sets pool LV");
+ }
+
+ if (!seg_is_pool(seg) &&
+ !seg_is_snapshot(seg)) {
+ if (seg->chunk_size)
+ seg_error("sets chunk_size");
+ }
+
+ if (!seg_is_thin_pool(seg) &&
+ !seg_is_thin_volume(seg)) {
+ if (seg->transaction_id)
+ seg_error("sets transaction_id");
+ }
+
+ if (!seg_unknown(seg)) {
+ if (seg->segtype_private)
+ seg_error("set segtype_private");
+ }
+}
+
/*
* Verify that an LV's segments are consecutive, complete and don't overlap.
*/
@@ -336,7 +464,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
{
struct lv_segment *seg, *seg2;
uint32_t le = 0;
- unsigned seg_count = 0, seg_found;
+ unsigned seg_count = 0, seg_found, external_lv_found = 0;
uint32_t area_multiplier, s;
struct seg_list *sl;
struct glv_list *glvl;
@@ -344,80 +472,15 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
struct replicator_site *rsite;
struct replicator_device *rdev;
- /* Check LV flags match first segment type */
- if (complete_vg) {
- if (lv_is_thin_volume(lv)) {
- if (dm_list_size(&lv->segments) != 1) {
- log_error("LV %s is thin volume without exactly one segment.",
- lv->name);
- inc_error_count;
- } else if (!seg_is_thin_volume(first_seg(lv))) {
- log_error("LV %s is thin volume without first thin volume segment.",
- lv->name);
- inc_error_count;
- }
- }
-
- if (lv_is_thin_pool(lv)) {
- if (dm_list_size(&lv->segments) != 1) {
- log_error("LV %s is thin pool volume without exactly one segment.",
- lv->name);
- inc_error_count;
- } else if (!seg_is_thin_pool(first_seg(lv))) {
- log_error("LV %s is thin pool without first thin pool segment.",
- lv->name);
- inc_error_count;
- }
- }
+ dm_list_iterate_items(seg, &lv->segments) {
+ seg_count++;
- if (lv_is_pool_data(lv) &&
- (!(seg2 = first_seg(lv)) || !(seg2 = find_pool_seg(seg2)) ||
- seg2->area_count != 1 || seg_type(seg2, 0) != AREA_LV ||
- seg_lv(seg2, 0) != lv)) {
- log_error("LV %s: segment 1 pool data LV does not point back to same LV",
- lv->name);
+ if (seg->lv != lv) {
+ log_error("LV %s invalid: segment %u is referencing different LV.",
+ lv->name, seg_count);
inc_error_count;
}
- if (lv_is_pool_metadata(lv)) {
- if (!(seg2 = first_seg(lv)) || !(seg2 = find_pool_seg(seg2)) ||
- seg2->metadata_lv != lv) {
- log_error("LV %s: segment 1 pool metadata LV does not point back to same LV",
- lv->name);
- inc_error_count;
- }
- if (lv_is_thin_pool_metadata(lv) &&
- !strstr(lv->name, "_tmeta")) {
- log_error("LV %s: thin pool metadata LV does not use _tmeta",
- lv->name);
- inc_error_count;
- } else if (lv_is_cache_pool_metadata(lv) &&
- !strstr(lv->name, "_cmeta")) {
- log_error("LV %s: cache pool metadata LV does not use _cmeta",
- lv->name);
- inc_error_count;
- }
- }
-
- if (lv_is_external_origin(lv)) {
- seg_found = 0;
- dm_list_iterate_items(sl, &lv->segs_using_this_lv)
- if (sl->seg->external_lv == lv)
- seg_found++;
- if (seg_found != lv->external_count) {
- log_error("LV %s: external origin count does not match.",
- lv->name);
- inc_error_count;
- }
- }
- }
-
- dm_list_iterate_items(seg, &lv->segments) {
- seg_count++;
-
- if (complete_vg && seg_is_raid(seg))
- _check_raid_seg(seg, &error_count);
-
if (seg->le != le) {
log_error("LV %s invalid: segment %u should begin at "
"LE %" PRIu32 " (found %" PRIu32 ").",
@@ -435,186 +498,6 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
inc_error_count;
}
- if (lv_is_error_when_full(lv) &&
- !seg_can_error_when_full(seg)) {
- log_error("LV %s: segment %u (%s) does not support flag "
- "ERROR_WHEN_FULL.", lv->name, seg_count, seg->segtype->name);
- inc_error_count;
- }
-
- if (complete_vg && seg->log_lv &&
- !seg_is_mirrored(seg) && lv_is_raid_image(lv)) {
- log_error("LV %s: segment %u log LV %s is not a "
- "mirror log or a RAID image",
- lv->name, seg_count, seg->log_lv->name);
- inc_error_count;
- }
-
- /*
- * Check mirror log - which is attached to the mirrored seg
- */
- if (complete_vg && seg->log_lv && seg_is_mirrored(seg)) {
- if (!lv_is_mirror_log(seg->log_lv)) {
- log_error("LV %s: segment %u log LV %s is not "
- "a mirror log",
- lv->name, seg_count, seg->log_lv->name);
- inc_error_count;
- }
-
- if (!(seg2 = first_seg(seg->log_lv)) ||
- find_mirror_seg(seg2) != seg) {
- log_error("LV %s: segment %u log LV does not "
- "point back to mirror segment",
- lv->name, seg_count);
- inc_error_count;
- }
- }
-
- if (complete_vg && lv_is_mirror_image(lv)) {
- if (!(seg2 = find_mirror_seg(seg)) ||
- !seg_is_mirrored(seg2)) {
- log_error("LV %s: segment %u mirror image "
- "is not mirrored",
- lv->name, seg_count);
- inc_error_count;
- }
- }
-
- /* Check the various thin segment types */
- if (complete_vg) {
- if (seg_is_thin_pool(seg)) {
- if (!lv_is_thin_pool(lv)) {
- log_error("LV %s is missing thin pool flag for segment %u",
- lv->name, seg_count);
- inc_error_count;
- }
-
- if (lv_is_thin_volume(lv)) {
- log_error("LV %s is a thin volume that must not contain thin pool segment %u",
- lv->name, seg_count);
- inc_error_count;
- }
-
- }
- if (seg_is_cache_pool(seg) &&
- !dm_list_empty(&seg->lv->segs_using_this_lv)) {
- switch (seg->cache_mode) {
- case CACHE_MODE_WRITETHROUGH:
- case CACHE_MODE_WRITEBACK:
- case CACHE_MODE_PASSTHROUGH:
- break;
- default:
- log_error("LV %s has invalid cache's feature flag.",
- lv->name);
- inc_error_count;
- }
- if (!seg->policy_name) {
- log_error("LV %s is missing cache policy name.", lv->name);
- inc_error_count;
- }
- }
- if (seg_is_pool(seg)) {
- if (seg->area_count != 1 ||
- seg_type(seg, 0) != AREA_LV) {
- log_error("LV %s: %s segment %u is missing a pool data LV",
- lv->name, seg->segtype->name, seg_count);
- inc_error_count;
- } else if (!(seg2 = first_seg(seg_lv(seg, 0))) || find_pool_seg(seg2) != seg) {
- log_error("LV %s: %s segment %u data LV does not refer back to pool LV",
- lv->name, seg->segtype->name, seg_count);
- inc_error_count;
- }
-
- if (!seg->metadata_lv) {
- log_error("LV %s: %s segment %u is missing a pool metadata LV",
- lv->name, seg->segtype->name, seg_count);
- inc_error_count;
- } else if (!(seg2 = first_seg(seg->metadata_lv)) ||
- find_pool_seg(seg2) != seg) {
- log_error("LV %s: %s segment %u metadata LV does not refer back to pool LV",
- lv->name, seg->segtype->name, seg_count);
- inc_error_count;
- }
-
- if (!validate_pool_chunk_size(lv->vg->cmd, seg->segtype, seg->chunk_size)) {
- log_error("LV %s: %s segment %u has invalid chunk size %u.",
- lv->name, seg->segtype->name, seg_count, seg->chunk_size);
- inc_error_count;
- }
- } else {
- if (seg->metadata_lv) {
- log_error("LV %s: segment %u must not have pool metadata LV set",
- lv->name, seg_count);
- inc_error_count;
- }
- }
-
- if (seg_is_thin_volume(seg)) {
- if (!lv_is_thin_volume(lv)) {
- log_error("LV %s is missing thin volume flag for segment %u",
- lv->name, seg_count);
- inc_error_count;
- }
-
- if (lv_is_thin_pool(lv)) {
- log_error("LV %s is a thin pool that must not contain thin volume segment %u",
- lv->name, seg_count);
- inc_error_count;
- }
-
- if (!seg->pool_lv) {
- log_error("LV %s: segment %u is missing thin pool LV",
- lv->name, seg_count);
- inc_error_count;
- } else if (!lv_is_thin_pool(seg->pool_lv)) {
- log_error("LV %s: thin volume segment %u pool LV is not flagged as a pool LV",
- lv->name, seg_count);
- inc_error_count;
- }
-
- if (seg->device_id > DM_THIN_MAX_DEVICE_ID) {
- log_error("LV %s: thin volume segment %u has too large device id %u",
- lv->name, seg_count, seg->device_id);
- inc_error_count;
- }
- if (seg->external_lv && (seg->external_lv->status & LVM_WRITE)) {
- log_error("LV %s: external origin %s is writable.",
- lv->name, seg->external_lv->name);
- inc_error_count;
- }
-
- if (seg->merge_lv) {
- if (!lv_is_thin_volume(seg->merge_lv)) {
- log_error("LV %s: thin volume segment %u merging LV %s is not flagged as a thin LV",
- lv->name, seg_count, seg->merge_lv->name);
- inc_error_count;
- }
- if (!lv_is_merging_origin(seg->merge_lv)) {
- log_error("LV %s: merging LV %s is not flagged as merging.",
- lv->name, seg->merge_lv->name);
- inc_error_count;
- }
- }
- } else if (seg_is_cache(seg)) {
- if (!lv_is_cache(lv)) {
- log_error("LV %s is missing cache flag for segment %u",
- lv->name, seg_count);
- inc_error_count;
- }
- if (!seg->pool_lv) {
- log_error("LV %s: segment %u is missing cache_pool LV",
- lv->name, seg_count);
- inc_error_count;
- }
- } else {
- if (seg->pool_lv) {
- log_error("LV %s: segment %u must not have pool LV set",
- lv->name, seg_count);
- inc_error_count;
- }
- }
- }
-
if (seg_is_snapshot(seg)) {
if (seg->cow && seg->cow == seg->origin) {
log_error("LV %s: segment %u has same LV %s for "
@@ -627,6 +510,9 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
if (seg_is_replicator(seg) && !check_replicator_segment(seg))
inc_error_count;
+ if (complete_vg)
+ _check_lv_segment(lv, seg, seg_count, &error_count);
+
for (s = 0; s < seg->area_count; s++) {
if (seg_type(seg, s) == AREA_UNASSIGNED) {
log_error("LV %s: segment %u has unassigned "
@@ -708,6 +594,12 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
le += seg->len;
}
+ if (le != lv->le_count) {
+ log_error("LV %s: inconsistent LE count %u != %u",
+ lv->name, le, lv->le_count);
+ inc_error_count;
+ }
+
dm_list_iterate_items(sl, &lv->segs_using_this_lv) {
seg = sl->seg;
seg_found = 0;
@@ -768,6 +660,10 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
lv->name);
inc_error_count;
}
+
+ /* Validation of external origin counter */
+ if (seg->external_lv == lv)
+ external_lv_found++;
}
dm_list_iterate_items(glvl, &lv->indirect_glvs) {
@@ -789,10 +685,51 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
}
}
- if (le != lv->le_count) {
- log_error("LV %s: inconsistent LE count %u != %u",
- lv->name, le, lv->le_count);
- inc_error_count;
+ /* Check LV flags match first segment type */
+ if (complete_vg) {
+ if ((seg_count != 1) &&
+ (lv_is_cache(lv) ||
+ lv_is_cache_pool(lv) ||
+ lv_is_raid(lv) ||
+ lv_is_snapshot(lv) ||
+ lv_is_thin_pool(lv) ||
+ lv_is_thin_volume(lv))) {
+ log_error("LV %s must have exactly one segment.",
+ lv->name);
+ inc_error_count;
+ }
+
+ if (lv_is_pool_data(lv) &&
+ (!(seg2 = first_seg(lv)) || !(seg2 = find_pool_seg(seg2)) ||
+ seg2->area_count != 1 || seg_type(seg2, 0) != AREA_LV ||
+ seg_lv(seg2, 0) != lv)) {
+ log_error("LV %s: segment 1 pool data LV does not point back to same LV",
+ lv->name);
+ inc_error_count;
+ }
+
+ if (lv_is_thin_pool_metadata(lv) && !strstr(lv->name, "_tmeta")) {
+ log_error("LV %s: thin pool metadata LV does not use _tmeta.",
+ lv->name);
+ inc_error_count;
+ } else if (lv_is_cache_pool_metadata(lv) && !strstr(lv->name, "_cmeta")) {
+ log_error("LV %s: cache pool metadata LV does not use _cmeta.",
+ lv->name);
+ inc_error_count;
+ }
+
+ if (lv_is_external_origin(lv)) {
+ if (lv->external_count != external_lv_found) {
+ log_error("LV %s: external origin count does not match.",
+ lv->name);
+ inc_error_count;
+ }
+ if (lv->status & LVM_WRITE) {
+ log_error("LV %s: external origin cant't be writable.",
+ lv->name);
+ inc_error_count;
+ }
+ }
}
out:
7 years, 3 months
master - lvmdbustest: Print messages if timeout value > 10%
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=eacff5c189d0cb...
Commit: eacff5c189d0cb3c6ac17a8f0af0fe440f12c4b7
Parent: a7e1f973ccd1abfc0f868f0b9c2382c2034e1633
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Dec 14 15:32:08 2016 -0600
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Dec 20 11:06:57 2016 -0600
lvmdbustest: Print messages if timeout value > 10%
We will dump some informational messages if the time to return when we
specify a timeout exceeds 10% of requested.
---
test/dbus/testlib.py | 25 ++++++++++++++++++++++---
1 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/test/dbus/testlib.py b/test/dbus/testlib.py
index 89e73d2..34ff33a 100644
--- a/test/dbus/testlib.py
+++ b/test/dbus/testlib.py
@@ -16,6 +16,7 @@ from collections import OrderedDict
import dbus
import os
import sys
+import time
BUS_NAME = os.getenv('LVM_DBUS_NAME', 'com.redhat.lvmdbus1')
BASE_INTERFACE = 'com.redhat.lvmdbus1'
@@ -188,10 +189,15 @@ class RemoteInterface(object):
def __init__(
self, dbus_object, interface, introspect,
- properties=None):
+ properties=None, timelimit=-1):
self.dbus_object = dbus_object
self.interface = interface
self.introspect = introspect
+ self.tmo = 0
+
+ if timelimit >= 0:
+ self.tmo = float(timelimit)
+ self.tmo *= 1.10
self.dbus_interface = dbus.Interface(self.dbus_object, self.interface)
self._set_props(properties)
@@ -203,7 +209,19 @@ class RemoteInterface(object):
return functools.partial(self, item)
def _wrapper(self, _method_name, *args, **kwargs):
+
+ # Lets see how long a method takes to execute, in call cases we should
+ # return something when the time limit has been reached.
+ start = time.time()
result = getattr(self.dbus_interface, _method_name)(*args, **kwargs)
+ end = time.time()
+
+ diff = end - start
+
+ if self.tmo > 0.0:
+ if diff > self.tmo:
+ std_err_print("\n Time exceeded: %f > %f %s" %
+ (diff, self.tmo, _method_name))
if self.introspect:
if 'RETURN_VALUE' in self.introspect[
@@ -236,13 +254,14 @@ class ClientProxy(object):
short_name = ClientProxy._intf_short_name(interface)
self.short_interface_names.append(short_name)
ro = RemoteInterface(self.dbus_object, interface, introspect,
- properties)
+ properties, timelimit=self.tmo)
setattr(self, short_name, ro)
def __init__(self, bus, object_path, interface_prop_hash=None,
- interfaces=None):
+ interfaces=None, timelimit=-1):
self.object_path = object_path
self.short_interface_names = []
+ self.tmo = timelimit
self.dbus_object = bus.get_object(
BUS_NAME, self.object_path, introspect=False)
7 years, 3 months
master - lvmdbusd: Use timeout_add instead
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a7e1f973ccd1ab...
Commit: a7e1f973ccd1abfc0f868f0b9c2382c2034e1633
Parent: 75568294be01f74ddadbf2c9bacf5d2fce219a44
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Wed Dec 14 15:30:01 2016 -0600
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Dec 20 11:06:57 2016 -0600
lvmdbusd: Use timeout_add instead
The function timeout_add_seconds has quite a bit of variability. Using
timeout_add which specifies the timeout in ms instead of seconds. Testing
shows that this is much more consistent which should improve clients that
are using shorter timeouts for the API and the connection.
---
daemons/lvmdbusd/request.py | 15 +++++++++------
1 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/daemons/lvmdbusd/request.py b/daemons/lvmdbusd/request.py
index 7c5da46..78392de 100644
--- a/daemons/lvmdbusd/request.py
+++ b/daemons/lvmdbusd/request.py
@@ -19,7 +19,6 @@ from .utils import log_error, mt_async_result
class RequestEntry(object):
def __init__(self, tmo, method, arguments, cb, cb_error,
return_tuple=True, job_state=None):
- self.tmo = tmo
self.method = method
self.arguments = arguments
self.cb = cb
@@ -35,23 +34,27 @@ class RequestEntry(object):
self._return_tuple = return_tuple
self._job_state = job_state
- if self.tmo < 0:
+ if tmo < 0:
# Client is willing to block forever
pass
elif tmo == 0:
self._return_job()
else:
- self.timer_id = GLib.timeout_add_seconds(
- tmo, RequestEntry._request_timeout, self)
+ # Note: using 990 instead of 1000 for second to ms conversion to
+ # account for overhead. Goal is to return just before the
+ # timeout amount has expired. Better to be a little early than
+ # late.
+ self.timer_id = GLib.timeout_add(
+ tmo * 990, RequestEntry._request_timeout, self)
@staticmethod
def _request_timeout(r):
"""
Method which gets called when the timer runs out!
:param r: RequestEntry which timed out
- :return: Nothing
+ :return: Result of timer_expired
"""
- r.timer_expired()
+ return r.timer_expired()
def _return_job(self):
# Return job is only called when we create a request object or when
7 years, 3 months
master - lvmdbusd: Use cfg.reload() instead of dbo.refresh
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=75568294be01f7...
Commit: 75568294be01f74ddadbf2c9bacf5d2fce219a44
Parent: 6fe6e8053a136af45174f153c00d404995af6e1c
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Mon Dec 12 16:15:12 2016 -0600
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Dec 20 11:06:57 2016 -0600
lvmdbusd: Use cfg.reload() instead of dbo.refresh
We want to update the data and send out any signals as needed, not just
update the in memory database.
---
daemons/lvmdbusd/lv.py | 4 ++--
daemons/lvmdbusd/vg.py | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/daemons/lvmdbusd/lv.py b/daemons/lvmdbusd/lv.py
index 79fff87..fa54322 100644
--- a/daemons/lvmdbusd/lv.py
+++ b/daemons/lvmdbusd/lv.py
@@ -618,7 +618,7 @@ class Lv(LvCommon):
rc, out, err = cmdhandler.activate_deactivate(
'lvchange', lv_name, activate, control_flags, options)
if rc == 0:
- dbo.refresh()
+ cfg.load()
return '/'
else:
raise dbus.exceptions.DBusException(
@@ -667,7 +667,7 @@ class Lv(LvCommon):
rc, out, err = cmdhandler.lv_tag(
lv_name, tags_add, tags_del, tag_options)
if rc == 0:
- dbo.refresh()
+ cfg.load()
return '/'
else:
raise dbus.exceptions.DBusException(
diff --git a/daemons/lvmdbusd/vg.py b/daemons/lvmdbusd/vg.py
index d84bb75..9b1df4e 100644
--- a/daemons/lvmdbusd/vg.py
+++ b/daemons/lvmdbusd/vg.py
@@ -727,7 +727,7 @@ class Vg(AutomatedProperties):
rc, out, err = cmdhandler.vg_tag(
vg_name, tags_add, tags_del, tag_options)
if rc == 0:
- dbo.refresh()
+ cfg.load()
return '/'
else:
raise dbus.exceptions.DBusException(
@@ -780,7 +780,7 @@ class Vg(AutomatedProperties):
if dbo:
rc, out, err = method(vg_name, value, options)
if rc == 0:
- dbo.refresh()
+ cfg.load()
return '/'
else:
raise dbus.exceptions.DBusException(
7 years, 3 months
master - lvmdbusd: Remove un-needed main thread execution
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6fe6e8053a136a...
Commit: 6fe6e8053a136af45174f153c00d404995af6e1c
Parent: f47da0ad234118f4a7a5e64b7a8480f6afd8e1de
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Mon Dec 12 16:13:27 2016 -0600
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Tue Dec 20 11:06:57 2016 -0600
lvmdbusd: Remove un-needed main thread execution
---
daemons/lvmdbusd/request.py | 7 +++++--
1 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/daemons/lvmdbusd/request.py b/daemons/lvmdbusd/request.py
index a2c2ac9..7c5da46 100644
--- a/daemons/lvmdbusd/request.py
+++ b/daemons/lvmdbusd/request.py
@@ -54,12 +54,15 @@ class RequestEntry(object):
r.timer_expired()
def _return_job(self):
+ # Return job is only called when we create a request object or when
+ # we pop a timer. In both cases we are running in the correct context
+ # and do not need to schedule the call back in main context.
self._job = Job(self, self._job_state)
cfg.om.register_object(self._job, True)
if self._return_tuple:
- mt_async_result(self.cb, ('/', self._job.dbus_object_path()))
+ self.cb(('/', self._job.dbus_object_path()))
else:
- mt_async_result(self.cb, self._job.dbus_object_path())
+ self.cb(self._job.dbus_object_path())
def run_cmd(self):
try:
7 years, 3 months
master - tests: usage of cached volume for snapshot
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=f47da0ad234118...
Commit: f47da0ad234118f4a7a5e64b7a8480f6afd8e1de
Parent: 0c56eb8f438a17a8c98470f9f6b2222235a7bf59
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Dec 19 14:05:16 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Dec 19 14:41:43 2016 +0100
tests: usage of cached volume for snapshot
---
test/shell/lvconvert-cache-snapshot.sh | 63 ++++++++++++++++++++++++++++++++
test/shell/lvconvert-cache.sh | 1 -
test/shell/lvcreate-cache-snapshot.sh | 63 ++++++++++++++++++++++++++++++++
3 files changed, 126 insertions(+), 1 deletions(-)
diff --git a/test/shell/lvconvert-cache-snapshot.sh b/test/shell/lvconvert-cache-snapshot.sh
new file mode 100644
index 0000000..8f0ab53
--- /dev/null
+++ b/test/shell/lvconvert-cache-snapshot.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+# Copyright (C) 2016 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Test various supported conversion of snapshot of cached volume
+
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+aux have_cache 1 3 0 || skip
+
+aux prepare_vg 1
+
+
+# Prepare cached LV
+lvcreate -aey -L1 -n $lv1 $vg
+lvcreate -H -L2 -n cpool $vg/$lv1
+
+# Prepare snapshot 'cow' LV
+lvcreate -L3 -n cow $vg
+
+# Can't use 'cached' cow volume
+not lvconvert -s cow $vg/$lv1
+
+# Use cached LV with 'striped' cow volume
+lvconvert -y -s $vg/$lv1 cow
+check lv_field $vg/cow segtype linear
+check lv_field $vg/$lv1 segtype cache
+
+# Drop cache while being in-use origin
+lvconvert --splitcache $vg/$lv1
+check lv_field $vg/$lv1 segtype linear
+
+# Cache existing origin
+lvconvert -y --cache $vg/$lv1 --cachepool $vg/cpool
+check lv_field $vg/$lv1 segtype cache
+
+# Cannot split from 'origin' (being cached LV)
+not lvconvert -y --splitsnapshot $vg/$lv1
+
+lvchange --cachemode writeback $vg/$lv1
+check lv_field $vg/$lv1 cache_mode "writeback"
+check grep_dmsetup status ${vg}-${lv1}-real "writeback"
+
+lvchange --cachemode writethrough $vg/$lv1
+check lv_field $vg/$lv1 cache_mode "writethrough"
+check grep_dmsetup status ${vg}-${lv1}-real "writethrough"
+
+# Split 'cow' from cached origin
+lvconvert -y --splitsnapshot $vg/cow
+get lv_field $vg/cow attr | grep "^-wi"
+
+vgremove -f $vg
diff --git a/test/shell/lvconvert-cache.sh b/test/shell/lvconvert-cache.sh
index 76116ea..31fe4e8 100644
--- a/test/shell/lvconvert-cache.sh
+++ b/test/shell/lvconvert-cache.sh
@@ -23,7 +23,6 @@ aux prepare_vg 5 80
lvcreate --type cache-pool -an -v -L 2 -n cpool $vg
lvcreate -H -L 4 -n corigin --cachepool $vg/cpool
-fail lvcreate -s -L2 $vg/corigin
fail lvcreate -s -L2 $vg/cpool
fail lvcreate -s -L2 $vg/cpool_cdata
fail lvcreate -s -L2 $vg/cpool_cmeta
diff --git a/test/shell/lvcreate-cache-snapshot.sh b/test/shell/lvcreate-cache-snapshot.sh
new file mode 100644
index 0000000..6b6ef2c
--- /dev/null
+++ b/test/shell/lvcreate-cache-snapshot.sh
@@ -0,0 +1,63 @@
+#!/bin/sh
+# Copyright (C) 2016 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# Exercise creation of snapshot of cached LV
+
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+which mkfs.ext2 || skip
+which fsck || skip
+
+aux have_cache 1 5 0 || skip
+
+aux prepare_vg 2
+
+lvcreate --type cache-pool -L1 $vg/cpool
+lvcreate -H -L4 -n $lv1 $vg/cpool
+
+lvcreate -s -L2 -n $lv2 $vg/$lv1
+check lv_field $vg/$lv1 segtype cache
+
+
+# Make some 'fs' data in snapshot
+mkfs.ext2 "$DM_DEV_DIR/$vg/$lv2"
+mkdir mnt
+mount "$DM_DEV_DIR/$vg/$lv2" mnt
+touch mnt/test
+umount mnt
+
+sync
+aux udev_wait
+
+# Merge snap to origin
+lvconvert --merge $vg/$lv2
+
+# Check cached origin has no valid fs.
+fsck -n "$DM_DEV_DIR/$vg/$lv1"
+
+# Check deactivation
+lvchange -an $vg
+
+# Check activation
+lvchange -ay $vg
+
+
+lvconvert --uncache $vg/$lv1
+check lv_field $vg/$lv1 segtype linear
+
+# Uncached origin is fine as well
+fsck -n "$DM_DEV_DIR/$vg/$lv1"
+
+
+vgremove -ff $vg
7 years, 3 months
master - cache: support cached origin for snapshot
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=0c56eb8f438a17...
Commit: 0c56eb8f438a17a8c98470f9f6b2222235a7bf59
Parent: eb3f83357afd2b7462f5be9f409424f588a138c8
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Dec 19 14:08:56 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Dec 19 14:41:42 2016 +0100
cache: support cached origin for snapshot
Enable 'lvcreate/lvconvert -s' for cached LV.
and supported operations:
Create a snapshot of cached LV
Split/Join snapshot LV to cached origin LV.
---
WHATS_NEW | 1 +
lib/metadata/cache_manip.c | 2 +-
lib/metadata/lv_manip.c | 2 +-
tools/lvconvert.c | 16 +++++++++++++++-
4 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index ab113ae..fa8f5c3 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Enable usage of cached volumes as snapshot origin LV.
Fix displayed lv name when splitting snapshot (2.02.146).
Warn about command not making metadata backup just once per command.
Enable usage of cached volume as thin volume's external origin.
diff --git a/lib/metadata/cache_manip.c b/lib/metadata/cache_manip.c
index 12b1054..404b1af 100644
--- a/lib/metadata/cache_manip.c
+++ b/lib/metadata/cache_manip.c
@@ -322,7 +322,7 @@ int validate_lv_cache_create_origin(const struct logical_volume *origin_lv)
if (lv_is_cache_type(origin_lv) ||
lv_is_mirror_type(origin_lv) ||
lv_is_thin_volume(origin_lv) || lv_is_thin_pool_metadata(origin_lv) ||
- lv_is_origin(origin_lv) || lv_is_merging_origin(origin_lv) ||
+ lv_is_merging_origin(origin_lv) ||
lv_is_cow(origin_lv) || lv_is_merging_cow(origin_lv) ||
lv_is_virtual(origin_lv)) {
log_error("Cache is not supported with %s segment type of the original logical volume %s.",
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 92a6d44..3862f11 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -7428,7 +7428,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
return NULL;
}
- if (lv_is_cache_type(origin_lv)) {
+ if (lv_is_cache_type(origin_lv) && !lv_is_cache(origin_lv)) {
log_error("Snapshots of cache type volume %s "
"is not supported.", display_lvname(origin_lv));
return NULL;
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 4103995..0f0f0ad 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2336,7 +2336,7 @@ static int _lvconvert_snapshot(struct cmd_context *cmd,
return_0;
if (lv_is_locked(org) ||
- lv_is_cache_type(org) ||
+ (lv_is_cache_type(org) && !lv_is_cache(org)) ||
lv_is_thin_type(org) ||
lv_is_pvmove(org) ||
lv_is_mirrored(org) ||
@@ -3771,6 +3771,16 @@ static int _convert_cache_volume_thin_pool(struct cmd_context *cmd, struct logic
}
/*
+ * Convert/Recombine cacheLV to be an origin for snapshot
+ * lvconvert --type snapshot cacheLV snapshotLV
+ */
+static int _convert_cache_volume_snapshot(struct cmd_context *cmd, struct logical_volume *lv,
+ struct lvconvert_params *lp)
+{
+ return _lvconvert_snapshot(cmd, lv, lp);
+}
+
+/*
* Split a cache volume from a cache pool LV.
* lvconvert --splitcache LV
*/
@@ -4311,6 +4321,10 @@ static int _convert_cache_volume(struct cmd_context *cmd, struct logical_volume
arg_is_set(cmd, thinpool_ARG))
return _convert_cache_volume_thin_pool(cmd, lv, lp);
+ if (!strcmp(lp->type_str, SEG_TYPE_NAME_SNAPSHOT) ||
+ arg_is_set(cmd, snapshot_ARG))
+ return _convert_cache_volume_snapshot(cmd, lv, lp);
+
/* The --thinpool alternative for --type thin-pool is not preferred, so not shown. */
log_error("Operation not permitted on cache LV %s.", display_lvname(lv));
7 years, 3 months
master - lvconvert: fix shown lv name for snapshot split
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=eb3f83357afd2b...
Commit: eb3f83357afd2b7462f5be9f409424f588a138c8
Parent: c90e9392e47a04f0d89c8ab0e0dca7fe9de00143
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Dec 19 14:06:55 2016 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Dec 19 14:41:16 2016 +0100
lvconvert: fix shown lv name for snapshot split
We can't keep 'display_lvname' for too long - it's using
ringbuffer and keeps limited number of names. So it's
safe only per few simple tests, but can't be used anymore
after some function calls..
(Fixes 00e641ef37a977129acc503f3fa1b67f556ac5eb)
---
WHATS_NEW | 1 +
tools/lvconvert.c | 10 +++++-----
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index fbaa369..ab113ae 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.169 -
=====================================
+ Fix displayed lv name when splitting snapshot (2.02.146).
Warn about command not making metadata backup just once per command.
Enable usage of cached volume as thin volume's external origin.
Support cache volume activation with -real layer.
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 393d286..4103995 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -2167,7 +2167,7 @@ static int _lvconvert_splitsnapshot(struct cmd_context *cmd, struct logical_volu
return_0;
if (lv_is_pvmove(cow) || lv_is_mirror_type(cow) || lv_is_raid_type(cow) || lv_is_thin_type(cow)) {
- log_error("LV %s type is unsupported with --splitsnapshot.", cow_name);
+ log_error("LV %s type is unsupported with --splitsnapshot.", display_lvname(cow));
return 0;
}
@@ -2179,8 +2179,8 @@ static int _lvconvert_splitsnapshot(struct cmd_context *cmd, struct logical_volu
lv_is_visible(cow) &&
lv_is_active(cow)) {
if (yes_no_prompt("Do you really want to split off active "
- "logical volume %s? [y/n]: ", cow_name) == 'n') {
- log_error("Logical volume %s not split.", cow_name);
+ "logical volume %s? [y/n]: ", display_lvname(cow)) == 'n') {
+ log_error("Logical volume %s not split.", display_lvname(cow));
return 0;
}
}
@@ -2189,14 +2189,14 @@ static int _lvconvert_splitsnapshot(struct cmd_context *cmd, struct logical_volu
if (!archive(vg))
return_0;
- log_verbose("Splitting snapshot %s from its origin.", cow_name);
+ log_verbose("Splitting snapshot %s from its origin.", display_lvname(cow));
if (!vg_remove_snapshot(cow))
return_0;
backup(vg);
- log_print_unless_silent("Logical Volume %s split from its origin.", cow_name);
+ log_print_unless_silent("Logical Volume %s split from its origin.", display_lvname(cow));
return 1;
}
7 years, 3 months
master - libdm: add dm_stats_bind_from_fd()
by Bryn Reeves
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=c90e9392e47a04...
Commit: c90e9392e47a04f0d89c8ab0e0dca7fe9de00143
Parent: 009b711834d26610d23d14bd8b7540eb69c836a7
Author: Bryn M. Reeves <bmr(a)redhat.com>
AuthorDate: Sun Dec 18 14:40:57 2016 +0000
Committer: Bryn M. Reeves <bmr(a)redhat.com>
CommitterDate: Sun Dec 18 20:47:17 2016 +0000
libdm: add dm_stats_bind_from_fd()
dmsetup already has a version of this function, and dmfilemapd will
need it too: move it to libdevmapper to avoid copying it around.
---
WHATS_NEW_DM | 1 +
libdm/.exported_symbols.DM_1_02_138 | 1 +
libdm/libdevmapper.h | 10 ++++++++++
libdm/libdm-stats.c | 19 +++++++++++++++++++
tools/dmsetup.c | 20 +-------------------
5 files changed, 32 insertions(+), 19 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index d57ddd7..3f9eeac 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.138 -
=====================================
+ Add dm_stats_bind_from_fd() to bind a stats handle from a file descriptor.
Do not try call callback when reverting activation on error path.
Fix file mapping for extents with physically adjacent extents.
Validation vsnprintf result in runtime translate of dm_log (1.02.136).
diff --git a/libdm/.exported_symbols.DM_1_02_138 b/libdm/.exported_symbols.DM_1_02_138
index 7535829..08f936f 100644
--- a/libdm/.exported_symbols.DM_1_02_138
+++ b/libdm/.exported_symbols.DM_1_02_138
@@ -1,3 +1,4 @@
dm_bit_get_last
dm_bit_get_prev
dm_bitset_parse_list
+dm_stats_bind_from_fd
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index ed46795..363cf8e 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -518,6 +518,16 @@ int dm_stats_bind_name(struct dm_stats *dms, const char *name);
int dm_stats_bind_uuid(struct dm_stats *dms, const char *uuid);
/*
+ * Bind a dm_stats handle to the device backing the file referenced
+ * by the specified file descriptor.
+ *
+ * File descriptor fd must reference a regular file, open for reading,
+ * in a local file system, backed by a device-mapper device, that
+ * supports the FIEMAP ioctl, and that returns data describing the
+ * physical location of extents.
+ */
+int dm_stats_bind_from_fd(struct dm_stats *dms, int fd);
+/*
* Test whether the running kernel supports the precise_timestamps
* feature. Presence of this feature also implies histogram support.
* The library will check this call internally and fails any attempt
diff --git a/libdm/libdm-stats.c b/libdm/libdm-stats.c
index 3978244..6e79a09 100644
--- a/libdm/libdm-stats.c
+++ b/libdm/libdm-stats.c
@@ -16,6 +16,7 @@
*/
#include "dmlib.h"
+#include "kdev_t.h"
#include "math.h" /* log10() */
@@ -452,6 +453,24 @@ int dm_stats_bind_uuid(struct dm_stats *dms, const char *uuid)
return 1;
}
+int dm_stats_bind_from_fd(struct dm_stats *dms, int fd)
+{
+ int major, minor;
+ struct stat buf;
+
+ if (fstat(fd, &buf)) {
+ log_error("fstat failed for fd %d.", fd);
+ return 0;
+ }
+
+ major = (int) MAJOR(buf.st_dev);
+ minor = (int) MINOR(buf.st_dev);
+
+ if (!dm_stats_bind_devno(dms, major, minor))
+ return_0;
+ return 1;
+}
+
static int _stats_check_precise_timestamps(const struct dm_stats *dms)
{
/* Already checked? */
diff --git a/tools/dmsetup.c b/tools/dmsetup.c
index 3f2c619..fabb183 100644
--- a/tools/dmsetup.c
+++ b/tools/dmsetup.c
@@ -4640,24 +4640,6 @@ static int _bind_stats_device(struct dm_stats *dms, const char *name)
return 1;
}
-static int _bind_stats_from_fd(struct dm_stats *dms, int fd)
-{
- int major, minor;
- struct stat buf;
-
- if (fstat(fd, &buf)) {
- log_error("fstat failed for fd %d.", fd);
- return 0;
- }
-
- major = (int) MAJOR(buf.st_dev);
- minor = (int) MINOR(buf.st_dev);
-
- if (!dm_stats_bind_devno(dms, major, minor))
- return_0;
- return 1;
-}
-
static int _stats_clear_one_region(struct dm_stats *dms, uint64_t region_id)
{
@@ -5068,7 +5050,7 @@ static int _stats_create_file(CMD_ARGS)
goto bad;
}
- if (!_bind_stats_from_fd(dms, fd))
+ if (!dm_stats_bind_from_fd(dms, fd))
goto_bad;
if (!strlen(program_id))
7 years, 3 months