All of lore.kernel.org
 help / color / mirror / Atom feed
From: lhh@sourceware.org <lhh@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] cluster/rgmanager ChangeLog src/daemons/groups ...
Date: 19 Apr 2007 18:05:37 -0000	[thread overview]
Message-ID: <20070419180537.28847.qmail@sourceware.org> (raw)

CVSROOT:	/cvs/cluster
Module name:	cluster
Branch: 	RHEL5
Changes by:	lhh at sourceware.org	2007-04-19 19:05:37

Modified files:
	rgmanager      : ChangeLog 
	rgmanager/src/daemons: groups.c rg_state.c 

Log message:
	Apply patch from Andrey Mirkin to fix 237144

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/ChangeLog.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.31.2.1&r2=1.31.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/groups.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.25.2.3&r2=1.25.2.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/rg_state.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.24.2.5&r2=1.24.2.6

--- cluster/rgmanager/ChangeLog	2007/04/12 17:23:05	1.31.2.1
+++ cluster/rgmanager/ChangeLog	2007/04/19 18:05:36	1.31.2.2
@@ -1,3 +1,9 @@
+2007-04-19 Lon Hohberger <lhh@redhat.com>
+	* src/daemons/groups.c, rg_state.c: Apply patch from Andrey
+	Mirkin to fix bug #237144; prevents exclusive services from
+	being accidentally (or intentionally) being started on the
+	same node
+
 2007-04-12 Lon Hohberger <lhh@redhat.com>
 	* src/daemons/main.c: Fix watchdog race condition causing
 	reboot; patch from Andrey Mirkin; bugzilla #236204
--- cluster/rgmanager/src/daemons/groups.c	2007/03/20 17:09:11	1.25.2.3
+++ cluster/rgmanager/src/daemons/groups.c	2007/04/19 18:05:37	1.25.2.4
@@ -20,6 +20,7 @@
 //#define DEBUG
 #include <platform.h>
 #include <resgroup.h>
+#include <reslist.h>
 #include <vf.h>
 #include <message.h>
 #include <ccs.h>
@@ -138,6 +139,105 @@
 }
 
 
+int
+count_resource_groups_local(cman_node_t *mp)
+{
+	resource_t *res;
+	resource_node_t *node;
+	char rgname[64], *val;
+	rg_state_t st;
+
+	mp->cn_svccount = 0;
+	mp->cn_svcexcl = 0;
+
+	pthread_rwlock_rdlock(&resource_lock);
+
+	list_do(&_tree, node) {
+
+		res = node->rn_resource;
+
+		res_build_name(rgname, sizeof(rgname), res);
+
+		if (get_rg_state_local(rgname, &st) < 0) {
+			continue;
+		}
+
+		if (st.rs_state != RG_STATE_STARTED &&
+		     st.rs_state != RG_STATE_STARTING)
+			continue;
+
+		if (mp->cn_nodeid != st.rs_owner)
+			continue;
+
+		++mp->cn_svccount;
+
+		val = res_attr_value(res, "exclusive");
+		if (val && ((!strcmp(val, "yes") ||
+				     (atoi(val)>0))) ) {
+			++mp->cn_svcexcl;
+		}
+
+	} while (!list_done(&_tree, node));
+
+	pthread_rwlock_unlock(&resource_lock);
+	return 0;
+}
+
+
+int
+have_exclusive_resources(void)
+{
+	resource_t *res;
+	char *val;
+
+	pthread_rwlock_rdlock(&resource_lock);
+
+	list_do(&_resources, res) {
+		val = res_attr_value(res, "exclusive");
+		if (val && ((!strcmp(val, "yes") ||
+						(atoi(val)>0))) ) {
+			pthread_rwlock_unlock(&resource_lock);
+			return 1;
+		}
+
+	} while (!list_done(&_resources, res));
+
+	pthread_rwlock_unlock(&resource_lock);
+
+	return 0;
+}
+
+
+int
+check_exclusive_resources(cluster_member_list_t *membership, char *svcName)
+{
+	cman_node_t *mp;
+	int exclusive, count; 
+	resource_t *res;
+	char *val;
+
+	mp = memb_id_to_p(membership, my_id());
+	assert(mp);
+	count_resource_groups_local(mp);
+	exclusive = mp->cn_svcexcl;
+	count = mp->cn_svccount;
+	pthread_rwlock_rdlock(&resource_lock);
+	res = find_root_by_ref(&_resources, svcName);
+	if (!res) {
+		pthread_rwlock_unlock(&resource_lock);
+		return RG_EFAIL;
+	}
+	val = res_attr_value(res, "exclusive");
+	pthread_rwlock_unlock(&resource_lock);
+	if (exclusive || (count && val && 
+			(!strcmp(val, "yes") || (atoi(val)>0)))) {
+		return RG_YES;
+	}
+
+	return 0;
+}
+
+
 /**
    Find the best target node for a service *besides* the current service
    owner.  Takes into account:
--- cluster/rgmanager/src/daemons/rg_state.c	2007/03/20 17:09:11	1.24.2.5
+++ cluster/rgmanager/src/daemons/rg_state.c	2007/04/19 18:05:37	1.24.2.6
@@ -48,6 +48,8 @@
 void get_recovery_policy(char *rg_name, char *buf, size_t buflen);
 int check_depend_safe(char *servicename);
 int group_migratory(char *servicename, int lock);
+int have_exclusive_resources(void);
+int check_exclusive_resources(cluster_member_list_t *membership, char *svcName);
 
 
 int 
@@ -687,6 +689,10 @@
 			ret = 1;
 			break;
 		}
+		if (req == RG_START_RECOVER) {
+			ret = 1;
+			break;
+		}
 
 		clulog(LOG_DEBUG, "Not starting disabled RG %s\n",
 		       svcName);
@@ -1463,6 +1469,7 @@
 }
 
 
+pthread_mutex_t exclusive_mutex = PTHREAD_MUTEX_INITIALIZER;
 /**
  * handle_start_req - Handle a generic start request from a user or during
  * service manager boot.
@@ -1478,6 +1485,7 @@
 {
 	int ret, tolerance = FOD_BEST;
 	cluster_member_list_t *membership = member_list();
+	int need_check = have_exclusive_resources();
 
 	/*
 	 * When a service request is from a user application (eg, clusvcadm),
@@ -1493,6 +1501,18 @@
 		free_member_list(membership);
 		return RG_EFAIL;
 	}
+	if (need_check) {
+		pthread_mutex_lock(&exclusive_mutex);
+		ret = check_exclusive_resources(membership, svcName);
+		if (ret != 0) {
+			free_member_list(membership);
+			pthread_mutex_unlock(&exclusive_mutex);
+			if (ret > 0)
+				goto relocate;
+			else
+				return RG_EFAIL;
+		}
+	}
 	free_member_list(membership);
 
 	/* Check for dependency.  We cannot start unless our
@@ -1505,6 +1525,8 @@
 	 * mask here - so that we can try all nodes if necessary.
 	 */
 	ret = svc_start(svcName, req);
