mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-31 05:47:43 +03:00
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.
This commit is contained in:
parent
674e8d4129
commit
cde65f67d5
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 :
|
||||
|
@ -2878,6 +2878,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();
|
||||
@ -2887,6 +2888,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;
|
||||
@ -3048,6 +3050,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.
|
||||
@ -3057,7 +3061,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));
|
||||
@ -3074,7 +3078,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));
|
||||
@ -3087,6 +3091,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);
|
||||
@ -3323,6 +3333,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();
|
||||
@ -3415,7 +3426,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);
|
||||
@ -3446,6 +3457,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();
|
||||
@ -3561,7 +3573,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;
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user