[Cluster-devel] cluster/rgmanager include/list.h include/resli ...

lhh at sourceware.org lhh at sourceware.org
Fri Mar 23 00:06:36 UTC 2007


CVSROOT:	/cvs/cluster
Module name:	cluster
Branch: 	RHEL5
Changes by:	lhh at sourceware.org	2007-03-23 00:06:35

Modified files:
	rgmanager/include: list.h reslist.h 
	rgmanager/src/daemons: reslist.c resrules.c restree.c test.c 
Removed files:
	rgmanager/src/resources: perlscript.pl 

Log message:
	Merge resource-order patch from RHEL4 + main branches

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/include/list.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.4&r2=1.4.2.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/include/reslist.h.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.15.2.1&r2=1.15.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/reslist.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.14.2.1&r2=1.14.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/resrules.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.16.2.1&r2=1.16.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/restree.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.23.2.1&r2=1.23.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/test.c.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.6.2.1&r2=1.6.2.2
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/resources/perlscript.pl.diff?cvsroot=cluster&only_with_tag=RHEL5&r1=1.1&r2=NONE

--- cluster/rgmanager/include/list.h	2006/06/02 17:37:10	1.4
+++ cluster/rgmanager/include/list.h	2007/03/23 00:06:34	1.4.2.1
@@ -29,6 +29,14 @@
 	} \
 } while (0)
 
+	
+#define list_prepend(list, newnode) \
+do { \
+	list_insert(list, newnode); \
+	*list = newnode; \
+} while (0)
+
+
 #define list_remove(list, oldnode) \
 do { \
 	if (le(oldnode) == le(*list)) { \
@@ -46,6 +54,11 @@
 	} \
 } while (0)
 
+/*
+   list_do(list, node) {
+   	stuff;
+   } while (!list_done(list, node));
+ */
 #define list_do(list, curr) \
 	if (*list && (curr = *list)) do
 
@@ -53,9 +66,29 @@
 	(curr && (((curr = (void *)le(curr)->le_next)) && (curr == *list)))
 
 /*
-   list_do(list, node) {
-   	stuff;
-   } while (!list_done(list, node));
+ * list_for(list, tmp, counter) {
+ *     stuff;
+ * }
+ * 
+ * counter = # of items in list when done.
+ * * sets cnt to 0 before even checking list;
+ * * checks for valid list
+ * * traverses list, incrementing counter.  If we get to the for loop,
+ *   there must be at least one item in the list
  */
+#define list_for(list, curr, cnt) \
+	if (!(cnt=0) && list && *list) \
+		for (curr = *list; \
+		     (cnt == 0) || (curr != *list); \
+		     curr = (void*)le(curr)->le_next, \
+		     cnt++)
+			
+#define list_for_rev(list, curr, cnt) \
+	if (!(cnt=0) && list && *list) \
+		for (curr = (void *)(le(*list)->le_prev); \
+		     (cnt == 0) || ((void *)curr != le(*list)->le_prev); \
+		     curr = (void*)(le(curr)->le_prev), \
+		     cnt++)
+				   
 
 #endif
--- cluster/rgmanager/include/reslist.h	2007/03/20 17:09:11	1.15.2.1
+++ cluster/rgmanager/include/reslist.h	2007/03/23 00:06:34	1.15.2.2
@@ -64,10 +64,11 @@
 
 
 typedef struct _resource_child {
-	char    rc_forbid;
+	char	*rc_name;
 	int	rc_startlevel;
 	int	rc_stoplevel;
-	char	*rc_name;
+	int	rc_forbid;
+	int	rc_flags;
 } resource_child_t;
 
 
