[Cluster-devel] cluster/rgmanager ChangeLog src/daemons/groups ...

lhh at sourceware.org lhh at sourceware.org
Thu Apr 19 18:05:37 UTC 2007


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 at 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 at 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;




More information about the Cluster-devel mailing list