summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2020-12-09 17:36:09 -0600
committerDavid Teigland <teigland@redhat.com>2020-12-09 17:36:09 -0600
commit9fe7aba251ff24c14277dfdf9be2d861a7699230 (patch)
tree638d631dafd2d28f98b2e0cbe79243c232ce4f44
parent57594fe673587ea33a6521733376862055ecbd65 (diff)
downloadlvm2-9fe7aba251ff24c14277dfdf9be2d861a7699230.tar.gz
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.
-rw-r--r--lib/activate/dev_manager.c36
-rw-r--r--lib/metadata/lv.c31
-rw-r--r--lib/metadata/lv.h3
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,