|
|
f0aa83 |
WHATS_NEW | 1 +
|
|
|
f0aa83 |
lib/activate/activate.c | 1 -
|
|
|
f0aa83 |
lib/locking/locking.c | 12 ++++--
|
|
|
f0aa83 |
lib/locking/locking.h | 2 +-
|
|
|
f0aa83 |
tools/pvmove.c | 109 ++++++++++++++++++++++++++++++++++++------------
|
|
|
f0aa83 |
5 files changed, 93 insertions(+), 32 deletions(-)
|
|
|
f0aa83 |
|
|
|
f0aa83 |
diff --git a/WHATS_NEW b/WHATS_NEW
|
|
|
f0aa83 |
index c3117de..da10eed 100644
|
|
|
f0aa83 |
--- a/WHATS_NEW
|
|
|
f0aa83 |
+++ b/WHATS_NEW
|
|
|
f0aa83 |
@@ -1,5 +1,6 @@
|
|
|
f0aa83 |
Version 2.02.178 -
|
|
|
f0aa83 |
=====================================
|
|
|
f0aa83 |
+ Restore pvmove support for wide-clustered active volumes (2.02.177).
|
|
|
f0aa83 |
Avoid non-exclusive activation of exclusive segment types.
|
|
|
f0aa83 |
Fix trimming sibling PVs when doing a pvmove of raid subLVs.
|
|
|
f0aa83 |
Preserve exclusive activation during thin snaphost merge.
|
|
|
f0aa83 |
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
|
|
|
f0aa83 |
index 18cc7cf..7a37130 100644
|
|
|
f0aa83 |
--- a/lib/activate/activate.c
|
|
|
f0aa83 |
+++ b/lib/activate/activate.c
|
|
|
f0aa83 |
@@ -2576,7 +2576,6 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
|
|
f0aa83 |
|
|
|
f0aa83 |
if (!laopts->exclusive &&
|
|
|
f0aa83 |
(lv_is_origin(lv) ||
|
|
|
f0aa83 |
- lv_is_pvmove(lv) ||
|
|
|
f0aa83 |
seg_only_exclusive(first_seg(lv)))) {
|
|
|
f0aa83 |
log_error(INTERNAL_ERROR "Trying non-exlusive activation of %s with "
|
|
|
f0aa83 |
"a volume type %s requiring exclusive activation.",
|
|
|
f0aa83 |
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
|
|
|
f0aa83 |
index 8daa61e..1a3ce9d 100644
|
|
|
f0aa83 |
--- a/lib/locking/locking.c
|
|
|
f0aa83 |
+++ b/lib/locking/locking.c
|
|
|
f0aa83 |
@@ -399,15 +399,19 @@ int activate_lv_excl(struct cmd_context *cmd, const struct logical_volume *lv)
|
|
|
f0aa83 |
}
|
|
|
f0aa83 |
|
|
|
f0aa83 |
/* Lock a list of LVs */
|
|
|
f0aa83 |
-int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs)
|
|
|
f0aa83 |
+int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusive)
|
|
|
f0aa83 |
{
|
|
|
f0aa83 |
struct dm_list *lvh;
|
|
|
f0aa83 |
struct lv_list *lvl;
|
|
|
f0aa83 |
|
|
|
f0aa83 |
dm_list_iterate_items(lvl, lvs) {
|
|
|
f0aa83 |
- if (!activate_lv_excl_local(cmd, lvl->lv)) {
|
|
|
f0aa83 |
- log_error("Failed to locally exclusively activate %s.",
|
|
|
f0aa83 |
- display_lvname(lvl->lv));
|
|
|
f0aa83 |
+ if (!exclusive && !lv_is_active_exclusive(lvl->lv)) {
|
|
|
f0aa83 |
+ if (!activate_lv(cmd, lvl->lv)) {
|
|
|
f0aa83 |
+ log_error("Failed to activate %s", display_lvname(lvl->lv));
|
|
|
f0aa83 |
+ return 0;
|
|
|
f0aa83 |
+ }
|
|
|
f0aa83 |
+ } else if (!activate_lv_excl(cmd, lvl->lv)) {
|
|
|
f0aa83 |
+ log_error("Failed to activate %s", display_lvname(lvl->lv));
|
|
|
f0aa83 |
dm_list_uniterate(lvh, lvs, &lvl->list) {
|
|
|
f0aa83 |
lvl = dm_list_item(lvh, struct lv_list);
|
|
|
f0aa83 |
if (!deactivate_lv(cmd, lvl->lv))
|
|
|
f0aa83 |
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
|
|
|
f0aa83 |
index 47841ed..f2fbb00 100644
|
|
|
f0aa83 |
--- a/lib/locking/locking.h
|
|
|
f0aa83 |
+++ b/lib/locking/locking.h
|
|
|
f0aa83 |
@@ -262,6 +262,6 @@ int sync_dev_names(struct cmd_context* cmd);
|
|
|
f0aa83 |
|
|
|
f0aa83 |
/* Process list of LVs */
|
|
|
f0aa83 |
struct volume_group;
|
|
|
f0aa83 |
-int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs);
|
|
|
f0aa83 |
+int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusive);
|
|
|
f0aa83 |
|
|
|
f0aa83 |
#endif
|
|
|
f0aa83 |
diff --git a/tools/pvmove.c b/tools/pvmove.c
|
|
|
f0aa83 |
index b3d1d89..cbd5cb8 100644
|
|
|
f0aa83 |
--- a/tools/pvmove.c
|
|
|
f0aa83 |
+++ b/tools/pvmove.c
|
|
|
f0aa83 |
@@ -64,6 +64,16 @@ static int _pvmove_target_present(struct cmd_context *cmd, int clustered)
|
|
|
f0aa83 |
return found;
|
|
|
f0aa83 |
}
|
|
|
f0aa83 |
|
|
|
f0aa83 |
+static unsigned _pvmove_is_exclusive(struct cmd_context *cmd,
|
|
|
f0aa83 |
+ struct volume_group *vg)
|
|
|
f0aa83 |
+{
|
|
|
f0aa83 |
+ if (vg_is_clustered(vg))
|
|
|
f0aa83 |
+ if (!_pvmove_target_present(cmd, 1))
|
|
|
f0aa83 |
+ return 1;
|
|
|
f0aa83 |
+
|
|
|
f0aa83 |
+ return 0;
|
|
|
f0aa83 |
+}
|
|
|
f0aa83 |
+
|
|
|
f0aa83 |
/* Allow /dev/vgname/lvname, vgname/lvname or lvname */
|
|
|
f0aa83 |
static const char *_extract_lvname(struct cmd_context *cmd, const char *vgname,
|
|
|
f0aa83 |
const char *arg)
|
|
|
f0aa83 |
@@ -320,7 +330,8 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
|
|
|
f0aa83 |
const char *lv_name,
|
|
|
f0aa83 |
struct dm_list *allocatable_pvs,
|
|
|
f0aa83 |
alloc_policy_t alloc,
|
|
|
f0aa83 |
- struct dm_list **lvs_changed)
|
|
|
f0aa83 |
+ struct dm_list **lvs_changed,
|
|
|
f0aa83 |
+ unsigned *exclusive)
|
|
|
f0aa83 |
{
|
|
|
f0aa83 |
struct logical_volume *lv_mirr, *lv;
|
|
|
f0aa83 |
struct lv_segment *seg;
|
|
|
f0aa83 |
@@ -329,6 +340,8 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
|
|
|
f0aa83 |
uint32_t log_count = 0;
|
|
|
f0aa83 |
int lv_found = 0;
|
|
|
f0aa83 |
int lv_skipped = 0;
|
|
|
f0aa83 |
+ int lv_active_count = 0;
|
|
|
f0aa83 |
+ int lv_exclusive_count = 0;
|
|
|
f0aa83 |
|
|
|
f0aa83 |
/* FIXME Cope with non-contiguous => splitting existing segments */
|
|
|
f0aa83 |
if (!(lv_mirr = lv_create_empty("pvmove%d", NULL,
|
|
|
f0aa83 |
@@ -422,33 +435,54 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
|
|
|
f0aa83 |
if (!lv_is_on_pvs(lv, source_pvl))
|
|
|
f0aa83 |
continue;
|
|
|
f0aa83 |
|
|
|
f0aa83 |
- seg = first_seg(lv);
|
|
|
f0aa83 |
- if (seg_is_raid(seg) || seg_is_mirrored(seg) ||
|
|
|
f0aa83 |
- lv_is_thin_volume(lv) || lv_is_thin_pool(lv)) {
|
|
|
f0aa83 |
- /*
|
|
|
f0aa83 |
- * Pass over top-level LVs - they were handled.
|
|
|
f0aa83 |
- * Allow sub-LVs to proceed.
|
|
|
f0aa83 |
- */
|
|
|
f0aa83 |
- continue;
|
|
|
f0aa83 |
- }
|
|
|
f0aa83 |
-
|
|
|
f0aa83 |
if (lv_is_locked(lv)) {
|
|
|
f0aa83 |
lv_skipped = 1;
|
|
|
f0aa83 |
log_print_unless_silent("Skipping locked LV %s.", display_lvname(lv));
|
|
|
f0aa83 |
continue;
|
|
|
f0aa83 |
}
|
|
|
f0aa83 |
|
|
|
f0aa83 |
- if (vg_is_clustered(vg) &&
|
|
|
f0aa83 |
- lv_is_visible(lv) &&
|
|
|
f0aa83 |
- lv_is_active(lv) &&
|
|
|
f0aa83 |
- !lv_is_active_exclusive_locally(lv)) {
|
|
|
f0aa83 |
- lv_skipped = 1;
|
|
|
f0aa83 |
- log_print_unless_silent("Skipping LV %s which is active, "
|
|
|
f0aa83 |
- "but not locally exclusively.",
|
|
|
f0aa83 |
- display_lvname(lv));
|
|
|
f0aa83 |
- continue;
|
|
|
f0aa83 |
+ if (vg_is_clustered(vg) && lv_is_visible(lv)) {
|
|
|
f0aa83 |
+ if (lv_is_active_exclusive_locally(lv)) {
|
|
|
f0aa83 |
+ if (lv_active_count) {
|
|
|
f0aa83 |
+ log_error("Cannot move in clustered VG %s "
|
|
|
f0aa83 |
+ "if some LVs are activated "
|
|
|
f0aa83 |
+ "exclusively while others don't.",
|
|
|
f0aa83 |
+ vg->name);
|
|
|
f0aa83 |
+ return NULL;
|
|
|
f0aa83 |
+ }
|
|
|
f0aa83 |
+
|
|
|
f0aa83 |
+ lv_exclusive_count++;
|
|
|
f0aa83 |
+ } else if (lv_is_active(lv)) {
|
|
|
f0aa83 |
+ if (seg_only_exclusive(first_seg(lv))) {
|
|
|
f0aa83 |
+ lv_skipped = 1;
|
|
|
f0aa83 |
+ log_print_unless_silent("Skipping LV %s which is active, "
|
|
|
f0aa83 |
+ "but not locally exclusively.",
|
|
|
f0aa83 |
+ display_lvname(lv));
|
|
|
f0aa83 |
+ continue;
|
|
|
f0aa83 |
+ }
|
|
|
f0aa83 |
+
|
|
|
f0aa83 |
+ if (*exclusive) {
|
|
|
f0aa83 |
+ log_error("Cannot move in clustered VG %s, "
|
|
|
f0aa83 |
+ "clustered mirror (cmirror) not detected "
|
|
|
f0aa83 |
+ "and LVs are activated non-exclusively.",
|
|
|
f0aa83 |
+ vg->name);
|
|
|
f0aa83 |
+ return NULL;
|
|
|
f0aa83 |
+ }
|
|
|
f0aa83 |
+
|
|
|
f0aa83 |
+ lv_active_count++;
|
|
|
f0aa83 |
+ }
|
|
|
f0aa83 |
}
|
|
|
f0aa83 |
|
|
|
f0aa83 |
+ seg = first_seg(lv);
|
|
|
f0aa83 |
+ if (seg_is_raid(seg) || seg_is_mirrored(seg) ||
|
|
|
f0aa83 |
+ seg_is_cache(seg) || seg_is_cache_pool(seg) ||
|
|
|
f0aa83 |
+ seg_is_thin(seg) || seg_is_thin_pool(seg))
|
|
|
f0aa83 |
+ /*
|
|
|
f0aa83 |
+ * Pass over top-level LVs - they were handled.
|
|
|
f0aa83 |
+ * Allow sub-LVs to proceed.
|
|
|
f0aa83 |
+ */
|
|
|
f0aa83 |
+ continue;
|
|
|
f0aa83 |
+
|
|
|
f0aa83 |
if (!_insert_pvmove_mirrors(cmd, lv_mirr, source_pvl, lv,
|
|
|
f0aa83 |
*lvs_changed))
|
|
|
f0aa83 |
return_NULL;
|
|
|
f0aa83 |
@@ -483,15 +517,35 @@ static struct logical_volume *_set_up_pvmove_lv(struct cmd_context *cmd,
|
|
|
f0aa83 |
return NULL;
|
|
|
f0aa83 |
}
|
|
|
f0aa83 |
|
|
|
f0aa83 |
+ if (lv_exclusive_count)
|
|
|
f0aa83 |
+ *exclusive = 1;
|
|
|
f0aa83 |
+
|
|
|
f0aa83 |
return lv_mirr;
|
|
|
f0aa83 |
}
|
|
|
f0aa83 |
|
|
|
f0aa83 |
+static int _activate_lv(struct cmd_context *cmd, struct logical_volume *lv_mirr,
|
|
|
f0aa83 |
+ unsigned exclusive)
|
|
|
f0aa83 |
+{
|
|
|
f0aa83 |
+ int r = 0;
|
|
|
f0aa83 |
+
|
|
|
f0aa83 |
+ if (exclusive || lv_is_active_exclusive(lv_mirr))
|
|
|
f0aa83 |
+ r = activate_lv_excl(cmd, lv_mirr);
|
|
|
f0aa83 |
+ else
|
|
|
f0aa83 |
+ r = activate_lv(cmd, lv_mirr);
|
|
|
f0aa83 |
+
|
|
|
f0aa83 |
+ if (!r)
|
|
|
f0aa83 |
+ stack;
|
|
|
f0aa83 |
+
|
|
|
f0aa83 |
+ return r;
|
|
|
f0aa83 |
+}
|
|
|
f0aa83 |
+
|
|
|
f0aa83 |
/*
|
|
|
f0aa83 |
* Called to set up initial pvmove LV only.
|
|
|
f0aa83 |
* (Not called after first or any other section completes.)
|
|
|
f0aa83 |
*/
|
|
|
f0aa83 |
static int _update_metadata(struct logical_volume *lv_mirr,
|
|
|
f0aa83 |
- struct dm_list *lvs_changed)
|
|
|
f0aa83 |
+ struct dm_list *lvs_changed,
|
|
|
f0aa83 |
+ unsigned exclusive)
|
|
|
f0aa83 |
{
|
|
|
f0aa83 |
struct lv_list *lvl;
|
|
|
f0aa83 |
struct logical_volume *lv = lv_mirr;
|
|
|
f0aa83 |
@@ -505,7 +559,7 @@ static int _update_metadata(struct logical_volume *lv_mirr,
|
|
|
f0aa83 |
return_0;
|
|
|
f0aa83 |
|
|
|
f0aa83 |
/* Ensure mirror LV is active */
|
|
|
f0aa83 |
- if (!activate_lv_excl_local(lv_mirr->vg->cmd, lv_mirr)) {
|
|
|
f0aa83 |
+ if (!_activate_lv(lv_mirr->vg->cmd, lv_mirr, exclusive)) {
|
|
|
f0aa83 |
if (test_mode())
|
|
|
f0aa83 |
return 1;
|
|
|
f0aa83 |
|
|
|
f0aa83 |
@@ -548,6 +602,7 @@ static int _pvmove_setup_single(struct cmd_context *cmd,
|
|
|
f0aa83 |
struct logical_volume *lv = NULL;
|
|
|
f0aa83 |
const char *pv_name = pv_dev_name(pv);
|
|
|
f0aa83 |
unsigned flags = PVMOVE_FIRST_TIME;
|
|
|
f0aa83 |
+ unsigned exclusive;
|
|
|
f0aa83 |
int r = ECMD_FAILED;
|
|
|
f0aa83 |
|
|
|
f0aa83 |
pp->found_pv = 1;
|
|
|
f0aa83 |
@@ -594,6 +649,8 @@ static int _pvmove_setup_single(struct cmd_context *cmd,
|
|
|
f0aa83 |
}
|
|
|
f0aa83 |
}
|
|
|
f0aa83 |
|
|
|
f0aa83 |
+ exclusive = _pvmove_is_exclusive(cmd, vg);
|
|
|
f0aa83 |
+
|
|
|
f0aa83 |
if ((lv_mirr = find_pvmove_lv(vg, pv_dev(pv), PVMOVE))) {
|
|
|
f0aa83 |
log_print_unless_silent("Detected pvmove in progress for %s.", pv_name);
|
|
|
f0aa83 |
if (pp->pv_count || lv_name)
|
|
|
f0aa83 |
@@ -605,7 +662,7 @@ static int _pvmove_setup_single(struct cmd_context *cmd,
|
|
|
f0aa83 |
}
|
|
|
f0aa83 |
|
|
|
f0aa83 |
/* Ensure mirror LV is active */
|
|
|
f0aa83 |
- if (!activate_lv_excl_local(cmd, lv_mirr)) {
|
|
|
f0aa83 |
+ if (!_activate_lv(cmd, lv_mirr, exclusive)) {
|
|
|
f0aa83 |
log_error("ABORTING: Temporary mirror activation failed.");
|
|
|
f0aa83 |
goto out;
|
|
|
f0aa83 |
}
|
|
|
f0aa83 |
@@ -630,12 +687,12 @@ static int _pvmove_setup_single(struct cmd_context *cmd,
|
|
|
f0aa83 |
|
|
|
f0aa83 |
if (!(lv_mirr = _set_up_pvmove_lv(cmd, vg, source_pvl, lv_name,
|
|
|
f0aa83 |
allocatable_pvs, pp->alloc,
|
|
|
f0aa83 |
- &lvs_changed)))
|
|
|
f0aa83 |
+ &lvs_changed, &exclusive)))
|
|
|
f0aa83 |
goto_out;
|
|
|
f0aa83 |
}
|
|
|
f0aa83 |
|
|
|
f0aa83 |
/* Lock lvs_changed and activate (with old metadata) */
|
|
|
f0aa83 |
- if (!activate_lvs(cmd, lvs_changed))
|
|
|
f0aa83 |
+ if (!activate_lvs(cmd, lvs_changed, exclusive))
|
|
|
f0aa83 |
goto_out;
|
|
|
f0aa83 |
|
|
|
f0aa83 |
/* FIXME Presence of a mirror once set PVMOVE - now remove associated logic */
|
|
|
f0aa83 |
@@ -646,7 +703,7 @@ static int _pvmove_setup_single(struct cmd_context *cmd,
|
|
|
f0aa83 |
goto out;
|
|
|
f0aa83 |
|
|
|
f0aa83 |
if (flags & PVMOVE_FIRST_TIME)
|
|
|
f0aa83 |
- if (!_update_metadata(lv_mirr, lvs_changed))
|
|
|
f0aa83 |
+ if (!_update_metadata(lv_mirr, lvs_changed, exclusive))
|
|
|
f0aa83 |
goto_out;
|
|
|
f0aa83 |
|
|
|
f0aa83 |
/* LVs are all in status LOCKED */
|