--- cluster/rgmanager/src/daemons/reslist.c	2007/01/26 20:41:40	1.14.2.1
+++ cluster/rgmanager/src/daemons/reslist.c	2007/03/23 00:06:34	1.14.2.2
@@ -412,17 +412,52 @@
 {
 	char *val = NULL, *ret = NULL;
 	xmlXPathObjectPtr obj;
+	xmlNodePtr node;
+	size_t size = 0;
+	int nnv = 0;
 
 	obj = xmlXPathEvalExpression((unsigned char *)query, ctx);
 	if (!obj)
 		return NULL;
+	if (!obj->nodesetval)
+		goto out;
+	if (obj->nodesetval->nodeNr <= 0)
+		goto out;
+
+	node = obj->nodesetval->nodeTab[0];
+	if(!node)
+		goto out;
+
+	if (((node->type == XML_ATTRIBUTE_NODE) && strstr(query, "@*")) ||
+	    ((node->type == XML_ELEMENT_NODE) && strstr(query, "child::*"))){
+		if (node->children && node->children->content)
+	  		size = strlen((char *)node->children->content)+
+				      strlen((char *)node->name)+2;
+		else 
+			size = strlen((char *)node->name)+2;
+		nnv = 1;
+	} else {
+		if (node->children && node->children->content) {
+			size = strlen((char *)node->children->content)+1;
+		} else {
+			goto out;
+		}
+	}
 
-	if (obj->nodesetval && obj->nodesetval->nodeNr >= 1) {
-		val = (char *)obj->nodesetval->nodeTab[0]->children->content;
-		if (strlen(val) >= 1)
-			ret = strdup(val);
+	val = (char *)malloc(size);
+	if(!val)
+		goto out;
+	memset(val, 0, size);
+	if (nnv) {
+		sprintf(val, "%s=%s", node->name, node->children ?
+			(char *)node->children->content:"");
+	} else {
+		sprintf(val, "%s", node->children ? node->children->content :
+			node->name);
 	}
 
+	ret = val;
+out:
 	xmlXPathFreeObject(obj);
 
 	return ret;
--- cluster/rgmanager/src/daemons/resrules.c	2007/01/26 20:41:40	1.16.2.1
+++ cluster/rgmanager/src/daemons/resrules.c	2007/03/23 00:06:34	1.16.2.2
@@ -449,11 +449,12 @@
    @param start		Start level
    @param stop		Stop level
    @param forbid	Do NOT allow this child type to exist
+   @param flags		set to 1 to note that it was defined inline
    @return		0 on success, nonzero on failure
  */
 int
 store_childtype(resource_child_t **childp, char *name, int start, int stop,
-		int forbid)
+		int forbid, int flags)
 {
 	int x = 0;
 	resource_child_t *child = *childp;
@@ -469,6 +470,7 @@
 		child[0].rc_startlevel = start;
 		child[0].rc_stoplevel = stop;
 		child[0].rc_forbid = forbid;
+		child[0].rc_flags = flags;
 		child[1].rc_name = NULL;
 
 		*childp = child;
@@ -485,6 +487,7 @@
 	child[x].rc_startlevel = start;
 	child[x].rc_stoplevel = stop;
 	child[x].rc_forbid = forbid;
+	child[x].rc_flags = flags;
 	child[x+1].rc_name = NULL;
 
 	*childp = child;
@@ -777,7 +780,7 @@
 		 */
 		if (childname)
 			store_childtype(&rr->rr_childtypes, childname,
-					startlevel, stoplevel, forbid);
+					startlevel, stoplevel, forbid, 0);
 	}
 
 	return 0;
--- cluster/rgmanager/src/daemons/restree.c	2007/03/20 17:09:11	1.23.2.1
+++ cluster/rgmanager/src/daemons/restree.c	2007/03/23 00:06:34	1.23.2.2
@@ -42,10 +42,17 @@
 
 /* XXX from resrules.c */
 int store_childtype(resource_child_t **childp, char *name, int start,
-		    int stop, int forbid);
+		    int stop, int forbid, int flags);
 int _res_op(resource_node_t **tree, resource_t *first, char *type,
 	    void * __attribute__((unused))ret, int op);
+static inline int
+_res_op_internal(resource_node_t **tree, resource_t *first,
+		 char *type, void *__attribute__((unused))ret, int realop,
+		 resource_node_t *node);
 void print_env(char **env);
+static inline int _res_op_internal(resource_node_t **tree, resource_t *first,
+		 char *type, void *__attribute__((unused))ret, int realop,
+		 resource_node_t *node);
 
 /* XXX from reslist.c */
 void * act_dup(resource_act_t *acts);
@@ -74,6 +81,17 @@
 };
 
 
