mrc0mmand / rpms / lvm2

Forked from rpms/lvm2 2 years ago
Clone

Blame SOURCES/lvm2-2_03_03-lvmlockd-make-lockstart-wait-for-existing-start.patch

146ac4
From 887f6099e6f6b662df356e7d26102ff84aa0c901 Mon Sep 17 00:00:00 2001
146ac4
From: David Teigland <teigland@redhat.com>
146ac4
Date: Wed, 16 Jan 2019 10:41:43 -0600
146ac4
Subject: [PATCH 4/5] lvmlockd: make lockstart wait for existing start
146ac4
146ac4
If there are two independent scripts doing:
146ac4
  vgchange --lockstart vg
146ac4
  lvchange -ay vg/lv
146ac4
146ac4
The first vgchange to do the lockstart will wait for
146ac4
the lockstart to complete before returning.
146ac4
The second vgchange to do the lockstart will see that
146ac4
the start is already in progress (from the first) and
146ac4
will do nothing.  This means the second does not wait
146ac4
for any lockstart to complete, and moves on to the
146ac4
lvchange which may find the lockspace still starting
146ac4
and fail.
146ac4
146ac4
To fix this, make the vgchange lockstart command
146ac4
wait for any lockstart's in progress to complete.
146ac4
---
146ac4
 daemons/lvmlockd/lvmlockd-core.c |  9 ++++++---
146ac4
 lib/locking/lvmlockd.c           | 12 +++++++++---
146ac4
 lib/locking/lvmlockd.h           |  2 +-
146ac4
 tools/vgchange.c                 |  5 ++++-
146ac4
 tools/vgcreate.c                 |  2 +-
146ac4
 5 files changed, 21 insertions(+), 9 deletions(-)
146ac4
146ac4
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
146ac4
index a9ce6fc..e2d4595 100644
146ac4
--- a/daemons/lvmlockd/lvmlockd-core.c
146ac4
+++ b/daemons/lvmlockd/lvmlockd-core.c
146ac4
@@ -2742,6 +2742,9 @@ static int add_lockspace_thread(const char *ls_name,
146ac4
 		if (ls2->thread_stop) {
146ac4
 			log_debug("add_lockspace_thread %s exists and stopping", ls->name);
146ac4
 			rv = -EAGAIN;
146ac4
+		} else if (!ls2->create_fail && !ls2->create_done) {
146ac4
+			log_debug("add_lockspace_thread %s exists and starting", ls->name);
146ac4
+			rv = -ESTARTING;
146ac4
 		} else {
146ac4
 			log_debug("add_lockspace_thread %s exists", ls->name);
146ac4
 			rv = -EEXIST;
146ac4
@@ -2983,7 +2986,7 @@ static int count_lockspace_starting(uint32_t client_id)
146ac4
 
146ac4
 	pthread_mutex_lock(&lockspaces_mutex);
146ac4
 	list_for_each_entry(ls, &lockspaces, list) {
146ac4
-		if (ls->start_client_id != client_id)
146ac4
+		if (client_id && (ls->start_client_id != client_id))
146ac4
 			continue;
146ac4
 
146ac4
 		if (!ls->create_done && !ls->create_fail) {
146ac4
@@ -3384,7 +3387,7 @@ static void *worker_thread_main(void *arg_in)
146ac4
 			add_client_result(act);
146ac4
 
146ac4
 		} else if (act->op == LD_OP_START_WAIT) {
146ac4
-			act->result = count_lockspace_starting(act->client_id);
146ac4
+			act->result = count_lockspace_starting(0);
146ac4
 			if (!act->result)
146ac4
 				add_client_result(act);
146ac4
 			else
146ac4
@@ -3418,7 +3421,7 @@ static void *worker_thread_main(void *arg_in)
146ac4
 		list_for_each_entry_safe(act, safe, &delayed_list, list) {
146ac4
 			if (act->op == LD_OP_START_WAIT) {
146ac4
 				log_debug("work delayed start_wait for client %u", act->client_id);
146ac4
-				act->result = count_lockspace_starting(act->client_id);
146ac4
+				act->result = count_lockspace_starting(0);
146ac4
 				if (!act->result) {
146ac4
 					list_del(&act->list);
146ac4
 					add_client_result(act);
146ac4
diff --git a/lib/locking/lvmlockd.c b/lib/locking/lvmlockd.c
146ac4
index 969a7fe..6168630 100644
146ac4
--- a/lib/locking/lvmlockd.c
146ac4
+++ b/lib/locking/lvmlockd.c
146ac4
@@ -1077,7 +1077,7 @@ void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg)
146ac4
  * that the VG lockspace being started is new.
146ac4
  */
146ac4
 
146ac4
-int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_init)
146ac4
+int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_init, int *exists)
146ac4
 {
146ac4
 	char uuid[64] __attribute__((aligned(8)));
146ac4
 	daemon_reply reply;
146ac4
@@ -1152,6 +1152,12 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_i
146ac4
 		log_debug("VG %s start error: already started", vg->name);
146ac4
 		ret = 1;
146ac4
 		break;
146ac4
+	case -ESTARTING:
146ac4
+		log_debug("VG %s start error: already starting", vg->name);
146ac4
+		if (exists)
146ac4
+			*exists = 1;
146ac4
+		ret = 1;
146ac4
+		break;
146ac4
 	case -EARGS:
146ac4
 		log_error("VG %s start failed: invalid parameters for %s", vg->name, vg->lock_type);
146ac4
 		break;
146ac4
@@ -2673,7 +2679,7 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int
146ac4
 		 * Depending on the problem that caused the rename to
146ac4
 		 * fail, it may make sense to not restart the VG here.
146ac4
 		 */
146ac4
-		if (!lockd_start_vg(cmd, vg, 0))
146ac4
+		if (!lockd_start_vg(cmd, vg, 0, NULL))
146ac4
 			log_error("Failed to restart VG %s lockspace.", vg->name);
146ac4
 		return 1;
146ac4
 	}
146ac4
@@ -2713,7 +2719,7 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int
146ac4
 		}
146ac4
 	}
146ac4
 
146ac4
-	if (!lockd_start_vg(cmd, vg, 1))
146ac4
+	if (!lockd_start_vg(cmd, vg, 1, NULL))
146ac4
 		log_error("Failed to start VG %s lockspace.", vg->name);
146ac4
 
146ac4
 	return 1;
146ac4
diff --git a/lib/locking/lvmlockd.h b/lib/locking/lvmlockd.h
146ac4
index 0a6ea96..1fbf765 100644
146ac4
--- a/lib/locking/lvmlockd.h
146ac4
+++ b/lib/locking/lvmlockd.h
146ac4
@@ -63,7 +63,7 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int
146ac4
 
146ac4
 /* start and stop the lockspace for a vg */
146ac4
 
146ac4
-int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_init);
146ac4
+int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_init, int *exists);
146ac4
 int lockd_stop_vg(struct cmd_context *cmd, struct volume_group *vg);
