basebuilder_pel7x64builder0
5 years ago
29 changed files with 7677 additions and 69 deletions
@ -0,0 +1,173 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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 @@
@@ -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