| From d06ad77b47f4dfd25bc3da88c0621ac073ad8ce5 Mon Sep 17 00:00:00 2001 |
| From: Zdenek Kabelac <zkabelac@redhat.com> |
| Date: Fri, 23 Aug 2019 13:08:34 +0200 |
| Subject: [PATCH 2/3] activation: extend handling of pending_delete |
| |
| With previous patch 30a98e4d6710a543692d40d11428ae4baea11b7b we |
| started to put devices one pending_delete list instead |
| of directly scheduling their removal. |
| |
| However we have operations like 'snapshot merge' where we are |
| resuming device tree in 2 subsequent activation calls - so |
| 1st such call will still have suspened devices and no chance |
| to push 'remove' ioctl. |
| |
| Since we curently cannot easily solve this by doing just single |
| activation call (which would be preferred solution) - we introduce |
| a preservation of pending_delete via command structure and |
| then restore it on next activation call. |
| |
| This way we keep to remove devices later - although it might be |
| not the best moment - this may need futher tunning. |
| |
| Also we don't keep the list of operation in 1 trasaction |
| (unless we do verify udev symlinks) - this could probably |
| also make it more correct in terms of which 'remove' can |
| be combined we already running 'resume'. |
| |
| Upstream-Status: Backport |
| Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com> |
| --- |
| lib/activate/dev_manager.c | 24 +++++++++++------------- |
| lib/commands/toolcontext.c | 8 ++++++++ |
| lib/commands/toolcontext.h | 1 + |
| 3 files changed, 20 insertions(+), 13 deletions(-) |
| |
| diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c |
| index 7101ffa12..7a7689291 100644 |
| --- a/lib/activate/dev_manager.c |
| +++ b/lib/activate/dev_manager.c |
| @@ -3591,6 +3591,7 @@ static int _clean_tree(struct dev_manager *dm, struct dm_tree_node *root, const |
| if (!dm_tree_deactivate_children(root, dl->str, strlen(dl->str))) |
| return_0; |
| } |
| + dm_list_init(&dm->pending_delete); |
| } |
| |
| return 1; |
| @@ -3717,25 +3718,22 @@ out_no_root: |
| int dev_manager_activate(struct dev_manager *dm, const struct logical_volume *lv, |
| struct lv_activate_opts *laopts) |
| { |
| + dm_list_splice(&dm->pending_delete, &lv->vg->cmd->pending_delete); |
| + |
| if (!_tree_action(dm, lv, laopts, ACTIVATE)) |
| return_0; |
| |
| - /* |
| - * When lvm2 resumes a device and shortly after that it removes it, |
| - * udevd rule will try to blindly call 'dmsetup info' on already removed |
| - * device leaving the trace inside syslog about failing operation. |
| - * |
| - * TODO: It's not completely clear this call here is the best fix. |
| - * Maybe there can be a better sequence, but ATM we do usually resume |
| - * error device i.e. on cache deletion and remove it. |
| - * TODO2: there could be more similar cases! |
| - */ |
| - if (!dm_list_empty(&dm->pending_delete)) |
| - fs_unlock(); |
| - |
| if (!_tree_action(dm, lv, laopts, CLEAN)) |
| return_0; |
| |
| + if (!dm_list_empty(&dm->pending_delete)) { |
| + log_debug("Preserving %d device(s) for removal while being suspended.", |
| + dm_list_size(&dm->pending_delete)); |
| + if (!(str_list_dup(lv->vg->cmd->mem, &lv->vg->cmd->pending_delete, |
| + &dm->pending_delete))) |
| + return_0; |
| + } |
| + |
| return 1; |
| } |
| |
| diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c |
| index 1e03ea235..0a9355361 100644 |
| --- a/lib/commands/toolcontext.c |
| +++ b/lib/commands/toolcontext.c |
| @@ -1734,6 +1734,8 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd, |
| cmd->current_settings = cmd->default_settings; |
| |
| cmd->initialized.config = 1; |
| + |
| + dm_list_init(&cmd->pending_delete); |
| out: |
| if (!cmd->initialized.config) { |
| destroy_toolcontext(cmd); |
| @@ -1922,6 +1924,12 @@ int refresh_toolcontext(struct cmd_context *cmd) |
| |
| cmd->initialized.config = 1; |
| |
| + if (!dm_list_empty(&cmd->pending_delete)) { |
| + log_debug(INTERNAL_ERROR "Unprocessed pending delete for %d devices.", |
| + dm_list_size(&cmd->pending_delete)); |
| + dm_list_init(&cmd->pending_delete); |
| + } |
| + |
| if (cmd->initialized.connections && !init_connections(cmd)) |
| return_0; |
| |
| diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h |
| index 6e4530c8a..54ddec320 100644 |
| --- a/lib/commands/toolcontext.h |
| +++ b/lib/commands/toolcontext.h |
| @@ -237,6 +237,7 @@ struct cmd_context { |
| const char *report_list_item_separator; |
| const char *time_format; |
| unsigned rand_seed; |
| + struct dm_list pending_delete; /* list of LVs for removal */ |
| }; |
| |
| /* |
| -- |
| 2.21.0 |
| |