cluster-devel.redhat.com archive mirror
 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 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).