Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=9fe7aba251ff24c14277df... Commit: 9fe7aba251ff24c14277dfdf9be2d861a7699230 Parent: 57594fe673587ea33a6521733376862055ecbd65 Author: David Teigland teigland@redhat.com AuthorDate: Wed Dec 9 17:36:09 2020 -0600 Committer: David Teigland teigland@redhat.com CommitterDate: Wed Dec 9 17:36:09 2020 -0600
cache: activation cache_check on cachevol
When using cache with a cachevol, the cache_check tool was not being run on the cache metadata during activation. cache_check clears the needs_check flag in the cache metadata, so if the flag was set due to an unclean shutdown, the activation would fail. --- lib/activate/dev_manager.c | 36 ++++++++++++++++++++++++------------ lib/metadata/lv.c | 31 +++++++++++++++++++++++++++++++ lib/metadata/lv.h | 3 +++ 3 files changed, 58 insertions(+), 12 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c index 85cfda246..8d27bd363 100644 --- a/lib/activate/dev_manager.c +++ b/lib/activate/dev_manager.c @@ -2270,21 +2270,31 @@ static int _pool_callback(struct dm_tree_node *node, const struct pool_cb_data *data = cb_data; const struct logical_volume *pool_lv = data->pool_lv; const struct logical_volume *mlv = first_seg(pool_lv)->metadata_lv; + struct cmd_context *cmd = pool_lv->vg->cmd; long buf[64 / sizeof(long)]; /* buffer for short disk header (64B) */ int args = 0; char *mpath; const char *argv[19] = { /* Max supported 15 args */ - find_config_tree_str_allow_empty(pool_lv->vg->cmd, data->exec, NULL) + find_config_tree_str_allow_empty(cmd, data->exec, NULL) };
if (!*argv[0]) /* *_check tool is unconfigured/disabled with "" setting */ return 1;
- if (!(mpath = lv_dmpath_dup(data->dm->mem, mlv))) { - log_error("Failed to build device path for checking pool metadata %s.", - display_lvname(mlv)); - return 0; + if (lv_is_cache_vol(pool_lv)) { + if (!(mpath = lv_dmpath_suffix_dup(data->dm->mem, pool_lv, "-cmeta"))) { + log_error("Failed to build device path for checking cachevol metadata %s.", + display_lvname(pool_lv)); + return 0; + } + } else { + if (!(mpath = lv_dmpath_dup(data->dm->mem, mlv))) { + log_error("Failed to build device path for checking pool metadata %s.", + display_lvname(mlv)); + return 0; + } } + log_debug("Running check command on %s", mpath);
if (data->skip_zero) { if ((fd = open(mpath, O_RDONLY)) < 0) { @@ -2312,7 +2322,7 @@ static int _pool_callback(struct dm_tree_node *node, } }
- if (!(cn = find_config_tree_array(mlv->vg->cmd, data->opts, NULL))) { + if (!(cn = find_config_tree_array(cmd, data->opts, NULL))) { log_error(INTERNAL_ERROR "Unable to find configuration for pool check options."); return 0; } @@ -2334,7 +2344,7 @@ static int _pool_callback(struct dm_tree_node *node,
argv[++args] = mpath;
- if (!(ret = exec_cmd(pool_lv->vg->cmd, (const char * const *)argv, + if (!(ret = exec_cmd(cmd, (const char * const *)argv, &status, 0))) { if (status == ENOENT) { log_warn("WARNING: Check is skipped, please install recommended missing binary %s!", @@ -2343,7 +2353,7 @@ static int _pool_callback(struct dm_tree_node *node, }
if ((data->version.maj || data->version.min || data->version.patch) && - !_check_tool_version(pool_lv->vg->cmd, argv[0], + !_check_tool_version(cmd, argv[0], data->version.maj, data->version.min, data->version.patch)) { log_warn("WARNING: Check is skipped, please upgrade installed version of %s!", argv[0]); @@ -2387,10 +2397,6 @@ static int _pool_register_callback(struct dev_manager *dm, return 1; #endif
- /* Skip for single-device cache pool */ - if (lv_is_cache(lv) && lv_is_cache_vol(first_seg(lv)->pool_lv)) - return 1; - if (!(data = dm_pool_zalloc(dm->mem, sizeof(*data)))) { log_error("Failed to allocated path for callback."); return 0; @@ -3483,6 +3489,12 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, !_pool_register_callback(dm, dnode, lv)) return_0;
+ if (lv_is_cache(lv) && lv_is_cache_vol(first_seg(lv)->pool_lv) && + /* Register callback only for layer activation or non-layered cache LV */ + (layer || !lv_layer(lv)) && + !_pool_register_callback(dm, dnode, lv)) + return_0; + /* * Update tables for ANY PVMOVE holders for active LV where the name starts with 'pvmove', * but it's not anymore PVMOVE LV and also it's not a PVMOVE _mimage LV. diff --git a/lib/metadata/lv.c b/lib/metadata/lv.c index fac47e530..475f21191 100644 --- a/lib/metadata/lv.c +++ b/lib/metadata/lv.c @@ -1034,6 +1034,37 @@ char *lv_dmpath_dup(struct dm_pool *mem, const struct logical_volume *lv) return repstr; }
+/* maybe factor a common function with lv_dmpath_dup */ +char *lv_dmpath_suffix_dup(struct dm_pool *mem, const struct logical_volume *lv, + const char *suffix) +{ + char *name; + char *repstr; + size_t len; + + if (!*lv->vg->name) + return dm_pool_strdup(mem, ""); + + if (!(name = dm_build_dm_name(mem, lv->vg->name, lv->name, NULL))) { + log_error("dm_build_dm_name failed"); + return NULL; + } + + len = strlen(dm_dir()) + strlen(name) + strlen(suffix) + 2; + + if (!(repstr = dm_pool_zalloc(mem, len))) { + log_error("dm_pool_alloc failed"); + return NULL; + } + + if (dm_snprintf(repstr, len, "%s/%s%s", dm_dir(), name, suffix) < 0) { + log_error("lv_dmpath snprintf failed"); + return NULL; + } + + return repstr; +} + char *lv_uuid_dup(struct dm_pool *mem, const struct logical_volume *lv) { return id_format_and_copy(mem ? mem : lv->vg->vgmem, &lv->lvid.id[1]); diff --git a/lib/metadata/lv.h b/lib/metadata/lv.h index e2e640f5d..28bd4b869 100644 --- a/lib/metadata/lv.h +++ b/lib/metadata/lv.h @@ -194,6 +194,9 @@ char *lv_lock_args_dup(struct dm_pool *mem, const struct logical_volume *lv); char *lvseg_kernel_discards_dup_with_info_and_seg_status(struct dm_pool *mem, const struct lv_with_info_and_seg_status *lvdm); char *lv_time_dup(struct dm_pool *mem, const struct logical_volume *lv, int iso_mode);
+char *lv_dmpath_suffix_dup(struct dm_pool *mem, const struct logical_volume *lv, + const char *suffix); + typedef enum { PERCENT_GET_DATA = 0, PERCENT_GET_METADATA,
lvm2-commits@lists.fedorahosted.org