+/* XXX MEGA HACK */
+#ifdef NO_CCS
+static int _no_op_mode_ = 0;
+void
+_no_op_mode(int arg)
+{
+	_no_op_mode_ = arg;
+}
+#endif
+
+
 /**
    ocf_strerror
  */
@@ -331,6 +349,14 @@
 		return -errno;
 #endif
 
+#ifdef NO_CCS
+	if (_no_op_mode_) {
+		printf("[%s] %s:%s\n", op, res->r_rule->rr_type,
+		       res->r_attrs->ra_value);
+		return 0;
+	}
+#endif
+
 	childpid = fork();
 	if (childpid < 0)
 		return -errno;
@@ -400,6 +426,97 @@
 }
 
 
+static inline int
+do_load_resource(int ccsfd, char *base,
+	         resource_rule_t *rule,
+	         resource_node_t **tree,
+		 resource_t **reslist,
+		 resource_node_t *parent,
+		 resource_node_t **newnode)
+{
+	char tok[512];
+	char *ref;
+	resource_node_t *node;
+	resource_t *curres;
+
+	snprintf(tok, sizeof(tok), "%s/@ref", base);
+
+#ifndef NO_CCS
+	if (ccs_get(ccsfd, tok, &ref) != 0) {
+#else
+	if (conf_get(tok, &ref) != 0) {
+#endif
+		/* There wasn't an existing resource. See if there
+		   is one defined inline */
+		curres = load_resource(ccsfd, rule, base);
+		if (!curres) {
+			/* No ref and no new one inline == 
+			   no more of the selected type */
+			return 1;
+		}
+
+	       	if (store_resource(reslist, curres) != 0) {
+	 		printf("Error storing %s resource\n",
+	 		       curres->r_rule->rr_type);
+	 		destroy_resource(curres);
+			return -1;
+	 	}
+
+		curres->r_flags = RF_INLINE;
+
+	} else {
+
+		curres = find_resource_by_ref(reslist, rule->rr_type,
+						      ref);
+		if (!curres) {
+			printf("Error: Reference to nonexistent "
+			       "resource %s (type %s)\n", ref,
+			       rule->rr_type);
+			free(ref);
+			return -1;
+		}
+
+		if (curres->r_flags & RF_INLINE) {
+			printf("Error: Reference to inlined "
+			       "resource %s (type %s) is illegal\n",
+			       ref, rule->rr_type);
+			free(ref);
+			return -1;
+		}
+		free(ref);
+	}
+
+	/* Load it if its max refs hasn't been exceeded */
+	if (rule->rr_maxrefs && (curres->r_refs >= rule->rr_maxrefs)){
+		printf("Warning: Max references exceeded for resource"
+		       " %s (type %s)\n", curres->r_attrs[0].ra_name,
+		       rule->rr_type);
+		return -1;
+	}
+
+	node = malloc(sizeof(*node));
+	if (!node)
+		return -1;
+
+	memset(node, 0, sizeof(*node));
+
+	//printf("New resource tree node: %s:%s \n", curres->r_rule->rr_type,curres->r_attrs->ra_value);
+
+	node->rn_child = NULL;
+	node->rn_parent = parent;
+	node->rn_resource = curres;
+	node->rn_state = RES_STOPPED;
+	node->rn_actions = (resource_act_t *)act_dup(curres->r_actions);
+	curres->r_refs++;
+
+	*newnode = node;
+
+	list_insert(tree, node);
+
+	return 0;
+}
+
+
 /**
    Build the resource tree.  If a new resource is defined inline, add it to
    the resource list.  All rules, however, must have already been read in.
@@ -425,127 +542,173 @@
 	char tok[512];
 	resource_rule_t *childrule;
 	resource_node_t *node;
-	resource_t *curres;
 	char *ref;
 	char *newchild;
-	int x, y, flags;
-
-	for (x = 1; ; x++) {
+	char *tmp;
+	int ccount = 0, x = 0, y = 0, flags = 0;
 
-		/* Search for base/type[x]/@ref - reference an existing
-		   resource */
-		snprintf(tok, sizeof(tok), "%s/%s[%d]/@ref", base,
-			 rule->rr_type, x);
+	//printf("DESCEND: %s / %s\n", rule?rule->rr_type:"(none)", base);
 
-#ifndef NO_CCS
-		if (ccs_get(ccsfd, tok, &ref) != 0) {
-#else
-		if (conf_get(tok, &ref) != 0) {
-#endif
-			/* There wasn't an existing resource. See if there
-			   is one defined inline */
-			snprintf(tok, sizeof(tok), "%s/%s[%d]", base, 
-				 rule->rr_type, x);
-
-			curres = load_resource(ccsfd, rule, tok);
-			if (!curres)
-				/* No ref and no new one inline == 
-				   no more of the selected type */
-				break;
-
-		       	if (store_resource(reslist, curres) != 0) {
-		 		printf("Error storing %s resource\n",
-		 		       curres->r_rule->rr_type);
-		 		destroy_resource(curres);
+	/* Pass 1: typed / defined children */
+	for (y = 0; rule && rule->rr_childtypes &&
+     	     rule->rr_childtypes[y].rc_name; y++) {
+		
+	
+		flags = 0;
+		list_for(rulelist, childrule, x) {
+			if (strcmp(rule->rr_childtypes[y].rc_name,
+				   childrule->rr_type))
 				continue;
-		 	}
-
-			curres->r_flags = RF_INLINE;
 
+			flags |= RFL_FOUND;
 
-		} else {
+			if (rule->rr_childtypes[y].rc_forbid)
+				flags |= RFL_FORBID;
 
-			curres = find_resource_by_ref(reslist, rule->rr_type,
-						      ref);
-			if (!curres) {
-				printf("Error: Reference to nonexistent "
-				       "resource %s (type %s)\n", ref,
-				       rule->rr_type);
-				free(ref);
-				continue;
-			}
-
-			if (curres->r_flags & RF_INLINE) {
-				printf("Error: Reference to inlined "
-				       "resource %s (type %s) is illegal\n",
-				       ref, rule->rr_type);
-				free(ref);
-				continue;
-			}
-			free(ref);
+			break;
 		}
 
-		/* Load it if its max refs hasn't been exceeded */
-		if (rule->rr_maxrefs && (curres->r_refs >= rule->rr_maxrefs)){
-			printf("Warning: Max references exceeded for resource"
-			       " %s (type %s)\n", curres->r_attrs[0].ra_name,
-			       rule->rr_type);
+		if (flags & RFL_FORBID)
+			/* Allow all *but* forbidden */
 			continue;
-		}
 
-		node = malloc(sizeof(*node));
-		if (!node)
+		if (!(flags & RFL_FOUND))
+			/* Not found?  Wait for pass 2 */
 			continue;
 
-		memset(node, 0, sizeof(*node));
+		//printf("looking for %s %s @ %s\n",
+			//rule->rr_childtypes[y].rc_name,
+			//childrule->rr_type, base);
+		for (x = 1; ; x++) {
+
+			/* Search for base/type[x]/@ref - reference an existing
+			   	resource */
+			snprintf(tok, sizeof(tok), "%s/%s[%d]", base,
+				 childrule->rr_type, x);
+
+			flags = 1;
+			switch(do_load_resource(ccsfd, tok, childrule, tree,
+						reslist, parent, &node)) {
+			case -1:
+				continue;
+			case 1:
+				/* 1 == no more */
+				//printf("No resource found @ %s\n", tok);
+				flags = 0;
+				break;
+			case 0:
+				break;
+			}
+			if (!flags)
+				break;
+
+			/* Got a child :: bump count */
+			snprintf(tok, sizeof(tok), "%s/%s[%d]", base,
+				 childrule->rr_type, x);
 
-		node->rn_child = NULL;
-		node->rn_parent = parent;
-		node->rn_resource = curres;
-		node->rn_state = RES_STOPPED;
-		node->rn_actions = (resource_act_t *)act_dup(curres->r_actions);
-		curres->r_refs++;
+			/* Kaboom */
+			build_tree(ccsfd, &node->rn_child, node, childrule,
+				   rulelist, reslist, tok);
 
-		list_insert(tree, node);
+		}
+	}
 
-		list_do(rulelist, childrule) {
 
-			flags = 0;
-			for (y = 0; rule->rr_childtypes &&
-		     	     rule->rr_childtypes[y].rc_name; y++) {
+	/* Pass 2: untyped children */
+	for (ccount=1; ; ccount++) {
+		snprintf(tok, sizeof(tok), "%s/child::*[%d]", base, ccount);
 
-				if (strcmp(rule->rr_childtypes[y].rc_name,
-					   childrule->rr_type))
-					continue;
+#ifndef NO_CCS
+		if (ccs_get(ccsfd, tok, &ref) != 0) {
+#else
+		if (conf_get(tok, &ref) != 0) {
+#endif
+			/* End of the line. */
+			//printf("End of the line: %s\n", tok);
+			break;
+		}
 
-				flags |= RFL_FOUND;
+		tmp = strchr(ref, '=');
+		if (tmp) {
+			*tmp = 0;
+		} else {
+			/* no = sign... bad */
+			free(ref);
+			continue;
+		}
 
-				if (rule->rr_childtypes[y].rc_forbid)
-					flags |= RFL_FORBID;
+		/* Find the resource rule */
+		flags = 0;
+		list_for(rulelist, childrule, x) {
+			if (!strcasecmp(childrule->rr_type, ref)) {
+				/* Ok, matching rule found */
+				flags = 1;
+				break;
 			}
+		}
+		/* No resource rule matching the child?  Press on... */
+		if (!flags)
+			continue;
 
-			if (flags & RFL_FORBID)
-				/* Allow all *but* forbidden */
+		flags = 0;
+		/* Don't descend on anything we should have already picked
+		   up on in the above loop */
+		for (y = 0; rule && rule->rr_childtypes &&
+		     rule->rr_childtypes[y].rc_name; y++) {
+			/* SKIP defined child types of any type */
+			if (strcmp(rule->rr_childtypes[y].rc_name, ref))
 				continue;
-
-			/* XXX Store new child type with start/stop level 0*/
-			/*     This is really ugly to do it here */
-			if (!(flags & RFL_FOUND)) {
-				newchild = strdup(childrule->rr_type);
-				store_childtype(&rule->rr_childtypes,
-						newchild, 0, 0, 0);
+			if (rule->rr_childtypes[y].rc_flags == 0) {
+				/* 2 = defined as a real child */
+				flags = 2;
+				break;
 			}
 
-			snprintf(tok, sizeof(tok), "%s/%s[%d]", base,
-				 rule->rr_type, x);
+			flags = 1;
+			break;
+		}
 
-			/* Kaboom */
-			build_tree(ccsfd, &node->rn_child, node, childrule,
-				   rulelist, reslist, tok);
+		if (flags == 2) {
+			free(ref);
+			continue;
+		}
+
+		/* store it once */
+		if (!flags && rule) {
+			//printf("Storing new child %s of %s\n",
+			       //ref, rule->rr_type);
+			newchild = strdup(ref);
+			store_childtype(&rule->rr_childtypes,
+					newchild, 0, 0, 0, 1);
+		}
+		free(ref);
+
+		x = 1;
+		switch(do_load_resource(ccsfd, tok, childrule, tree,
+				        reslist, parent, &node)) {
+		case -1:
+			continue;
+		case 1:
+			/* no more found */
+			x = 0;
+			printf("No resource found @ %s\n", tok);
+			break;
+		case 0:
+			/* another is found */
+			break;
+		}
+		if (!x) /* no more found */
+			break;
 
-		} while (!list_done(rulelist, childrule));
+		/* childrule = rule set of this child at this point */
+		/* tok = set above; if we got this far, we're all set */
+		/* Kaboom */
+
+		build_tree(ccsfd, &node->rn_child, node, childrule,
+			   rulelist, reslist, tok);
 	}
 
+	//printf("ASCEND: %s / %s\n", rule?rule->rr_type:"(none)", base);
 	return 0;
 }
 
@@ -572,11 +735,7 @@
 	snprintf(tok, sizeof(tok), "%s", RESOURCE_TREE_ROOT);
 
 	/* Find and build the list of root nodes */
-	list_do(rulelist, curr) {
-
-		build_tree(ccsfd, &root, NULL, curr, rulelist, reslist, tok);
-
-	} while (!list_done(rulelist, curr));
+	build_tree(ccsfd, &root, NULL, NULL/*curr*/, rulelist, reslist, tok);
 
 	if (root)
 		*tree = root;
@@ -601,9 +760,9 @@
 			destroy_resource_tree(&(*tree)->rn_child);
 
 		list_remove(tree, node);
-               if(node->rn_actions){
-                       free(node->rn_actions);
-               }
+		if(node->rn_actions){
+			free(node->rn_actions);
+		}
 		free(node);
 	}
 }
@@ -704,6 +863,7 @@
 }
 
 
+#if 0
 static inline int
 _do_child_default_level(resource_node_t **tree, resource_t *first,
 			void *ret, int op)
@@ -740,6 +900,55 @@
 
 	return 0;
 }
+#endif
+
+
+static inline int
+_xx_child_internal(resource_node_t *node, resource_t *first,
+		   resource_node_t *child, void *ret, int op)
+{
+	int x;
+	resource_rule_t *rule = node->rn_resource->r_rule;
+
+	for (x = 0; rule->rr_childtypes &&
+     	     rule->rr_childtypes[x].rc_name; x++) {
+		if (!strcmp(child->rn_resource->r_rule->rr_type,
+			    rule->rr_childtypes[x].rc_name)) {
+			if (rule->rr_childtypes[x].rc_startlevel ||
+			    rule->rr_childtypes[x].rc_stoplevel) {
+				return 0;
+			}
+		}
+	}
+
+	return _res_op_internal(&child, first,
+	 		       child->rn_resource->r_rule->rr_type,
+			       ret, op, child);
+}
+
+
+static inline int
+_do_child_default_level(resource_node_t **tree, resource_t *first,
+			void *ret, int op)
+{
+	resource_node_t *node = *tree, *child;
+	int y, rv = 0;
+
+	if (op == RS_START || op == RS_STATUS) {
+		list_for(&node->rn_child, child, y) {
+			rv = _xx_child_internal(node, first, child, ret, op);
+			if (rv)
+				return rv;
+		}
+	} else {
+		list_for_rev(&node->rn_child, child, y) {
+			rv += _xx_child_internal(node, first, child, ret, op);
+		}
+	}
+
+	return rv;
+}
+
 
 
 
@@ -924,6 +1133,7 @@
 			in the subtree).
    @see			_res_op_by_level res_exec
  */
