From mboxrd@z Thu Jan 1 00:00:00 1970 From: lhh@sourceware.org Date: 26 Jan 2007 21:42:59 -0000 Subject: [Cluster-devel] cluster/rgmanager include/reslist.h init.d/rgm ... Message-ID: <20070126214259.30283.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 Changes by: lhh at sourceware.org 2007-01-26 21:42:32 Modified files: rgmanager/include: reslist.h rgmanager/init.d: rgmanager rgmanager/src/daemons: fo_domain.c reslist.c resrules.c restree.c Log message: Add override for action timings Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/include/reslist.h.diff?cvsroot=cluster&r1=1.15&r2=1.16 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/init.d/rgmanager.diff?cvsroot=cluster&r1=1.5&r2=1.6 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/fo_domain.c.diff?cvsroot=cluster&r1=1.11&r2=1.12 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/reslist.c.diff?cvsroot=cluster&r1=1.14&r2=1.15 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/resrules.c.diff?cvsroot=cluster&r1=1.16&r2=1.17 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/restree.c.diff?cvsroot=cluster&r1=1.23&r2=1.24 --- cluster/rgmanager/include/reslist.h 2006/09/27 16:28:41 1.15 +++ cluster/rgmanager/include/reslist.h 2007/01/26 21:42:24 1.16 @@ -75,18 +75,19 @@ typedef struct _resource_attribute { - int ra_flags; - /* XXX possible alignment problem on ia64 */ char *ra_name; char *ra_value; + int ra_flags; + int _pad_; } resource_attr_t; typedef struct _resource_child { - char rc_forbid; + char *rc_name; int rc_startlevel; int rc_stoplevel; - char *rc_name; + int rc_forbid; + int _pad_; } resource_child_t; @@ -96,6 +97,7 @@ time_t ra_last; time_t ra_interval; int ra_depth; + int ra_flags; } resource_act_t; @@ -139,7 +141,7 @@ list_head(); char *fdn_name; int fdn_prio; - int _pad_; /* align */ + int fdn_nodeid; } fod_node_t; typedef struct _fod { --- cluster/rgmanager/init.d/rgmanager 2006/06/02 17:37:10 1.5 +++ cluster/rgmanager/init.d/rgmanager 2007/01/26 21:42:30 1.6 @@ -95,10 +95,14 @@ start) echo -n $"Starting $ID: " daemon $RGMGRD $RGMGR_OPTS + ret=$? echo # To be consistent... - touch /var/lock/subsys/rgmanager + if [ $ret -eq 0 ]; then + touch /var/lock/subsys/rgmanager + fi + exit $ret ;; restart) --- cluster/rgmanager/src/daemons/fo_domain.c 2006/09/27 16:28:41 1.11 +++ cluster/rgmanager/src/daemons/fo_domain.c 2007/01/26 21:42:30 1.12 @@ -65,11 +65,12 @@ int group_property(char *, char *, char *, size_t); fod_node_t * -get_node(int ccsfd, char *base, int idx, fod_t *domain) +fod_get_node(int ccsfd, char *base, int idx, fod_t *domain) { fod_node_t *fodn; char xpath[256]; - char *ret; + char *ret, *nid; + int nodeid; snprintf(xpath, sizeof(xpath), "%s/failoverdomainnode[%d]/@name", base, idx); @@ -86,6 +87,20 @@ return NULL; } while (!list_done(&domain->fd_nodes, fodn)); + snprintf(xpath, sizeof(xpath), + "/cluster/clusternodes/clusternode[@name=\"%s\"]/@nodeid", + ret); + if ((ccs_get(ccsfd, xpath, &nid) == 0) && nid) { + nodeid = atoi(nid); + free(nid); + } else { + clulog(LOG_ERR, "#XX: Node %s in domain %s is not in " + "the configuration\n", ret, domain->fd_name); + /* No nodeid == bad failover domain */ + free(ret); + return NULL; + } + fodn = malloc(sizeof(*fodn)); if (!fodn) return NULL; @@ -94,7 +109,8 @@ /* Already malloc'd; simply store */ fodn->fdn_name = ret; fodn->fdn_prio = 0; - + fodn->fdn_nodeid = nodeid; + snprintf(xpath, sizeof(xpath), "%s/failoverdomainnode[%d]/@priority", base, idx); if (ccs_get(ccsfd, xpath, &ret) != 0) @@ -110,10 +126,10 @@ fod_t * -get_domain(int ccsfd, char *base, int idx, fod_t **domains) +fod_get_domain(int ccsfd, char *base, int idx, fod_t **domains) { fod_t *fod; - fod_node_t *fodn; + fod_node_t *fodn, *curr; char xpath[256]; char *ret; int x = 1; @@ -169,12 +185,22 @@ base, idx); do { - fodn = get_node(ccsfd, xpath, x++, fod); + fodn = fod_get_node(ccsfd, xpath, x++, fod); if (fodn) { + /* + list_do(&fod->fd_nodes, curr) { + // insert sorted + if (fodn->fdn_prio < curr->fdn_prio) { + list_insert(&fod->fd_nodes, fodn); + if (curr == fod->fd_nodes) + fod->fd_nodes = fodn; + } + } while (!list_done(&fod->fd_nodes, curr)); + */ list_insert(&fod->fd_nodes, fodn); } } while (fodn); - + return fod; } @@ -190,7 +216,7 @@ RESOURCE_TREE_ROOT "/failoverdomains"); do { - fod = get_domain(ccsfd, xpath, x++, domains); + fod = fod_get_domain(ccsfd, xpath, x++, domains); if (fod) { list_insert(domains, fod); } @@ -200,6 +226,22 @@ } +fod_t * +fod_find_domain(fod_t **domains, char *name) +{ + fod_t *dom; + + list_do(domains, dom) { + + if (!strcasecmp(dom->fd_name, name)) + return dom; + + } while (!list_done(domains,dom)); + + return NULL; +} + + void deconstruct_domains(fod_t **domains) { @@ -244,8 +286,12 @@ } list_do(&fod->fd_nodes, fodn) { - printf(" Node %s (priority %d)\n", + printf(" Node %s priority %d", fodn->fdn_name, fodn->fdn_prio); + if (fodn->fdn_nodeid) { + printf(" nodeid %d", fodn->fdn_nodeid); + } + printf("\n"); } while (!list_done(&fod->fd_nodes, fodn)); } while (!list_done(domains, fod)); } --- cluster/rgmanager/src/daemons/reslist.c 2006/07/11 23:52:41 1.14 +++ cluster/rgmanager/src/daemons/reslist.c 2007/01/26 21:42:30 1.15 @@ -261,8 +261,6 @@ /** Find a root resource by ref (service, usually). No name is required. - Only one type of root resource may exist because of the primary - attribute flag @param reslist List of resources to traverse. @param ref Reference @@ -286,6 +284,7 @@ } else { /* Default type */ type = "service"; + name = ref; } list_do(reslist, curr) { @@ -542,6 +541,83 @@ } +/* Copied from resrules.c -- _get_actions */ +void +_get_actions_ccs(int ccsfd, char *base, resource_t *res) +{ + char xpath[256]; + int idx = 0; + char *act, *ret; + int interval, timeout, depth; + + do { + /* setting these to -1 prevents overwriting with 0 */ + interval = -1; + depth = -1; + act = NULL; + timeout = -1; + + snprintf(xpath, sizeof(xpath), + "%s/action[%d]/@name", base, ++idx); + +#ifndef NO_CCS + if (ccs_get(ccsfd, xpath, &act) != 0) +#else + if (conf_get(xpath, &act) != 0) +#endif + break; + + snprintf(xpath, sizeof(xpath), + "%s/action[%d]/@timeout", base, idx); +#ifndef NO_CCS + if (ccs_get(ccsfd, xpath, &ret) == 0 && ret) { +#else + if (conf_get(xpath, &ret) == 0 && ret) { +#endif + timeout = expand_time(ret); + if (timeout < 0) + timeout = 0; + free(ret); + } + + snprintf(xpath, sizeof(xpath), + "%s/action[%d]/@interval", base, idx); +#ifndef NO_CCS + if (ccs_get(ccsfd, xpath, &ret) == 0 && ret) { +#else + if (conf_get(xpath, &ret) == 0 && ret) { +#endif + interval = expand_time(ret); + if (interval < 0) + interval = 0; + free(ret); + } + + if (!strcmp(act, "status") || !strcmp(act, "monitor")) { + snprintf(xpath, sizeof(xpath), + "%s/action[%d]/@depth", base, idx); +#ifndef NO_CCS + if (ccs_get(ccsfd, xpath, &ret) == 0 && ret) { +#else + if (conf_get(xpath, &ret) == 0 && ret) { +#endif + depth = atoi(ret); + if (depth < 0) + depth = 0; + + /* */ + if (ret[0] == '*') + depth = -1; + free(ret); + } + } + + if (store_action(&res->r_actions, act, depth, timeout, + interval) != 0) + free(act); + } while (1); +} + /** Try to load all the attributes in our rule set. If none are found, @@ -653,6 +729,7 @@ } res->r_actions = act_dup(rule->rr_actions); + _get_actions_ccs(ccsfd, base, res); return res; } --- cluster/rgmanager/src/daemons/resrules.c 2006/10/20 20:59:49 1.16 +++ cluster/rgmanager/src/daemons/resrules.c 2007/01/26 21:42:30 1.17 @@ -46,16 +46,28 @@ store_rule(resource_rule_t **rulelist, resource_rule_t *newrule) { resource_rule_t *curr; - + list_do(rulelist, curr) { - if (!strcmp(newrule->rr_type, curr->rr_type)) { + if (!strcasecmp(newrule->rr_type, curr->rr_type)) { fprintf(stderr, "Error storing %s: Duplicate\n", newrule->rr_type); return -1; } } while (!list_done(rulelist, curr)); - + + /* insert sorted in alphabetical order so rg_test produces + * reproducible output all the time */ + list_do(rulelist, curr) { + if (strcasecmp(newrule->rr_type, curr->rr_type) < 0) { + list_insert(&curr, newrule); + /* reset list if we have a new low */ + if (curr == *rulelist) + *rulelist = newrule; + return 0; + } + } while (!list_done(rulelist, curr)); + list_insert(rulelist, newrule); return 0; } @@ -218,17 +230,36 @@ } +/** + * Store a resource action + * @param actsp Action array; may be modified and returned! + * @param name Name of the action + * @param depth Resource depth (status/monitor; -1 means *ALL LEVELS* + * ... this means that only the highest-level check depth + * will ever be performed!) + * @param timeout Timeout (not used) + * @param interval Time interval for status/monitor + * @return 0 on success, -1 on failure + * + */ int store_action(resource_act_t **actsp, char *name, int depth, int timeout, int interval) { - int x = 0; + int x = 0, replace = 0; resource_act_t *acts = *actsp; if (!name) return -1; + + if (depth < 0 && timeout < 0 && interval < 0) + return -1; if (!acts) { + /* Can't create with anything < 0 */ + if (depth < 0 || timeout < 0 || interval < 0) + return -1; + acts = malloc(sizeof(resource_act_t) * 2); if (!acts) return -1; @@ -244,17 +275,38 @@ for (x = 0; acts[x].ra_name; x++) { if (!strcmp(acts[x].ra_name, name) && - depth == acts[x].ra_depth) { - printf("Skipping duplicate action/depth %s/%d\n", - name, depth); - return -1; + (depth == acts[x].ra_depth || depth == -1)) { + printf("Replacing action '%s' depth %d: ", + name, acts[x].ra_depth); + if (timeout >= 0) { + printf("timeout: %d->%d ", + (int)acts[x].ra_timeout, + (int)timeout); + acts[x].ra_timeout = timeout; + } + if (interval >= 0) { + printf("interval: %d->%d", + (int)acts[x].ra_interval, + (int)interval); + acts[x].ra_interval = interval; + } + printf("\n"); + replace = 1; } } + + if (replace) + /* If we replaced something, we're done */ + return 1; + + /* Can't create with anything < 0 */ + if (depth < 0 || timeout < 0 || interval < 0) + return -1; acts = realloc(acts, sizeof(resource_act_t) * (x+2)); if (!acts) return -1; - + acts[x].ra_name = name; acts[x].ra_depth = depth; acts[x].ra_timeout = timeout; @@ -267,6 +319,7 @@ } + void _get_actions(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, resource_rule_t *rr) @@ -294,8 +347,8 @@ ret = xpath_get_one(doc, ctx, xpath); if (ret) { timeout = expand_time(ret); - if (interval < 0) - interval = 0; + if (timeout < 0) + timeout = 0; free(ret); } @@ -322,9 +375,8 @@ } if (store_action(&rr->rr_actions, act, depth, timeout, - interval) < 0) + interval) != 0) free(act); - } while (1); } @@ -866,6 +918,14 @@ type = xpath_get_one(doc, ctx, base); if (!type) break; + + if (!strcasecmp(type, "action")) { + fprintf(stderr, + "Error: Resource type '%s' is reserved", + type); + free(type); + break; + } rr = malloc(sizeof(*rr)); if (!rr) @@ -944,6 +1004,7 @@ struct dirent *de; char *fn;//, *dot; char path[2048]; + struct stat st_buf; dir = opendir(rpath); if (!dir) @@ -962,8 +1023,15 @@ snprintf(path, sizeof(path), "%s/%s", rpath, de->d_name); - - load_resource_rulefile(path, rules); + + if (stat(path, &st_buf)) + continue; + + if (S_ISDIR(st_buf.st_mode)) + continue; + + if (st_buf.st_mode & (S_IXUSR|S_IXOTH|S_IXGRP)) + load_resource_rulefile(path, rules); } xmlCleanupParser(); --- cluster/rgmanager/src/daemons/restree.c 2006/09/21 18:04:04 1.23 +++ cluster/rgmanager/src/daemons/restree.c 2007/01/26 21:42:30 1.24 @@ -632,6 +632,7 @@ { resource_node_t *node; int x, y; + char *val; list_do(tree, node) { for (x = 0; x < level; x++) @@ -654,11 +655,14 @@ node->rn_resource->r_attrs[x].ra_value; x++) { for (y = 0; y < level+1; y++) printf(" "); + + val = attr_value(node, + node->rn_resource->r_attrs[x].ra_name); + if (!val && + node->rn_resource->r_attrs[x].ra_flags&RA_INHERIT) + continue; printf("%s = \"%s\";\n", - node->rn_resource->r_attrs[x].ra_name, - attr_value(node, - node->rn_resource->r_attrs[x].ra_name) - ); + node->rn_resource->r_attrs[x].ra_name, val); } _print_resource_tree(&node->rn_child, level + 1);