summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Rajnoha <prajnoha@redhat.com>2014-12-03 14:20:00 +0100
committerPeter Rajnoha <prajnoha@redhat.com>2015-02-09 14:20:27 +0100
commit07a9be6343f25d56ed34cdfc8c7907d003a9587e (patch)
tree5f651d238dcd36633cd218f5fe2ceda6d02ec6de
parent27a0aa83caec10987b6e1b59c7a85b967bedcde0 (diff)
downloadlvm2-07a9be6343f25d56ed34cdfc8c7907d003a9587e.tar.gz
toollib: select the whole structure if at least one of its items is selected
This applies to: - process_each_lv_in_vg - the VG is selected only if at least one of its LVs is selected - process_each_segment_in_lv - the LV is selected only if at least one of its LV segments is selected - process_each_pv_in_vg - the VG is selected only if at least one of its PVs is selected - process_each_segment_in_pv - the PV is selected only if at least one of its PV segments is selected So this patch causes the selection result to be properly propagated up to callers.
-rw-r--r--tools/toollib.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/tools/toollib.c b/tools/toollib.c
index 21c1d212e..689fbe176 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -198,6 +198,28 @@ int ignore_vg(struct volume_group *vg, const char *vg_name, int allow_inconsiste
}
/*
+ * This functiona updates the "selected" arg only if last item processed
+ * is selected so this implements the "whole structure is selected if
+ * at least one of its items is selected".
+ */
+static void _update_selection_result(struct processing_handle *handle, int *selected)
+{
+ if (!handle || !handle->selection_handle)
+ return;
+
+ if (handle->selection_handle->selected)
+ *selected = 1;
+}
+
+static void _set_final_selection_result(struct processing_handle *handle, int selected)
+{
+ if (!handle || !handle->selection_handle)
+ return;
+
+ handle->selection_handle->selected = selected;
+}
+
+/*
* Metadata iteration functions
*/
int process_each_segment_in_pv(struct cmd_context *cmd,
@@ -207,6 +229,7 @@ int process_each_segment_in_pv(struct cmd_context *cmd,
process_single_pvseg_fn_t process_single_pvseg)
{
struct pv_segment *pvseg;
+ int selected = 0;
int ret_max = ECMD_PROCESSED;
int ret;
struct pv_segment _free_pv_segment = { .pv = pv };
@@ -223,6 +246,7 @@ int process_each_segment_in_pv(struct cmd_context *cmd,
return_ECMD_FAILED;
ret = process_single_pvseg(cmd, vg, pvseg, handle);
+ _update_selection_result(handle, &selected);
if (ret != ECMD_PROCESSED)
stack;
if (ret > ret_max)
@@ -230,6 +254,8 @@ int process_each_segment_in_pv(struct cmd_context *cmd,
}
}
+ /* the PV is selected if at least one PV segment is selected */
+ _set_final_selection_result(handle, selected);
return ret_max;
}
@@ -239,6 +265,7 @@ int process_each_segment_in_lv(struct cmd_context *cmd,
process_single_seg_fn_t process_single_seg)
{
struct lv_segment *seg;
+ int selected = 0;
int ret_max = ECMD_PROCESSED;
int ret;
@@ -247,12 +274,15 @@ int process_each_segment_in_lv(struct cmd_context *cmd,
return_ECMD_FAILED;
ret = process_single_seg(cmd, seg, handle);
+ _update_selection_result(handle, &selected);
if (ret != ECMD_PROCESSED)
stack;
if (ret > ret_max)
ret_max = ret;
}
+ /* the LV is selected if at least one LV segment is selected */
+ _set_final_selection_result(handle, selected);
return ret_max;
}
@@ -1629,6 +1659,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t flags,
struct vgnameid_list *vgnl;
const char *vg_name;
const char *vg_uuid;
+ int selected = 0;
int ret_max = ECMD_PROCESSED;
int ret;
int skip;
@@ -1666,6 +1697,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t flags,
(!dm_list_empty(arg_tags) && str_list_match_list(arg_tags, &vg->tags, NULL))) &&
select_match_vg(cmd, handle, vg)) {
ret = process_single_vg(cmd, vg_name, vg, handle);
+ _update_selection_result(handle, &selected);
if (ret != ECMD_PROCESSED)
stack;
if (ret > ret_max)
@@ -1678,6 +1710,8 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t flags,
unlock_and_release_vg(cmd, vg, vg_name);
}
+ /* the VG is selected if at least one LV is selected */
+ _set_final_selection_result(handle, selected);
return ret_max;
}
@@ -1792,6 +1826,7 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
unsigned lvargs_supplied = 0;
struct lv_list *lvl;
struct dm_str_list *sl;
+ int selected = 0;
if (!vg_check_status(vg, EXPORTED_VG)) {
ret_max = ECMD_FAILED;
@@ -1887,6 +1922,8 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
log_very_verbose("Processing LV %s in VG %s.", lvl->lv->name, vg->name);
ret = process_single_lv(cmd, lvl->lv, handle);
+ if (handle_supplied)
+ _update_selection_result(handle, &selected);
if (ret != ECMD_PROCESSED)
stack;
if (ret > ret_max)
@@ -1911,6 +1948,8 @@ int process_each_lv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
out:
if (!handle_supplied)
destroy_processing_handle(cmd, handle, 1);
+ else
+ _set_final_selection_result(handle, selected);
return ret_max;
}
@@ -2680,6 +2719,7 @@ int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
struct processing_handle *handle,
process_single_pv_fn_t process_single_pv)
{
+ int selected = 0;
int ret_max = ECMD_PROCESSED;
int ret;
struct pv_list *pvl;
@@ -2689,12 +2729,14 @@ int process_each_pv_in_vg(struct cmd_context *cmd, struct volume_group *vg,
return_ECMD_FAILED;
ret = process_single_pv(cmd, vg, pvl->pv, handle);
+ _update_selection_result(handle, &selected);
if (ret != ECMD_PROCESSED)
stack;
if (ret > ret_max)
ret_max = ret;
}
+ _set_final_selection_result(handle, selected);
return ret_max;
}