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

pvmove: reinstantiate clustered pvmove

In fact  pvmove does support  'clustered-core' target for clustered
pvmove of LVs activated on multiple nodes.

This patch restores support for activation of pvmove on all nodes
for LVs that are also activate on all nodes.
This commit is contained in:
Zdenek Kabelac 2018-01-31 10:53:09 +01:00
parent 34fb5202bd
commit 083c221cbe
5 changed files with 93 additions and 32 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.178 -
=====================================
Restore pvmove support for wide-clustered active volumes (2.02.177).
Avoid non-exclusive activation of exclusive segment types.
Fix trimming sibling PVs when doing a pvmove of raid subLVs.
Preserve exclusive activation during thin snaphost merge.

View File

@ -2576,7 +2576,6 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
if (!laopts->exclusive &&
(lv_is_origin(lv) ||
lv_is_pvmove(lv) ||
seg_only_exclusive(first_seg(lv)))) {
log_error(INTERNAL_ERROR "Trying non-exlusive activation of %s with "
"a volume type %s requiring exclusive activation.",

View File

@ -399,15 +399,19 @@ int activate_lv_excl(struct cmd_context *cmd, const struct logical_volume *lv)
}
/* Lock a list of LVs */
int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs)
int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusive)
{
struct dm_list *lvh;
struct lv_list *lvl;
dm_list_iterate_items(lvl, lvs) {
if (!activate_lv_excl_local(cmd, lvl->lv)) {
log_error("Failed to locally exclusively activate %s.",
display_lvname(lvl->lv));
if (!exclusive && !lv_is_active_exclusive(lvl->lv)) {
if (!activate_lv(cmd, lvl->lv)) {
log_error("Failed to activate %s", display_lvname(lvl->lv));
return 0;
}
} else if (!activate_lv_excl(cmd, lvl->lv)) {
log_error("Failed to activate %s", display_lvname(lvl->lv));
dm_list_uniterate(lvh, lvs, &lvl->list) {
lvl = dm_list_item(lvh, struct lv_list);
if (!deactivate_lv(cmd, lvl->lv))

View File

@ -262,6 +262,6 @@ int sync_dev_names(struct cmd_context* cmd);
/* Process list of LVs */
struct volume_group;
int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs);
int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusive);
#endif

View File

@ -64,6 +64,16 @@ static int _pvmove_target_present(struct cmd_context *cmd, int clustered)
return found;
}
static unsigned _pvmove_is_exclusive(struct cmd_context *cmd,
struct volume_group *vg)
{
if (vg_is_clustered(vg))
if (!_pvmove_target_present(cmd, 1))
return 1;
return 0;
}
/* Allow /dev/vgname/lvname, vgname/lvname or lvname */
static const char *_extract_lvname(struct cmd_context *cmd, const char *vgname,
const char *arg)
@ -320,7 +330,8 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
const char *lv_name,
struct dm_list *allocatable_pvs,
alloc_policy_t alloc,
struct dm_list **lvs_changed)
struct dm_list **lvs_changed,
unsigned *exclusive)
{
struct logical_volume *lv_mirr, *lv;
struct lv_segment *seg;
@ -329,6 +340,8 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
uint32_t log_count = 0;
int lv_found = 0;
int lv_skipped = 0;
int lv_active_count = 0;
int lv_exclusive_count = 0;
/* FIXME Cope with non-contiguous => splitting existing segments */
if (!(lv_mirr = lv_create_empty("pvmove%d", NULL,
@ -422,33 +435,54 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
if (!lv_is_on_pvs(lv, source_pvl))
continue;
seg = first_seg(lv);
if (seg_is_raid(seg) || seg_is_mirrored(seg) ||
lv_is_thin_volume(lv) || lv_is_thin_pool(lv)) {
/*
* Pass over top-level LVs - they were handled.
* Allow sub-LVs to proceed.
*/
continue;
}
if (lv_is_locked(lv)) {
lv_skipped = 1;
log_print_unless_silent("Skipping locked LV %s.", display_lvname(lv));
continue;
}
if (vg_is_clustered(vg) &&
lv_is_visible(lv) &&
lv_is_active(lv) &&
!lv_is_active_exclusive_locally(lv)) {
lv_skipped = 1;
log_print_unless_silent("Skipping LV %s which is active, "
"but not locally exclusively.",
display_lvname(lv));
continue;
if (vg_is_clustered(vg) && lv_is_visible(lv)) {
if (lv_is_active_exclusive_locally(lv)) {
if (lv_active_count) {
log_error("Cannot move in clustered VG %s "
"if some LVs are activated "
"exclusively while others don't.",
vg->name);
return NULL;
}
lv_exclusive_count++;
} else if (lv_is_active(lv)) {
if (seg_only_exclusive(first_seg(lv))) {
lv_skipped = 1;
log_print_unless_silent("Skipping LV %s which is active, "
"but not locally exclusively.",
display_lvname(lv));
continue;
}
if (*exclusive) {
log_error("Cannot move in clustered VG %s, "
"clustered mirror (cmirror) not detected "
"and LVs are activated non-exclusively.",
vg->name);
return NULL;
}
lv_active_count++;
}
}
seg = first_seg(lv);
if (seg_is_raid(seg) || seg_is_mirrored(seg) ||
seg_is_cache(seg) || seg_is_cache_pool(seg) ||
seg_is_thin(seg) || seg_is_thin_pool(seg))
/*
* Pass over top-level LVs - they were handled.
* Allow sub-LVs to proceed.
*/
continue;
if (!_insert_pvmove_mirrors(cmd, lv_mirr, source_pvl, lv,
*lvs_changed))
return_NULL;
@ -483,15 +517,35 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
return NULL;
}
if (lv_exclusive_count)
*exclusive = 1;
return lv_mirr;
}
static int _activate_lv(struct cmd_context *cmd, struct logical_volume *lv_mirr,
unsigned exclusive)
{
int r = 0;
if (exclusive || lv_is_active_exclusive(lv_mirr))
r = activate_lv_excl(cmd, lv_mirr);
else
r = activate_lv(cmd, lv_mirr);
if (!r)
stack;
return r;
}
/*
* Called to set up initial pvmove LV only.
* (Not called after first or any other section completes.)
*/
static int _update_metadata(struct logical_volume *lv_mirr,
struct dm_list *lvs_changed)
struct dm_list *lvs_changed,
unsigned exclusive)
{
struct lv_list *lvl;
struct logical_volume *lv = lv_mirr;
@ -505,7 +559,7 @@ static int _update_metadata(struct logical_volume *lv_mirr,
return_0;
/* Ensure mirror LV is active */
if (!activate_lv_excl_local(lv_mirr->vg->cmd, lv_mirr)) {
if (!_activate_lv(lv_mirr->vg->cmd, lv_mirr, exclusive)) {
if (test_mode())
return 1;
@ -548,6 +602,7 @@ static int _pvmove_setup_single(struct cmd_context *cmd,
struct logical_volume *lv = NULL;
const char *pv_name = pv_dev_name(pv);
unsigned flags = PVMOVE_FIRST_TIME;
unsigned exclusive;
int r = ECMD_FAILED;
pp->found_pv = 1;
@ -594,6 +649,8 @@ static int _pvmove_setup_single(struct cmd_context *cmd,
}
}
exclusive = _pvmove_is_exclusive(cmd, vg);
if ((lv_mirr = find_pvmove_lv(vg, pv_dev(pv), PVMOVE))) {
log_print_unless_silent("Detected pvmove in progress for %s.", pv_name);
if (pp->pv_count || lv_name)
@ -605,7 +662,7 @@ static int _pvmove_setup_single(struct cmd_context *cmd,
}
/* Ensure mirror LV is active */
if (!activate_lv_excl_local(cmd, lv_mirr)) {
if (!_activate_lv(cmd, lv_mirr, exclusive)) {
log_error("ABORTING: Temporary mirror activation failed.");
goto out;
}
@ -630,12 +687,12 @@ static int _pvmove_setup_single(struct cmd_context *cmd,
if (!(lv_mirr = _set_up_pvmove_lv(cmd, vg, source_pvl, lv_name,
allocatable_pvs, pp->alloc,
&lvs_changed)))
&lvs_changed, &exclusive)))
goto_out;
}
/* Lock lvs_changed and activate (with old metadata) */
if (!activate_lvs(cmd, lvs_changed))
if (!activate_lvs(cmd, lvs_changed, exclusive))
goto_out;
/* FIXME Presence of a mirror once set PVMOVE - now remove associated logic */
@ -646,7 +703,7 @@ static int _pvmove_setup_single(struct cmd_context *cmd,
goto out;
if (flags & PVMOVE_FIRST_TIME)
if (!_update_metadata(lv_mirr, lvs_changed))
if (!_update_metadata(lv_mirr, lvs_changed, exclusive))
goto_out;
/* LVs are all in status LOCKED */