[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