146ac4
 int lockd_start_wait(struct cmd_context *cmd);
146ac4
 
146ac4
diff --git a/tools/vgchange.c b/tools/vgchange.c
146ac4
index 0f9241c..f3d535c 100644
146ac4
--- a/tools/vgchange.c
146ac4
+++ b/tools/vgchange.c
146ac4
@@ -560,6 +560,7 @@ static int _vgchange_lock_start(struct cmd_context *cmd, struct volume_group *vg
146ac4
 {
146ac4
 	const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
146ac4
 	int auto_opt = 0;
146ac4
+	int exists = 0;
146ac4
 	int r;
146ac4
 
146ac4
 	if (!vg_is_shared(vg))
146ac4
@@ -586,10 +587,12 @@ static int _vgchange_lock_start(struct cmd_context *cmd, struct volume_group *vg
146ac4
 	}
146ac4
 
146ac4
 do_start:
146ac4
-	r = lockd_start_vg(cmd, vg, 0);
146ac4
+	r = lockd_start_vg(cmd, vg, 0, &exists;;
146ac4
 
146ac4
 	if (r)
146ac4
 		vp->lock_start_count++;
146ac4
+	else if (exists)
146ac4
+		vp->lock_start_count++;
146ac4
 	if (!strcmp(vg->lock_type, "sanlock"))
146ac4
 		vp->lock_start_sanlock = 1;
146ac4
 
146ac4
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
146ac4
index 2a40bc7..b595349 100644
146ac4
--- a/tools/vgcreate.c
146ac4
+++ b/tools/vgcreate.c
146ac4
@@ -202,7 +202,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
146ac4
 	if (vg_is_shared(vg)) {
146ac4
 		const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
146ac4
 
146ac4
-		if (!lockd_start_vg(cmd, vg, 1)) {
146ac4
+		if (!lockd_start_vg(cmd, vg, 1, NULL)) {
146ac4
 			log_error("Failed to start locking");
146ac4
 			goto out;
146ac4
 		}
146ac4
-- 
146ac4
1.8.3.1
146ac4