+#if 0
 int
 _res_op(resource_node_t **tree, resource_t *first,
 	char *type, void * __attribute__((unused))ret, int realop)
@@ -1044,7 +1254,159 @@
 
 	return 0;
 }
+#endif
+
+
+static inline int
+_res_op_internal(resource_node_t **tree, resource_t *first,
+		 char *type, void *__attribute__((unused))ret, int realop,
+		 resource_node_t *node)
+{
+	int rv, me, op;
+
+	/* Restore default operation. */
+	op = realop;
+
+	/* If we're starting by type, do that funky thing. */
+	if (type && strlen(type) &&
+	    strcmp(node->rn_resource->r_rule->rr_type, type))
+		return 0;
 
+	/* If the resource is found, all nodes in the subtree must
+	   have the operation performed as well. */
+	me = !first || (node->rn_resource == first);
+
+	//printf("begin %s: %s %s [0x%x]\n", res_ops[op],
+	       //node->rn_resource->r_rule->rr_type,
+	       //primary_attr_value(node->rn_resource),
+	       //node->rn_flags);
+
+	if (me) {
+		/*
+		   If we've been marked as a node which
+		   needs to be started or stopped, clear
+		   that flag and start/stop this resource
+		   and all resource babies.
+
+		   Otherwise, don't do anything; look for
+		   children with RF_NEEDSTART and
+		   RF_NEEDSTOP flags.
+
+		   CONDSTART and CONDSTOP are no-ops if
+		   the appropriate flag is not set.
+		 */
+	       	if ((op == RS_CONDSTART) &&
+		    (node->rn_flags & RF_NEEDSTART)) {
+			printf("Node %s:%s - CONDSTART\n",
+			       node->rn_resource->r_rule->rr_type,
+			       primary_attr_value(node->rn_resource));
+			op = RS_START;
+		}
+
+		if ((op == RS_CONDSTOP) &&
+		    (node->rn_flags & RF_NEEDSTOP)) {
+			printf("Node %s:%s - CONDSTOP\n",
+			       node->rn_resource->r_rule->rr_type,
+			       primary_attr_value(node->rn_resource));
+			op = RS_STOP;
+		}
+	}
+
+	/* Start starts before children */
+	if (me && (op == RS_START)) {
+		node->rn_flags &= ~RF_NEEDSTART;
+
+		rv = res_exec(node, agent_op_str(op), NULL, 0);
+		if (rv != 0) {
+			node->rn_state = RES_FAILED;
+			return rv;
+		}
+
+		set_time("start", 0, node);
+		clear_checks(node);
+
+		if (node->rn_state != RES_STARTED) {
+			++node->rn_resource->r_incarnations;
+			node->rn_state = RES_STARTED;
+		}
+	} else if (me && (op == RS_STATUS)) {
+		/* Check status before children*/
+		rv = do_status(node);
+		if (rv != 0)
+			return rv;
+	}
+
+	if (node->rn_child) {
+		rv = _res_op_by_level(&node, me?NULL:first, ret, op);
+		if (rv != 0)
+			return rv;
+	}
+
+	/* Stop should occur after children have stopped */
+	if (me && (op == RS_STOP)) {
+		node->rn_flags &= ~RF_NEEDSTOP;
+		rv = res_exec(node, agent_op_str(op), NULL, 0);
+
+		if (rv != 0) {
+			node->rn_state = RES_FAILED;
+			return rv;
+		}
+
+		if (node->rn_state != RES_STOPPED) {
+			--node->rn_resource->r_incarnations;
+			node->rn_state = RES_STOPPED;
+		}
+	}
+
+	//printf("end %s: %s %s\n", res_ops[op],
+	       //node->rn_resource->r_rule->rr_type,
+	       //primary_attr_value(node->rn_resource));
+	
+	return 0;
+}
+
+
+/**
+   Nasty codependent function.  Perform an operation by type for all siblings
+   at some point in the tree.  This allows indirectly-dependent resources
+   (such as IP addresses and user scripts) to have ordering without requiring
+   a direct dependency.
+
+   @param tree		Resource tree to search/perform operations on
+   @param first		Resource we're looking to perform the operation on,
+   			if one exists.
+   @param type		Type to look for.
+   @param ret		Unused, but will be used to store status information
+   			such as resources consumed, etc, in the future.
+   @param realop	Operation to perform if either first is found,
+   			or no first is declared (in which case, all nodes
+			in the subtree).
+   @see			_res_op_by_level res_exec
+ */
+int
+_res_op(resource_node_t **tree, resource_t *first,
+	char *type, void * __attribute__((unused))ret, int realop)
+{
+  	resource_node_t *node;
+ 	int count = 0, rv;
+ 	
+ 	if (realop == RS_STOP) {
+ 		list_for_rev(tree, node, count) {
+ 			rv = _res_op_internal(tree, first, type, ret, realop,
+ 					      node);
+ 			if (rv != 0) 
+ 				return rv;
+ 		}
+ 	} else {
+ 		list_for(tree, node, count) {
+ 			rv = _res_op_internal(tree, first, type, ret, realop,
+ 					      node);
+ 			if (rv != 0) 
+ 				return rv;
+ 		}
+ 	}
+	return 0;
+}
 
 /**
    Start all occurrences of a resource in a tree
--- cluster/rgmanager/src/daemons/test.c	2007/03/20 17:09:11	1.6.2.1
+++ cluster/rgmanager/src/daemons/test.c	2007/03/23 00:06:34	1.6.2.2
@@ -48,8 +48,8 @@
 	"\trules\n\n"
 
 
+void _no_op_mode(int);
 void malloc_dump_table(void);
-
 char *agentpath = RESOURCE_ROOTDIR;
 
 
@@ -77,6 +77,7 @@
 }
 
 
+
 int
 test_func(int argc, char **argv)
 {
@@ -319,6 +320,11 @@
 			shift();
 			ret = test_func(argc, argv);
 			goto out;
+		} else if (!strcmp(argv[1], "noop")) {
+			shift();
+			_no_op_mode(1);
+			ret = test_func(argc, argv);
+			goto out;
 		} else if (!strcmp(argv[1], "rules")) {
 			shift();
 			ret = rules_func(argc, argv);




More information about the Cluster-devel mailing list