1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00

lvm-exec: refactor code

Add prepare_exec_args() for reading option list for
thin/cache_repair, thin/cache_check.
This commit is contained in:
Zdenek Kabelac 2023-07-16 17:35:20 +02:00
parent f78b02477b
commit 4d2311655b
6 changed files with 69 additions and 110 deletions

View File

@ -2457,8 +2457,6 @@ static int _pool_callback(struct dm_tree_node *node,
dm_node_callback_t type, void *cb_data)
{
int ret, status = 0, fd;
const struct dm_config_node *cn;
const struct dm_config_value *cv;
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;
@ -2466,11 +2464,11 @@ static int _pool_callback(struct dm_tree_node *node,
long buf[64 / sizeof(long)]; /* buffer for short disk header (64B) */
int args = 0;
char *mpath;
const char *argv[19] = { /* Max supported 15 args */
const char *argv[DEFAULT_MAX_EXEC_ARGS + 7] = { /* Max supported 15 args */
find_config_tree_str_allow_empty(cmd, data->exec, NULL)
};
if (!*argv[0]) /* *_check tool is unconfigured/disabled with "" setting */
if (!argv[0] || !*argv[0]) /* *_check tool is unconfigured/disabled with "" setting */
return 1;
if (lv_is_cache_vol(pool_lv)) {
@ -2517,26 +2515,8 @@ static int _pool_callback(struct dm_tree_node *node,
}
}
if (!(cn = find_config_tree_array(cmd, data->opts, NULL))) {
log_error(INTERNAL_ERROR "Unable to find configuration for pool check options.");
return 0;
}
for (cv = cn->v; cv && args < 16; cv = cv->next) {
if (cv->type != DM_CFG_STRING) {
log_error("Invalid string in config file: "
"global/%s_check_options.",
data->global);
return 0;
}
if (cv->v.str[0])
argv[++args] = cv->v.str;
}
if (args == 16) {
log_error("Too many options for %s command.", argv[0]);
return 0;
}
if (!prepare_exec_args(cmd, argv, &args, data->opts))
return_0;
argv[++args] = mpath;

View File

@ -105,6 +105,8 @@
# define DEFAULT_DMEVENTD_PATH DMEVENTD_PATH
#endif
#define DEFAULT_MAX_EXEC_ARGS 15 /* Max number of accepted options args */
#ifdef THIN_CHECK_NEEDS_CHECK
# define DEFAULT_THIN_CHECK_OPTION1 "-q"
# define DEFAULT_THIN_CHECK_OPTION2 "--clear-needs-check-flag"

View File

@ -460,9 +460,7 @@ int thin_pool_prepare_metadata(struct logical_volume *metadata_lv,
{
struct cmd_context *cmd = metadata_lv->vg->cmd;
char lv_path[PATH_MAX], md_path[64], buffer[512];
const struct dm_config_node *cn;
const struct dm_config_value *cv;
const char *argv[20] = { /* Max supported 15 option args */
const char *argv[DEFAULT_MAX_EXEC_ARGS + 7] = {
find_config_tree_str_allow_empty(cmd, global_thin_restore_executable_CFG, NULL)
};
int args = 0;
@ -477,25 +475,8 @@ int thin_pool_prepare_metadata(struct logical_volume *metadata_lv,
return 0;
}
if (!(cn = find_config_tree_array(cmd, global_thin_restore_options_CFG, NULL))) {
log_error(INTERNAL_ERROR "Unable to find configuration for pool check options.");
return 0;
}
for (cv = cn->v; cv && args < 16; cv = cv->next) {
if (cv->type != DM_CFG_STRING) {
log_error("Invalid string in config file: "
"global/thin_restore_options.");
return 0;
}
if (cv->v.str[0])
argv[++args] = cv->v.str;
}
if (args == 16) {
log_error("Too many options for %s command.", argv[0]);
return 0;
}
if (!prepare_exec_args(cmd, argv, &args, global_thin_restore_options_CFG))
return_0;
if (test_mode()) {
log_verbose("Test mode: Skipping creation of provisioned thin pool metadata.");

View File

@ -217,3 +217,34 @@ int pipe_close(struct pipe_data *pdata)
return (status == 0) ? 1 : 0;
}
int prepare_exec_args(struct cmd_context *cmd,
const char *argv[], int *argc, int options_id)
{
const struct dm_config_value *cv;
const struct dm_config_node *cn;
if (!(cn = find_config_tree_array(cmd, options_id, NULL))) {
log_error(INTERNAL_ERROR "Unable to find configuration for %s options.",
argv[0]);
return 0;
}
for (cv = cn->v; cv; cv = cv->next) {
if (*argc >= DEFAULT_MAX_EXEC_ARGS) {
log_error("Too many options for %s command.", argv[0]);
return 0;
}
if (cv->type != DM_CFG_STRING) {
log_error("Invalid string in config file: "
"global/%s_options.", argv[0]);
return 0;
}
if (cv->v.str[0])
argv[++(*argc)] = cv->v.str;
}
return 1;
}

View File

@ -67,4 +67,8 @@ FILE *pipe_open(struct cmd_context *cmd, const char *const argv[],
int pipe_close(struct pipe_data *pdata);
/* Prepare argv options list */
int prepare_exec_args(struct cmd_context *cmd,
const char *argv[], int *argc, int options_id);
#endif

View File

@ -19,8 +19,6 @@
#include "lib/metadata/metadata.h"
#include "lvconvert_poll.h"
#define MAX_PDATA_ARGS 10 /* Max number of accepted args for d-m-p-d tools */
typedef enum {
/* Split:
* For a mirrored or raid LV, split mirror into two mirrors, optionally tracking
@ -2341,13 +2339,11 @@ static int _lvconvert_thin_pool_repair(struct cmd_context *cmd,
const char *dmdir = dm_dir();
const char *thin_dump =
find_config_tree_str_allow_empty(cmd, global_thin_dump_executable_CFG, NULL);
const char *thin_repair =
find_config_tree_str_allow_empty(cmd, global_thin_repair_executable_CFG, NULL);
const struct dm_config_node *cn;
const struct dm_config_value *cv;
int ret = 0, status;
int args = 0;
const char *argv[MAX_PDATA_ARGS + 7]; /* Max supported args */
const char *argv[DEFAULT_MAX_EXEC_ARGS + 7] = { /* Max supported args */
find_config_tree_str_allow_empty(cmd, global_thin_repair_executable_CFG, NULL)
};
char *dm_name, *trans_id_str;
char meta_path[PATH_MAX];
char pms_path[PATH_MAX];
@ -2357,9 +2353,15 @@ static int _lvconvert_thin_pool_repair(struct cmd_context *cmd,
struct pipe_data pdata;
FILE *f;
if (!thin_repair || !thin_repair[0]) {
log_error("Thin repair commnand is not configured. Repair is disabled.");
return 0; /* Checking disabled */
if (!argv[0] || !*argv[0]) {
log_error("Thin repair command is not configured. Repair is disabled.");
return 0;
}
if (thin_pool_is_active(pool_lv)) {
log_error("Cannot repair active pool %s. Use lvchange -an first.",
display_lvname(pool_lv));
return 0;
}
pmslv = pool_lv->vg->pool_metadata_spare_lv;
@ -2388,36 +2390,13 @@ static int _lvconvert_thin_pool_repair(struct cmd_context *cmd,
return 0;
}
if (!(cn = find_config_tree_array(cmd, global_thin_repair_options_CFG, NULL))) {
log_error(INTERNAL_ERROR "Unable to find configuration for global/thin_repair_options");
return 0;
}
if (!prepare_exec_args(cmd, argv, &args, global_thin_repair_options_CFG))
return_0;
for (cv = cn->v; cv && args < MAX_PDATA_ARGS; cv = cv->next) {
if (cv->type != DM_CFG_STRING) {
log_error("Invalid string in config file: "
"global/thin_repair_options");
return 0;
}
argv[++args] = cv->v.str;
}
if (args >= MAX_PDATA_ARGS) {
log_error("Too many options for thin repair command.");
return 0;
}
argv[0] = thin_repair;
argv[++args] = "-i";
argv[++args] = meta_path;
argv[++args] = "-o";
argv[++args] = pms_path;
argv[++args] = NULL;
if (thin_pool_is_active(pool_lv)) {
log_error("Active pools cannot be repaired. Use lvchange -an first.");
return 0;
}
if (!activate_lv(cmd, pmslv)) {
log_error("Cannot activate pool metadata spare volume %s.",
@ -2439,7 +2418,7 @@ static int _lvconvert_thin_pool_repair(struct cmd_context *cmd,
}
/* Check matching transactionId when thin-pool is used by lvm2 (transactionId != 0) */
if (first_seg(pool_lv)->transaction_id && thin_dump[0]) {
if (first_seg(pool_lv)->transaction_id && thin_dump && thin_dump[0]) {
argv[0] = thin_dump;
argv[1] = pms_path;
argv[2] = NULL;
@ -2455,13 +2434,15 @@ static int _lvconvert_thin_pool_repair(struct cmd_context *cmd,
(trans_id_str = strstr(meta_path, "transaction=\"")) &&
(sscanf(trans_id_str + 13, FMTu64, &trans_id) == 1) &&
(trans_id != first_seg(pool_lv)->transaction_id) &&
((trans_id - 1) != first_seg(pool_lv)->transaction_id))
((trans_id - 1) != first_seg(pool_lv)->transaction_id)) {
log_error("Transaction id " FMTu64 " from pool \"%s/%s\" "
"does not match repaired transaction id "
FMTu64 " from %s.",
first_seg(pool_lv)->transaction_id,
pool_lv->vg->name, pool_lv->name, trans_id,
pms_path);
ret = 0;
}
(void) pipe_close(&pdata); /* killing pipe */
}
@ -2539,13 +2520,11 @@ static int _lvconvert_cache_repair(struct cmd_context *cmd,
struct dm_list *pvh, int poolmetadataspare)
{
const char *dmdir = dm_dir();
const char *cache_repair =
find_config_tree_str_allow_empty(cmd, global_cache_repair_executable_CFG, NULL);
const struct dm_config_node *cn;
const struct dm_config_value *cv;
int ret = 0, status;
int args = 0;
const char *argv[MAX_PDATA_ARGS + 7]; /* Max supported args */
const char *argv[DEFAULT_MAX_EXEC_ARGS + 7] = { /* Max supported args */
find_config_tree_str_allow_empty(cmd, global_cache_repair_executable_CFG, NULL)
};
char *dm_name;
char meta_path[PATH_MAX];
char pms_path[PATH_MAX];
@ -2561,8 +2540,8 @@ static int _lvconvert_cache_repair(struct cmd_context *cmd,
pool_lv = lv_is_cache_pool(cache_lv) ? cache_lv : first_seg(cache_lv)->pool_lv;
mlv = first_seg(pool_lv)->metadata_lv;
if (!cache_repair || !cache_repair[0]) {
log_error("Cache repair commnand is not configured. Repair is disabled.");
if (!argv[0] || !*argv[0]) {
log_error("Cache repair command is not configured. Repair is disabled.");
return 0; /* Checking disabled */
}
@ -2592,31 +2571,13 @@ static int _lvconvert_cache_repair(struct cmd_context *cmd,
return 0;
}
if (!(cn = find_config_tree_array(cmd, global_cache_repair_options_CFG, NULL))) {
log_error(INTERNAL_ERROR "Unable to find configuration for global/cache_repair_options");
return 0;
}
if (!prepare_exec_args(cmd, argv, &args, global_cache_repair_options_CFG))
return_0;
for (cv = cn->v; cv && args < MAX_PDATA_ARGS; cv = cv->next) {
if (cv->type != DM_CFG_STRING) {
log_error("Invalid string in config file: "
"global/cache_repair_options");
return 0;
}
argv[++args] = cv->v.str;
}
if (args >= MAX_PDATA_ARGS) {
log_error("Too many options for cache repair command.");
return 0;
}
argv[0] = cache_repair;
argv[++args] = "-i";
argv[++args] = meta_path;
argv[++args] = "-o";
argv[++args] = pms_path;
argv[++args] = NULL;
if (lv_is_active(cache_lv)) {
log_error("Only inactive cache can be repaired.");