stable-2.02 - lv_manip: add space into message
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=8af590b1bbb5796d20c...
Commit: 8af590b1bbb5796d20c32d41b6e4dcb7d2441fb9
Parent: aa4f1f117a355c7046a348fd217fdfab20242ae6
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Oct 19 10:28:06 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Oct 20 22:41:34 2020 +0200
lv_manip: add space into message
---
lib/metadata/lv_manip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 4b1b4de61..42d18abb8 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -904,7 +904,7 @@ static uint32_t _round_to_stripe_boundary(struct volume_group *vg, uint32_t exte
/* Round up extents to stripe divisible amount */
if ((size_rest = extents % stripes)) {
new_extents += extend ? stripes - size_rest : -size_rest;
- log_print_unless_silent("Rounding size %s (%u extents) %s to stripe boundary size %s(%u extents).",
+ log_print_unless_silent("Rounding size %s (%u extents) %s to stripe boundary size %s (%u extents).",
display_size(vg->cmd, (uint64_t) extents * vg->extent_size), extents,
new_extents < extents ? "down" : "up",
display_size(vg->cmd, (uint64_t) new_extents * vg->extent_size), new_extents);
3 years, 6 months
master - tests: check dmevent with bigger reserved_stack
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=6be29e1179725bcee19...
Commit: 6be29e1179725bcee19ff263635bb2927ef928bc
Parent: fdec4cd3e6fef08b76b410136156dbd487dad8d0
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Oct 20 22:28:58 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Oct 20 22:28:58 2020 +0200
tests: check dmevent with bigger reserved_stack
Check dmeventd remains working when reserved_stack
is above 300KiB.
---
test/shell/lvextend-thin-data-dmeventd.sh | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/test/shell/lvextend-thin-data-dmeventd.sh b/test/shell/lvextend-thin-data-dmeventd.sh
index 7dfec4acc..7d37f16b3 100644
--- a/test/shell/lvextend-thin-data-dmeventd.sh
+++ b/test/shell/lvextend-thin-data-dmeventd.sh
@@ -30,10 +30,13 @@ test_equal_() {
aux have_thin 1 10 0 || skip
-aux prepare_dmeventd
-
+# set reserved stack size above dmeventd 300KiB stack
+# ATM such value should be simply ignored
aux lvmconf "activation/thin_pool_autoextend_percent = 10" \
- "activation/thin_pool_autoextend_threshold = 75"
+ "activation/thin_pool_autoextend_threshold = 75" \
+ "activation/reserved_stack = 512"
+
+aux prepare_dmeventd
aux prepare_pvs 3 256
get_devs
3 years, 6 months
master - memlock: allocate at most halve of rlimit stack
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=fdec4cd3e6fef08b76b...
Commit: fdec4cd3e6fef08b76b410136156dbd487dad8d0
Parent: bd272e3bcea38a12b2b9789cfb9b7d4a9a3d3574
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Oct 20 22:26:44 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Oct 20 22:26:44 2020 +0200
memlock: allocate at most halve of rlimit stack
Touch of stack allocation validated given size with rlimit
and if the reserved_stack was above rlimit, its been completely
ignored - now we will always touch stack upto rlimit/2 size.
---
lib/mm/memlock.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/lib/mm/memlock.c b/lib/mm/memlock.c
index 883795d28..0c05038fe 100644
--- a/lib/mm/memlock.c
+++ b/lib/mm/memlock.c
@@ -167,10 +167,13 @@ static void _allocate_memory(void)
char *areas[max_areas];
/* Check if we could preallocate requested stack */
- if ((getrlimit (RLIMIT_STACK, &limit) == 0) &&
- ((_size_stack * 2) < limit.rlim_cur) &&
- ((stack_mem = alloca(_size_stack))))
- _touch_memory(stack_mem, _size_stack);
+ if (getrlimit(RLIMIT_STACK, &limit) == 0) {
+ limit.rlim_cur /= 2;
+ if (_size_stack > limit.rlim_cur)
+ _size_stack = limit.rlim_cur;
+ if ((stack_mem = alloca(_size_stack)))
+ _touch_memory(stack_mem, _size_stack);
+ }
/* FIXME else warn user setting got ignored */
/*
3 years, 6 months
master - lvmcmdlib: lvm2_init_threaded
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=bd272e3bcea38a12b2b...
Commit: bd272e3bcea38a12b2b9789cfb9b7d4a9a3d3574
Parent: 756066a2e85062be5e406d9139fc1033746d7ff9
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Oct 20 22:22:52 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Oct 20 22:22:52 2020 +0200
lvmcmdlib: lvm2_init_threaded
cmd context has 'threaded' value that used be set
by clvmd - and allowed proper memory locking management.
Reuse same bit for dmeventd.
Since dmeventd is using 300KiB stack per thread,
we will ignore any user settings for allocation/reserved_stack
until some better solution is find.
This avoids crashing of dmevend when user changes this value
and because in most cases lvm2 should work ok with 64K stack
size, this change should not cause any problems.
---
daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c | 2 +-
tools/lvm2cmd-static.c | 7 ++++++-
tools/lvm2cmd.c | 7 ++++++-
tools/lvm2cmd.h | 6 ++++++
tools/lvm2cmdline.h | 4 ++--
tools/lvmcmdlib.c | 4 ++--
tools/lvmcmdline.c | 8 +++++---
7 files changed, 28 insertions(+), 10 deletions(-)
diff --git a/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c b/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c
index 04bc8993d..56498170f 100644
--- a/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c
+++ b/daemons/dmeventd/plugins/lvm2/dmeventd_lvm.c
@@ -71,7 +71,7 @@ int dmeventd_lvm2_init(void)
if (!_lvm_handle) {
lvm2_log_fn(_lvm2_print_log);
- if (!(_lvm_handle = lvm2_init()))
+ if (!(_lvm_handle = lvm2_init_threaded()))
goto out;
/*
diff --git a/tools/lvm2cmd-static.c b/tools/lvm2cmd-static.c
index 2b5f300e7..0c11516db 100644
--- a/tools/lvm2cmd-static.c
+++ b/tools/lvm2cmd-static.c
@@ -17,5 +17,10 @@
void *lvm2_init(void)
{
- return cmdlib_lvm2_init(1);
+ return cmdlib_lvm2_init(1, 0);
+}
+
+void *lvm2_init_threaded(void)
+{
+ return cmdlib_lvm2_init(1, 1);
}
diff --git a/tools/lvm2cmd.c b/tools/lvm2cmd.c
index 54090ca98..62ca5f6b4 100644
--- a/tools/lvm2cmd.c
+++ b/tools/lvm2cmd.c
@@ -17,7 +17,12 @@
void *lvm2_init(void)
{
- return cmdlib_lvm2_init(0);
+ return cmdlib_lvm2_init(0, 0);
+}
+
+void *lvm2_init_threaded(void)
+{
+ return cmdlib_lvm2_init(0, 1);
}
int lvm_shell(struct cmd_context *cmd __attribute__((unused)),
diff --git a/tools/lvm2cmd.h b/tools/lvm2cmd.h
index cd2e0ec9d..39a8d6036 100644
--- a/tools/lvm2cmd.h
+++ b/tools/lvm2cmd.h
@@ -58,6 +58,12 @@ void lvm2_log_fn(lvm2_log_fn_t log_fn);
*/
void *lvm2_init(void);
+/*
+ * Initialise library for threaded user
+ * Returns a handle so repeated use of lvm2_run is more efficient.
+ */
+void *lvm2_init_threaded(void);
+
/*
* Disable any dmeventd calls that the library may otherwise do. Useful to avoid
* recursive calls from dmeventd to itself.
diff --git a/tools/lvm2cmdline.h b/tools/lvm2cmdline.h
index 0073f9025..84cab9359 100644
--- a/tools/lvm2cmdline.h
+++ b/tools/lvm2cmdline.h
@@ -28,10 +28,10 @@ struct cmdline_context {
int lvm2_main(int argc, char **argv);
-void *cmdlib_lvm2_init(unsigned static_compile);
+void *cmdlib_lvm2_init(unsigned static_compile, unsigned threaded);
void lvm_fin(struct cmd_context *cmd);
-struct cmd_context *init_lvm(unsigned set_connections, unsigned set_filters);
+struct cmd_context *init_lvm(unsigned set_connections, unsigned set_filters, unsigned threaded);
int lvm_register_commands(struct cmd_context *cmdtool, const char *name);
int lvm_split(char *str, int *argc, char **argv, int max);
int lvm_run_command(struct cmd_context *cmd, int argc, char **argv);
diff --git a/tools/lvmcmdlib.c b/tools/lvmcmdlib.c
index aa85c9ccd..152d176b2 100644
--- a/tools/lvmcmdlib.c
+++ b/tools/lvmcmdlib.c
@@ -25,12 +25,12 @@
#include <time.h>
#include <sys/resource.h>
-void *cmdlib_lvm2_init(unsigned static_compile)
+void *cmdlib_lvm2_init(unsigned static_compile, unsigned threaded)
{
struct cmd_context *cmd;
init_is_static(static_compile);
- if (!(cmd = init_lvm(1, 1)))
+ if (!(cmd = init_lvm(1, 1, threaded)))
return NULL;
if (!lvm_register_commands(cmd, NULL))
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index e8d732878..3a2ce93b5 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -3434,7 +3434,9 @@ static int _close_stray_fds(const char *command, struct custom_fds *custom_fds)
return 1;
}
-struct cmd_context *init_lvm(unsigned set_connections, unsigned set_filters)
+struct cmd_context *init_lvm(unsigned set_connections,
+ unsigned set_filters,
+ unsigned threaded)
{
struct cmd_context *cmd;
@@ -3448,7 +3450,7 @@ struct cmd_context *init_lvm(unsigned set_connections, unsigned set_filters)
*/
dm_set_name_mangling_mode(DM_STRING_MANGLING_NONE);
- if (!(cmd = create_toolcontext(0, NULL, 1, 0,
+ if (!(cmd = create_toolcontext(0, NULL, 1, threaded,
set_connections, set_filters))) {
udev_fin_library_context();
return_NULL;
@@ -3602,7 +3604,7 @@ int lvm2_main(int argc, char **argv)
if (!alias && (argc > 2) && !strcmp(argv[2], "-?"))
argv[2] = (char *)"-h";
- if (!(cmd = init_lvm(0, 0)))
+ if (!(cmd = init_lvm(0, 0, 0)))
return EINIT_FAILED;
/* Store original argv location so we may customise it if we become a daemon */
3 years, 6 months
master - libdm: relocate code for sending messages
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=756066a2e85062be5e4...
Commit: 756066a2e85062be5e406d9139fc1033746d7ff9
Parent: 3e06061d82dbcc2f464f0fdcd6610f25177bfa1f
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Oct 19 16:48:04 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Oct 19 16:53:19 2020 +0200
libdm: relocate code for sending messages
To be able to send messages for recently resumed devices,
move code into inner loop.
Matching commit c1a6b10d09aae6179e4f08c7d8c03d5e3068ad94.
---
libdm/libdm-deptree.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index e784cbc9c..f16db8568 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -1966,22 +1966,22 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
r = 0;
continue;
}
+
+ /*
+ * FIXME: Implement delayed error reporting
+ * activation should be stopped only in the case,
+ * the submission of transation_id message fails,
+ * resume should continue further, just whole command
+ * has to report failure.
+ */
+ if (r && (child->props.send_messages > 1) &&
+ !(r = _node_send_messages(child, uuid_prefix, uuid_prefix_len, 1)))
+ stack;
}
if (awaiting_peer_rename)
priority--; /* redo priority level */
}
- /*
- * FIXME: Implement delayed error reporting
- * activation should be stopped only in the case,
- * the submission of transation_id message fails,
- * resume should continue further, just whole command
- * has to report failure.
- */
- if (r && (dnode->props.send_messages > 1) &&
- !(r = _node_send_messages(dnode, uuid_prefix, uuid_prefix_len, 1)))
- stack;
-
return r;
}
3 years, 6 months
master - cov: split check for type assignment
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=3e06061d82dbcc2f464...
Commit: 3e06061d82dbcc2f464f0fdcd6610f25177bfa1f
Parent: a17ec7e0baa737b45900cc4f97823c95f9dd8c56
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Oct 19 16:43:50 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Oct 19 16:53:19 2020 +0200
cov: split check for type assignment
Check that type is always defined, if not make it explicit internal
error (although logged as debug - so catched only with proper lvm.conf
setting).
This ensures later type being NULL can't be dereferenced with coredump.
---
device_mapper/libdm-report.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/device_mapper/libdm-report.c b/device_mapper/libdm-report.c
index 85d3d0f82..9279e3370 100644
--- a/device_mapper/libdm-report.c
+++ b/device_mapper/libdm-report.c
@@ -749,10 +749,11 @@ static void _display_fields_more(struct dm_report *rh,
id_len = strlen(type->prefix) + 3;
for (f = 0; fields[f].report_fn; f++) {
- if ((type = _find_type(rh, fields[f].type)) && type->desc)
- desc = type->desc;
- else
- desc = " ";
+ if (!(type = _find_type(rh, fields[f].type))) {
+ log_debug(INTERNAL_ERROR "Field type undefined.");
+ continue;
+ }
+ desc = (type->desc) ? : " ";
if (desc != last_desc) {
if (*last_desc)
log_warn(" ");
3 years, 6 months
master - dm: remove created devices on error path
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=a17ec7e0baa737b4590...
Commit: a17ec7e0baa737b45900cc4f97823c95f9dd8c56
Parent: b75c2dfe1b28efae08be9c7b55e904b8b695a8cd
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Oct 16 20:58:58 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Oct 19 16:53:19 2020 +0200
dm: remove created devices on error path
DM tree keeps track of created device while preloading a device tree.
When fail occures during such preload, it will now try to remove
all created and preloaded device. This makes it easier to maintain
stacking of device, since we do not need to check in-depth for
existance of all possible created devices during the failure.
---
WHATS_NEW_DM | 1 +
device_mapper/libdm-deptree.c | 81 +++++++++++++------------------------------
libdm/libdm-deptree.c | 75 +++++++++++++--------------------------
3 files changed, 51 insertions(+), 106 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 2600ca308..9624c0d78 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -7,6 +7,7 @@ Version 1.02.173 - 09th August 2020
Version 1.02.171 - 26th March 2020
==================================
+ Try to remove all created devices on dm preload tree error path.
Fix dm_list interators with gcc 10 optimization (-ftree-pta).
Dmeventd handles timer without looping on short intervals.
diff --git a/device_mapper/libdm-deptree.c b/device_mapper/libdm-deptree.c
index d9e1683ca..6ce956fa2 100644
--- a/device_mapper/libdm-deptree.c
+++ b/device_mapper/libdm-deptree.c
@@ -2136,7 +2136,7 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
return r;
}
-static int _create_node(struct dm_tree_node *dnode)
+static int _create_node(struct dm_tree_node *dnode, struct dm_tree_node *parent)
{
int r = 0;
struct dm_task *dmt;
@@ -2185,38 +2185,15 @@ static int _create_node(struct dm_tree_node *dnode)
"Unable to get DM task info for %s.",
dnode->name);
}
+
+ if (r)
+ dm_list_add_h(&parent->activated, &dnode->activated_list);
out:
dm_task_destroy(dmt);
return r;
}
-/*
- * _remove_node
- *
- * This function is only used to remove a DM device that has failed
- * to load any table.
- */
-static int _remove_node(struct dm_tree_node *dnode)
-{
- if (!dnode->info.exists)
- return 1;
-
- if (dnode->info.live_table || dnode->info.inactive_table) {
- log_error(INTERNAL_ERROR
- "_remove_node called on device with loaded table(s).");
- return 0;
- }
-
- if (!_deactivate_node(dnode->name, dnode->info.major, dnode->info.minor,
- &dnode->dtree->cookie, dnode->udev_flags, 0)) {
- log_error("Failed to clean-up device with no table: %s.",
- _node_name(dnode));
- return 0;
- }
- return 1;
-}
-
static int _build_dev_string(char *devbuf, size_t bufsize, struct dm_tree_node *node)
{
if (!dm_format_dev(devbuf, bufsize, node->info.major, node->info.minor)) {
@@ -3229,6 +3206,16 @@ static int _dm_tree_revert_activated(struct dm_tree_node *parent)
return 1;
}
+static int _dm_tree_wait_and_revert_activated(struct dm_tree_node *dnode)
+{
+ if (!dm_udev_wait(dm_tree_get_cookie(dnode)))
+ stack;
+
+ dm_tree_set_cookie(dnode, 0);
+
+ return _dm_tree_revert_activated(dnode);
+}
+
int dm_tree_preload_children(struct dm_tree_node *dnode,
const char *uuid_prefix,
size_t uuid_prefix_len)
@@ -3258,7 +3245,7 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
return_0;
/* FIXME Cope if name exists with no uuid? */
- if (!child->info.exists && !(node_created = _create_node(child)))
+ if (!child->info.exists && !(node_created = _create_node(child, dnode)))
return_0;
/* Propagate delayed resume from exteded child node */
@@ -3268,24 +3255,15 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
if (!child->info.inactive_table &&
child->props.segment_count &&
!_load_node(child)) {
+ stack;
/*
- * If the table load does not succeed, we remove the
- * device in the kernel that would otherwise have an
- * empty table. This makes the create + load of the
- * device atomic. However, if other dependencies have
- * already been created and loaded; this code is
- * insufficient to remove those - only the node
- * encountering the table load failure is removed.
+ * If the table load fails, try to device in the kernel
+ * together with other created and preloaded devices.
*/
- if (node_created) {
- if (!_remove_node(child))
- return_0;
- if (!dm_udev_wait(dm_tree_get_cookie(dnode)))
- stack;
- dm_tree_set_cookie(dnode, 0);
- (void) _dm_tree_revert_activated(child);
- }
- return_0;
+ if (!_dm_tree_wait_and_revert_activated(dnode))
+ stack;
+ r = 0;
+ continue;
}
/* No resume for a device without parents or with unchanged or smaller size */
@@ -3303,28 +3281,19 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
&child->info, &child->dtree->cookie, child->udev_flags,
child->info.suspended)) {
log_error("Unable to resume %s.", _node_name(child));
- /* If the device was not previously active, we might as well remove this node. */
- if (!child->info.live_table &&
- !_deactivate_node(child->name, child->info.major, child->info.minor,
- &child->dtree->cookie, child->udev_flags, 0))
- log_error("Unable to deactivate %s.", _node_name(child));
+ if (!_dm_tree_wait_and_revert_activated(dnode))
+ stack;
r = 0;
- /* Each child is handled independently */
continue;
}
if (node_created) {
- /* Collect newly introduced devices for revert */
- dm_list_add_h(&dnode->activated, &child->activated_list);
-
/* When creating new node also check transaction_id. */
if (child->props.send_messages &&
!_node_send_messages(child, uuid_prefix, uuid_prefix_len, 0)) {
stack;
- if (!dm_udev_wait(dm_tree_get_cookie(dnode)))
+ if (!_dm_tree_wait_and_revert_activated(dnode))
stack;
- dm_tree_set_cookie(dnode, 0);
- (void) _dm_tree_revert_activated(dnode);
r = 0;
continue;
}
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 59616eb3a..e784cbc9c 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -1985,7 +1985,7 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
return r;
}
-static int _create_node(struct dm_tree_node *dnode)
+static int _create_node(struct dm_tree_node *dnode, struct dm_tree_node *parent)
{
int r = 0;
struct dm_task *dmt;
@@ -2034,38 +2034,15 @@ static int _create_node(struct dm_tree_node *dnode)
"Unable to get DM task info for %s.",
dnode->name);
}
+
+ if (r)
+ dm_list_add_h(&parent->activated, &dnode->activated_list);
out:
dm_task_destroy(dmt);
return r;
}
-/*
- * _remove_node
- *
- * This function is only used to remove a DM device that has failed
- * to load any table.
- */
-static int _remove_node(struct dm_tree_node *dnode)
-{
- if (!dnode->info.exists)
- return 1;
-
- if (dnode->info.live_table || dnode->info.inactive_table) {
- log_error(INTERNAL_ERROR
- "_remove_node called on device with loaded table(s).");
- return 0;
- }
-
- if (!_deactivate_node(dnode->name, dnode->info.major, dnode->info.minor,
- &dnode->dtree->cookie, dnode->udev_flags, 0)) {
- log_error("Failed to clean-up device with no table: %s.",
- _node_name(dnode));
- return 0;
- }
- return 1;
-}
-
static int _build_dev_string(char *devbuf, size_t bufsize, struct dm_tree_node *node)
{
if (!dm_format_dev(devbuf, bufsize, node->info.major, node->info.minor)) {
@@ -2846,6 +2823,16 @@ static int _dm_tree_revert_activated(struct dm_tree_node *parent)
return 1;
}
+static int _dm_tree_wait_and_revert_activated(struct dm_tree_node *dnode)
+{
+ if (!dm_udev_wait(dm_tree_get_cookie(dnode)))
+ stack;
+
+ dm_tree_set_cookie(dnode, 0);
+
+ return _dm_tree_revert_activated(dnode);
+}
+
int dm_tree_preload_children(struct dm_tree_node *dnode,
const char *uuid_prefix,
size_t uuid_prefix_len)
@@ -2875,7 +2862,7 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
return_0;
/* FIXME Cope if name exists with no uuid? */
- if (!child->info.exists && !(node_created = _create_node(child)))
+ if (!child->info.exists && !(node_created = _create_node(child, dnode)))
return_0;
/* Propagate delayed resume from exteded child node */
@@ -2885,18 +2872,15 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
if (!child->info.inactive_table &&
child->props.segment_count &&
!_load_node(child)) {
+ stack;
/*
- * If the table load does not succeed, we remove the
- * device in the kernel that would otherwise have an
- * empty table. This makes the create + load of the
- * device atomic. However, if other dependencies have
- * already been created and loaded; this code is
- * insufficient to remove those - only the node
- * encountering the table load failure is removed.
+ * If the table load fails, try to device in the kernel
+ * together with other created and preloaded devices.
*/
- if (node_created && !_remove_node(child))
- return_0;
- return_0;
+ if (!_dm_tree_wait_and_revert_activated(dnode))
+ stack;
+ r = 0;
+ continue;
}
/* No resume for a device without parents or with unchanged or smaller size */
@@ -2911,28 +2895,19 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
&child->info, &child->dtree->cookie, child->udev_flags,
child->info.suspended)) {
log_error("Unable to resume %s.", _node_name(child));
- /* If the device was not previously active, we might as well remove this node. */
- if (!child->info.live_table &&
- !_deactivate_node(child->name, child->info.major, child->info.minor,
- &child->dtree->cookie, child->udev_flags, 0))
- log_error("Unable to deactivate %s.", _node_name(child));
+ if (!_dm_tree_wait_and_revert_activated(dnode))
+ stack;
r = 0;
- /* Each child is handled independently */
continue;
}
if (node_created) {
- /* Collect newly introduced devices for revert */
- dm_list_add_h(&dnode->activated, &child->activated_list);
-
/* When creating new node also check transaction_id. */
if (child->props.send_messages &&
!_node_send_messages(child, uuid_prefix, uuid_prefix_len, 0)) {
stack;
- if (!dm_udev_wait(dm_tree_get_cookie(dnode)))
+ if (!_dm_tree_wait_and_revert_activated(dnode))
stack;
- dm_tree_set_cookie(dnode, 0);
- (void) _dm_tree_revert_activated(dnode);
r = 0;
continue;
}
3 years, 6 months
master - debug: shorten error message
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b75c2dfe1b28efae08b...
Commit: b75c2dfe1b28efae08be9c7b55e904b8b695a8cd
Parent: b2a326b511950c301fceb7f4901671af53f0e8af
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Oct 19 14:28:58 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Oct 19 16:53:18 2020 +0200
debug: shorten error message
Just check for sigint during log_error().
---
lib/metadata/lv_manip.c | 26 ++++++++------------------
1 file changed, 8 insertions(+), 18 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 4f59900d1..72c85914d 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -7682,13 +7682,10 @@ int wipe_lv(struct logical_volume *lv, struct wipe_params wp)
TYPE_DM_SNAPSHOT_COW,
wp.yes, wp.force, NULL)) {
sigint_restore();
- if (sigint_caught()) {
- log_error("Interrupted initialization logical volume %s.",
- display_lvname(lv));
- return 0;
- }
label_scan_invalidate(dev);
- log_error("Filed to wipe signatures of logical volume %s.",
+ log_error("%s logical volume %s.",
+ sigint_caught() ?
+ "Interrupted initialization of" : "Failed to wipe signatures on",
display_lvname(lv));
return 0;
}
@@ -7733,12 +7730,9 @@ int wipe_lv(struct logical_volume *lv, struct wipe_params wp)
log_sys_debug("ioctl", "BLKZEROOUT");
sigint_restore();
label_scan_invalidate(dev);
- if (sigint_caught())
- log_error("Interrupted initialization logical volume %s.",
- display_lvname(lv));
- else
- log_error("Failed to initialize logical volume %s at position " FMTu64 " and size " FMTu64 ".",
- display_lvname(lv), range[0], range[1]);
+ log_error("%s logical volume %s at position " FMTu64 " and size " FMTu64 ".",
+ sigint_caught() ? "Interrupted initialization of" : "Failed to initialize",
+ display_lvname(lv), range[0], range[1]);
return 0;
}
}
@@ -7747,12 +7741,8 @@ retry_with_dev_set:
#endif
if (!dev_set_bytes(dev, UINT64_C(0), (size_t) zero_sectors << SECTOR_SHIFT, wp.zero_value)) {
sigint_restore();
- if (sigint_caught()) {
- log_error("Interrupted initialization logical volume %s.",
- display_lvname(lv));
- return 0;
- }
- log_error("Failed to initialize %s of logical volume %s with value %d.",
+ log_error("%s %s of logical volume %s with value %d.",
+ sigint_caught() ? "Interrupted initialization" : "Failed to initialize",
display_size(lv->vg->cmd, zero_sectors),
display_lvname(lv), wp.zero_value);
return 0;
3 years, 6 months
master - libdm: validate thin-pool before sending messages
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b2a326b511950c301fc...
Commit: b2a326b511950c301fceb7f4901671af53f0e8af
Parent: 4b0565b82f9f2bab0d9fdbc23c63e63cbddba61d
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Sep 28 23:12:48 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Oct 19 16:53:18 2020 +0200
libdm: validate thin-pool before sending messages
Alhtough lvm2 does validation on its side, ensure DM code
is not sending messages to failed thin pool.
---
libdm/libdm-deptree.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index ffd084e52..59616eb3a 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -1600,6 +1600,15 @@ static int _node_send_messages(struct dm_tree_node *dnode,
if (!have_messages || !send)
return 1; /* transaction_id is matching */
+ if (stp.fail || stp.read_only || stp.needs_check) {
+ log_error("Cannot send messages to thin pool %s%s%s%s.",
+ _node_name(dnode),
+ stp.fail ? " in failed state" : "",
+ stp.read_only ? " with read only metadata" : "",
+ stp.needs_check ? " which needs check first" : "");
+ return 0;
+ }
+
dm_list_iterate_items(tmsg, &seg->thin_messages) {
if (!(_thin_pool_node_message(dnode, tmsg)))
return_0;
3 years, 6 months
master - libdm: enhance error message
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4b0565b82f9f2bab0d9...
Commit: 4b0565b82f9f2bab0d9fdbc23c63e63cbddba61d
Parent: 4c1caa7e26b6f8011ca083395650d11943a42a8a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Sep 25 19:10:30 2020 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Mon Oct 19 16:53:18 2020 +0200
libdm: enhance error message
---
libdm/libdm-deptree.c | 33 +++++++++++++++++++++++++++++++--
1 file changed, 31 insertions(+), 2 deletions(-)
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 887e8f275..ffd084e52 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -1503,8 +1503,37 @@ static int _thin_pool_node_message(struct dm_tree_node *dnode, struct thin_messa
}
if (!_node_message(dnode->info.major, dnode->info.minor,
- tm->expected_errno, buf))
- return_0;
+ tm->expected_errno, buf)) {
+ switch (m->type) {
+ case DM_THIN_MESSAGE_CREATE_SNAP:
+ case DM_THIN_MESSAGE_CREATE_THIN:
+ if (errno == EEXIST) {
+ /*
+ * ATM errno from ioctl() is preserved through code error path chain
+ * If this would ever change, another way need to be used to
+ * obtain result from failed DM message
+ */
+ log_error("Thin pool %s already contain thin device with device_id %u.",
+ _node_name(dnode), m->u.m_create_snap.device_id);
+ /*
+ * TODO:
+ *
+ * Give some useful advice how to solve this problem,
+ * until lvconvert --repair can handle this automatically
+ */
+ log_error("Manual intervention may be required to remove device dev_id=%u in thin pool metadata.",
+ m->u.m_create_snap.device_id);
+ log_error("Optionally new thin volume with device_id=%u can be manually added into a volume group.",
+ m->u.m_create_snap.device_id);
+ log_warn("WARNING: When uncertain how to do this, contact support!");
+ return 0;
+ }
+ /* fall through */
+ default:
+ return_0;
+ }
+
+ }
return 1;
}
3 years, 6 months