summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Rajnoha <prajnoha@redhat.com>2015-07-13 14:02:26 +0200
committerPeter Rajnoha <prajnoha@redhat.com>2015-07-14 16:22:45 +0200
commita50ab30fc19f592a4822a0b626886f578ea2f339 (patch)
treecdc7b580e9d3264a60de1be7abbb119b17bc15e5
parentfe4587458ccb0848aa527b80e5579f70b880ab91 (diff)
downloadlvm2-dev-prajnoha-report-select-extensions.tar.gz
config: add metadata/removed_ancestor_lv_names_to_trackdev-prajnoha-report-select-extensions
Limit the number of removed ancestor LV names to track - the number of removed LVs from the ancestor chain can go into infinity otherwise by adding new items and then removing to/from the ancestry chain. Add metadata/removed_ancestor_lv_names_to_track to limit the number of removed LVs to track in the ancestry chain or even disable it completely (metadata/removed_ancestor_lv_names=0).
-rw-r--r--conf/example.conf.in14
-rw-r--r--lib/commands/toolcontext.c1
-rw-r--r--lib/commands/toolcontext.h1
-rw-r--r--lib/config/config_settings.h13
-rw-r--r--lib/config/defaults.h1
-rw-r--r--lib/format_text/import_vsn1.c20
-rw-r--r--lib/metadata/pool_manip.c13
7 files changed, 54 insertions, 9 deletions
diff --git a/conf/example.conf.in b/conf/example.conf.in
index 3900ad41b..48a298b34 100644
--- a/conf/example.conf.in
+++ b/conf/example.conf.in
@@ -1366,6 +1366,20 @@ activation {
# This configuration option is advanced.
# stripesize = 64
+ # Configuration option metadata/removed_ancestor_lv_names_to_track.
+ # Number of removed ancestor LV names to track.
+ # Thin snapshots can be chained so that one thin snapshot can
+ # be an origin for another thin snapshot (snapshot of a snapshot),
+ # hence creating an ancestry chain. The length of the chain is
+ # limited only by available metadata and memory size. When an LV
+ # is removed from the chain, LVM is able to remember its name.
+ # Then, LVM is able to display even removed LVs when ancestors and
+ # descendants are reported (lv_full_ancestors and lv_full_descendants
+ # reporting fields).
+ # This setting limits the number of removed LVs to track.
+ # Set to 0 to disable this feature.
+ # removed_ancestor_lv_names_to_track = 10
+
# Configuration option metadata/dirs.
# Directories holding live copies of text format metadata.
# These directories must not be on logical volumes!
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 002627bd3..3a74350e6 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -477,6 +477,7 @@ int process_profilable_config(struct cmd_context *cmd)
cmd->report_binary_values_as_numeric = find_config_tree_bool(cmd, report_binary_values_as_numeric_CFG, NULL);
cmd->default_settings.suffix = find_config_tree_bool(cmd, global_suffix_CFG, NULL);
cmd->report_list_item_separator = find_config_tree_str(cmd, report_list_item_separator_CFG, NULL);
+ cmd->removed_ancestor_lv_names_to_track = find_config_tree_int(cmd, metadata_removed_ancestor_lv_names_to_track_CFG, NULL);
if (!(cmd->time_format = _set_time_format(cmd)))
return 0;
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 283783f5d..eddc5abca 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -95,6 +95,7 @@ struct cmd_context {
unsigned ignore_clustered_vgs:1;
unsigned threaded:1; /* Set if running within a thread e.g. clvmd */
+ unsigned removed_ancestor_lv_names_to_track;
const char *time_format;
unsigned independent_metadata_areas:1; /* Active formats have MDAs outside PVs */
diff --git a/lib/config/config_settings.h b/lib/config/config_settings.h
index ce03b36be..1fb4f3fea 100644
--- a/lib/config/config_settings.h
+++ b/lib/config/config_settings.h
@@ -1318,6 +1318,19 @@ cfg(metadata_pvmetadataignore_CFG, "pvmetadataignore", metadata_CFG_SECTION, CFG
cfg(metadata_stripesize_CFG, "stripesize", metadata_CFG_SECTION, CFG_ADVANCED | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_STRIPESIZE, vsn(1, 0, 0), NULL, 0, NULL, NULL)
+cfg(metadata_removed_ancestor_lv_names_to_track_CFG, "removed_ancestor_lv_names_to_track", metadata_CFG_SECTION, CFG_PROFILABLE | CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_REMOVED_ANCESTOR_LV_NAMES_TO_TRACK, vsn(2, 2, 126), NULL, 0, NULL,
+ "Number of removed ancestor LV names to track.\n"
+ "Thin snapshots can be chained so that one thin snapshot can\n"
+ "be an origin for another thin snapshot (snapshot of a snapshot),\n"
+ "hence creating an ancestry chain. The length of the chain is\n"
+ "limited only by available metadata and memory size. When an LV\n"
+ "is removed from the chain, LVM is able to remember its name.\n"
+ "Then, LVM is able to display even removed LVs when ancestors and\n"
+ "descendants are reported (lv_full_ancestors and lv_full_descendants\n"
+ "reporting fields).\n"
+ "This setting limits the number of removed LVs to track.\n"
+ "Set to 0 to disable this feature.\n")
+
cfg_array(metadata_dirs_CFG, "dirs", metadata_CFG_SECTION, CFG_ADVANCED | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL, 0, NULL,
"Directories holding live copies of text format metadata.\n"
"These directories must not be on logical volumes!\n"
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 5ee9b1c4e..578a8e897 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -129,6 +129,7 @@
#define DEFAULT_PVMETADATASIZE 255
#define DEFAULT_PVMETADATACOPIES 1
#define DEFAULT_VGMETADATACOPIES 0
+#define DEFAULT_REMOVED_ANCESTOR_LV_NAMES_TO_TRACK 10
#define DEFAULT_LABELSECTOR UINT64_C(1)
#define DEFAULT_READ_AHEAD "auto"
#define DEFAULT_UDEV_RULES 1
diff --git a/lib/format_text/import_vsn1.c b/lib/format_text/import_vsn1.c
index 12564714d..3304ae131 100644
--- a/lib/format_text/import_vsn1.c
+++ b/lib/format_text/import_vsn1.c
@@ -155,12 +155,18 @@ static int _read_flag_config(const struct dm_config_node *n, uint64_t *status, i
return 1;
}
-static int _read_str_list(struct dm_pool *mem, struct dm_list *list, const struct dm_config_value *cv)
+static int _read_str_list(struct dm_pool *mem, struct dm_list *list,
+ const struct dm_config_value *cv,
+ int is_limited, unsigned limit)
{
+ unsigned i = 0;
+
if (cv->type == DM_CFG_EMPTY_ARRAY)
return 1;
while (cv) {
+ if (is_limited && (i >= limit))
+ break;
if (cv->type != DM_CFG_STRING) {
log_error("Found an item that is not a string");
return 0;
@@ -170,6 +176,7 @@ static int _read_str_list(struct dm_pool *mem, struct dm_list *list, const struc
return_0;
cv = cv->next;
+ i++;
}
return 1;
@@ -291,7 +298,7 @@ static int _read_pv(struct format_instance *fid,
/* Optional tags */
if (dm_config_get_list(pvn, "tags", &cv) &&
- !(_read_str_list(mem, &pv->tags, cv))) {
+ !(_read_str_list(mem, &pv->tags, cv, 0, 0))) {
log_error("Couldn't read tags for physical volume %s in %s.",
pv_dev_name(pv), vg->name);
return 0;
@@ -402,7 +409,7 @@ static int _read_segment(struct logical_volume *lv, const struct dm_config_node
/* Optional tags */
if (dm_config_get_list(sn_child, "tags", &cv) &&
- !(_read_str_list(mem, &seg->tags, cv))) {
+ !(_read_str_list(mem, &seg->tags, cv, 0, 0))) {
log_error("Couldn't read tags for a segment of %s/%s.",
lv->vg->name, lv->name);
return 0;
@@ -662,14 +669,15 @@ static int _read_lvnames(struct format_instance *fid __attribute__((unused)),
/* Optional tags */
if (dm_config_get_list(lvn, "tags", &cv) &&
- !(_read_str_list(mem, &lv->tags, cv))) {
+ !(_read_str_list(mem, &lv->tags, cv, 0, 0))) {
log_error("Couldn't read tags for logical volume %s/%s.",
vg->name, lv->name);
return 0;
}
if (dm_config_get_list(lvn, "removed_ancestor_lv_names", &cv) &&
- !(_read_str_list(mem, &lv->removed_ancestor_lv_names, cv))) {
+ !(_read_str_list(mem, &lv->removed_ancestor_lv_names, cv, 1,
+ vg->cmd->removed_ancestor_lv_names_to_track))) {
log_error("Couldn't read removed ancestor names for logical "
"volume %s/%s.", vg->name, lv->name);
return 0;
@@ -976,7 +984,7 @@ static struct volume_group *_read_vg(struct format_instance *fid,
/* Optional tags */
if (dm_config_get_list(vgn, "tags", &cv) &&
- !(_read_str_list(vg->vgmem, &vg->tags, cv))) {
+ !(_read_str_list(vg->vgmem, &vg->tags, cv, 0, 0))) {
log_error("Couldn't read tags for volume group %s.", vg->name);
goto bad;
}
diff --git a/lib/metadata/pool_manip.c b/lib/metadata/pool_manip.c
index 5ed7ad638..a71d79587 100644
--- a/lib/metadata/pool_manip.c
+++ b/lib/metadata/pool_manip.c
@@ -125,18 +125,23 @@ int attach_pool_lv(struct lv_segment *seg,
}
static int _copy_removed_ancestor_lv_names(struct logical_volume *lv_from,
- struct logical_volume *lv_to)
+ struct logical_volume *lv_to,
+ unsigned limit)
{
struct dm_str_list *sl_from, *sl_to;
const char *lv_name;
+ unsigned i = 0;
dm_list_iterate_items(sl_from, &lv_from->removed_ancestor_lv_names) {
+ if (i >= limit)
+ break;
if (!(sl_to = dm_pool_alloc(lv_to->vg->vgmem, sizeof(*sl_to))) ||
!(lv_name = dm_pool_strdup(lv_to->vg->vgmem, sl_from->str)))
return_0;
sl_to->str = lv_name;
dm_list_add(&lv_to->removed_ancestor_lv_names, &sl_to->list);
+ i++;
}
return 1;
@@ -236,7 +241,8 @@ int detach_pool_lv(struct lv_segment *seg)
!attach_thin_indirect_origin(sl->seg, origin))
return_0;
- if (!_copy_removed_ancestor_lv_names(seg->lv, sl->seg->lv))
+ if (!_copy_removed_ancestor_lv_names(seg->lv, sl->seg->lv,
+ sl->seg->lv->vg->cmd->removed_ancestor_lv_names_to_track - 1))
return_0;
if (!str_list_add_h_no_dup_check(sl->seg->lv->vg->vgmem,
@@ -263,7 +269,8 @@ int detach_pool_lv(struct lv_segment *seg)
!attach_thin_indirect_origin(sl->seg, origin))
return_0;
- if (!_copy_removed_ancestor_lv_names(seg->lv, sl->seg->lv))
+ if (!_copy_removed_ancestor_lv_names(seg->lv, sl->seg->lv,
+ sl->seg->lv->vg->cmd->removed_ancestor_lv_names_to_track - 1))
return_0;
if (!str_list_add_h_no_dup_check(seg->lv->vg->vgmem,