master - cleanup: reorder condition
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=27a1a0e5c04806e217d...
Commit: 27a1a0e5c04806e217dbd9c197dc95c05341ed54
Parent: 1287edf6264b910a1f0d6dfbd809c2b51fe3ff2a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Mar 29 22:53:13 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Apr 20 12:17:01 2018 +0200
cleanup: reorder condition
There is no point to wait for sync for non-locally active LV.
---
lib/metadata/lv_manip.c | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index e377cf8..97a4e39 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -7149,6 +7149,12 @@ int wipe_lv(struct logical_volume *lv, struct wipe_params wp)
/* nothing to do */
return 1;
+ if (!lv_is_active_locally(lv)) {
+ log_error("Volume \"%s/%s\" is not active locally (volume_list activation filter?).",
+ lv->vg->name, lv->name);
+ return 0;
+ }
+
/* Wait until devices are available */
if (!sync_local_dev_names(lv->vg->cmd)) {
log_error("Failed to sync local devices before wiping LV %s.",
@@ -7156,12 +7162,6 @@ int wipe_lv(struct logical_volume *lv, struct wipe_params wp)
return 0;
}
- if (!lv_is_active_locally(lv)) {
- log_error("Volume \"%s/%s\" is not active locally (volume_list activation filter?).",
- lv->vg->name, lv->name);
- return 0;
- }
-
/*
* FIXME:
* <clausen> also, more than 4k
5 years, 11 months
master - cleanup: call uname once
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1287edf6264b910a1f0...
Commit: 1287edf6264b910a1f0d6dfbd809c2b51fe3ff2a
Parent: d81e3f9b067f9eb44122a8637966bfa838716135
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Mar 27 21:07:13 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Apr 20 12:16:58 2018 +0200
cleanup: call uname once
Call uname() once and keep result for mirror use-case.
---
WHATS_NEW_DM | 1 +
libdm/ioctl/libdm-iface.c | 19 +++++++++++++++----
libdm/libdm-common.h | 2 ++
libdm/libdm-deptree.c | 16 +++-------------
4 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index d3cdf7d..8fc3230 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.147 -
=====================================
+ Reuse uname() result for mirror target.
Recognize also mounted btrfs through dm_device_has_mounted_fs().
Add missing log_error() into dm_stats_populate() returning 0.
Avoid calling dm_stats_populat() for DM devices without any stats regions.
diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c
index 3965be6..769b69c 100644
--- a/libdm/ioctl/libdm-iface.c
+++ b/libdm/ioctl/libdm-iface.c
@@ -133,9 +133,9 @@ static char *_align(char *ptr, unsigned int a)
}
#ifdef DM_IOCTLS
-static int _kernel_major = 0;
-static int _kernel_minor = 0;
-static int _kernel_release = 0;
+static unsigned _kernel_major = 0;
+static unsigned _kernel_minor = 0;
+static unsigned _kernel_release = 0;
static int _uname(void)
{
@@ -151,7 +151,7 @@ static int _uname(void)
return 0;
}
- parts = sscanf(_uts.release, "%d.%d.%d",
+ parts = sscanf(_uts.release, "%u.%u.%u",
&_kernel_major, &_kernel_minor, &_kernel_release);
/* Kernels with a major number of 2 always had 3 parts. */
@@ -164,6 +164,17 @@ static int _uname(void)
return 1;
}
+int get_uname_version(unsigned *major, unsigned *minor, unsigned *release)
+{
+ if (!_uname())
+ return_0;
+
+ *major = _kernel_major;
+ *minor = _kernel_minor;
+ *release = _kernel_release;
+
+ return 1;
+}
/*
* Set number to NULL to populate _dm_bitset - otherwise first
* match is returned.
diff --git a/libdm/libdm-common.h b/libdm/libdm-common.h
index 4dc1870..010d876 100644
--- a/libdm/libdm-common.h
+++ b/libdm/libdm-common.h
@@ -53,4 +53,6 @@ void dec_suspended(void);
int parse_thin_pool_status(const char *params, struct dm_status_thin_pool *s);
+int get_uname_version(unsigned *major, unsigned *minor, unsigned *release);
+
#endif
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 98dda44..ab05456 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -2105,24 +2105,14 @@ static int _mirror_emit_segment_line(struct dm_task *dmt, struct load_segment *s
int block_on_error = 0;
int handle_errors = 0;
int dm_log_userspace = 0;
- struct utsname uts;
unsigned log_parm_count;
- int pos = 0, parts;
+ int pos = 0;
char logbuf[DM_FORMAT_DEV_BUFSIZE];
const char *logtype;
unsigned kmaj = 0, kmin = 0, krel = 0;
- if (uname(&uts) == -1) {
- log_error("Cannot read kernel release version.");
- return 0;
- }
-
- /* Kernels with a major number of 2 always had 3 parts. */
- parts = sscanf(uts.release, "%u.%u.%u", &kmaj, &kmin, &krel);
- if (parts < 1 || (kmaj < 3 && parts < 3)) {
- log_error("Wrong kernel release version %s.", uts.release);
- return 0;
- }
+ if (!get_uname_version(&kmaj, &kmin, &krel))
+ return_0;
if ((seg->flags & DM_BLOCK_ON_ERROR)) {
/*
5 years, 11 months
master - mirror: use vg mempool
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=d81e3f9b067f9eb4412...
Commit: d81e3f9b067f9eb44122a8637966bfa838716135
Parent: 05f954ee9b6339680c4430721a5c6bbc425fe315
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Mar 29 23:12:57 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Apr 20 12:16:14 2018 +0200
mirror: use vg mempool
Use vg mempool with mirror log metadata update.
---
lib/metadata/mirror.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index e09103d..8fcf94e 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -341,7 +341,7 @@ static int _init_mirror_log(struct cmd_context *cmd,
/* Temporary tag mirror log for activation */
dm_list_iterate_items(sl, tagsl)
- if (!str_list_add(cmd->mem, &log_lv->tags, sl->str)) {
+ if (!str_list_add(log_lv->vg->vgmem, &log_lv->tags, sl->str)) {
log_error("Aborting. Unable to tag mirror log.");
return 0;
}
5 years, 11 months
master - mirror: checking for mirror segtype
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=05f954ee9b6339680c4...
Commit: 05f954ee9b6339680c4430721a5c6bbc425fe315
Parent: 79d214032b21074709cd24669f53b5e24c5c377d
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Apr 20 10:01:28 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Apr 20 12:16:14 2018 +0200
mirror: checking for mirror segtype
Checking more correctly for mirror segtype here instead of
mirrored one which can be also 'raid'.
---
lib/metadata/lv_manip.c | 7 +++----
1 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 707aec3..e377cf8 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4187,7 +4187,7 @@ int lv_extend(struct logical_volume *lv,
if (segtype_is_pool(segtype)) {
if (!(r = create_pool(lv, segtype, ah, stripes, stripe_size)))
stack;
- } else if (!segtype_is_mirrored(segtype) && !segtype_is_raid(segtype)) {
+ } else if (!segtype_is_mirror(segtype) && !segtype_is_raid(segtype)) {
if (!(r = lv_add_segment(ah, 0, ah->area_count, lv, segtype,
stripe_size, 0u, 0)))
stack;
@@ -7337,7 +7337,7 @@ static int _vg_check_features(struct volume_group *vg,
if (!(features & FMT_SEGMENTS) &&
(seg_is_cache(lp) ||
seg_is_cache_pool(lp) ||
- seg_is_mirrored(lp) ||
+ seg_is_mirror(lp) ||
seg_is_raid(lp) ||
seg_is_thin(lp))) {
log_error("Metadata does not support %s segments.",
@@ -7778,8 +7778,7 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
return_NULL;
/* FIXME Log allocation and attachment should have happened inside lv_extend. */
- if (lp->log_count &&
- !seg_is_raid(first_seg(lv)) && seg_is_mirrored(first_seg(lv))) {
+ if (lp->log_count && segtype_is_mirror(create_segtype)) {
if (!add_mirror_log(cmd, lv, lp->log_count,
first_seg(lv)->region_size,
lp->pvh, lp->alloc)) {
5 years, 11 months
master - mirror: validate region_size for mirrors
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=79d214032b21074709c...
Commit: 79d214032b21074709cd24669f53b5e24c5c377d
Parent: 1693fef529e7e1536d91956cfc4256c98cae58ab
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Apr 19 17:38:04 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Apr 20 12:16:13 2018 +0200
mirror: validate region_size for mirrors
Check for region size properties of mirror segments.
---
WHATS_NEW | 1 +
lib/metadata/merge.c | 8 ++++++++
2 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 434f4a0..2d085a1 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.178 -
=====================================
+ Extend validation of region_size for mirror segment.
Reload whole device stack when reinitilizing mirror log.
Mirrors without monitoring are WARNING and not blocking on error.
Detect too big region_size with clustered mirrors.
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
index f0da2fe..90b40e2 100644
--- a/lib/metadata/merge.c
+++ b/lib/metadata/merge.c
@@ -391,6 +391,14 @@ static void _check_lv_segment(struct logical_volume *lv, struct lv_segment *seg,
if (!(seg2 = first_seg(seg->log_lv)) || (find_mirror_seg(seg2) != seg))
seg_error("log LV does not point back to mirror segment");
}
+ if (seg_is_mirror(seg)) {
+ if (!seg->region_size)
+ seg_error("region size is zero");
+ else if (seg->region_size > seg->lv->size)
+ seg_error("region size is bigger then LV itself");
+ else if (!is_power_of_2(seg->region_size))
+ seg_error("region size is non power of 2");
+ }
} else { /* !mirrored */
if (seg->log_lv) {
if (lv_is_raid_image(lv))
5 years, 11 months
master - mirror: properly reload table for log init
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=1693fef529e7e1536d9...
Commit: 1693fef529e7e1536d91956cfc4256c98cae58ab
Parent: 55d83f9f6ee1892d419bdd9d50c3450ac41f6749
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Mar 29 23:26:22 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Apr 20 12:15:36 2018 +0200
mirror: properly reload table for log init
Since mirror can be stacked, we need to properly reload whole
table stack, otherwice we may mishandle devices in dm table.
---
WHATS_NEW | 2 ++
lib/metadata/mirror.c | 14 ++++++++++----
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 6affa13..434f4a0 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
Version 2.02.178 -
=====================================
+ Reload whole device stack when reinitilizing mirror log.
+ Mirrors without monitoring are WARNING and not blocking on error.
Detect too big region_size with clustered mirrors.
Fix evaluation of maximal region size for mirror log.
Enhance mirror log size estimation and use smaller size when possible.
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index 6c8732b..e09103d 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -315,6 +315,7 @@ static int _write_log_header(struct cmd_context *cmd, struct logical_volume *lv)
* Initialize mirror log contents
*/
static int _init_mirror_log(struct cmd_context *cmd,
+ struct logical_volume *lock_holder,
struct logical_volume *log_lv, int in_sync,
struct dm_list *tagsl, int remove_on_failure)
{
@@ -346,7 +347,10 @@ static int _init_mirror_log(struct cmd_context *cmd,
}
/* store mirror log on disk(s) */
- if (!vg_write(log_lv->vg) || !vg_commit(log_lv->vg))
+ if (!lock_holder) {
+ if (!vg_write(log_lv->vg) || !vg_commit(log_lv->vg))
+ return_0;
+ } else if (!lv_update_and_reload((struct logical_volume*) lock_holder))
return_0;
if (!activate_lv_excl_local(cmd, log_lv)) {
@@ -1021,7 +1025,9 @@ static int _remove_mirror_images(struct logical_volume *lv,
/* Mirror with only 1 area is 'in sync'. */
if (new_area_count == 1 && is_temporary_mirror_layer(lv)) {
detached_log_lv = detach_mirror_log(mirrored_seg);
- if (!_init_mirror_log(lv->vg->cmd, detached_log_lv,
+ if (!_init_mirror_log(lv->vg->cmd,
+ (struct logical_volume*)lv_lock_holder(mirrored_seg->lv),
+ detached_log_lv,
1, &lv->tags, 0)) {
/* As a result, unnecessary sync may run after
* collapsing. But safe.*/
@@ -1822,7 +1828,7 @@ static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd,
}
}
- if (!_init_mirror_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
+ if (!_init_mirror_log(cmd, NULL, log_lv, in_sync, &lv->tags, 1)) {
log_error("Failed to initialise mirror log.");
return NULL;
}
@@ -1870,7 +1876,7 @@ struct logical_volume *prepare_mirror_log(struct logical_volume *lv,
goto out;
}
- if (!_init_mirror_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
+ if (!_init_mirror_log(cmd, NULL, log_lv, in_sync, &lv->tags, 1)) {
log_error("Failed to initialise mirror log.");
log_lv = NULL;
goto out;
5 years, 11 months
master - mirror: block_on_error only with monitoring
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=55d83f9f6ee1892d419...
Commit: 55d83f9f6ee1892d419bdd9d50c3450ac41f6749
Parent: 66400d003d357611f19f99fb68500c364fbef547
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Mar 29 21:10:58 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Apr 20 12:13:51 2018 +0200
mirror: block_on_error only with monitoring
When user configured lvm2 to NOT user monitoring, activated mirror
actually hang upon error and it's quite unusable moment.
So instead Warn those 'brave' non-monitoring users about possible
problem and activation mirror without blocking error handling.
This also makes it a bit simpler for test suite to handle trouble
cases when test is running without dmeventd.
---
lib/commands/toolcontext.h | 1 +
lib/mirror/mirrored.c | 10 ++++++++--
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 4225c57..89d1088 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -169,6 +169,7 @@ struct cmd_context {
unsigned activate_component:1; /* command activates component LV */
unsigned process_component_lvs:1; /* command processes also component LVs */
+ unsigned mirror_warn_printed:1; /* command already printed warning about non-monitored mirrors */
/*
* Filtering.
*/
diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c
index e6dc99b..10828e8 100644
--- a/lib/mirror/mirrored.c
+++ b/lib/mirror/mirrored.c
@@ -314,8 +314,14 @@ static int _add_log(struct dm_pool *mem, struct lv_segment *seg,
if (mirror_in_sync() && !(seg->status & PVMOVE))
log_flags |= DM_NOSYNC;
- if (_block_on_error_available && !(seg->status & PVMOVE))
- log_flags |= DM_BLOCK_ON_ERROR;
+ if (_block_on_error_available && !(seg->status & PVMOVE)) {
+ if (dmeventd_monitor_mode() > 0)
+ log_flags |= DM_BLOCK_ON_ERROR;
+ else {
+ log_warn_suppress(seg->lv->vg->cmd->mirror_warn_printed, "WARNING: Mirrors without monitoring will not react on failures.");
+ seg->lv->vg->cmd->mirror_warn_printed = 1;
+ }
+ }
return dm_tree_node_add_mirror_target_log(node, region_size, clustered, log_dlid, area_count, log_flags);
}
5 years, 11 months
master - mirror: fix region_size for clustered VG
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=66400d003d357611f19...
Commit: 66400d003d357611f19f99fb68500c364fbef547
Parent: a19456b868849816f21cfd7517777c5999c43a89
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Apr 20 10:07:42 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Apr 20 12:13:48 2018 +0200
mirror: fix region_size for clustered VG
When adjusting region size for clustered VG it always needs to fit
2 full bitset into 1MB due to old limits of CPG.
This is relatively big amount of bits, but we have still limitation
for region size to fit into 32bits (0x8000000).
So for too big mirrors this operation needs to fail - so whenever
function returns now 0, it means we can't find matching region_size.
Since return 0 is now 'error' we need to also pass proper region_size
when creating pvmove mirror.
---
WHATS_NEW | 1 +
lib/metadata/lv_manip.c | 20 +++++++-------------
lib/metadata/mirror.c | 21 ++++++++++++---------
lib/mirror/mirrored.c | 12 ++++++------
tools/lvconvert.c | 20 +++++++++++---------
tools/pvmove.c | 5 +++--
6 files changed, 40 insertions(+), 39 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 9682d22..6affa13 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.178 -
=====================================
+ Detect too big region_size with clustered mirrors.
Fix evaluation of maximal region size for mirror log.
Enhance mirror log size estimation and use smaller size when possible.
Fix incorrect mirror log size calculation on 32bit arch.
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index b8bbdec..707aec3 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -7582,6 +7582,13 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
return NULL;
}
+ if (!(lp->region_size = adjusted_mirror_region_size(vg->cmd,
+ vg->extent_size,
+ lp->extents,
+ lp->region_size, 0,
+ vg_is_clustered(vg))))
+ return_NULL;
+
/* FIXME This will not pass cluster lock! */
init_mirror_in_sync(lp->nosync);
@@ -7591,19 +7598,6 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
lp->segtype->name);
status |= LV_NOTSYNCED;
}
-
- if (seg_is_raid(lp)) {
- /* Value raid target constraint */
- if (lp->region_size > (uint64_t)vg->extent_size * lp->extents) {
- log_error("Cannot create RAID LV with region size larger than LV size.");
- return NULL;
- }
- } else
- lp->region_size = adjusted_mirror_region_size(vg->cmd,
- vg->extent_size,
- lp->extents,
- lp->region_size, 0,
- vg_is_clustered(vg));
} else if (pool_lv && seg_is_thin_volume(lp)) {
if (!lv_is_thin_pool(pool_lv)) {
log_error("Logical volume %s is not a thin pool.",
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index db2883b..6c8732b 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -193,10 +193,12 @@ uint32_t adjusted_mirror_region_size(struct cmd_context *cmd,
* This code should be removed when the CPG restriction is
* lifted.
*/
- region_min = (uint64_t) extents * extent_size / CMIRROR_REGION_COUNT_LIMIT;
- region_min_pow2 = 1;
- while (region_min_pow2 < region_min)
- region_min_pow2 *= 2;
+ region_min = region_max / CMIRROR_REGION_COUNT_LIMIT;
+ if (region_min > UINT32_MAX / 2) {
+ log_error("Can't find proper region size for too big mirror.");
+ return 0;
+ }
+ region_min_pow2 = UINT64_C(1) << (1 + 31 - clz(region_min));
if (region_size < region_min_pow2) {
if (internal)
@@ -1591,11 +1593,12 @@ static int _add_mirrors_that_preserve_segments(struct logical_volume *lv,
if (!(segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_MIRROR)))
return_0;
- adjusted_region_size = adjusted_mirror_region_size(cmd,
- lv->vg->extent_size,
- lv->le_count,
- region_size, 1,
- vg_is_clustered(lv->vg));
+ if (!(adjusted_region_size = adjusted_mirror_region_size(cmd,
+ lv->vg->extent_size,
+ lv->le_count,
+ region_size, 1,
+ vg_is_clustered(lv->vg))))
+ return_0;
if (!(ah = allocate_extents(lv->vg, NULL, segtype, 1, mirrors, 0, 0,
lv->le_count, allocatable_pvs, alloc, 0,
diff --git a/lib/mirror/mirrored.c b/lib/mirror/mirrored.c
index a46cc29..e6dc99b 100644
--- a/lib/mirror/mirrored.c
+++ b/lib/mirror/mirrored.c
@@ -378,12 +378,12 @@ static int _mirrored_add_target_line(struct dev_manager *dm, struct dm_pool *mem
}
region_size = seg->region_size;
- } else
- region_size = adjusted_mirror_region_size(cmd,
- seg->lv->vg->extent_size,
- seg->area_len,
- mirr_state->default_region_size, 1,
- vg_is_clustered(seg->lv->vg));
+ } else if (!(region_size = adjusted_mirror_region_size(cmd,
+ seg->lv->vg->extent_size,
+ seg->area_len,
+ mirr_state->default_region_size, 1,
+ vg_is_clustered(seg->lv->vg))))
+ return_0;
if (!dm_tree_node_add_mirror_target(node, len))
return_0;
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index 21db0ef..44fdd16 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -628,10 +628,11 @@ static int _lv_update_log_type(struct cmd_context *cmd,
/* Adding redundancy to the log */
if (old_log_count < log_count) {
- region_size = adjusted_mirror_region_size(cmd, lv->vg->extent_size,
- lv->le_count,
- region_size, 0,
- vg_is_clustered(lv->vg));
+ if (!(region_size = adjusted_mirror_region_size(cmd, lv->vg->extent_size,
+ lv->le_count,
+ region_size, 0,
+ vg_is_clustered(lv->vg))))
+ return_0;
if (!add_mirror_log(cmd, original_lv, log_count,
region_size, operable_pvs, alloc))
@@ -833,17 +834,18 @@ static int _lvconvert_mirrors_aux(struct cmd_context *cmd,
return 1;
}
+ if (!(region_size = adjusted_mirror_region_size(cmd, lv->vg->extent_size,
+ lv->le_count,
+ lp->region_size ? : seg->region_size, 0,
+ vg_is_clustered(lv->vg))))
+ return_0;
+
if (lv_component_is_active(lv)) {
log_error("Cannot convert logical volume %s with active component LV(s).",
display_lvname(lv));
return 0;
}
- region_size = adjusted_mirror_region_size(cmd, lv->vg->extent_size,
- lv->le_count,
- lp->region_size ? : seg->region_size, 0,
- vg_is_clustered(lv->vg));
-
if (!operable_pvs)
operable_pvs = pvh;
diff --git a/tools/pvmove.c b/tools/pvmove.c
index 84efdf4..9ad17f6 100644
--- a/tools/pvmove.c
+++ b/tools/pvmove.c
@@ -511,8 +511,9 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
return NULL;
}
- if (!lv_add_mirrors(cmd, lv_mirr, 1, 1, 0, 0, log_count,
- allocatable_pvs, alloc,
+ if (!lv_add_mirrors(cmd, lv_mirr, 1, 1, 0,
+ get_default_region_size(cmd),
+ log_count, allocatable_pvs, alloc,
(arg_is_set(cmd, atomic_ARG)) ?
MIRROR_BY_SEGMENTED_LV : MIRROR_BY_SEG)) {
log_error("Failed to convert pvmove LV to mirrored.");
5 years, 11 months
master - mirror: fix calcs for maximal region_size
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=a19456b868849816f21...
Commit: a19456b868849816f21cfd7517777c5999c43a89
Parent: 91965af9b1d53e6bf89ef7a849c0347277e72276
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Apr 20 10:03:26 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Apr 20 12:13:08 2018 +0200
mirror: fix calcs for maximal region_size
Since extent_size is no longer power_of_2 this max region size
evalution was rather producing random bitsize as a combination
of lowest bit from number of extents and extent size itself.
Correct calculation to use whole LV size and pick biggest
possible power of 2 value smaller then UINT32_MAX.
---
WHATS_NEW | 1 +
lib/metadata/mirror.c | 10 +++++-----
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index ca9e6fa..9682d22 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.178 -
=====================================
+ Fix evaluation of maximal region size for mirror log.
Enhance mirror log size estimation and use smaller size when possible.
Fix incorrect mirror log size calculation on 32bit arch.
Enhnace preloading tree creating.
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index 6107619..db2883b 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -161,17 +161,17 @@ uint32_t adjusted_mirror_region_size(struct cmd_context *cmd,
uint32_t extent_size, uint32_t extents,
uint32_t region_size, int internal, int clustered)
{
- uint64_t region_max;
- uint64_t region_min, region_min_pow2;
+ uint64_t region_max, region_min;
+ uint32_t region_min_pow2;
- region_max = (UINT64_C(1) << (ffs((int)extents) - 1)) * (UINT64_C(1) << (ffs((int)extent_size) - 1));
+ region_max = (uint64_t) extents * extent_size;
if (region_max < UINT32_MAX && region_size > region_max) {
- region_size = (uint32_t) region_max;
+ region_size = UINT64_C(1) << (31 - clz(region_max));
if (!internal)
log_print_unless_silent("Using reduced mirror region size of %s",
display_size(cmd, region_size));
- else
+ else
log_verbose("Using reduced mirror region size of %s",
display_size(cmd, region_size));
}
5 years, 11 months
master - mirror: improve mirror log size estimation
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=91965af9b1d53e6bf89...
Commit: 91965af9b1d53e6bf89ef7a849c0347277e72276
Parent: 73189170f53ea661e7bf117404cdb5f461f0df1b
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Apr 20 10:12:25 2018 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Apr 20 12:11:42 2018 +0200
mirror: improve mirror log size estimation
Drop mirrored mirror log limitation that applies only in very limited
use-case and actually mirrored mirror log is deprecated anyway.
So 'disk' mirror log is selecting the correct minimal size, and
bigger size is only enforced with real mirrored mirror log.
Also for mirrored mirror log we let use 'smalled' region size if needed
so if user uses 1G region size, we still keep small mirror log
with much smaller region size in this case when needed.
Also mirror log extent calculation is now properly detecting error
with too big mirrors where previosly trimmed uint32_t was applies
unintentionally.
---
WHATS_NEW | 1 +
lib/metadata/lv_manip.c | 21 ++++++++-------------
lib/metadata/mirror.c | 16 ++++++++++++----
3 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 0bb94aa..ca9e6fa 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.178 -
=====================================
+ Enhance mirror log size estimation and use smaller size when possible.
Fix incorrect mirror log size calculation on 32bit arch.
Enhnace preloading tree creating.
Fix regression on acceptance of any LV on lvconvert.
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index f275ecd..b8bbdec 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1681,19 +1681,14 @@ static uint32_t _mirror_log_extents(uint32_t region_size, uint32_t pe_size, uint
log_size >>= SECTOR_SHIFT;
log_size = dm_div_up(log_size, pe_size);
- /*
- * Kernel requires a mirror to be at least 1 region large. So,
- * if our mirror log is itself a mirror, it must be at least
- * 1 region large. This restriction may not be necessary for
- * non-mirrored logs, but we apply the rule anyway.
- *
- * (The other option is to make the region size of the log
- * mirror smaller than the mirror it is acting as a log for,
- * but that really complicates things. It's much easier to
- * keep the region_size the same for both.)
- */
- return (log_size > (region_size / pe_size)) ? log_size :
- (region_size / pe_size);
+ if (log_size > UINT32_MAX) {
+ log_error("Log size needs too many extents "FMTu64" with region size of %u sectors.",
+ log_size, region_size);
+ log_size = UINT32_MAX;
+ /* VG likely will not have enough free space for this allocation -> error */
+ }
+
+ return (uint32_t) log_size;
}
/* Is there enough total space or should we give up immediately? */
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index d3ced60..6107619 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -1805,10 +1805,18 @@ static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd,
return NULL;
}
- if ((log_count > 1) &&
- !_form_mirror(cmd, ah, log_lv, log_count-1, 1, 0, region_size, 2)) {
- log_error("Failed to form mirrored log.");
- return NULL;
+ if (log_count > 1) {
+ /* Kernel requires a mirror to be at least 1 region large. */
+ if (region_size > log_lv->size) {
+ region_size = UINT64_C(1) << (31 - clz(log_lv->size));
+ log_debug("Adjusting region_size to %s for mirrored log.",
+ display_size(cmd, (uint64_t)region_size));
+ }
+
+ if (!_form_mirror(cmd, ah, log_lv, log_count-1, 1, 0, region_size, 2)) {
+ log_error("Failed to form mirrored log.");
+ return NULL;
+ }
}
if (!_init_mirror_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
5 years, 11 months