All of lore.kernel.org
 help / color / mirror / Atom feed
From: Zdenek Kabelac <zkabelac@sourceware.org>
To: lvm-devel@redhat.com
Subject: master - pvmove: reinstantiate clustered pvmove
Date: Thu, 1 Feb 2018 15:58:49 -0500	[thread overview]
Message-ID: <201802012058.w11KwnMa018375@lists01.pubmisc.prod.ext.phx2.redhat.com> (raw)

Gitweb:        https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=083c221cbebccd8ea893e87f17c69fba378d8645
Commit:        083c221cbebccd8ea893e87f17c69fba378d8645
Parent:        34fb5202bdb3172a44fb3d957e184df4fb0412d8
Author:        Zdenek Kabelac <zkabelac@redhat.com>
AuthorDate:    Wed Jan 31 10:53:09 2018 +0100
Committer:     Zdenek Kabelac <zkabelac@redhat.com>
CommitterDate: Thu Feb 1 21:55:20 2018 +0100

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.
---
 WHATS_NEW               |    1 +
 lib/activate/activate.c |    1 -
 lib/locking/locking.c   |   12 +++--
 lib/locking/locking.h   |    2 +-
 tools/pvmove.c          |  109 +++++++++++++++++++++++++++++++++++-----------
 5 files changed, 93 insertions(+), 32 deletions(-)

diff --git a/WHATS_NEW b/WHATS_NEW
index bc73cd7..75a147b 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -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.
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 18cc7cf..7a37130 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -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.",
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
index 8daa61e..1a3ce9d 100644
--- a/lib/locking/locking.c
+++ b/lib/locking/locking.c
@@ -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))
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
index 47841ed..f2fbb00 100644
--- a/lib/locking/locking.h
+++ b/lib/locking/locking.h
@@ -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
diff --git a/tools/pvmove.c b/tools/pvmove.c
index b3d1d89..cbd5cb8 100644
--- a/tools/pvmove.c
+++ b/tools/pvmove.c
@@ -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 */



             reply	other threads:[~2018-02-01 20:58 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-02-01 20:58 Zdenek Kabelac [this message]
2018-02-07  7:17 ` master - pvmove: reinstantiate clustered pvmove Eric Ren
2018-02-07 10:06   ` Eric Ren
2018-02-07 16:49   ` Zdenek Kabelac
2018-02-08  1:45     ` Eric Ren
2018-02-08 12:42       ` Zdenek Kabelac
2018-02-09  2:21         ` Eric Ren
2018-02-09 12:05           ` Zdenek Kabelac
2018-02-09 13:29             ` Eric Ren
2018-02-15 13:20               ` Zdenek Kabelac
2018-02-23  8:40                 ` Eric Ren

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=201802012058.w11KwnMa018375@lists01.pubmisc.prod.ext.phx2.redhat.com \
    --to=zkabelac@sourceware.org \
    --cc=lvm-devel@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.