diff options
author | Peter Rajnoha <prajnoha@redhat.com> | 2015-07-13 14:02:26 +0200 |
---|---|---|
committer | Peter Rajnoha <prajnoha@redhat.com> | 2015-07-14 16:22:45 +0200 |
commit | a50ab30fc19f592a4822a0b626886f578ea2f339 (patch) | |
tree | cdc7b580e9d3264a60de1be7abbb119b17bc15e5 | |
parent | fe4587458ccb0848aa527b80e5579f70b880ab91 (diff) | |
download | lvm2-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.in | 14 | ||||
-rw-r--r-- | lib/commands/toolcontext.c | 1 | ||||
-rw-r--r-- | lib/commands/toolcontext.h | 1 | ||||
-rw-r--r-- | lib/config/config_settings.h | 13 | ||||
-rw-r--r-- | lib/config/defaults.h | 1 | ||||
-rw-r--r-- | lib/format_text/import_vsn1.c | 20 | ||||
-rw-r--r-- | lib/metadata/pool_manip.c | 13 |
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, |