basebuilder_pel7x64builder0
4 years ago
29 changed files with 7677 additions and 69 deletions
@ -0,0 +1,173 @@ |
|||||||
|
From 12041b03584bb2fa36f797ece4b0f9a41760a303 Mon Sep 17 00:00:00 2001 |
||||||
|
From: David Teigland <teigland@redhat.com> |
||||||
|
Date: Wed, 24 Jul 2019 11:32:13 -0500 |
||||||
|
Subject: [PATCH 2/4] Fix rounding writes up to sector size |
||||||
|
|
||||||
|
Do this at two levels, although one would be enough to |
||||||
|
fix the problem seen recently: |
||||||
|
|
||||||
|
- Ignore any reported sector size other than 512 of 4096. |
||||||
|
If either sector size (physical or logical) is reported |
||||||
|
as 512, then use 512. If neither are reported as 512, |
||||||
|
and one or the other is reported as 4096, then use 4096. |
||||||
|
If neither is reported as either 512 or 4096, then use 512. |
||||||
|
|
||||||
|
- When rounding up a limited write in bcache to be a multiple |
||||||
|
of the sector size, check that the resulting write size is |
||||||
|
not larger than the bcache block itself. (This shouldn't |
||||||
|
happen if the sector size is 512 or 4096.) |
||||||
|
|
||||||
|
(cherry picked from commit 7550665ba49ac7d497d5b212e14b69298ef01361) |
||||||
|
|
||||||
|
Conflicts: |
||||||
|
lib/device/dev-io.c |
||||||
|
|
||||||
|
(cherry picked from commit 44c460954be5c63cf5338bd9151344fe2626565f) |
||||||
|
--- |
||||||
|
lib/device/bcache.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++++++-- |
||||||
|
1 file changed, 87 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/lib/device/bcache.c b/lib/device/bcache.c |
||||||
|
index b64707e..77d1543 100644 |
||||||
|
--- a/lib/device/bcache.c |
||||||
|
+++ b/lib/device/bcache.c |
||||||
|
@@ -169,6 +169,7 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd, |
||||||
|
sector_t offset; |
||||||
|
sector_t nbytes; |
||||||
|
sector_t limit_nbytes; |
||||||
|
+ sector_t orig_nbytes; |
||||||
|
sector_t extra_nbytes = 0; |
||||||
|
|
||||||
|
if (((uintptr_t) data) & e->page_mask) { |
||||||
|
@@ -191,11 +192,41 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd, |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
+ /* |
||||||
|
+ * If the bcache block offset+len goes beyond where lvm is |
||||||
|
+ * intending to write, then reduce the len being written |
||||||
|
+ * (which is the bcache block size) so we don't write past |
||||||
|
+ * the limit set by lvm. If after applying the limit, the |
||||||
|
+ * resulting size is not a multiple of the sector size (512 |
||||||
|
+ * or 4096) then extend the reduced size to be a multiple of |
||||||
|
+ * the sector size (we don't want to write partial sectors.) |
||||||
|
+ */ |
||||||
|
if (offset + nbytes > _last_byte_offset) { |
||||||
|
limit_nbytes = _last_byte_offset - offset; |
||||||
|
- if (limit_nbytes % _last_byte_sector_size) |
||||||
|
+ |
||||||
|
+ if (limit_nbytes % _last_byte_sector_size) { |
||||||
|
extra_nbytes = _last_byte_sector_size - (limit_nbytes % _last_byte_sector_size); |
||||||
|
|
||||||
|
+ /* |
||||||
|
+ * adding extra_nbytes to the reduced nbytes (limit_nbytes) |
||||||
|
+ * should make the final write size a multiple of the |
||||||
|
+ * sector size. This should never result in a final size |
||||||
|
+ * larger than the bcache block size (as long as the bcache |
||||||
|
+ * block size is a multiple of the sector size). |
||||||
|
+ */ |
||||||
|
+ if (limit_nbytes + extra_nbytes > nbytes) { |
||||||
|
+ log_warn("Skip extending write at %llu len %llu limit %llu extra %llu sector_size %llu", |
||||||
|
+ (unsigned long long)offset, |
||||||
|
+ (unsigned long long)nbytes, |
||||||
|
+ (unsigned long long)limit_nbytes, |
||||||
|
+ (unsigned long long)extra_nbytes, |
||||||
|
+ (unsigned long long)_last_byte_sector_size); |
||||||
|
+ extra_nbytes = 0; |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ orig_nbytes = nbytes; |
||||||
|
+ |
||||||
|
if (extra_nbytes) { |
||||||
|
log_debug("Limit write at %llu len %llu to len %llu rounded to %llu", |
||||||
|
(unsigned long long)offset, |
||||||
|
@@ -210,6 +241,22 @@ static bool _async_issue(struct io_engine *ioe, enum dir d, int fd, |
||||||
|
(unsigned long long)limit_nbytes); |
||||||
|
nbytes = limit_nbytes; |
||||||
|
} |
||||||
|
+ |
||||||
|
+ /* |
||||||
|
+ * This shouldn't happen, the reduced+extended |
||||||
|
+ * nbytes value should never be larger than the |
||||||
|
+ * bcache block size. |
||||||
|
+ */ |
||||||
|
+ if (nbytes > orig_nbytes) { |
||||||
|
+ log_error("Invalid adjusted write at %llu len %llu adjusted %llu limit %llu extra %llu sector_size %llu", |
||||||
|
+ (unsigned long long)offset, |
||||||
|
+ (unsigned long long)orig_nbytes, |
||||||
|
+ (unsigned long long)nbytes, |
||||||
|
+ (unsigned long long)limit_nbytes, |
||||||
|
+ (unsigned long long)extra_nbytes, |
||||||
|
+ (unsigned long long)_last_byte_sector_size); |
||||||
|
+ return false; |
||||||
|
+ } |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@@ -403,6 +450,7 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd, |
||||||
|
uint64_t nbytes = len; |
||||||
|
sector_t limit_nbytes = 0; |
||||||
|
sector_t extra_nbytes = 0; |
||||||
|
+ sector_t orig_nbytes = 0; |
||||||
|
|
||||||
|
if (offset > _last_byte_offset) { |
||||||
|
log_error("Limit write at %llu len %llu beyond last byte %llu", |
||||||
|
@@ -415,9 +463,30 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd, |
||||||
|
|
||||||
|
if (offset + nbytes > _last_byte_offset) { |
||||||
|
limit_nbytes = _last_byte_offset - offset; |
||||||
|
- if (limit_nbytes % _last_byte_sector_size) |
||||||
|
+ |
||||||
|
+ if (limit_nbytes % _last_byte_sector_size) { |
||||||
|
extra_nbytes = _last_byte_sector_size - (limit_nbytes % _last_byte_sector_size); |
||||||
|
|
||||||
|
+ /* |
||||||
|
+ * adding extra_nbytes to the reduced nbytes (limit_nbytes) |
||||||
|
+ * should make the final write size a multiple of the |
||||||
|
+ * sector size. This should never result in a final size |
||||||
|
+ * larger than the bcache block size (as long as the bcache |
||||||
|
+ * block size is a multiple of the sector size). |
||||||
|
+ */ |
||||||
|
+ if (limit_nbytes + extra_nbytes > nbytes) { |
||||||
|
+ log_warn("Skip extending write at %llu len %llu limit %llu extra %llu sector_size %llu", |
||||||
|
+ (unsigned long long)offset, |
||||||
|
+ (unsigned long long)nbytes, |
||||||
|
+ (unsigned long long)limit_nbytes, |
||||||
|
+ (unsigned long long)extra_nbytes, |
||||||
|
+ (unsigned long long)_last_byte_sector_size); |
||||||
|
+ extra_nbytes = 0; |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ orig_nbytes = nbytes; |
||||||
|
+ |
||||||
|
if (extra_nbytes) { |
||||||
|
log_debug("Limit write at %llu len %llu to len %llu rounded to %llu", |
||||||
|
(unsigned long long)offset, |
||||||
|
@@ -432,6 +501,22 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd, |
||||||
|
(unsigned long long)limit_nbytes); |
||||||
|
nbytes = limit_nbytes; |
||||||
|
} |
||||||
|
+ |
||||||
|
+ /* |
||||||
|
+ * This shouldn't happen, the reduced+extended |
||||||
|
+ * nbytes value should never be larger than the |
||||||
|
+ * bcache block size. |
||||||
|
+ */ |
||||||
|
+ if (nbytes > orig_nbytes) { |
||||||
|
+ log_error("Invalid adjusted write at %llu len %llu adjusted %llu limit %llu extra %llu sector_size %llu", |
||||||
|
+ (unsigned long long)offset, |
||||||
|
+ (unsigned long long)orig_nbytes, |
||||||
|
+ (unsigned long long)nbytes, |
||||||
|
+ (unsigned long long)limit_nbytes, |
||||||
|
+ (unsigned long long)extra_nbytes, |
||||||
|
+ (unsigned long long)_last_byte_sector_size); |
||||||
|
+ return false; |
||||||
|
+ } |
||||||
|
} |
||||||
|
|
||||||
|
where = offset; |
||||||
|
-- |
||||||
|
1.8.3.1 |
||||||
|
|
@ -0,0 +1,15 @@ |
|||||||
|
WHATS_NEW | 4 ++++ |
||||||
|
1 file changed, 4 insertions(+) |
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW |
||||||
|
index cf2ec3e..d99f183 100644 |
||||||
|
--- a/WHATS_NEW |
||||||
|
+++ b/WHATS_NEW |
||||||
|
@@ -1,3 +1,7 @@ |
||||||
|
+Version 2.02.187 - |
||||||
|
+=================================== |
||||||
|
+ Prevent creating VGs with PVs with different logical block sizes. |
||||||
|
+ |
||||||
|
Version 2.02.186 - 27th August 2019 |
||||||
|
=================================== |
||||||
|
Improve internal removal of cached devices. |
@ -0,0 +1,25 @@ |
|||||||
|
From 165dfc7cf803e5e00d7239e2521582a9c9838178 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Marian Csontos <mcsontos@redhat.com> |
||||||
|
Date: Wed, 4 Mar 2020 13:22:10 +0100 |
||||||
|
Subject: [PATCH 3/4] bcache: Fix memory leak in error path |
||||||
|
|
||||||
|
(cherry picked from commit deaf304ee6d88cd47632a345b92b3949cd06d752) |
||||||
|
--- |
||||||
|
lib/device/bcache.c | 1 + |
||||||
|
1 file changed, 1 insertion(+) |
||||||
|
|
||||||
|
diff --git a/lib/device/bcache.c b/lib/device/bcache.c |
||||||
|
index 77d1543..a74b6b3 100644 |
||||||
|
--- a/lib/device/bcache.c |
||||||
|
+++ b/lib/device/bcache.c |
||||||
|
@@ -515,6 +515,7 @@ static bool _sync_issue(struct io_engine *ioe, enum dir d, int fd, |
||||||
|
(unsigned long long)limit_nbytes, |
||||||
|
(unsigned long long)extra_nbytes, |
||||||
|
(unsigned long long)_last_byte_sector_size); |
||||||
|
+ free(io); |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
-- |
||||||
|
1.8.3.1 |
||||||
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,17 @@ |
|||||||
|
libdm/libdm-common.c | 3 ++- |
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c |
||||||
|
index c300223..b06e678 100644 |
||||||
|
--- a/libdm/libdm-common.c |
||||||
|
+++ b/libdm/libdm-common.c |
||||||
|
@@ -2012,7 +2012,8 @@ static int _sysfs_get_kernel_name(uint32_t major, uint32_t minor, char *buf, siz |
||||||
|
log_sys_error("readlink", sysfs_path); |
||||||
|
else { |
||||||
|
log_sys_debug("readlink", sysfs_path); |
||||||
|
- return _sysfs_find_kernel_name(major, minor, buf, buf_size); |
||||||
|
+ r = _sysfs_find_kernel_name(major, minor, buf, buf_size); |
||||||
|
+ goto bad; |
||||||
|
} |
||||||
|
goto bad; |
||||||
|
} |
@ -0,0 +1,22 @@ |
|||||||
|
tools/dmsetup.c | 6 ++++-- |
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/tools/dmsetup.c b/tools/dmsetup.c |
||||||
|
index 60e0638..15a09c6 100644 |
||||||
|
--- a/tools/dmsetup.c |
||||||
|
+++ b/tools/dmsetup.c |
||||||
|
@@ -941,10 +941,12 @@ static int _display_info_cols(struct dm_task *dmt, struct dm_info *info) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
- /* group report with no groups? */ |
||||||
|
+ /* Group report with no groups is not an error */ |
||||||
|
if ((walk_flags == DM_STATS_WALK_GROUP) |
||||||
|
- && !dm_stats_get_nr_groups(obj.stats)) |
||||||
|
+ && !dm_stats_get_nr_groups(obj.stats)) { |
||||||
|
+ r = 1; |
||||||
|
goto out; |
||||||
|
+ } |
||||||
|
|
||||||
|
dm_stats_walk_init(obj.stats, walk_flags); |
||||||
|
dm_stats_walk_do(obj.stats) { |
@ -0,0 +1,92 @@ |
|||||||
|
WHATS_NEW | 1 + |
||||||
|
tools/lvconvert.c | 52 +++++++++++++++++++++++++++++++++++++++++++++++----- |
||||||
|
2 files changed, 48 insertions(+), 5 deletions(-) |
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW |
||||||
|
index 399864d..d1f4530 100644 |
||||||
|
--- a/WHATS_NEW |
||||||
|
+++ b/WHATS_NEW |
||||||
|
@@ -2,6 +2,7 @@ Version 2.02.187 - |
||||||
|
=================================== |
||||||
|
Prevent creating VGs with PVs with different logical block sizes. |
||||||
|
Pvmove runs in exlusively activating mode for exclusively active LVs. |
||||||
|
+ Enhance validation for thin and cache pool conversion and swapping. |
||||||
|
|
||||||
|
Version 2.02.186 - 27th August 2019 |
||||||
|
=================================== |
||||||
|
diff --git a/tools/lvconvert.c b/tools/lvconvert.c |
||||||
|
index e66f063..799e746 100644 |
||||||
|
--- a/tools/lvconvert.c |
||||||
|
+++ b/tools/lvconvert.c |
||||||
|
@@ -4309,24 +4309,66 @@ static int _lvconvert_to_pool_or_swap_metadata_single(struct cmd_context *cmd, |
||||||
|
struct dm_list *use_pvh = NULL; |
||||||
|
int to_thinpool = 0; |
||||||
|
int to_cachepool = 0; |
||||||
|
+ int lvt_enum = get_lvt_enum(lv); |
||||||
|
+ struct lv_type *lvtype; |
||||||
|
|
||||||
|
switch (cmd->command->command_enum) { |
||||||
|
case lvconvert_to_thinpool_or_swap_metadata_CMD: |
||||||
|
+ if (lv_is_cache(lv)) |
||||||
|
+ /* For cached LV check the cache origin LV type */ |
||||||
|
+ lvt_enum = get_lvt_enum(seg_lv(first_seg(lv), 0)); |
||||||
|
to_thinpool = 1; |
||||||
|
break; |
||||||
|
case lvconvert_to_cachepool_or_swap_metadata_CMD: |
||||||
|
+ if (lv_is_cache(lv)) |
||||||
|
+ goto_bad; /* Cache over cache is not supported */ |
||||||
|
to_cachepool = 1; |
||||||
|
break; |
||||||
|
default: |
||||||
|
- log_error(INTERNAL_ERROR "Invalid lvconvert pool command"); |
||||||
|
- return 0; |
||||||
|
- }; |
||||||
|
+ log_error(INTERNAL_ERROR "Invalid lvconvert pool command."); |
||||||
|
+ return ECMD_FAILED; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ switch (lvt_enum) { |
||||||
|
+ case thinpool_LVT: |
||||||
|
+ if (!to_thinpool) |
||||||
|
+ goto_bad; /* can't accept cache-pool */ |
||||||
|
+ break; /* swap thin-pool */ |
||||||
|
+ case cachepool_LVT: |
||||||
|
+ if (!to_cachepool) |
||||||
|
+ goto_bad; /* can't accept thin-pool */ |
||||||
|
+ break; /* swap cache-pool */ |
||||||
|
+ case linear_LVT: |
||||||
|
+ case raid_LVT: |
||||||
|
+ case striped_LVT: |
||||||
|
+ case zero_LVT: |
||||||
|
+ break; |
||||||
|
+ default: |
||||||
|
+bad: |
||||||
|
+ lvtype = get_lv_type(lvt_enum); |
||||||
|
+ log_error("LV %s with type %s cannot be used as a %s pool LV.", |
||||||
|
+ display_lvname(lv), lvtype ? lvtype->name : "unknown", |
||||||
|
+ to_thinpool ? "thin" : "cache"); |
||||||
|
+ return ECMD_FAILED; |
||||||
|
+ } |
||||||
|
|
||||||
|
if (lv_is_origin(lv)) { |
||||||
|
log_error("Cannot convert logical volume %s under snapshot.", |
||||||
|
display_lvname(lv)); |
||||||
|
- return 0; |
||||||
|
- }; |
||||||
|
+ return ECMD_FAILED; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ if (!lv_is_visible(lv)) { |
||||||
|
+ log_error("Can't convert internal LV %s.", |
||||||
|
+ display_lvname(lv)); |
||||||
|
+ return ECMD_FAILED; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ if (lv_is_locked(lv)) { |
||||||
|
+ log_error("Can't convert locked LV %s.", |
||||||
|
+ display_lvname(lv)); |
||||||
|
+ return ECMD_FAILED; |
||||||
|
+ } |
||||||
|
|
||||||
|
if (cmd->position_argc > 1) { |
||||||
|
/* First pos arg is required LV, remaining are optional PVs. */ |
@ -0,0 +1,16 @@ |
|||||||
|
lib/metadata/lv_manip.c | 2 ++ |
||||||
|
1 file changed, 2 insertions(+) |
||||||
|
|
||||||
|
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c |
||||||
|
index 9af90f9..6db8575 100644 |
||||||
|
--- a/lib/metadata/lv_manip.c |
||||||
|
+++ b/lib/metadata/lv_manip.c |
||||||
|
@@ -5446,6 +5446,8 @@ static struct logical_volume *_lvresize_setup_aux(struct logical_volume *lv, |
||||||
|
struct lv_segment *mseg = last_seg(lv); |
||||||
|
|
||||||
|
lp->alloc = lv->alloc; |
||||||
|
+ lp->percent = PERCENT_NONE; |
||||||
|
+ lp->segtype = mseg->segtype; |
||||||
|
lp->mirrors = seg_is_mirrored(mseg) ? lv_mirror_count(lv) : 0; |
||||||
|
lp->resizefs = 0; |
||||||
|
lp->stripes = lp->mirrors ? mseg->area_count / lp->mirrors : 0; |
@ -0,0 +1,51 @@ |
|||||||
|
WHATS_NEW | 1 + |
||||||
|
libdaemon/server/daemon-server.c | 11 +++++++++-- |
||||||
|
2 files changed, 10 insertions(+), 2 deletions(-) |
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW |
||||||
|
index 00b84f9..ac70074 100644 |
||||||
|
--- a/WHATS_NEW |
||||||
|
+++ b/WHATS_NEW |
||||||
|
@@ -1,5 +1,6 @@ |
||||||
|
Version 2.02.187 - |
||||||
|
=================================== |
||||||
|
+ Fix lvmetad shutdown and avoid lenghty timeouts when rebooting system. |
||||||
|
Prevent creating VGs with PVs with different logical block sizes. |
||||||
|
Pvmove runs in exlusively activating mode for exclusively active LVs. |
||||||
|
Activate thin-pool layered volume as 'read-only' device. |
||||||
|
diff --git a/libdaemon/server/daemon-server.c b/libdaemon/server/daemon-server.c |
||||||
|
index bc58f7b..62f403a 100644 |
||||||
|
--- a/libdaemon/server/daemon-server.c |
||||||
|
+++ b/libdaemon/server/daemon-server.c |
||||||
|
@@ -89,6 +89,13 @@ static int _is_idle(daemon_state s) |
||||||
|
|
||||||
|
static struct timespec *_get_timeout(daemon_state s) |
||||||
|
{ |
||||||
|
+ static struct timespec _tm = { 0 }; |
||||||
|
+ |
||||||
|
+ if (_shutdown_requested) { |
||||||
|
+ _tm.tv_sec = 1; |
||||||
|
+ return &_tm; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
return s.idle ? s.idle->ptimeout : NULL; |
||||||
|
} |
||||||
|
|
||||||
|
@@ -506,7 +513,7 @@ static int _handle_connect(daemon_state s) |
||||||
|
socklen_t sl = sizeof(sockaddr); |
||||||
|
|
||||||
|
client.socket_fd = accept(s.socket_fd, (struct sockaddr *) &sockaddr, &sl); |
||||||
|
- if (client.socket_fd < 0) { |
||||||
|
+ if (client.socket_fd < 0 || _shutdown_requested) { |
||||||
|
if (errno != EAGAIN || !_shutdown_requested) |
||||||
|
ERROR(&s, "Failed to accept connection: %s.", strerror(errno)); |
||||||
|
return 0; |
||||||
|
@@ -672,7 +679,7 @@ void daemon_start(daemon_state s) |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
- if (FD_ISSET(s.socket_fd, &in)) { |
||||||
|
+ if (!_shutdown_requested && FD_ISSET(s.socket_fd, &in)) { |
||||||
|
timeout_count = 0; |
||||||
|
_handle_connect(s); |
||||||
|
} |
@ -0,0 +1,16 @@ |
|||||||
|
lib/metadata/mirror.c | 2 +- |
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c |
||||||
|
index cd8ce1e..6cd88cb 100644 |
||||||
|
--- a/lib/metadata/mirror.c |
||||||
|
+++ b/lib/metadata/mirror.c |
||||||
|
@@ -790,7 +790,7 @@ static int _split_mirror_images(struct logical_volume *lv, |
||||||
|
|
||||||
|
act = lv_is_active(lv_lock_holder(lv)); |
||||||
|
|
||||||
|
- if (act && (!deactivate_lv(cmd, new_lv) || !_activate_lv_like_model(lv, new_lv))) { |
||||||
|
+ if (act && !_activate_lv_like_model(lv, new_lv)) { |
||||||
|
log_error("Failed to rename newly split LV in the kernel"); |
||||||
|
return 0; |
||||||
|
} |
@ -0,0 +1,283 @@ |
|||||||
|
lib/activate/activate.c | 40 +++++++++++++++++++++++++--------------- |
||||||
|
lib/activate/activate.h | 2 ++ |
||||||
|
lib/activate/dev_manager.c | 28 +++++++++++++++++++--------- |
||||||
|
lib/activate/dev_manager.h | 2 +- |
||||||
|
4 files changed, 47 insertions(+), 25 deletions(-) |
||||||
|
|
||||||
|
diff --git a/lib/activate/activate.c b/lib/activate/activate.c |
||||||
|
index aba5d14..c395d58 100644 |
||||||
|
--- a/lib/activate/activate.c |
||||||
|
+++ b/lib/activate/activate.c |
||||||
|
@@ -671,7 +671,7 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv, |
||||||
|
int use_layer, struct lvinfo *info, |
||||||
|
const struct lv_segment *seg, |
||||||
|
struct lv_seg_status *seg_status, |
||||||
|
- int with_open_count, int with_read_ahead) |
||||||
|
+ int with_open_count, int with_read_ahead, int with_name_check) |
||||||
|
{ |
||||||
|
struct dm_info dminfo; |
||||||
|
|
||||||
|
@@ -691,7 +691,7 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv, |
||||||
|
/* New thin-pool has no layer, but -tpool suffix needs to be queried */ |
||||||
|
if (!use_layer && lv_is_new_thin_pool(lv)) { |
||||||
|
/* Check if there isn't existing old thin pool mapping in the table */ |
||||||
|
- if (!dev_manager_info(cmd, lv, NULL, 0, 0, &dminfo, NULL, NULL)) |
||||||
|
+ if (!dev_manager_info(cmd, lv, NULL, 0, 0, 0, &dminfo, NULL, NULL)) |
||||||
|
return_0; |
||||||
|
if (!dminfo.exists) |
||||||
|
use_layer = 1; |
||||||
|
@@ -704,8 +704,9 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv, |
||||||
|
|
||||||
|
if (!dev_manager_info(cmd, lv, |
||||||
|
(use_layer) ? lv_layer(lv) : NULL, |
||||||
|
- with_open_count, with_read_ahead, |
||||||
|
- &dminfo, (info) ? &info->read_ahead : NULL, |
||||||
|
+ with_open_count, with_read_ahead, with_name_check, |
||||||
|
+ &dminfo, |
||||||
|
+ (info) ? &info->read_ahead : NULL, |
||||||
|
seg_status)) |
||||||
|
return_0; |
||||||
|
|
||||||
|
@@ -734,7 +735,7 @@ int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_la |
||||||
|
if (!activation()) |
||||||
|
return 0; |
||||||
|
|
||||||
|
- return _lv_info(cmd, lv, use_layer, info, NULL, NULL, with_open_count, with_read_ahead); |
||||||
|
+ return _lv_info(cmd, lv, use_layer, info, NULL, NULL, with_open_count, with_read_ahead, 0); |
||||||
|
} |
||||||
|
|
||||||
|
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer, |
||||||
|
@@ -752,6 +753,15 @@ int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer, |
||||||
|
return r; |
||||||
|
} |
||||||
|
|
||||||
|
+int lv_info_with_name_check(struct cmd_context *cmd, const struct logical_volume *lv, |
||||||
|
+ int use_layer, struct lvinfo *info) |
||||||
|
+{ |
||||||
|
+ if (!activation()) |
||||||
|
+ return 0; |
||||||
|
+ |
||||||
|
+ return _lv_info(cmd, lv, use_layer, info, NULL, NULL, 0, 0, 1); |
||||||
|
+} |
||||||
|
+ |
||||||
|
/* |
||||||
|
* Returns 1 if lv_with_info_and_seg_status info structure populated, |
||||||
|
* else 0 on failure or if device not active locally. |
||||||
|
@@ -779,16 +789,16 @@ int lv_info_with_seg_status(struct cmd_context *cmd, |
||||||
|
* STATUS is collected from cache LV */ |
||||||
|
if (!(lv_seg = get_only_segment_using_this_lv(lv))) |
||||||
|
return_0; |
||||||
|
- (void) _lv_info(cmd, lv_seg->lv, 1, NULL, lv_seg, &status->seg_status, 0, 0); |
||||||
|
+ (void) _lv_info(cmd, lv_seg->lv, 1, NULL, lv_seg, &status->seg_status, 0, 0, 0); |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
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) && |
||||||
|
+ if (_lv_info(cmd, lv, 1, &status->info, lv_seg, &status->seg_status, 0, 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) && |
||||||
|
+ if (!_lv_info(cmd, lv, 0, NULL, NULL, NULL, 0, 0, 0) && |
||||||
|
!status->seg_status.thin_pool->needs_check) |
||||||
|
status->info.exists = 0; /* So pool LV is not active */ |
||||||
|
} |
||||||
|
@@ -797,10 +807,10 @@ int lv_info_with_seg_status(struct cmd_context *cmd, |
||||||
|
|
||||||
|
if (lv_is_external_origin(lv)) { |
||||||
|
if (!_lv_info(cmd, lv, 0, &status->info, NULL, NULL, |
||||||
|
- with_open_count, with_read_ahead)) |
||||||
|
+ with_open_count, with_read_ahead, 0)) |
||||||
|
return_0; |
||||||
|
|
||||||
|
- (void) _lv_info(cmd, lv, 1, NULL, lv_seg, &status->seg_status, 0, 0); |
||||||
|
+ (void) _lv_info(cmd, lv, 1, NULL, lv_seg, &status->seg_status, 0, 0, 0); |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
@@ -813,13 +823,13 @@ int lv_info_with_seg_status(struct cmd_context *cmd, |
||||||
|
/* Show INFO for actual origin and grab status for merging origin */ |
||||||
|
if (!_lv_info(cmd, lv, 0, &status->info, lv_seg, |
||||||
|
lv_is_merging_origin(lv) ? &status->seg_status : NULL, |
||||||
|
- with_open_count, with_read_ahead)) |
||||||
|
+ with_open_count, with_read_ahead, 0)) |
||||||
|
return_0; |
||||||
|
|
||||||
|
if (status->info.exists && |
||||||
|
(status->seg_status.type != SEG_STATUS_SNAPSHOT)) /* Not merging */ |
||||||
|
/* Grab STATUS from layered -real */ |
||||||
|
- (void) _lv_info(cmd, lv, 1, NULL, lv_seg, &status->seg_status, 0, 0); |
||||||
|
+ (void) _lv_info(cmd, lv, 1, NULL, lv_seg, &status->seg_status, 0, 0, 0); |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
@@ -828,7 +838,7 @@ int lv_info_with_seg_status(struct cmd_context *cmd, |
||||||
|
olv = origin_from_cow(lv); |
||||||
|
|
||||||
|
if (!_lv_info(cmd, olv, 0, &status->info, first_seg(olv), &status->seg_status, |
||||||
|
- with_open_count, with_read_ahead)) |
||||||
|
+ with_open_count, with_read_ahead, 0)) |
||||||
|
return_0; |
||||||
|
|
||||||
|
if (status->seg_status.type == SEG_STATUS_SNAPSHOT || |
||||||
|
@@ -849,7 +859,7 @@ int lv_info_with_seg_status(struct cmd_context *cmd, |
||||||
|
} |
||||||
|
|
||||||
|
return _lv_info(cmd, lv, 0, &status->info, lv_seg, &status->seg_status, |
||||||
|
- with_open_count, with_read_ahead); |
||||||
|
+ with_open_count, with_read_ahead, 0); |
||||||
|
} |
||||||
|
|
||||||
|
#define OPEN_COUNT_CHECK_RETRIES 25 |
||||||
|
@@ -2834,7 +2844,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, |
||||||
|
laopts->noscan ? " noscan" : "", |
||||||
|
laopts->temporary ? " temporary" : ""); |
||||||
|
|
||||||
|
- if (!lv_info(cmd, lv, 0, &info, 0, 0)) |
||||||
|
+ if (!lv_info_with_name_check(cmd, lv, 0, &info)) |
||||||
|
goto_out; |
||||||
|
|
||||||
|
/* |
||||||
|
diff --git a/lib/activate/activate.h b/lib/activate/activate.h |
||||||
|
index 43d26d1..a938cb4 100644 |
||||||
|
--- a/lib/activate/activate.h |
||||||
|
+++ b/lib/activate/activate.h |
||||||
|
@@ -135,6 +135,8 @@ int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_la |
||||||
|
struct lvinfo *info, int with_open_count, int with_read_ahead); |
||||||
|
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); |
||||||
|
+int lv_info_with_name_check(struct cmd_context *cmd, const struct logical_volume *lv, |
||||||
|
+ int use_layer, struct lvinfo *info); |
||||||
|
|
||||||
|
/* |
||||||
|
* Returns 1 if lv_info_and_seg_status structure has been populated, |
||||||
|
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c |
||||||
|
index a5e026c..1ca97c1 100644 |
||||||
|
--- a/lib/activate/dev_manager.c |
||||||
|
+++ b/lib/activate/dev_manager.c |
||||||
|
@@ -239,6 +239,7 @@ static uint32_t _seg_len(const struct lv_segment *seg) |
||||||
|
static int _info_run(const char *dlid, struct dm_info *dminfo, |
||||||
|
uint32_t *read_ahead, |
||||||
|
struct lv_seg_status *seg_status, |
||||||
|
+ const char *name_check, |
||||||
|
int with_open_count, int with_read_ahead, |
||||||
|
uint32_t major, uint32_t minor) |
||||||
|
{ |
||||||
|
@@ -249,6 +250,7 @@ static int _info_run(const char *dlid, struct dm_info *dminfo, |
||||||
|
void *target = NULL; |
||||||
|
uint64_t target_start, target_length, start, length; |
||||||
|
char *target_name, *target_params; |
||||||
|
+ const char *dev_name; |
||||||
|
|
||||||
|
if (seg_status) { |
||||||
|
dmtask = DM_DEVICE_STATUS; |
||||||
|
@@ -262,6 +264,11 @@ static int _info_run(const char *dlid, struct dm_info *dminfo, |
||||||
|
with_open_count, with_flush, 0))) |
||||||
|
return_0; |
||||||
|
|
||||||
|
+ if (name_check && dminfo->exists && |
||||||
|
+ (dev_name = dm_task_get_name(dmt)) && |
||||||
|
+ (strcmp(name_check, dev_name) != 0)) |
||||||
|
+ dminfo->exists = 0; /* mismatching name -> device does not exist */ |
||||||
|
+ |
||||||
|
if (with_read_ahead && dminfo->exists) { |
||||||
|
if (!dm_task_get_read_ahead(dmt, read_ahead)) |
||||||
|
goto_out; |
||||||
|
@@ -777,18 +784,19 @@ static int _original_uuid_format_check_required(struct cmd_context *cmd) |
||||||
|
|
||||||
|
static int _info(struct cmd_context *cmd, |
||||||
|
const char *name, const char *dlid, |
||||||
|
- int with_open_count, int with_read_ahead, |
||||||
|
+ int with_open_count, int with_read_ahead, int with_name_check, |
||||||
|
struct dm_info *dminfo, uint32_t *read_ahead, |
||||||
|
struct lv_seg_status *seg_status) |
||||||
|
{ |
||||||
|
char old_style_dlid[sizeof(UUID_PREFIX) + 2 * ID_LEN]; |
||||||
|
const char *suffix, *suffix_position; |
||||||
|
+ const char *name_check = (with_name_check) ? name : NULL; |
||||||
|
unsigned i = 0; |
||||||
|
|
||||||
|
log_debug_activation("Getting device info for %s [%s].", name, dlid); |
||||||
|
|
||||||
|
/* Check for dlid */ |
||||||
|
- if (!_info_run(dlid, dminfo, read_ahead, seg_status, |
||||||
|
+ if (!_info_run(dlid, dminfo, read_ahead, seg_status, name_check, |
||||||
|
with_open_count, with_read_ahead, 0, 0)) |
||||||
|
return_0; |
||||||
|
|
||||||
|
@@ -804,7 +812,8 @@ static int _info(struct cmd_context *cmd, |
||||||
|
(void) strncpy(old_style_dlid, dlid, sizeof(old_style_dlid)); |
||||||
|
old_style_dlid[sizeof(old_style_dlid) - 1] = '\0'; |
||||||
|
if (!_info_run(old_style_dlid, dminfo, read_ahead, seg_status, |
||||||
|
- with_open_count, with_read_ahead, 0, 0)) |
||||||
|
+ name_check, with_open_count, with_read_ahead, |
||||||
|
+ 0, 0)) |
||||||
|
return_0; |
||||||
|
if (dminfo->exists) |
||||||
|
return 1; |
||||||
|
@@ -817,7 +826,7 @@ static int _info(struct cmd_context *cmd, |
||||||
|
|
||||||
|
/* Check for dlid before UUID_PREFIX was added */ |
||||||
|
if (!_info_run(dlid + sizeof(UUID_PREFIX) - 1, dminfo, read_ahead, seg_status, |
||||||
|
- with_open_count, with_read_ahead, 0, 0)) |
||||||
|
+ name_check, with_open_count, with_read_ahead, 0, 0)) |
||||||
|
return_0; |
||||||
|
|
||||||
|
return 1; |
||||||
|
@@ -825,12 +834,12 @@ static int _info(struct cmd_context *cmd, |
||||||
|
|
||||||
|
static int _info_by_dev(uint32_t major, uint32_t minor, struct dm_info *info) |
||||||
|
{ |
||||||
|
- return _info_run(NULL, info, NULL, 0, 0, 0, major, minor); |
||||||
|
+ return _info_run(NULL, info, NULL, NULL, NULL, 0, 0, major, minor); |
||||||
|
} |
||||||
|
|
||||||
|
int dev_manager_info(struct cmd_context *cmd, |
||||||
|
const struct logical_volume *lv, const char *layer, |
||||||
|
- int with_open_count, int with_read_ahead, |
||||||
|
+ int with_open_count, int with_read_ahead, int with_name_check, |
||||||
|
struct dm_info *dminfo, uint32_t *read_ahead, |
||||||
|
struct lv_seg_status *seg_status) |
||||||
|
{ |
||||||
|
@@ -843,7 +852,8 @@ int dev_manager_info(struct cmd_context *cmd, |
||||||
|
if (!(dlid = build_dm_uuid(cmd->mem, lv, layer))) |
||||||
|
goto_out; |
||||||
|
|
||||||
|
- if (!(r = _info(cmd, name, dlid, with_open_count, with_read_ahead, |
||||||
|
+ if (!(r = _info(cmd, name, dlid, |
||||||
|
+ with_open_count, with_read_ahead, with_name_check, |
||||||
|
dminfo, read_ahead, seg_status))) |
||||||
|
stack; |
||||||
|
out: |
||||||
|
@@ -1953,7 +1963,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, |
||||||
|
if (!(dlid = build_dm_uuid(dm->track_pending_delete ? dm->cmd->pending_delete_mem : dm->mem, lv, layer))) |
||||||
|
return_0; |
||||||
|
|
||||||
|
- if (!_info(dm->cmd, name, dlid, 1, 0, &info, NULL, NULL)) |
||||||
|
+ if (!_info(dm->cmd, name, dlid, 1, 0, 0, &info, NULL, NULL)) |
||||||
|
return_0; |
||||||
|
|
||||||
|
/* |
||||||
|
@@ -2479,7 +2489,7 @@ static char *_add_error_or_zero_device(struct dev_manager *dm, struct dm_tree *d |
||||||
|
seg->lv->name, errid))) |
||||||
|
return_NULL; |
||||||
|
|
||||||
|
- if (!_info(dm->cmd, name, dlid, 1, 0, &info, NULL, NULL)) |
||||||
|
+ if (!_info(dm->cmd, name, dlid, 1, 0, 0, &info, NULL, NULL)) |
||||||
|
return_NULL; |
||||||
|
|
||||||
|
if (!info.exists) { |
||||||
|
diff --git a/lib/activate/dev_manager.h b/lib/activate/dev_manager.h |
||||||
|
index 5be417b..20b6a26 100644 |
||||||
|
--- a/lib/activate/dev_manager.h |
||||||
|
+++ b/lib/activate/dev_manager.h |
||||||
|
@@ -47,7 +47,7 @@ void dev_manager_exit(void); |
||||||
|
*/ |
||||||
|
int dev_manager_info(struct cmd_context *cmd, const struct logical_volume *lv, |
||||||
|
const char *layer, |
||||||
|
- int with_open_count, int with_read_ahead, |
||||||
|
+ int with_open_count, int with_read_ahead, int with_name_check, |
||||||
|
struct dm_info *dminfo, uint32_t *read_ahead, |
||||||
|
struct lv_seg_status *seg_status); |
||||||
|
|
@ -0,0 +1,30 @@ |
|||||||
|
WHATS_NEW | 1 + |
||||||
|
tools/pvmove.c | 3 ++- |
||||||
|
2 files changed, 3 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW |
||||||
|
index d99f183..399864d 100644 |
||||||
|
--- a/WHATS_NEW |
||||||
|
+++ b/WHATS_NEW |
||||||
|
@@ -1,6 +1,7 @@ |
||||||
|
Version 2.02.187 - |
||||||
|
=================================== |
||||||
|
Prevent creating VGs with PVs with different logical block sizes. |
||||||
|
+ Pvmove runs in exlusively activating mode for exclusively active LVs. |
||||||
|
|
||||||
|
Version 2.02.186 - 27th August 2019 |
||||||
|
=================================== |
||||||
|
diff --git a/tools/pvmove.c b/tools/pvmove.c |
||||||
|
index 754bd58..3a447c4 100644 |
||||||
|
--- a/tools/pvmove.c |
||||||
|
+++ b/tools/pvmove.c |
||||||
|
@@ -674,7 +674,8 @@ static int _pvmove_setup_single(struct cmd_context *cmd, |
||||||
|
dm_list_iterate_items(lvl, lvs_changed) { |
||||||
|
lvh = lv_lock_holder(lvl->lv); |
||||||
|
/* Exclusive LV decides whether pvmove must be also exclusive */ |
||||||
|
- if (lv_is_origin(lvh) || seg_only_exclusive(first_seg(lvh))) |
||||||
|
+ if (lv_is_origin(lvh) || seg_only_exclusive(first_seg(lvh)) || |
||||||
|
+ lv_is_active_exclusive(lvh)) |
||||||
|
exclusive = 1; |
||||||
|
} |
||||||
|
|
@ -0,0 +1,17 @@ |
|||||||
|
tools/pvmove.c | 3 ++- |
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/tools/pvmove.c b/tools/pvmove.c |
||||||
|
index 3a447c4..cecff00 100644 |
||||||
|
--- a/tools/pvmove.c |
||||||
|
+++ b/tools/pvmove.c |
||||||
|
@@ -397,7 +397,8 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd, |
||||||
|
/* Presence of exclusive LV decides whether pvmove must be also exclusive */ |
||||||
|
if (!seg_only_exclusive(seg)) { |
||||||
|
holder = lv_lock_holder(lv); |
||||||
|
- if (seg_only_exclusive(first_seg(holder)) || lv_is_origin(holder) || lv_is_cow(holder)) |
||||||
|
+ if (seg_only_exclusive(first_seg(holder)) || lv_is_origin(holder) || |
||||||
|
+ lv_is_cow(holder) || lv_is_active_exclusive(holder)) |
||||||
|
needs_exclusive = 1; |
||||||
|
} else |
||||||
|
needs_exclusive = 1; |
@ -0,0 +1,16 @@ |
|||||||
|
lib/metadata/metadata.c | 2 ++ |
||||||
|
1 file changed, 2 insertions(+) |
||||||
|
|
||||||
|
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c |
||||||
|
index 123f7f5..d448fd9 100644 |
||||||
|
--- a/lib/metadata/metadata.c |
||||||
|
+++ b/lib/metadata/metadata.c |
||||||
|
@@ -3435,6 +3435,8 @@ static struct volume_group *_vg_read_orphans(struct cmd_context *cmd, |
||||||
|
|
||||||
|
dm_list_init(&head.list); |
||||||
|
|
||||||
|
+ *consistent = 1; |
||||||
|
+ |
||||||
|
if (!(vginfo = lvmcache_vginfo_from_vgname(orphan_vgname, NULL))) |
||||||
|
return_NULL; |
||||||
|
|
@ -0,0 +1,328 @@ |
|||||||
|
From 8aac4049c270ae8beb741a2cd80084810945a718 Mon Sep 17 00:00:00 2001 |
||||||
|
From: David Teigland <teigland@redhat.com> |
||||||
|
Date: Tue, 3 Sep 2019 15:14:08 -0500 |
||||||
|
Subject: [PATCH 1/4] pvscan: fix activation of incomplete VGs |
||||||
|
|
||||||
|
For a long time there has been a bug in the activation |
||||||
|
done by the initial pvscan (which scans all devs to |
||||||
|
initialize the lvmetad cache.) It was attempting to |
||||||
|
activate all VGs, even those that were not complete. |
||||||
|
|
||||||
|
lvmetad tells pvscan when a VG is complete, and pvscan |
||||||
|
needs to use this information to decide which VGs to |
||||||
|
activate. |
||||||
|
|
||||||
|
When there are problems that prevent lvmetad from being |
||||||
|
used (e.g. lvmetad is disabled or not running), pvscan |
||||||
|
activation cannot use lvmetad to determine when a VG |
||||||
|
is complete, so it now checks if devices are present |
||||||
|
for all PVs in the VG before activating. |
||||||
|
|
||||||
|
(The recent commit "pvscan: avoid redundant activation" |
||||||
|
could make this bug more apparent because redundant |
||||||
|
activations can cover up the effect of activating an |
||||||
|
incomplete VG and missing some LV activations.) |
||||||
|
|
||||||
|
(cherry picked from commit 6b12930860a993624d6325aec2e9c561f4412aa9) |
||||||
|
--- |
||||||
|
lib/cache/lvmetad.c | 15 ++++++++---- |
||||||
|
lib/cache/lvmetad.h | 2 +- |
||||||
|
tools/lvmcmdline.c | 2 +- |
||||||
|
tools/lvscan.c | 2 +- |
||||||
|
tools/pvscan.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++----- |
||||||
|
tools/vgcfgrestore.c | 2 +- |
||||||
|
tools/vgimport.c | 2 +- |
||||||
|
tools/vgimportclone.c | 2 +- |
||||||
|
tools/vgscan.c | 2 +- |
||||||
|
9 files changed, 77 insertions(+), 17 deletions(-) |
||||||
|
|
||||||
|
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c |
||||||
|
index 1eda567..e659711 100644 |
||||||
|
--- a/lib/cache/lvmetad.c |
||||||
|
+++ b/lib/cache/lvmetad.c |
||||||
|
@@ -1704,6 +1704,13 @@ int lvmetad_pv_found(struct cmd_context *cmd, const struct id *pvid, struct devi |
||||||
|
changed = daemon_reply_int(reply, "changed", 0); |
||||||
|
} |
||||||
|
|
||||||
|
+ if (vg && vg->system_id && vg->system_id[0] && |
||||||
|
+ cmd->system_id && cmd->system_id[0] && |
||||||
|
+ strcmp(vg->system_id, cmd->system_id)) { |
||||||
|
+ log_debug_lvmetad("Ignore foreign VG %s on %s", vg->name , dev_name(dev)); |
||||||
|
+ goto out; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
/* |
||||||
|
* If lvmetad now sees all PVs in the VG, it returned the |
||||||
|
* "complete" status string. Add this VG name to the list |
||||||
|
@@ -1734,7 +1741,7 @@ int lvmetad_pv_found(struct cmd_context *cmd, const struct id *pvid, struct devi |
||||||
|
log_error("str_list_add failed"); |
||||||
|
} |
||||||
|
} |
||||||
|
- |
||||||
|
+out: |
||||||
|
daemon_reply_destroy(reply); |
||||||
|
|
||||||
|
return result; |
||||||
|
@@ -2347,7 +2354,7 @@ bad: |
||||||
|
* generally revert disk scanning and not use lvmetad. |
||||||
|
*/ |
||||||
|
|
||||||
|
-int lvmetad_pvscan_all_devs(struct cmd_context *cmd, int do_wait) |
||||||
|
+int lvmetad_pvscan_all_devs(struct cmd_context *cmd, int do_wait, struct dm_list *found_vgnames) |
||||||
|
{ |
||||||
|
struct device_list *devl, *devl2; |
||||||
|
struct dm_list scan_devs; |
||||||
|
@@ -2429,7 +2436,7 @@ int lvmetad_pvscan_all_devs(struct cmd_context *cmd, int do_wait) |
||||||
|
|
||||||
|
dm_list_del(&devl->list); |
||||||
|
|
||||||
|
- ret = lvmetad_pvscan_single(cmd, devl->dev, NULL, NULL); |
||||||
|
+ ret = lvmetad_pvscan_single(cmd, devl->dev, found_vgnames, NULL); |
||||||
|
|
||||||
|
label_scan_invalidate(devl->dev); |
||||||
|
|
||||||
|
@@ -2774,7 +2781,7 @@ void lvmetad_validate_global_cache(struct cmd_context *cmd, int force) |
||||||
|
* we rescanned for the token, and the time we acquired the global |
||||||
|
* lock.) |
||||||
|
*/ |
||||||
|
- if (!lvmetad_pvscan_all_devs(cmd, 1)) { |
||||||
|
+ if (!lvmetad_pvscan_all_devs(cmd, 1, NULL)) { |
||||||
|
log_warn("WARNING: Not using lvmetad because cache update failed."); |
||||||
|
lvmetad_make_unused(cmd); |
||||||
|
return; |
||||||
|
diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h |
||||||
|
index 73c2645..55ce16a 100644 |
||||||
|
--- a/lib/cache/lvmetad.h |
||||||
|
+++ b/lib/cache/lvmetad.h |
||||||
|
@@ -151,7 +151,7 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev, |
||||||
|
struct dm_list *found_vgnames, |
||||||
|
struct dm_list *changed_vgnames); |
||||||
|
|
||||||
|
-int lvmetad_pvscan_all_devs(struct cmd_context *cmd, int do_wait); |
||||||
|
+int lvmetad_pvscan_all_devs(struct cmd_context *cmd, int do_wait, struct dm_list *found_vgnames); |
||||||
|
|
||||||
|
int lvmetad_vg_clear_outdated_pvs(struct volume_group *vg); |
||||||
|
void lvmetad_validate_global_cache(struct cmd_context *cmd, int force); |
||||||
|
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c |
||||||
|
index f82827d..75a0401 100644 |
||||||
|
--- a/tools/lvmcmdline.c |
||||||
|
+++ b/tools/lvmcmdline.c |
||||||
|
@@ -2991,7 +2991,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv) |
||||||
|
*/ |
||||||
|
if (lvmetad_used() && !_cmd_no_lvmetad_autoscan(cmd)) { |
||||||
|
if (cmd->include_foreign_vgs || !lvmetad_token_matches(cmd)) { |
||||||
|
- if (lvmetad_used() && !lvmetad_pvscan_all_devs(cmd, cmd->include_foreign_vgs ? 1 : 0)) { |
||||||
|
+ if (lvmetad_used() && !lvmetad_pvscan_all_devs(cmd, cmd->include_foreign_vgs ? 1 : 0, NULL)) { |
||||||
|
log_warn("WARNING: Not using lvmetad because cache update failed."); |
||||||
|
lvmetad_make_unused(cmd); |
||||||
|
} |
||||||
|
diff --git a/tools/lvscan.c b/tools/lvscan.c |
||||||
|
index c38208a..34e9f31 100644 |
||||||
|
--- a/tools/lvscan.c |
||||||
|
+++ b/tools/lvscan.c |
||||||
|
@@ -103,7 +103,7 @@ int lvscan(struct cmd_context *cmd, int argc, char **argv) |
||||||
|
|
||||||
|
/* Needed because this command has NO_LVMETAD_AUTOSCAN. */ |
||||||
|
if (lvmetad_used() && (!lvmetad_token_matches(cmd) || lvmetad_is_disabled(cmd, &reason))) { |
||||||
|
- if (lvmetad_used() && !lvmetad_pvscan_all_devs(cmd, 0)) { |
||||||
|
+ if (lvmetad_used() && !lvmetad_pvscan_all_devs(cmd, 0, NULL)) { |
||||||
|
log_warn("WARNING: Not using lvmetad because cache update failed."); |
||||||
|
lvmetad_make_unused(cmd); |
||||||
|
} |
||||||
|
diff --git a/tools/pvscan.c b/tools/pvscan.c |
||||||
|
index e5afe0c..9e76f52 100644 |
||||||
|
--- a/tools/pvscan.c |
||||||
|
+++ b/tools/pvscan.c |
||||||
|
@@ -38,6 +38,7 @@ struct pvscan_params { |
||||||
|
|
||||||
|
struct pvscan_aa_params { |
||||||
|
int refresh_all; |
||||||
|
+ int all_vgs; |
||||||
|
unsigned int activate_errors; |
||||||
|
struct dm_list changed_vgnames; |
||||||
|
}; |
||||||
|
@@ -223,6 +224,28 @@ void online_vg_file_remove(const char *vgname) |
||||||
|
unlink(path); |
||||||
|
} |
||||||
|
|
||||||
|
+static void _online_files_remove(const char *dirpath) |
||||||
|
+{ |
||||||
|
+ char path[PATH_MAX]; |
||||||
|
+ DIR *dir; |
||||||
|
+ struct dirent *de; |
||||||
|
+ |
||||||
|
+ if (!(dir = opendir(dirpath))) |
||||||
|
+ return; |
||||||
|
+ |
||||||
|
+ while ((de = readdir(dir))) { |
||||||
|
+ if (de->d_name[0] == '.') |
||||||
|
+ continue; |
||||||
|
+ |
||||||
|
+ memset(path, 0, sizeof(path)); |
||||||
|
+ snprintf(path, sizeof(path), "%s/%s", dirpath, de->d_name); |
||||||
|
+ if (unlink(path)) |
||||||
|
+ log_sys_debug("unlink", path); |
||||||
|
+ } |
||||||
|
+ if (closedir(dir)) |
||||||
|
+ log_sys_debug("closedir", dirpath); |
||||||
|
+} |
||||||
|
+ |
||||||
|
/* |
||||||
|
* pvscan --cache does not perform any lvmlockd locking, and |
||||||
|
* pvscan --cache -aay skips autoactivation in lockd VGs. |
||||||
|
@@ -271,6 +294,8 @@ static int _pvscan_autoactivate_single(struct cmd_context *cmd, const char *vg_n |
||||||
|
struct volume_group *vg, struct processing_handle *handle) |
||||||
|
{ |
||||||
|
struct pvscan_aa_params *pp = (struct pvscan_aa_params *)handle->custom_handle; |
||||||
|
+ struct pv_list *pvl; |
||||||
|
+ int incomplete = 0; |
||||||
|
|
||||||
|
if (vg_is_clustered(vg)) |
||||||
|
return ECMD_PROCESSED; |
||||||
|
@@ -281,6 +306,24 @@ static int _pvscan_autoactivate_single(struct cmd_context *cmd, const char *vg_n |
||||||
|
if (is_lockd_type(vg->lock_type)) |
||||||
|
return ECMD_PROCESSED; |
||||||
|
|
||||||
|
+ /* |
||||||
|
+ * This all_vgs case only happens in fallback cases when there's some |
||||||
|
+ * problem preventing the use of lvmetad. When lvmetad can be properly |
||||||
|
+ * used, the found_vgnames list should have the names of complete VGs |
||||||
|
+ * that should be activated. |
||||||
|
+ */ |
||||||
|
+ if (pp->all_vgs) { |
||||||
|
+ dm_list_iterate_items(pvl, &vg->pvs) { |
||||||
|
+ if (!pvl->pv->dev) |
||||||
|
+ incomplete++; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ if (incomplete) { |
||||||
|
+ log_print("pvscan[%d] VG %s incomplete (need %d).", getpid(), vg->name, incomplete); |
||||||
|
+ return ECMD_PROCESSED; |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
+ |
||||||
|
log_debug("pvscan autoactivating VG %s.", vg_name); |
||||||
|
|
||||||
|
#if 0 |
||||||
|
@@ -377,6 +420,7 @@ static int _pvscan_autoactivate(struct cmd_context *cmd, struct pvscan_aa_params |
||||||
|
if (all_vgs) { |
||||||
|
cmd->cname->flags |= ALL_VGS_IS_DEFAULT; |
||||||
|
pp->refresh_all = 1; |
||||||
|
+ pp->all_vgs = 1; |
||||||
|
} |
||||||
|
|
||||||
|
ret = process_each_vg(cmd, 0, NULL, NULL, vgnames, 0, 0, handle, _pvscan_autoactivate_single); |
||||||
|
@@ -463,17 +507,23 @@ static int _pvscan_cache(struct cmd_context *cmd, int argc, char **argv) |
||||||
|
* Scan all devices when no args are given. |
||||||
|
*/ |
||||||
|
if (!argc && !devno_args) { |
||||||
|
+ _online_files_remove(_vgs_online_dir); |
||||||
|
+ |
||||||
|
log_verbose("Scanning all devices."); |
||||||
|
|
||||||
|
- if (!lvmetad_pvscan_all_devs(cmd, 1)) { |
||||||
|
+ if (!lvmetad_pvscan_all_devs(cmd, 1, &found_vgnames)) { |
||||||
|
log_warn("WARNING: Not using lvmetad because cache update failed."); |
||||||
|
lvmetad_make_unused(cmd); |
||||||
|
+ all_vgs = 1; |
||||||
|
} |
||||||
|
if (lvmetad_used() && lvmetad_is_disabled(cmd, &reason)) { |
||||||
|
log_warn("WARNING: Not using lvmetad because %s.", reason); |
||||||
|
lvmetad_make_unused(cmd); |
||||||
|
+ all_vgs = 1; |
||||||
|
} |
||||||
|
- all_vgs = 1; |
||||||
|
+ |
||||||
|
+ if (!all_vgs && do_activate) |
||||||
|
+ log_print("pvscan[%d] activating all complete VGs (no args)", getpid()); |
||||||
|
goto activate; |
||||||
|
} |
||||||
|
|
||||||
|
@@ -485,7 +535,7 @@ static int _pvscan_cache(struct cmd_context *cmd, int argc, char **argv) |
||||||
|
* never scan any devices other than those specified. |
||||||
|
*/ |
||||||
|
if (!lvmetad_token_matches(cmd)) { |
||||||
|
- if (lvmetad_used() && !lvmetad_pvscan_all_devs(cmd, 0)) { |
||||||
|
+ if (lvmetad_used() && !lvmetad_pvscan_all_devs(cmd, 0, &found_vgnames)) { |
||||||
|
log_warn("WARNING: Not updating lvmetad because cache update failed."); |
||||||
|
ret = ECMD_FAILED; |
||||||
|
goto out; |
||||||
|
@@ -493,9 +543,12 @@ static int _pvscan_cache(struct cmd_context *cmd, int argc, char **argv) |
||||||
|
if (lvmetad_used() && lvmetad_is_disabled(cmd, &reason)) { |
||||||
|
log_warn("WARNING: Not using lvmetad because %s.", reason); |
||||||
|
lvmetad_make_unused(cmd); |
||||||
|
+ all_vgs = 1; |
||||||
|
+ log_print("pvscan[%d] activating all directly (lvmetad disabled from scan) %s", getpid(), dev_arg ?: ""); |
||||||
|
} |
||||||
|
- log_print("pvscan[%d] activating all directly (lvmetad token) %s", getpid(), dev_arg ?: ""); |
||||||
|
- all_vgs = 1; |
||||||
|
+ |
||||||
|
+ if (!all_vgs) |
||||||
|
+ log_print("pvscan[%d] activating all complete VGs for init", getpid()); |
||||||
|
goto activate; |
||||||
|
} |
||||||
|
|
||||||
|
@@ -808,7 +861,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv) |
||||||
|
|
||||||
|
/* Needed because this command has NO_LVMETAD_AUTOSCAN. */ |
||||||
|
if (lvmetad_used() && (!lvmetad_token_matches(cmd) || lvmetad_is_disabled(cmd, &reason))) { |
||||||
|
- if (lvmetad_used() && !lvmetad_pvscan_all_devs(cmd, 0)) { |
||||||
|
+ if (lvmetad_used() && !lvmetad_pvscan_all_devs(cmd, 0, NULL)) { |
||||||
|
log_warn("WARNING: Not using lvmetad because cache update failed."); |
||||||
|
lvmetad_make_unused(cmd); |
||||||
|
} |
||||||
|
diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c |
||||||
|
index 48a2fa4..e7f9848 100644 |
||||||
|
--- a/tools/vgcfgrestore.c |
||||||
|
+++ b/tools/vgcfgrestore.c |
||||||
|
@@ -177,7 +177,7 @@ rescan: |
||||||
|
} |
||||||
|
if (!refresh_filters(cmd)) |
||||||
|
stack; |
||||||
|
- if (!lvmetad_pvscan_all_devs(cmd, 1)) { |
||||||
|
+ if (!lvmetad_pvscan_all_devs(cmd, 1, NULL)) { |
||||||
|
log_warn("WARNING: Failed to scan devices."); |
||||||
|
log_warn("WARNING: Update lvmetad with pvscan --cache."); |
||||||
|
goto out; |
||||||
|
diff --git a/tools/vgimport.c b/tools/vgimport.c |
||||||
|
index ea50198..d4455ec 100644 |
||||||
|
--- a/tools/vgimport.c |
||||||
|
+++ b/tools/vgimport.c |
||||||
|
@@ -96,7 +96,7 @@ int vgimport(struct cmd_context *cmd, int argc, char **argv) |
||||||
|
* import it. |
||||||
|
*/ |
||||||
|
if (lvmetad_used()) { |
||||||
|
- if (!lvmetad_pvscan_all_devs(cmd, 1)) { |
||||||
|
+ if (!lvmetad_pvscan_all_devs(cmd, 1, NULL)) { |
||||||
|
log_warn("WARNING: Not using lvmetad because cache update failed."); |
||||||
|
lvmetad_make_unused(cmd); |
||||||
|
} |
||||||
|
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c |
||||||
|
index c4c5d4c..ac3766b 100644 |
||||||
|
--- a/tools/vgimportclone.c |
||||||
|
+++ b/tools/vgimportclone.c |
||||||
|
@@ -377,7 +377,7 @@ out: |
||||||
|
if (!refresh_filters(cmd)) |
||||||
|
stack; |
||||||
|
|
||||||
|
- if (!lvmetad_pvscan_all_devs(cmd, 1)) { |
||||||
|
+ if (!lvmetad_pvscan_all_devs(cmd, 1, NULL)) { |
||||||
|
log_warn("WARNING: Failed to scan devices."); |
||||||
|
log_warn("WARNING: Update lvmetad with pvscan --cache."); |
||||||
|
} |
||||||
|
diff --git a/tools/vgscan.c b/tools/vgscan.c |
||||||
|
index 1ec9083..7a63996 100644 |
||||||
|
--- a/tools/vgscan.c |
||||||
|
+++ b/tools/vgscan.c |
||||||
|
@@ -101,7 +101,7 @@ int vgscan(struct cmd_context *cmd, int argc, char **argv) |
||||||
|
log_verbose("Ignoring vgscan --cache command because lvmetad is not in use."); |
||||||
|
|
||||||
|
if (lvmetad_used() && (arg_is_set(cmd, cache_long_ARG) || !lvmetad_token_matches(cmd) || lvmetad_is_disabled(cmd, &reason))) { |
||||||
|
- if (lvmetad_used() && !lvmetad_pvscan_all_devs(cmd, arg_is_set(cmd, cache_long_ARG))) { |
||||||
|
+ if (lvmetad_used() && !lvmetad_pvscan_all_devs(cmd, arg_is_set(cmd, cache_long_ARG), NULL)) { |
||||||
|
log_warn("WARNING: Not using lvmetad because cache update failed."); |
||||||
|
lvmetad_make_unused(cmd); |
||||||
|
} |
||||||
|
-- |
||||||
|
1.8.3.1 |
||||||
|
|
@ -0,0 +1,51 @@ |
|||||||
|
From 56474336821cf703073bd0d82f9428697b85ec29 Mon Sep 17 00:00:00 2001 |
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com> |
||||||
|
Date: Fri, 7 Feb 2020 15:14:05 +0100 |
||||||
|
Subject: [PATCH] raid: better place for blocking reshapes |
||||||
|
|
||||||
|
Still the place can be better to block only particular reshape |
||||||
|
operations which ATM cause kernel problems. |
||||||
|
|
||||||
|
We check if the new number of images is higher - and prevent to take |
||||||
|
conversion if the volume is in use (i.e. thin-pool's data LV). |
||||||
|
|
||||||
|
(cherry picked from commit 96985b1373d58b411a80c2985f348466e78cbe6e) |
||||||
|
(cherry picked from commit 253d10f840682f85dad0e4c29f55ff50f94792fa) |
||||||
|
--- |
||||||
|
lib/metadata/raid_manip.c | 13 +++++++------ |
||||||
|
1 file changed, 7 insertions(+), 6 deletions(-) |
||||||
|
|
||||||
|
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c |
||||||
|
index 7481ebf..eae0a8d 100644 |
||||||
|
--- a/lib/metadata/raid_manip.c |
||||||
|
+++ b/lib/metadata/raid_manip.c |
||||||
|
@@ -2299,6 +2299,13 @@ static int _raid_reshape(struct logical_volume *lv, |
||||||
|
if ((new_image_count = new_stripes + seg->segtype->parity_devs) < 2) |
||||||
|
return_0; |
||||||
|
|
||||||
|
+ /* FIXME Can't reshape volume in use - aka not toplevel devices */ |
||||||
|
+ if (old_image_count < new_image_count && |
||||||
|
+ !dm_list_empty(&seg->lv->segs_using_this_lv)) { |
||||||
|
+ log_error("Unable to convert stacked volume %s.", display_lvname(seg->lv)); |
||||||
|
+ return 0; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
if (!_check_max_raid_devices(new_image_count)) |
||||||
|
return_0; |
||||||
|
|
||||||
|
@@ -6218,12 +6225,6 @@ static int _set_convenient_raid145610_segtype_to(const struct lv_segment *seg_fr |
||||||
|
if (!(*segtype = get_segtype_from_flag(cmd, seg_flag))) |
||||||
|
return_0; |
||||||
|
|
||||||
|
- /* FIXME Can't reshape volume in use - aka not toplevel devices */ |
||||||
|
- if (!dm_list_empty(&seg_from->lv->segs_using_this_lv)) { |
||||||
|
- log_error("Can't reshape stacked volume %s.", display_lvname(seg_from->lv)); |
||||||
|
- return 0; |
||||||
|
- } |
||||||
|
- |
||||||
|
if (segtype_sav != *segtype) { |
||||||
|
log_warn("Replaced LV type %s%s with possible type %s.", |
||||||
|
segtype_sav->name, _get_segtype_alias_str(seg_from->lv, segtype_sav), |
||||||
|
-- |
||||||
|
1.8.3.1 |
||||||
|
|
@ -0,0 +1,32 @@ |
|||||||
|
WHATS_NEW | 1 + |
||||||
|
lib/metadata/raid_manip.c | 6 ++++++ |
||||||
|
2 files changed, 7 insertions(+) |
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW |
||||||
|
index ac70074..01d0bc6 100644 |
||||||
|
--- a/WHATS_NEW |
||||||
|
+++ b/WHATS_NEW |
||||||
|
@@ -1,5 +1,6 @@ |
||||||
|
Version 2.02.187 - |
||||||
|
=================================== |
||||||
|
+ Prevent raid reshaping of stacked volumes. |
||||||
|
Fix lvmetad shutdown and avoid lenghty timeouts when rebooting system. |
||||||
|
Prevent creating VGs with PVs with different logical block sizes. |
||||||
|
Pvmove runs in exlusively activating mode for exclusively active LVs. |
||||||
|
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c |
||||||
|
index bffae60..768f261 100644 |
||||||
|
--- a/lib/metadata/raid_manip.c |
||||||
|
+++ b/lib/metadata/raid_manip.c |
||||||
|
@@ -6445,6 +6445,12 @@ int lv_raid_convert(struct logical_volume *lv, |
||||||
|
uint32_t available_slvs, removed_slvs; |
||||||
|
takeover_fn_t takeover_fn; |
||||||
|
|
||||||
|
+ /* FIXME Can't reshape volume in use - aka not toplevel devices */ |
||||||
|
+ if (!dm_list_empty(&lv->segs_using_this_lv)) { |
||||||
|
+ log_error("Can't reshape stacked volume %s.", display_lvname(lv)); |
||||||
|
+ return 0; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
/* FIXME If not active, prompt and activate */ |
||||||
|
/* FIXME Some operations do not require the LV to be active */ |
||||||
|
/* LV must be active to perform raid conversion operations */ |
@ -0,0 +1,34 @@ |
|||||||
|
lib/metadata/raid_manip.c | 13 +++++++------ |
||||||
|
1 file changed, 7 insertions(+), 6 deletions(-) |
||||||
|
|
||||||
|
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c |
||||||
|
index 768f261..7481ebf 100644 |
||||||
|
--- a/lib/metadata/raid_manip.c |
||||||
|
+++ b/lib/metadata/raid_manip.c |
||||||
|
@@ -6217,6 +6217,13 @@ static int _set_convenient_raid145610_segtype_to(const struct lv_segment *seg_fr |
||||||
|
if (seg_flag) { |
||||||
|
if (!(*segtype = get_segtype_from_flag(cmd, seg_flag))) |
||||||
|
return_0; |
||||||
|
+ |
||||||
|
+ /* FIXME Can't reshape volume in use - aka not toplevel devices */ |
||||||
|
+ if (!dm_list_empty(&seg_from->lv->segs_using_this_lv)) { |
||||||
|
+ log_error("Can't reshape stacked volume %s.", display_lvname(seg_from->lv)); |
||||||
|
+ return 0; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
if (segtype_sav != *segtype) { |
||||||
|
log_warn("Replaced LV type %s%s with possible type %s.", |
||||||
|
segtype_sav->name, _get_segtype_alias_str(seg_from->lv, segtype_sav), |
||||||
|
@@ -6445,12 +6452,6 @@ int lv_raid_convert(struct logical_volume *lv, |
||||||
|
uint32_t available_slvs, removed_slvs; |
||||||
|
takeover_fn_t takeover_fn; |
||||||
|
|
||||||
|
- /* FIXME Can't reshape volume in use - aka not toplevel devices */ |
||||||
|
- if (!dm_list_empty(&lv->segs_using_this_lv)) { |
||||||
|
- log_error("Can't reshape stacked volume %s.", display_lvname(lv)); |
||||||
|
- return 0; |
||||||
|
- } |
||||||
|
- |
||||||
|
/* FIXME If not active, prompt and activate */ |
||||||
|
/* FIXME Some operations do not require the LV to be active */ |
||||||
|
/* LV must be active to perform raid conversion operations */ |
@ -0,0 +1,35 @@ |
|||||||
|
lib/activate/dev_manager.c | 11 ++++++++++- |
||||||
|
1 file changed, 10 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c |
||||||
|
index 56608e3..a5e026c 100644 |
||||||
|
--- a/lib/activate/dev_manager.c |
||||||
|
+++ b/lib/activate/dev_manager.c |
||||||
|
@@ -1592,6 +1592,9 @@ int dev_manager_thin_percent(struct dev_manager *dm, |
||||||
|
return 1; |
||||||
|
} |
||||||
|
|
||||||
|
+/* |
||||||
|
+ * Explore state of running DM table to obtain currently used deviceId |
||||||
|
+ */ |
||||||
|
int dev_manager_thin_device_id(struct dev_manager *dm, |
||||||
|
const struct logical_volume *lv, |
||||||
|
uint32_t *device_id) |
||||||
|
@@ -1601,10 +1604,16 @@ int dev_manager_thin_device_id(struct dev_manager *dm, |
||||||
|
struct dm_info info; |
||||||
|
uint64_t start, length; |
||||||
|
char *params, *target_type = NULL; |
||||||
|
+ const char *layer = lv_layer(lv); |
||||||
|
int r = 0; |
||||||
|
|
||||||
|
+ if (lv_is_merging_origin(lv) && !lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0)) |
||||||
|
+ /* If the merge has already happened, that table |
||||||
|
+ * can already be using correct LV without -real layer */ |
||||||
|
+ layer = NULL; |
||||||
|
+ |
||||||
|
/* Build dlid for the thin layer */ |
||||||
|
- if (!(dlid = build_dm_uuid(dm->mem, lv, lv_layer(lv)))) |
||||||
|
+ if (!(dlid = build_dm_uuid(dm->mem, lv, layer))) |
||||||
|
return_0; |
||||||
|
|
||||||
|
if (!(dmt = _setup_task_run(DM_DEVICE_TABLE, &info, NULL, dlid, 0, 0, 0, 0, 1, 0))) |
@ -0,0 +1,17 @@ |
|||||||
|
lib/activate/activate.c | 3 ++- |
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/lib/activate/activate.c b/lib/activate/activate.c |
||||||
|
index 0790817..aba5d14 100644 |
||||||
|
--- a/lib/activate/activate.c |
||||||
|
+++ b/lib/activate/activate.c |
||||||
|
@@ -831,7 +831,8 @@ int lv_info_with_seg_status(struct cmd_context *cmd, |
||||||
|
with_open_count, with_read_ahead)) |
||||||
|
return_0; |
||||||
|
|
||||||
|
- if (status->seg_status.type == SEG_STATUS_SNAPSHOT) { |
||||||
|
+ if (status->seg_status.type == SEG_STATUS_SNAPSHOT || |
||||||
|
+ (lv_is_thin_volume(olv) && (status->seg_status.type == SEG_STATUS_THIN))) { |
||||||
|
log_debug_activation("Snapshot merge is in progress, querying status of %s instead.", |
||||||
|
display_lvname(lv)); |
||||||
|
/* |
@ -0,0 +1,54 @@ |
|||||||
|
lib/metadata/snapshot_manip.c | 19 +------------------ |
||||||
|
1 file changed, 1 insertion(+), 18 deletions(-) |
||||||
|
|
||||||
|
diff --git a/lib/metadata/snapshot_manip.c b/lib/metadata/snapshot_manip.c |
||||||
|
index 156b4c8..63e3361 100644 |
||||||
|
--- a/lib/metadata/snapshot_manip.c |
||||||
|
+++ b/lib/metadata/snapshot_manip.c |
||||||
|
@@ -286,7 +286,6 @@ int vg_add_snapshot(struct logical_volume *origin, |
||||||
|
|
||||||
|
int vg_remove_snapshot(struct logical_volume *cow) |
||||||
|
{ |
||||||
|
- int merging_snapshot = 0; |
||||||
|
struct logical_volume *origin = origin_from_cow(cow); |
||||||
|
int is_origin_active = lv_is_active(origin); |
||||||
|
|
||||||
|
@@ -315,17 +314,6 @@ int vg_remove_snapshot(struct logical_volume *cow) |
||||||
|
* preload origin IFF "snapshot-merge" target is active |
||||||
|
* - IMPORTANT: avoids preload if inactivate merge is pending |
||||||
|
*/ |
||||||
|
- if (lv_has_target_type(origin->vg->vgmem, origin, NULL, |
||||||
|
- TARGET_NAME_SNAPSHOT_MERGE)) { |
||||||
|
- /* |
||||||
|
- * preload origin to: |
||||||
|
- * - allow proper release of -cow |
||||||
|
- * - avoid allocations with other devices suspended |
||||||
|
- * when transitioning from "snapshot-merge" to |
||||||
|
- * "snapshot-origin after a merge completes. |
||||||
|
- */ |
||||||
|
- merging_snapshot = 1; |
||||||
|
- } |
||||||
|
} |
||||||
|
|
||||||
|
if (!lv_remove(cow->snapshot->lv)) { |
||||||
|
@@ -367,7 +355,7 @@ int vg_remove_snapshot(struct logical_volume *cow) |
||||||
|
* the LV lock on cluster has to be grabbed, so use |
||||||
|
* activate_lv() which resumes suspend cow device. |
||||||
|
*/ |
||||||
|
- if (!merging_snapshot && !activate_lv(cow->vg->cmd, cow)) { |
||||||
|
+ if (!activate_lv(cow->vg->cmd, cow)) { |
||||||
|
log_error("Failed to activate %s.", cow->name); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
@@ -376,11 +364,6 @@ int vg_remove_snapshot(struct logical_volume *cow) |
||||||
|
log_error("Failed to resume %s.", origin->name); |
||||||
|
return 0; |
||||||
|
} |
||||||
|
- |
||||||
|
- if (merging_snapshot && !activate_lv(cow->vg->cmd, cow)) { |
||||||
|
- log_error("Failed to activate %s.", cow->name); |
||||||
|
- return 0; |
||||||
|
- } |
||||||
|
} |
||||||
|
|
||||||
|
return 1; |
@ -0,0 +1,32 @@ |
|||||||
|
WHATS_NEW | 1 + |
||||||
|
lib/activate/dev_manager.c | 5 +++++ |
||||||
|
2 files changed, 6 insertions(+) |
||||||
|
|
||||||
|
diff --git a/WHATS_NEW b/WHATS_NEW |
||||||
|
index d1f4530..00b84f9 100644 |
||||||
|
--- a/WHATS_NEW |
||||||
|
+++ b/WHATS_NEW |
||||||
|
@@ -2,6 +2,7 @@ Version 2.02.187 - |
||||||
|
=================================== |
||||||
|
Prevent creating VGs with PVs with different logical block sizes. |
||||||
|
Pvmove runs in exlusively activating mode for exclusively active LVs. |
||||||
|
+ Activate thin-pool layered volume as 'read-only' device. |
||||||
|
Enhance validation for thin and cache pool conversion and swapping. |
||||||
|
|
||||||
|
Version 2.02.186 - 27th August 2019 |
||||||
|
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c |
||||||
|
index dc64159..56608e3 100644 |
||||||
|
--- a/lib/activate/dev_manager.c |
||||||
|
+++ b/lib/activate/dev_manager.c |
||||||
|
@@ -84,6 +84,11 @@ int read_only_lv(const struct logical_volume *lv, const struct lv_activate_opts |
||||||
|
if (lv_is_raid_image(lv) || lv_is_raid_metadata(lv)) |
||||||
|
return 0; /* Keep RAID SubLvs writable */ |
||||||
|
|
||||||
|
+ if (!layer) { |
||||||
|
+ if (lv_is_thin_pool(lv)) |
||||||
|
+ return 1; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
return (laopts->read_only || !(lv->status & LVM_WRITE)); |
||||||
|
} |
||||||
|
|
@ -0,0 +1,208 @@ |
|||||||
|
lib/commands/toolcontext.h | 1 + |
||||||
|
lib/config/config_settings.h | 5 +++++ |
||||||
|
lib/metadata/metadata-exported.h | 1 + |
||||||
|
lib/metadata/metadata.c | 44 +++++++++++++++++++++++++++++++++++++ |
||||||
|
tools/lvmcmdline.c | 2 ++ |
||||||
|
tools/toollib.c | 47 ++++++++++++++++++++++++++++++++++++++++ |
||||||
|
tools/vgcreate.c | 2 ++ |
||||||
|
7 files changed, 102 insertions(+) |
||||||
|
|
||||||
|
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h |
||||||
|
index 4b2a079..497f4bd 100644 |
||||||
|
--- a/lib/commands/toolcontext.h |
||||||
|
+++ b/lib/commands/toolcontext.h |
||||||
|
@@ -155,6 +155,7 @@ struct cmd_context { |
||||||
|
unsigned include_shared_vgs:1; /* report/display cmds can reveal lockd VGs */ |
||||||
|
unsigned include_active_foreign_vgs:1; /* cmd should process foreign VGs with active LVs */ |
||||||
|
unsigned vg_read_print_access_error:1; /* print access errors from vg_read */ |
||||||
|
+ unsigned allow_mixed_block_sizes:1; |
||||||
|
unsigned force_access_clustered:1; |
||||||
|
unsigned lockd_gl_disable:1; |
||||||
|
unsigned lockd_vg_disable:1; |
||||||
|
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h |
||||||
|
index 9904a62..622e982 100644 |
||||||
|
--- a/lib/config/config_settings.h |
||||||
|
+++ b/lib/config/config_settings.h |
||||||
|
@@ -470,6 +470,11 @@ cfg(devices_allow_changes_with_duplicate_pvs_CFG, "allow_changes_with_duplicate_ |
||||||
|
"Enabling this setting allows the VG to be used as usual even with\n" |
||||||
|
"uncertain devices.\n") |
||||||
|
|
||||||
|
+cfg(devices_allow_mixed_block_sizes_CFG, "allow_mixed_block_sizes", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 3, 6), NULL, 0, NULL, |
||||||
|
+ "Allow PVs in the same VG with different logical block sizes.\n" |
||||||
|
+ "When allowed, the user is responsible to ensure that an LV is\n" |
||||||
|
+ "using PVs with matching block sizes when necessary.\n") |
||||||
|
+ |
||||||
|
cfg_array(allocation_cling_tag_list_CFG, "cling_tag_list", allocation_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 77), NULL, 0, NULL, |
||||||
|
"Advise LVM which PVs to use when searching for new space.\n" |
||||||
|
"When searching for free space to extend an LV, the 'cling' allocation\n" |
||||||
|
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h |
||||||
|
index 2245c29..5674545 100644 |
||||||
|
--- a/lib/metadata/metadata-exported.h |
||||||
|
+++ b/lib/metadata/metadata-exported.h |
||||||
|
@@ -593,6 +593,7 @@ struct pvcreate_params { |
||||||
|
unsigned is_remove : 1; /* is removing PVs, not creating */ |
||||||
|
unsigned preserve_existing : 1; |
||||||
|
unsigned check_failed : 1; |
||||||
|
+ unsigned check_consistent_block_size : 1; |
||||||
|
}; |
||||||
|
|
||||||
|
struct lvresize_params { |
||||||
|
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c |
||||||
|
index 3620240..123f7f5 100644 |
||||||
|
--- a/lib/metadata/metadata.c |
||||||
|
+++ b/lib/metadata/metadata.c |
||||||
|
@@ -699,12 +699,40 @@ int vg_extend_each_pv(struct volume_group *vg, struct pvcreate_params *pp) |
||||||
|
{ |
||||||
|
struct pv_list *pvl; |
||||||
|
unsigned int max_phys_block_size = 0; |
||||||
|
+ unsigned int physical_block_size, logical_block_size; |
||||||
|
+ unsigned int prev_lbs = 0; |
||||||
|
+ int inconsistent_existing_lbs = 0; |
||||||
|
|
||||||
|
log_debug_metadata("Adding PVs to VG %s.", vg->name); |
||||||
|
|
||||||
|
if (vg_bad_status_bits(vg, RESIZEABLE_VG)) |
||||||
|
return_0; |
||||||
|
|
||||||
|
+ /* |
||||||
|
+ * Check if existing PVs have inconsistent block sizes. |
||||||
|
+ * If so, do not enforce new devices to be consistent. |
||||||
|
+ */ |
||||||
|
+ dm_list_iterate_items(pvl, &vg->pvs) { |
||||||
|
+ logical_block_size = 0; |
||||||
|
+ physical_block_size = 0; |
||||||
|
+ |
||||||
|
+ if (!dev_get_direct_block_sizes(pvl->pv->dev, &physical_block_size, &logical_block_size)) |
||||||
|
+ continue; |
||||||
|
+ |
||||||
|
+ if (!logical_block_size) |
||||||
|
+ continue; |
||||||
|
+ |
||||||
|
+ if (!prev_lbs) { |
||||||
|
+ prev_lbs = logical_block_size; |
||||||
|
+ continue; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ if (prev_lbs != logical_block_size) { |
||||||
|
+ inconsistent_existing_lbs = 1; |
||||||
|
+ break; |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
+ |
||||||
|
dm_list_iterate_items(pvl, &pp->pvs) { |
||||||
|
log_debug_metadata("Adding PV %s to VG %s.", pv_dev_name(pvl->pv), vg->name); |
||||||
|
|
||||||
|
@@ -715,6 +743,22 @@ int vg_extend_each_pv(struct volume_group *vg, struct pvcreate_params *pp) |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
+ logical_block_size = 0; |
||||||
|
+ physical_block_size = 0; |
||||||
|
+ |
||||||
|
+ if (!dev_get_direct_block_sizes(pvl->pv->dev, &physical_block_size, &logical_block_size)) |
||||||
|
+ log_warn("WARNING: PV %s has unknown block size.", pv_dev_name(pvl->pv)); |
||||||
|
+ |
||||||
|
+ else if (prev_lbs && logical_block_size && (logical_block_size != prev_lbs)) { |
||||||
|
+ if (vg->cmd->allow_mixed_block_sizes || inconsistent_existing_lbs) |
||||||
|
+ log_debug("Devices have inconsistent block sizes (%u and %u)", prev_lbs, logical_block_size); |
||||||
|
+ else { |
||||||
|
+ log_error("Devices have inconsistent logical block sizes (%u and %u).", |
||||||
|
+ prev_lbs, logical_block_size); |
||||||
|
+ return 0; |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
+ |
||||||
|
if (!add_pv_to_vg(vg, pv_dev_name(pvl->pv), pvl->pv, 0)) { |
||||||
|
log_error("PV %s cannot be added to VG %s.", |
||||||
|
pv_dev_name(pvl->pv), vg->name); |
||||||
|
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c |
||||||
|
index f238b64..f82827d 100644 |
||||||
|
--- a/tools/lvmcmdline.c |
||||||
|
+++ b/tools/lvmcmdline.c |
||||||
|
@@ -2308,6 +2308,8 @@ static int _get_current_settings(struct cmd_context *cmd) |
||||||
|
if (cmd->cname->flags & CAN_USE_ONE_SCAN) |
||||||
|
cmd->can_use_one_scan = 1; |
||||||
|
|
||||||
|
+ cmd->allow_mixed_block_sizes = find_config_tree_bool(cmd, devices_allow_mixed_block_sizes_CFG, NULL); |
||||||
|
+ |
||||||
|
cmd->partial_activation = 0; |
||||||
|
cmd->degraded_activation = 0; |
||||||
|
activation_mode = find_config_tree_str(cmd, activation_mode_CFG, NULL); |
||||||
|
diff --git a/tools/toollib.c b/tools/toollib.c |
||||||
|
index 81953ee..0b957cc 100644 |
||||||
|
--- a/tools/toollib.c |
||||||
|
+++ b/tools/toollib.c |
||||||
|
@@ -5506,6 +5506,8 @@ int pvcreate_each_device(struct cmd_context *cmd, |
||||||
|
struct device_list *devl; |
||||||
|
const char *pv_name; |
||||||
|
int consistent = 0; |
||||||
|
+ unsigned int physical_block_size, logical_block_size; |
||||||
|
+ unsigned int prev_pbs = 0, prev_lbs = 0; |
||||||
|
int must_use_all = (cmd->cname->flags & MUST_USE_ALL_ARGS); |
||||||
|
int found; |
||||||
|
unsigned i; |
||||||
|
@@ -5584,6 +5586,51 @@ int pvcreate_each_device(struct cmd_context *cmd, |
||||||
|
pd->dev = dev_cache_get(pd->name, cmd->full_filter); |
||||||
|
|
||||||
|
/* |
||||||
|
+ * Check for consistent block sizes. |
||||||
|
+ */ |
||||||
|
+ if (pp->check_consistent_block_size) { |
||||||
|
+ dm_list_iterate_items(pd, &pp->arg_devices) { |
||||||
|
+ if (!pd->dev) |
||||||
|
+ continue; |
||||||
|
+ |
||||||
|
+ logical_block_size = 0; |
||||||
|
+ physical_block_size = 0; |
||||||
|
+ |
||||||
|
+ if (!dev_get_direct_block_sizes(pd->dev, &physical_block_size, &logical_block_size)) { |
||||||
|
+ log_warn("WARNING: Unknown block size for device %s.", dev_name(pd->dev)); |
||||||
|
+ continue; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ if (!logical_block_size) { |
||||||
|
+ log_warn("WARNING: Unknown logical_block_size for device %s.", dev_name(pd->dev)); |
||||||
|
+ continue; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ if (!prev_lbs) { |
||||||
|
+ prev_lbs = logical_block_size; |
||||||
|
+ prev_pbs = physical_block_size; |
||||||
|
+ continue; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ if (prev_lbs == logical_block_size) { |
||||||
|
+ /* Require lbs to match, just warn about unmatching pbs. */ |
||||||
|
+ if (!cmd->allow_mixed_block_sizes && prev_pbs && physical_block_size && |
||||||
|
+ (prev_pbs != physical_block_size)) |
||||||
|
+ log_warn("WARNING: Devices have inconsistent physical block sizes (%u and %u).", |
||||||
|
+ prev_pbs, physical_block_size); |
||||||
|
+ continue; |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ if (!cmd->allow_mixed_block_sizes) { |
||||||
|
+ log_error("Devices have inconsistent logical block sizes (%u and %u).", |
||||||
|
+ prev_lbs, logical_block_size); |
||||||
|
+ log_print("See lvm.conf allow_mixed_block_sizes."); |
||||||
|
+ return 0; |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
+ } |
||||||
|
+ |
||||||
|
+ /* |
||||||
|
* Use process_each_pv to search all existing PVs and devices. |
||||||
|
* |
||||||
|
* This is a slightly different way to use process_each_pv, because the |
||||||
|
diff --git a/tools/vgcreate.c b/tools/vgcreate.c |
||||||
|
index 4356d99..7add53b 100644 |
||||||
|
--- a/tools/vgcreate.c |
||||||
|
+++ b/tools/vgcreate.c |
||||||
|
@@ -48,6 +48,8 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv) |
||||||
|
/* Don't create a new PV on top of an existing PV like pvcreate does. */ |
||||||
|
pp.preserve_existing = 1; |
||||||
|
|
||||||
|
+ pp.check_consistent_block_size = 1; |
||||||
|
+ |
||||||
|
if (!vgcreate_params_set_defaults(cmd, &vp_def, NULL)) |
||||||
|
return EINVALID_CMD_LINE; |
||||||
|
vp_def.vg_name = vg_name; |
@ -0,0 +1,34 @@ |
|||||||
|
From 16a03878cd39cb1fb0c052a41901b6660f9f674c Mon Sep 17 00:00:00 2001 |
||||||
|
From: Zdenek Kabelac <zkabelac@redhat.com> |
||||||
|
Date: Wed, 8 Apr 2020 11:46:42 +0200 |
||||||
|
Subject: [PATCH 4/4] lvconvert: no validation for thin-pools not used by lvm2 |
||||||
|
|
||||||
|
lvm2 supports thin-pool to be later used by other tools doing |
||||||
|
virtual volumes themself (i.e. docker) - in this case we |
||||||
|
shall not validate transaction Id - is this is used by |
||||||
|
other tools and lvm2 keeps value 0 - so the transationId |
||||||
|
validation need to be skipped in this case. |
||||||
|
|
||||||
|
(cherry picked from commit 1316cafbe988307264e4f87dbcffaf56bc2ab388) |
||||||
|
(cherry picked from commit ca84deb23f0cfb51dbeba0ffe44f757345e6f8a0) |
||||||
|
--- |
||||||
|
tools/lvconvert.c | 3 ++- |
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/tools/lvconvert.c b/tools/lvconvert.c |
||||||
|
index 799e746..bf14eec 100644 |
||||||
|
--- a/tools/lvconvert.c |
||||||
|
+++ b/tools/lvconvert.c |
||||||
|
@@ -2330,7 +2330,8 @@ static int _lvconvert_thin_pool_repair(struct cmd_context *cmd, |
||||||
|
goto deactivate_mlv; |
||||||
|
} |
||||||
|
|
||||||
|
- if (thin_dump[0]) { |
||||||
|
+ /* Check matching transactionId when thin-pool is used by lvm2 (transactionId != 0) */ |
||||||
|
+ if (first_seg(pool_lv)->transaction_id && thin_dump[0]) { |
||||||
|
argv[0] = thin_dump; |
||||||
|
argv[1] = pms_path; |
||||||
|
argv[2] = NULL; |
||||||
|
-- |
||||||
|
1.8.3.1 |
||||||
|
|
@ -0,0 +1,47 @@ |
|||||||
|
conf/example.conf.in | 6 ++++++ |
||||||
|
lib/config/config_settings.h | 2 +- |
||||||
|
lib/config/defaults.h | 1 + |
||||||
|
3 files changed, 8 insertions(+), 1 deletion(-) |
||||||
|
|
||||||
|
diff --git a/conf/example.conf.in b/conf/example.conf.in |
||||||
|
index 6f7b161..9fa1235 100644 |
||||||
|
--- a/conf/example.conf.in |
||||||
|
+++ b/conf/example.conf.in |
||||||
|
@@ -326,6 +326,12 @@ devices { |
||||||
|
# Enabling this setting allows the VG to be used as usual even with |
||||||
|
# uncertain devices. |
||||||
|
allow_changes_with_duplicate_pvs = 1 |
||||||
|
+ |
||||||
|
+ # Configuration option devices/allow_mixed_block_sizes. |
||||||
|
+ # Allow PVs in the same VG with different logical block sizes. |
||||||
|
+ # When allowed, the user is responsible to ensure that an LV is |
||||||
|
+ # using PVs with matching block sizes when necessary. |
||||||
|
+ allow_mixed_block_sizes = 1 |
||||||
|
} |
||||||
|
|
||||||
|
# Configuration section allocation. |
||||||
|
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h |
||||||
|
index 622e982..055b883 100644 |
||||||
|
--- a/lib/config/config_settings.h |
||||||
|
+++ b/lib/config/config_settings.h |
||||||
|
@@ -470,7 +470,7 @@ cfg(devices_allow_changes_with_duplicate_pvs_CFG, "allow_changes_with_duplicate_ |
||||||
|
"Enabling this setting allows the VG to be used as usual even with\n" |
||||||
|
"uncertain devices.\n") |
||||||
|
|
||||||
|
-cfg(devices_allow_mixed_block_sizes_CFG, "allow_mixed_block_sizes", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 3, 6), NULL, 0, NULL, |
||||||
|
+cfg(devices_allow_mixed_block_sizes_CFG, "allow_mixed_block_sizes", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ALLOW_MIXED_BLOCK_SIZES, vsn(2, 2, 186), NULL, 0, NULL, |
||||||
|
"Allow PVs in the same VG with different logical block sizes.\n" |
||||||
|
"When allowed, the user is responsible to ensure that an LV is\n" |
||||||
|
"using PVs with matching block sizes when necessary.\n") |
||||||
|
diff --git a/lib/config/defaults.h b/lib/config/defaults.h |
||||||
|
index 0d55928..e689208 100644 |
||||||
|
--- a/lib/config/defaults.h |
||||||
|
+++ b/lib/config/defaults.h |
||||||
|
@@ -46,6 +46,7 @@ |
||||||
|
#define DEFAULT_ISSUE_DISCARDS 0 |
||||||
|
#define DEFAULT_PV_MIN_SIZE_KB 2048 |
||||||
|
#define DEFAULT_ALLOW_CHANGES_WITH_DUPLICATE_PVS 1 |
||||||
|
+#define DEFAULT_ALLOW_MIXED_BLOCK_SIZES 1 |
||||||
|
|
||||||
|
#define DEFAULT_LOCKING_LIB "liblvm2clusterlock.so" |
||||||
|
#define DEFAULT_ERROR_WHEN_FULL 0 |
Loading…
Reference in new issue