From mboxrd@z Thu Jan 1 00:00:00 1970 From: lhh@sourceware.org Date: 23 Mar 2007 00:06:36 -0000 Subject: [Cluster-devel] cluster/rgmanager include/list.h include/resli ... Message-ID: <20070323000636.4431.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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);