linux-lvm.redhat.com archive mirror
 help / color / mirror / Atom feed
From: Vladislav Bogdanov <bubble@hoster-ok.com>
To: linux-lvm@redhat.com
Subject: [linux-lvm] [PATCH 01/10] lvchange: Allow cluster lock conversion
Date: Tue, 19 Mar 2013 13:32:41 +0000	[thread overview]
Message-ID: <1363699970-10002-2-git-send-email-bubble@hoster-ok.com> (raw)
In-Reply-To: <1363699970-10002-1-git-send-email-bubble@hoster-ok.com>

Allow clvm locks to be converted shared <-> exclusive with corosync/dlm.

Without this it is impossible to alow both
* VM migration (shared lock is required)
* host-side snapshots of VM disks (exlusive lock is required)

Locks are only converted if --force parameter passed to lvchange.

Internally LKF_CONVERT flag is passed to dlm, so that is a real lock
conversion.

Also deny release of an exclusive lock on a remote note without --force
flag to lvchange -an.

Signed-off-by: Vladislav Bogdanov <bubble@hoster-ok.com>
---
 lib/locking/cluster_locking.c |    6 +++++-
 lib/locking/locking.c         |   32 ++++++++++++++++++++++++++++++++
 lib/locking/locking.h         |   10 +++++++++-
 tools/lvchange.c              |   30 ++++++++++++++++++++++--------
 4 files changed, 68 insertions(+), 10 deletions(-)

diff --git a/lib/locking/cluster_locking.c b/lib/locking/cluster_locking.c
index f9d6328..c3bd202 100644
--- a/lib/locking/cluster_locking.c
+++ b/lib/locking/cluster_locking.c
@@ -330,6 +330,9 @@ static int _lock_for_cluster(struct cmd_context *cmd, unsigned char clvmd_cmd,
 	if (flags & LCK_REVERT)
 		args[1] |= LCK_REVERT_MODE;
 
+	if (flags & LCK_TRY_CONVERT)
+		args[1] |= LCK_CONVERT;
+
 	if (mirror_in_sync())
 		args[1] |= LCK_MIRROR_NOSYNC_MODE;
 
@@ -491,7 +494,7 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
 		return 0;
 	}
 
