diff options
author | David Teigland <teigland@redhat.com> | 2016-01-12 14:57:52 -0600 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2016-01-18 11:53:01 -0600 |
commit | 683436efb9171eb0860295cfd450414e4ea488a0 (patch) | |
tree | a8da055e607e0dd895b5dcce2eb4b5955f8b916a | |
parent | 5cd4d46f303ecf5212b5de0eb96c0a356453d289 (diff) | |
download | lvm2-dev-dct-pvmove-2.tar.gz |
pvmove: use toollibdev-dct-pvmove-2
Previously, pvmove used the function find_pv_in_vg() which did the
equivalent of process_each_pv() by doing:
find_pv_by_name() -> get_pvs() ->
get_pvs_internal() -> _get_pvs() -> get_vgids() ->
/* equivalent to process_each_pv */
dm_list_iterate_items(vgids)
vg = vg_read_internal()
dm_list_iterate_items(&vg->pvs)
With the found 'pv', it would do vg_read() on pv_vg_name(pv),
and then do the actual pvmove processing.
This commit simplifies by using process_each_pv() and putting
the actual pvmove processing into the "single" function.
This eliminates both find_pv_by_name() and the vg_read().
The processing code that followed vg_read remains the same.
-rw-r--r-- | tools/pvmove.c | 232 | ||||
-rw-r--r-- | tools/toollib.h | 2 |
2 files changed, 109 insertions, 125 deletions
diff --git a/tools/pvmove.c b/tools/pvmove.c index d3eb1ab5f..9e152a334 100644 --- a/tools/pvmove.c +++ b/tools/pvmove.c @@ -22,6 +22,21 @@ #define PVMOVE_FIRST_TIME 0x00000001 /* Called for first time */ +struct pvmove_params { + char *pv_name_arg; /* original unmodified arg */ + char *lv_name_arg; /* original unmodified arg */ + alloc_policy_t alloc; + int pv_count; + char **pv_names; + + union lvid *lvid; + char *id_vg_name; + char *id_lv_name; + unsigned in_progress; + int setup_result; + int found_pv; +}; + static int _pvmove_target_present(struct cmd_context *cmd, int clustered) { const struct segment_type *segtype; @@ -586,63 +601,39 @@ static int _copy_id_components(struct cmd_context *cmd, return 1; } -static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name, - int argc, char **argv, union lvid *lvid, char **vg_name_copy, - char **lv_mirr_name) +static int _pvmove_setup_single(struct cmd_context *cmd, + struct volume_group *vg, + struct physical_volume *pv, + struct processing_handle *handle) { + struct pvmove_params *pp = (struct pvmove_params *) handle->custom_handle; const char *lv_name = NULL; - const char *vg_name; - char *pv_name_arg; - struct volume_group *vg; struct dm_list *source_pvl; struct dm_list *allocatable_pvs; - alloc_policy_t alloc; struct dm_list *lvs_changed; - struct physical_volume *pv; struct logical_volume *lv_mirr; - uint32_t lockd_state = 0; + const char *pv_name = pv_dev_name(pv); unsigned flags = PVMOVE_FIRST_TIME; unsigned exclusive; int r = ECMD_FAILED; - pv_name_arg = argv[0]; - argc--; - argv++; - - /* Find PV (in VG) */ - if (!(pv = find_pv_by_name(cmd, pv_name, 0, 0))) { - stack; - return EINVALID_CMD_LINE; - } - - vg_name = pv_vg_name(pv); + pp->found_pv = 1; + pp->setup_result = ECMD_FAILED; - if (arg_count(cmd, name_ARG)) { - if (!(lv_name = _extract_lvname(cmd, vg_name, arg_value(cmd, name_ARG)))) { - stack; - free_pv_fid(pv); - return EINVALID_CMD_LINE; + if (pp->lv_name_arg) { + if (!(lv_name = _extract_lvname(cmd, vg->name, pp->lv_name_arg))) { + log_error("Failed to find an LV name."); + pp->setup_result = EINVALID_CMD_LINE; + return ECMD_FAILED; } if (!validate_name(lv_name)) { log_error("Logical volume name %s is invalid", lv_name); - free_pv_fid(pv); - return EINVALID_CMD_LINE; + pp->setup_result = EINVALID_CMD_LINE; + return ECMD_FAILED; } } - /* Read VG */ - log_verbose("Finding volume group \"%s\"", vg_name); - - if (!lockd_vg(cmd, vg_name, "ex", 0, &lockd_state)) - return_ECMD_FAILED; - - vg = vg_read(cmd, vg_name, NULL, READ_FOR_UPDATE, lockd_state); - if (vg_read_error(vg)) { - release_vg(vg); - goto out_ret; - } - /* * We cannot move blocks from under the sanlock leases, so disallow * pvmoving any PVs used by the lvmlock LV. @@ -657,8 +648,8 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name, if (seg_type(lvseg, s) == AREA_PV) { sanlock_pv = seg_pv(lvseg, s); if (sanlock_pv->dev == pv->dev) { - log_error("Cannot pvmove device %s used for sanlock leases.", pv_dev_name(pv)); - goto out; + log_error("Cannot pvmove device %s used for sanlock leases.", pv_name); + return ECMD_FAILED; } } } @@ -669,7 +660,7 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name, if ((lv_mirr = find_pvmove_lv(vg, pv_dev(pv), PVMOVE))) { log_print_unless_silent("Detected pvmove in progress for %s", pv_name); - if (argc || lv_name) + if (pp->pv_count || lv_name) log_error("Ignoring remaining command line arguments"); if (!(lvs_changed = lvs_using_lv(cmd, vg, lv_mirr))) { @@ -687,23 +678,22 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name, } else { /* Determine PE ranges to be moved */ if (!(source_pvl = create_pv_list(cmd->mem, vg, 1, - &pv_name_arg, 0))) + &pp->pv_name_arg, 0))) goto_out; - alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, ALLOC_INHERIT); - if (alloc == ALLOC_INHERIT) - alloc = vg->alloc; + if (pp->alloc == ALLOC_INHERIT) + pp->alloc = vg->alloc; /* Get PVs we can use for allocation */ - if (!(allocatable_pvs = _get_allocatable_pvs(cmd, argc, argv, - vg, pv, alloc))) + if (!(allocatable_pvs = _get_allocatable_pvs(cmd, pp->pv_count, pp->pv_names, + vg, pv, pp->alloc))) goto_out; if (!archive(vg)) goto_out; if (!(lv_mirr = _set_up_pvmove_lv(cmd, vg, source_pvl, lv_name, - allocatable_pvs, alloc, + allocatable_pvs, pp->alloc, &lvs_changed, &exclusive))) goto_out; } @@ -716,7 +706,7 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name, /* init_pvmove(1); */ /* vg->status |= PVMOVE; */ - if (!_copy_id_components(cmd, lv_mirr, vg_name_copy, lv_mirr_name, lvid)) + if (!_copy_id_components(cmd, lv_mirr, &pp->id_vg_name, &pp->id_lv_name, pp->lvid)) goto out; if (flags & PVMOVE_FIRST_TIME) @@ -724,70 +714,31 @@ static int _set_up_pvmove(struct cmd_context *cmd, const char *pv_name, goto_out; /* LVs are all in status LOCKED */ + pp->setup_result = ECMD_PROCESSED; r = ECMD_PROCESSED; out: - free_pv_fid(pv); - unlock_and_release_vg(cmd, vg, vg_name); -out_ret: - /* - * Release explicitly because the command may continue running - * for some time monitoring the progress, and we don not want - * or need the lockd lock held over that. - */ - if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) - stack; - return r; } -static int _read_poll_id_from_pvname(struct cmd_context *cmd, const char *pv_name, - union lvid *lvid, char **vg_name_copy, - char **lv_name_copy, unsigned *in_progress) +static int _pvmove_read_single(struct cmd_context *cmd, + struct volume_group *vg, + struct physical_volume *pv, + struct processing_handle *handle) { - int ret = 0; - const char *vg_name; + struct pvmove_params *pp = (struct pvmove_params *) handle->custom_handle; struct logical_volume *lv; - struct physical_volume *pv; - struct volume_group *vg; - uint32_t lockd_state = 0; - - if (!pv_name) { - log_error(INTERNAL_ERROR "Invalid PV name parameter."); - return 0; - } - - if (!(pv = find_pv_by_name(cmd, pv_name, 0, 0))) - return_0; - - vg_name = pv_vg_name(pv); - - if (!lockd_vg(cmd, vg_name, "sh", 0, &lockd_state)) - return_0; - - /* need read-only access */ - vg = vg_read(cmd, vg_name, NULL, 0, lockd_state); - if (vg_read_error(vg)) { - log_error("ABORTING: Can't read VG for %s.", pv_name); - release_vg(vg); - ret = 0; - goto out; - } + int ret = ECMD_FAILED; if (!(lv = find_pvmove_lv(vg, pv_dev(pv), PVMOVE))) { log_print_unless_silent("%s: No pvmove in progress - already finished or aborted.", - pv_name); - ret = 1; - *in_progress = 0; - } else if (_copy_id_components(cmd, lv, vg_name_copy, lv_name_copy, lvid)) { - ret = 1; - *in_progress = 1; + pv_dev_name(pv)); + ret = ECMD_PROCESSED; + pp->in_progress = 0; + } else if (_copy_id_components(cmd, lv, &pp->id_vg_name, &pp->id_lv_name, pp->lvid)) { + ret = ECMD_PROCESSED; + pp->in_progress = 1; } - unlock_and_release_vg(cmd, vg, vg_name); -out: - if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state)) - stack; - free_pv_fid(pv); return ret; } @@ -859,11 +810,12 @@ int pvmove_poll(struct cmd_context *cmd, const char *pv_name, int pvmove(struct cmd_context *cmd, int argc, char **argv) { - char *colon; - int ret; - unsigned in_progress = 1; + struct pvmove_params pp = { 0 }; + struct processing_handle *handle = NULL; union lvid *lvid = NULL; - char *pv_name = NULL, *vg_name = NULL, *lv_name = NULL; + char *pv_name = NULL; + char *colon; + unsigned is_abort = arg_is_set(cmd, abort_ARG); /* dm raid1 target must be present in every case */ if (!_pvmove_target_present(cmd, 0)) { @@ -895,6 +847,12 @@ int pvmove(struct cmd_context *cmd, int argc, char **argv) log_error("Failed to allocate lvid."); return ECMD_FAILED; } + pp.lvid = lvid; + + if (!(pp.pv_name_arg = dm_pool_strdup(cmd->mem, argv[0]))) { + log_error("Failed to clone PV name."); + return ECMD_FAILED; + } if (!(pv_name = dm_pool_strdup(cmd->mem, argv[0]))) { log_error("Failed to clone PV name."); @@ -907,31 +865,56 @@ int pvmove(struct cmd_context *cmd, int argc, char **argv) if (colon) *colon = '\0'; - /* - * To do a reverse mapping from PV name to VG name, we need the - * correct global mapping of PVs to VGs. - */ - if (!lockd_gl(cmd, "sh", 0)) { - stack; + argc--; + argv++; + + pp.pv_count = argc; + pp.pv_names = argv; + + if (arg_count(cmd, name_ARG)) { + if (!(pp.lv_name_arg = dm_pool_strdup(cmd->mem, arg_value(cmd, name_ARG)))) { + log_error("Failed to clone LV name."); + return ECMD_FAILED; + } + } + + pp.alloc = (alloc_policy_t) arg_uint_value(cmd, alloc_ARG, ALLOC_INHERIT); + + pp.in_progress = 1; + + /* Normal pvmove setup requires ex lock from lvmlockd. */ + if (is_abort) + cmd->lockd_vg_default_sh = 1; + + if (!(handle = init_processing_handle(cmd))) { + log_error("Failed to initialize processing handle."); return ECMD_FAILED; } - /* - * FIXME: use process_each_pv() where the "single" function - * depends on the abort arg. The single functions would not - * need to use find_pv_by_name() (which includes a hidden - * equivalent of process_each_pv), or vg_read(). - */ - if (!arg_count(cmd, abort_ARG)) { - if ((ret = _set_up_pvmove(cmd, pv_name, argc, argv, lvid, &vg_name, &lv_name)) != ECMD_PROCESSED) { + handle->custom_handle = &pp; + + process_each_pv(cmd, 1, &pv_name, NULL, + is_abort ? 0 : READ_FOR_UPDATE, + handle, + is_abort ? &_pvmove_read_single : &_pvmove_setup_single); + + destroy_processing_handle(cmd, handle); + + if (!is_abort) { + if (!pp.found_pv) { + stack; + return EINVALID_CMD_LINE; + } + + if (pp.setup_result != ECMD_PROCESSED) { stack; - return ret; + return pp.setup_result; } } else { - if (!_read_poll_id_from_pvname(cmd, pv_name, lvid, &vg_name, &lv_name, &in_progress)) + if (!pp.found_pv) return_ECMD_FAILED; - if (!in_progress) + if (!pp.in_progress) return ECMD_PROCESSED; } @@ -943,6 +926,7 @@ int pvmove(struct cmd_context *cmd, int argc, char **argv) lockd_gl(cmd, "un", 0); } - return pvmove_poll(cmd, pv_name, lvid ? lvid->s : NULL, vg_name, lv_name, + return pvmove_poll(cmd, pv_name, lvid ? lvid->s : NULL, + pp.id_vg_name, pp.id_lv_name, arg_is_set(cmd, background_ARG)); } diff --git a/tools/toollib.h b/tools/toollib.h index 400bac520..e1ac323c4 100644 --- a/tools/toollib.h +++ b/tools/toollib.h @@ -102,7 +102,7 @@ int process_each_vg(struct cmd_context *cmd, int argc, char **argv, process_single_vg_fn_t process_single_vg); int process_each_pv(struct cmd_context *cmd, int argc, char **argv, - const char *vg_name, uint32_t lock_type, + const char *vg_name, uint32_t read_flags, struct processing_handle *handle, process_single_pv_fn_t process_single_pv); |