[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