Gitweb:
https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ad86cda4d79704dcce1...
Commit: ad86cda4d79704dcce13d98cd9579baab56b7e7b
Parent: 36523a398d50381f8355e719b98c3ce584b81a23
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Aug 27 12:18:47 2019 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Aug 27 15:59:33 2019 +0200
activation: use cmd pending mem for pending_delete
Since we need to preserve allocated strings across 2 separate
activation calls of '_tree_action()' we need to use other mem
pool them dm->mem - but since cmd->mem is released between
individual lvm2 locking calls, we rather introduce a new separate
mem pool just for pending deletes with easy to see life-span.
(not using 'libmem' as it would basicaly keep allocations over
the whole lifetime of clvmd)
This patch is fixing previous commmit where the memory was
improperly used after pool release.
---
lib/activate/dev_manager.c | 31 ++++++++++++-------------------
lib/commands/toolcontext.c | 10 ++++++++++
lib/commands/toolcontext.h | 1 +
3 files changed, 23 insertions(+), 19 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index dd585da..dc64159 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -64,7 +64,6 @@ struct dev_manager {
int activation; /* building activation tree */
int suspend; /* building suspend tree */
unsigned track_external_lv_deps;
- struct dm_list pending_delete; /* str_list of dlid(s) with pending delete */
unsigned track_pending_delete;
unsigned track_pvmove_deps;
@@ -1251,8 +1250,6 @@ struct dev_manager *dev_manager_create(struct cmd_context *cmd,
dm_udev_set_sync_support(cmd->current_settings.udev_sync);
- dm_list_init(&dm->pending_delete);
-
return dm;
bad:
@@ -1939,7 +1936,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree
*dtree,
if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
return_0;
- if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
+ 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))
@@ -1981,7 +1978,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree
*dtree,
if (info.exists && dm->track_pending_delete) {
log_debug_activation("Tracking pending delete for %s (%s).",
display_lvname(lv), dlid);
- if (!str_list_add(dm->mem, &dm->pending_delete, dlid))
+ if (!str_list_add(dm->cmd->pending_delete_mem,
&dm->cmd->pending_delete, dlid))
return_0;
}
@@ -3218,20 +3215,26 @@ static int _clean_tree(struct dev_manager *dm, struct dm_tree_node
*root, const
if (non_toplevel_tree_dlid && !strcmp(non_toplevel_tree_dlid, uuid))
continue;
- if (!str_list_add(dm->mem, &dm->pending_delete, uuid))
+ if (!(uuid = dm_pool_strdup(dm->cmd->pending_delete_mem, uuid))) {
+ log_error("_clean_tree: Failed to duplicate uuid.");
+ return 0;
+ }
+
+ if (!str_list_add(dm->cmd->pending_delete_mem,
&dm->cmd->pending_delete, uuid))
return_0;
}
/* Deactivate any tracked pending delete nodes */
- if (!dm_list_empty(&dm->pending_delete) && !dm_get_suspended_counter())
{
+ if (!dm_list_empty(&dm->cmd->pending_delete) &&
!dm_get_suspended_counter()) {
fs_unlock();
dm_tree_set_cookie(root, fs_get_cookie());
- dm_list_iterate_items(dl, &dm->pending_delete) {
+ dm_list_iterate_items(dl, &dm->cmd->pending_delete) {
log_debug_activation("Deleting tracked UUID %s.", dl->str);
if (!dm_tree_deactivate_children(root, dl->str, strlen(dl->str)))
return_0;
}
- dm_list_init(&dm->pending_delete);
+ dm_list_init(&dm->cmd->pending_delete);
+ dm_pool_empty(dm->cmd->pending_delete_mem);
}
return 1;
@@ -3358,22 +3361,12 @@ 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;
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 c90cb57..95fb343 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1761,6 +1761,8 @@ void destroy_config_context(struct cmd_context *cmd)
dm_pool_destroy(cmd->mem);
if (cmd->libmem)
dm_pool_destroy(cmd->libmem);
+ if (cmd->pending_delete_mem)
+ dm_pool_destroy(cmd->pending_delete_mem);
dm_free(cmd);
}
@@ -1789,6 +1791,9 @@ struct cmd_context *create_config_context(void)
if (!(cmd->mem = dm_pool_create("command", 4 * 1024)))
goto out;
+ if (!(cmd->pending_delete_mem = dm_pool_create("pending_delete", 1024)))
+ goto_out;
+
dm_list_init(&cmd->config_files);
dm_list_init(&cmd->tags);
@@ -1937,6 +1942,9 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd,
goto out;
}
+ if (!(cmd->pending_delete_mem = dm_pool_create("pending_delete", 1024)))
+ goto_out;
+
if (!_init_lvm_conf(cmd))
goto_out;
@@ -2264,6 +2272,8 @@ void destroy_toolcontext(struct cmd_context *cmd)
if (cmd->libmem)
dm_pool_destroy(cmd->libmem);
+ if (cmd->pending_delete_mem)
+ dm_pool_destroy(cmd->pending_delete_mem);
#ifndef VALGRIND_POOL
if (cmd->linebuffer) {
/* Reset stream buffering to defaults */
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 9c225b8..4b2a079 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -232,6 +232,7 @@ struct cmd_context {
const char *time_format;
unsigned rand_seed;
struct dm_list pending_delete; /* list of LVs for removal */
+ struct dm_pool *pending_delete_mem; /* memory pool for pending deletes */
};
/*