summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2016-11-29 12:00:15 -0600
committerDavid Teigland <teigland@redhat.com>2016-11-30 16:37:29 -0600
commit268374c2354180573a631d4bca96f6e08d91dee5 (patch)
tree35e7ba9046fc5154fe674836b811b86d63a0f1fa
parent45e23131b8da4f6083c463963f5644808a813539 (diff)
downloadlvm2-268374c2354180573a631d4bca96f6e08d91dee5.tar.gz
process_each_lv: add check_single_lv function
The new check_single_lv() function is called prior to the existing process_single_lv(). If the check function returns 0, the LV will not be processed. The check_single_lv function is meant to be a standard method to validate the combination of specific command + specific LV, and decide if the combination is allowed. The check_single function can be used by anything that calls process_each_lv. As commands are migrated to take advantage of command definitions, each command definition gets its own entry point which calls process_each for itself, passing a pair of check_single/process_single functions which can be specific to the narrowly defined command def.
-rw-r--r--tools/lvchange.c2
-rw-r--r--tools/lvconvert.c4
-rw-r--r--tools/lvdisplay.c2
-rw-r--r--tools/lvremove.c2
-rw-r--r--tools/lvscan.c2
-rw-r--r--tools/reporter.c8
-rw-r--r--tools/toollib.c20
-rw-r--r--tools/toollib.h14
-rw-r--r--tools/vgdisplay.c2
-rw-r--r--tools/vgmknodes.c2
-rw-r--r--tools/vgremove.c2
11 files changed, 43 insertions, 17 deletions
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 250d7209b..2bcb98a24 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -1434,5 +1434,5 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
return process_each_lv(cmd, argc, argv, NULL, NULL,
update ? READ_FOR_UPDATE : 0, NULL,
- &_lvchange_single);
+ NULL, &_lvchange_single);
}
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index d6824d8f0..afbae0f07 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -4770,7 +4770,7 @@ int lvconvert(struct cmd_context * cmd, int argc, char **argv)
if (lp.merge) {
ret = process_each_lv(cmd, argc, argv, NULL, NULL,
- READ_FOR_UPDATE, handle, &_lvconvert_merge_single);
+ READ_FOR_UPDATE, handle, NULL, &_lvconvert_merge_single);
} else {
int saved_ignore_suspended_devices = ignore_suspended_devices();
@@ -4780,7 +4780,7 @@ int lvconvert(struct cmd_context * cmd, int argc, char **argv)
}
ret = process_each_lv(cmd, 0, NULL, lp.vg_name, lp.lv_name,
- READ_FOR_UPDATE, handle, &_lvconvert_single);
+ READ_FOR_UPDATE, handle, NULL, &_lvconvert_single);
init_ignore_suspended_devices(saved_ignore_suspended_devices);
}
diff --git a/tools/lvdisplay.c b/tools/lvdisplay.c
index c60b463ea..b8c4b461a 100644
--- a/tools/lvdisplay.c
+++ b/tools/lvdisplay.c
@@ -58,5 +58,5 @@ int lvdisplay(struct cmd_context *cmd, int argc, char **argv)
return EINVALID_CMD_LINE;
}
- return process_each_lv(cmd, argc, argv, NULL, NULL, 0, NULL, &_lvdisplay_single);
+ return process_each_lv(cmd, argc, argv, NULL, NULL, 0, NULL, NULL, &_lvdisplay_single);
}
diff --git a/tools/lvremove.c b/tools/lvremove.c
index d807d04eb..4653817e1 100644
--- a/tools/lvremove.c
+++ b/tools/lvremove.c
@@ -27,5 +27,5 @@ int lvremove(struct cmd_context *cmd, int argc, char **argv)
cmd->include_historical_lvs = 1;
return process_each_lv(cmd, argc, argv, NULL, NULL, READ_FOR_UPDATE, NULL,
- &lvremove_single);
+ NULL, &lvremove_single);
}
diff --git a/tools/lvscan.c b/tools/lvscan.c
index 4e188d06d..ab3238b49 100644
--- a/tools/lvscan.c
+++ b/tools/lvscan.c
@@ -119,5 +119,5 @@ int lvscan(struct cmd_context *cmd, int argc, char **argv)
*/
}
- return process_each_lv(cmd, argc, argv, NULL, NULL, 0, NULL, &lvscan_single);
+ return process_each_lv(cmd, argc, argv, NULL, NULL, 0, NULL, NULL, &lvscan_single);
}
diff --git a/tools/reporter.c b/tools/reporter.c
index b7a2f39b5..52abc5fed 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -517,14 +517,14 @@ static int _report_all_in_vg(struct cmd_context *cmd, struct processing_handle *
r = _vgs_single(cmd, vg->name, vg, handle);
break;
case LVS:
- r = process_each_lv_in_vg(cmd, vg, NULL, NULL, 0, handle,
+ r = process_each_lv_in_vg(cmd, vg, NULL, NULL, 0, handle, NULL,
do_lv_info && !do_lv_seg_status ? &_lvs_with_info_single :
!do_lv_info && do_lv_seg_status ? &_lvs_with_status_single :
do_lv_info && do_lv_seg_status ? &_lvs_with_info_and_status_single :
&_lvs_single);
break;
case SEGS:
- r = process_each_lv_in_vg(cmd, vg, NULL, NULL, 0, handle,
+ r = process_each_lv_in_vg(cmd, vg, NULL, NULL, 0, handle, NULL,
do_lv_info && !do_lv_seg_status ? &_lvsegs_with_info_single :
!do_lv_info && do_lv_seg_status ? &_lvsegs_with_status_single :
do_lv_info && do_lv_seg_status ? &_lvsegs_with_info_and_status_single :
@@ -1099,7 +1099,7 @@ static int _do_report(struct cmd_context *cmd, struct processing_handle *handle,
if (args->full_report_vg)
r = _report_all_in_vg(cmd, handle, args->full_report_vg, LVS, lv_info_needed, lv_segment_status_needed);
else
- r = process_each_lv(cmd, args->argc, args->argv, NULL, NULL, 0, handle,
+ r = process_each_lv(cmd, args->argc, args->argv, NULL, NULL, 0, handle, NULL,
lv_info_needed && !lv_segment_status_needed ? &_lvs_with_info_single :
!lv_info_needed && lv_segment_status_needed ? &_lvs_with_status_single :
lv_info_needed && lv_segment_status_needed ? &_lvs_with_info_and_status_single :
@@ -1133,7 +1133,7 @@ static int _do_report(struct cmd_context *cmd, struct processing_handle *handle,
if (args->full_report_vg)
r = _report_all_in_vg(cmd, handle, args->full_report_vg, SEGS, lv_info_needed, lv_segment_status_needed);
else
- r = process_each_lv(cmd, args->argc, args->argv, NULL, NULL, 0, handle,
+ r = process_each_lv(cmd, args->argc, args->argv, NULL, NULL, 0, handle, NULL,
lv_info_needed && !lv_segment_status_needed ? &_lvsegs_with_info_single :
!lv_info_needed && lv_segment_status_needed ? &_lvsegs_with_status_single :
lv_info_needed && lv_segment_status_needed ? &_lvsegs_with_info_and_status_single :
diff --git a/tools/toollib.c b/tools/toollib.c
index db153998d..456216b43 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -2873,6 +2873,7 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
struct dm_list *arg_lvnames, const struct dm_list *tags_in,
int stop_on_error,
struct processing_handle *handle,
+ check_single_lv_fn_t check_single_lv,
process_single_lv_fn_t process_single_lv)
{
log_report_t saved_log_report_state = log_get_report_state();
@@ -2882,6 +2883,7 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
int ret = 0;
int whole_selected = 0;
int handle_supplied = handle != NULL;
+ int lv_is_named_arg;
unsigned process_lv;
unsigned process_all = 0;
unsigned tags_supplied = 0;
@@ -3043,6 +3045,8 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
if (lv_is_removed(lvl->lv))
continue;
+ lv_is_named_arg = str_list_match_item(&found_arg_lvnames, lvl->lv->name);
+
/*
* The command definition may include restrictions on the
* types and properties of LVs that can be processed.
@@ -3052,7 +3056,7 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
/* FIXME: include this result in report log? */
/* FIXME: avoid duplicating message for each level */
- if (str_list_match_item(&found_arg_lvnames, lvl->lv->name)) {
+ if (lv_is_named_arg) {
log_error("Operation not permitted (%s %d) on LV %s.",
cmd->command->command_line_id, cmd->command->command_line_enum,
display_lvname(lvl->lv));
@@ -3069,7 +3073,7 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
/* FIXME: include this result in report log? */
/* FIXME: avoid duplicating message for each level */
- if (str_list_match_item(&found_arg_lvnames, lvl->lv->name)) {
+ if (lv_is_named_arg) {
log_error("Operation not permitted (%s %d) on LV %s.",
cmd->command->command_line_id, cmd->command->command_line_enum,
display_lvname(lvl->lv));
@@ -3082,6 +3086,12 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
continue;
}
+ if (check_single_lv && !check_single_lv(cmd, lvl->lv, handle, lv_is_named_arg)) {
+ if (lv_is_named_arg)
+ ret_max = ECMD_FAILED;
+ continue;
+ }
+
log_very_verbose("Processing LV %s in VG %s.", lvl->lv->name, vg->name);
ret = process_single_lv(cmd, lvl->lv, handle);
@@ -3318,6 +3328,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
struct dm_list *arg_lvnames,
struct dm_list *arg_tags,
struct processing_handle *handle,
+ check_single_lv_fn_t check_single_lv,
process_single_lv_fn_t process_single_lv)
{
log_report_t saved_log_report_state = log_get_report_state();
@@ -3410,7 +3421,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
goto endvg;
ret = process_each_lv_in_vg(cmd, vg, &lvnames, tags_arg, 0,
- handle, process_single_lv);
+ handle, check_single_lv, process_single_lv);
if (ret != ECMD_PROCESSED)
stack;
report_log_ret_code(ret);
@@ -3441,6 +3452,7 @@ int process_each_lv(struct cmd_context *cmd,
const char *one_vgname, const char *one_lvname,
uint32_t read_flags,
struct processing_handle *handle,
+ check_single_lv_fn_t check_single_lv,
process_single_lv_fn_t process_single_lv)
{
log_report_t saved_log_report_state = log_get_report_state();
@@ -3556,7 +3568,7 @@ int process_each_lv(struct cmd_context *cmd,
_choose_vgs_to_process(cmd, &arg_vgnames, &vgnameids_on_system, &vgnameids_to_process);
ret = _process_lv_vgnameid_list(cmd, read_flags, &vgnameids_to_process, &arg_vgnames, &arg_lvnames,
- &arg_tags, handle, process_single_lv);
+ &arg_tags, handle, check_single_lv, process_single_lv);
if (ret > ret_max)
ret_max = ret;
diff --git a/tools/toollib.h b/tools/toollib.h
index d44b825ef..67e45a2ec 100644
--- a/tools/toollib.h
+++ b/tools/toollib.h
@@ -98,6 +98,18 @@ typedef int (*process_single_pvseg_fn_t) (struct cmd_context * cmd,
struct pv_segment * pvseg,
struct processing_handle *handle);
+/*
+ * Called prior to process_single_lv() to decide if the LV should be
+ * processed. If this returns 0, the LV is not processed.
+ *
+ * This can evaluate the combination of command definition and
+ * the LV object to decide if the combination is allowed.
+ */
+typedef int (*check_single_lv_fn_t) (struct cmd_context *cmd,
+ struct logical_volume *lv,
+ struct processing_handle *handle,
+ int lv_is_named_arg);
+
int process_each_vg(struct cmd_context *cmd,
int argc, char **argv,
const char *one_vgname,
@@ -125,6 +137,7 @@ int process_each_segment_in_pv(struct cmd_context *cmd,
int process_each_lv(struct cmd_context *cmd, int argc, char **argv,
const char *one_vgname, const char *one_lvname,
uint32_t flags, struct processing_handle *handle,
+ check_single_lv_fn_t check_single_lv,
process_single_lv_fn_t process_single_lv);
@@ -141,6 +154,7 @@ int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
struct dm_list *arg_lvnames, const struct dm_list *tagsl,
int stop_on_error, struct processing_handle *handle,
+ check_single_lv_fn_t check_single_lv,
process_single_lv_fn_t process_single_lv);
struct processing_handle *init_processing_handle(struct cmd_context *cmd, struct processing_handle *parent_handle);
diff --git a/tools/vgdisplay.c b/tools/vgdisplay.c
index 7bb2e6a2b..7fc64b055 100644
--- a/tools/vgdisplay.c
+++ b/tools/vgdisplay.c
@@ -38,7 +38,7 @@ static int vgdisplay_single(struct cmd_context *cmd, const char *vg_name,
vgdisplay_extents(vg);
process_each_lv_in_vg(cmd, vg, NULL, NULL, 0, NULL,
- (process_single_lv_fn_t)lvdisplay_full);
+ NULL, (process_single_lv_fn_t)lvdisplay_full);
log_print("--- Physical volumes ---");
process_each_pv_in_vg(cmd, vg, NULL,
diff --git a/tools/vgmknodes.c b/tools/vgmknodes.c
index f974ff359..9942af7b2 100644
--- a/tools/vgmknodes.c
+++ b/tools/vgmknodes.c
@@ -33,5 +33,5 @@ int vgmknodes(struct cmd_context *cmd, int argc, char **argv)
if (!lv_mknodes(cmd, NULL))
return_ECMD_FAILED;
- return process_each_lv(cmd, argc, argv, NULL, NULL, LCK_VG_READ, NULL, &_vgmknodes_single);
+ return process_each_lv(cmd, argc, argv, NULL, NULL, LCK_VG_READ, NULL, NULL, &_vgmknodes_single);
}
diff --git a/tools/vgremove.c b/tools/vgremove.c
index f0da2f81f..d105fc645 100644
--- a/tools/vgremove.c
+++ b/tools/vgremove.c
@@ -62,7 +62,7 @@ static int vgremove_single(struct cmd_context *cmd, const char *vg_name,
}
if ((ret = process_each_lv_in_vg(cmd, vg, NULL, NULL, 1, &void_handle,
- (process_single_lv_fn_t)lvremove_single)) != ECMD_PROCESSED) {
+ NULL, (process_single_lv_fn_t)lvremove_single)) != ECMD_PROCESSED) {
stack;
return ret;
}