+	if (need_check)
+		pthread_mutex_unlock(&exclusive_mutex);
 
 	/* 
 	   If services are locked, return the error 
@@ -1544,6 +1566,7 @@
 		return RG_EABORT;
 	}
 	
+relocate:
 	/*
 	 * OK, it failed to start - but succeeded to stop.  Now,
 	 * we should relocate the service.
@@ -1581,6 +1604,7 @@
 	int x;
 	uint32_t me = my_id();
 	cluster_member_list_t *membership = member_list();
+	int need_check = have_exclusive_resources();
 
 	/* XXX ok, so we need to say "should I start this if I was the
 	   only cluster member online */
@@ -1601,10 +1625,23 @@
 		free_member_list(membership);
 		return RG_EFAIL;
 	}
+	if (need_check) {
+		pthread_mutex_lock(&exclusive_mutex);
+		if (check_exclusive_resources(membership, svcName) != 0) {
+			free_member_list(membership);
+			pthread_mutex_unlock(&exclusive_mutex);
+			return RG_EFAIL;
+		}
+	}
 	free_member_list(membership);
 
-	if (svc_start(svcName, req) == 0)
+	if (svc_start(svcName, req) == 0) {
+		if (need_check)
+			pthread_mutex_unlock(&exclusive_mutex);
 		return 0;
+	}
+	if (need_check)
+		pthread_mutex_unlock(&exclusive_mutex);
 
 	if (svc_stop(svcName, RG_STOP_RECOVER) == 0)
 		return RG_EFAIL;



             reply	other threads:[~2007-04-19 18:05 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-04-19 18:05 lhh [this message]
  -- strict thread matches above, loose matches on Subject: below --
2007-12-12 21:41 [Cluster-devel] cluster/rgmanager ChangeLog src/daemons/groups lhh
2007-09-28 15:14 lhh
2007-07-31 18:26 lhh
2007-07-10 18:25 lhh
2007-07-10 18:24 lhh
2007-07-02 15:15 lhh
2007-07-02 15:13 lhh
2007-04-19 17:59 lhh

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=20070419180537.28847.qmail@sourceware.org \
    --to=lhh@sourceware.org \
    /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.