-	log_very_verbose("Locking %s %s %s (%s%s%s%s%s%s%s%s%s) (0x%x)", lock_scope, lockname,
+	log_very_verbose("Locking %s %s %s (%s%s%s%s%s%s%s%s%s%s) (0x%x)", lock_scope, lockname,
 			 lock_type, lock_scope,
 			 flags & LCK_NONBLOCK ? "|NONBLOCK" : "",
 			 flags & LCK_HOLD ? "|HOLD" : "",
@@ -501,6 +504,7 @@ int lock_resource(struct cmd_context *cmd, const char *resource, uint32_t flags)
 			 flags & LCK_CACHE ? "|CACHE" : "",
 			 flags & LCK_ORIGIN_ONLY ? "|ORIGIN_ONLY" : "",
 			 flags & LCK_REVERT ? "|REVERT" : "",
+			 flags & LCK_TRY_CONVERT ? "|CONVERT" : "",
 			 flags);
 
 	/* Send a message to the cluster manager */
diff --git a/lib/locking/locking.c b/lib/locking/locking.c
index 7aa519b..ff46046 100644
--- a/lib/locking/locking.c
+++ b/lib/locking/locking.c
@@ -540,6 +540,16 @@ int suspend_lvs(struct cmd_context *cmd, struct dm_list *lvs,
 	return 1;
 }
 
+int deactivate_lv(struct cmd_context *cmd, struct logical_volume *lv)
+{
+	if (vg_is_clustered(lv->vg)) {
+		if (lv_is_active_exclusive(lv) && ! lv_is_active_exclusive_locally(lv)) {
+			return_0;
+		}
+	}
+	lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE);
+}
+
 /*
  * First try to activate exclusively locally.
  * Then if the VG is clustered and the LV is not yet active (e.g. due to 
@@ -567,6 +577,28 @@ int activate_lv_excl(struct cmd_context *cmd, struct logical_volume *lv)
 	return lv_is_active_exclusive(lv);
 }
 
+int activate_lv_excl_force(struct cmd_context *cmd, struct logical_volume *lv) 
+{
+	/* Non-clustered VGs are only activated locally. */
+	if (!vg_is_clustered(lv->vg))
+		return activate_lv_excl_local(cmd, lv);
+
+	if (lv_is_active_exclusive_locally(lv))
+		return 1;
+
+	if (!activate_lv_excl_local_force(cmd, lv))
+		return_0;
+
+	if (lv_is_active_exclusive(lv))
+		return 1;
+
+	/* FIXME Deal with error return codes. */
+	if (activate_lv_excl_remote_force(cmd, lv))
+		stack;
+
+	return lv_is_active_exclusive(lv);
+}
+
 /* Lock a list of LVs */
 int activate_lvs(struct cmd_context *cmd, struct dm_list *lvs, unsigned exclusive)
 {
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
index 23c312d..b441a6c 100644
--- a/lib/locking/locking.h
+++ b/lib/locking/locking.h
@@ -101,6 +101,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
 #define LCK_CACHE	0x00000100U	/* Operation on cache only using P_ lock */
 #define LCK_ORIGIN_ONLY	0x00000200U	/* Operation should bypass any snapshots */
 #define LCK_REVERT	0x00000400U	/* Revert any incomplete change */
+#define LCK_TRY_CONVERT			0x00004000U	/* Convert existing lock */
 
 /*
  * Additional lock bits for cluster communication via args[1]
@@ -176,19 +177,26 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
 #define revert_lv(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_RESUME | LCK_REVERT)
 #define suspend_lv(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD)
 #define suspend_lv_origin(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_SUSPEND | LCK_HOLD | LCK_ORIGIN_ONLY)
-#define deactivate_lv(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE)
 
 #define activate_lv(cmd, lv)	lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD)
 #define activate_lv_excl_local(cmd, lv)	\
 				lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD | LCK_LOCAL)
 #define activate_lv_excl_remote(cmd, lv)	\
 				lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD | LCK_REMOTE)
+#define activate_lv_excl_local_force(cmd, lv)	\
+				lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD | LCK_LOCAL | (lv_is_active(lv) && ! lv_is_active_exclusive(lv) ? LCK_TRY_CONVERT : 0))
+#define activate_lv_excl_remote_force(cmd, lv)	\
+				lock_lv_vol(cmd, lv, LCK_LV_EXCLUSIVE | LCK_HOLD | LCK_REMOTE | (lv_is_active(lv) && ! lv_is_active_exclusive(lv) ? LCK_TRY_CONVERT : 0))
 
 struct logical_volume;
 int activate_lv_excl(struct cmd_context *cmd, struct logical_volume *lv);
+int activate_lv_excl_force(struct cmd_context *cmd, struct logical_volume *lv);
+int deactivate_lv(struct cmd_context *cmd, struct logical_volume *lv);
 
 #define activate_lv_local(cmd, lv)	\
 	lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL)
+#define activate_lv_local_force(cmd, lv)	\
+	lock_lv_vol(cmd, lv, LCK_LV_ACTIVATE | LCK_HOLD | LCK_LOCAL | (lv_is_active_exclusive_locally(lv) ? LCK_TRY_CONVERT : 0))
 #define deactivate_lv_local(cmd, lv)	\
 	lock_lv_vol(cmd, lv, LCK_LV_DEACTIVATE | LCK_LOCAL)
 #define drop_cached_metadata(vg)	\
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 04facdd..5740bea 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -238,15 +238,29 @@ static int _lvchange_activate(struct cmd_context *cmd, struct logical_volume *lv
 		if ((activate == CHANGE_AE) ||
 		    lv_is_origin(lv) ||
 		    lv_is_thin_type(lv)) {
-			log_verbose("Activating logical volume \"%s\" "
-				    "exclusively", lv->name);
-			if (!activate_lv_excl(cmd, lv))
-				return_0;
+			if (arg_count(cmd, force_ARG)) {
+				log_verbose("Activating logical volume \"%s\" "
+					    "exclusively (forced)", lv->name);
+				if (!activate_lv_excl_force(cmd, lv))
+					return_0;
+			} else {
+				log_verbose("Activating logical volume \"%s\" "
+					    "exclusively", lv->name);
+				if (!activate_lv_excl(cmd, lv))
+					return_0;
+			}
 		} else if (activate == CHANGE_ALY) {
-			log_verbose("Activating logical volume \"%s\" locally",
-				    lv->name);
-			if (!activate_lv_local(cmd, lv))
-				return_0;
+			if (arg_count(cmd, force_ARG)) {
+				log_verbose("Activating logical volume \"%s\" locally (forced)",
+					    lv->name);
+				if (!activate_lv_local_force(cmd, lv))
+					return_0;
+			} else {
+				log_verbose("Activating logical volume \"%s\" locally",
+					    lv->name);
+				if (!activate_lv_local(cmd, lv))
+					return_0;
+			}
 		} else {
 			log_verbose("Activating logical volume \"%s\"",
 				    lv->name);
-- 
1.7.1

  reply	other threads:[~2013-03-19 13:32 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-03-19 13:32 [linux-lvm] [PATCH 00/10] Enhancements to a clustered logical volume activation Vladislav Bogdanov
2013-03-19 13:32 ` Vladislav Bogdanov [this message]
2013-03-19 15:23   ` [linux-lvm] [PATCH 01/10] lvchange: Allow cluster lock conversion David Teigland
2013-03-19 15:33     ` Vladislav Bogdanov
2013-03-19 15:44       ` Vladislav Bogdanov
2013-03-19 16:03         ` David Teigland
2013-03-19 16:36           ` Vladislav Bogdanov
2013-03-19 13:32 ` [linux-lvm] [PATCH 02/10] clvmd: Fix buffer size Vladislav Bogdanov
2013-03-19 13:32 ` [linux-lvm] [PATCH 03/10] clvmd: Allow node names to be obtained from corosync's CMAP Vladislav Bogdanov
2013-03-19 13:32 ` [linux-lvm] [PATCH 04/10] clvmd: fix positive return value is not an error in csid->name translation Vladislav Bogdanov
2013-03-19 13:32 ` [linux-lvm] [PATCH 05/10] clvmd: use correct flags for local command execution Vladislav Bogdanov
2013-03-19 13:32 ` [linux-lvm] [PATCH 06/10] clvmd: additional debugging - print message bodies Vladislav Bogdanov
2013-03-19 13:32 ` [linux-lvm] [PATCH 07/10] locking: Allow lock management (activation, deactivation, conversion) on a remote nodes Vladislav Bogdanov
2013-03-19 13:32 ` [linux-lvm] [PATCH 08/10] lvchange: implement remote lock management Vladislav Bogdanov
2013-03-19 13:32 ` [linux-lvm] [PATCH 09/10] man: document --force option to lvchange, provide examples Vladislav Bogdanov
2013-03-19 13:32 ` [linux-lvm] [PATCH 10/10] man: document --node option to lvchange Vladislav Bogdanov
2013-03-19 15:32   ` David Teigland
2013-03-19 15:42     ` Vladislav Bogdanov
2013-03-19 15:54       ` David Teigland
2013-03-19 16:52         ` Vladislav Bogdanov
2013-03-19 17:16           ` David Teigland
2013-03-19 17:36             ` Vladislav Bogdanov
2013-03-20  8:45               ` Zdenek Kabelac
2013-03-20 12:12                 ` Vladislav Bogdanov
2013-03-21 18:31                 ` Vladislav Bogdanov
2013-03-21 19:01                   ` Zdenek Kabelac
2013-03-21 19:16                     ` Vladislav Bogdanov
2013-03-21 18:23     ` Vladislav Bogdanov
2013-03-19 16:42 ` [linux-lvm] [PATCH 00/10] Enhancements to a clustered logical volume activation Alasdair G Kergon
2013-03-19 17:42   ` Vladislav Bogdanov
2013-06-05 13:23     ` [linux-lvm] clvmd leaving kernel dlm uncontrolled lockspace Andreas Pflug
2013-06-05 15:13       ` David Teigland
2013-06-05 17:29         ` Andreas Pflug
2013-06-06  6:17         ` Andreas Pflug
2013-06-06 11:06           ` matthew patton
2013-06-06 17:54             ` Andreas Pflug

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=1363699970-10002-2-git-send-email-bubble@hoster-ok.com \
    --to=bubble@hoster-ok.com \
    --cc=linux-lvm@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).