From mboxrd@z Thu Jan 1 00:00:00 1970 From: lhh@sourceware.org Date: 13 Dec 2006 18:20:00 -0000 Subject: [Cluster-devel] cluster/rgmanager src/daemons/rg_forward.c src ... Message-ID: <20061213182000.17363.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: RHEL4 Changes by: lhh at sourceware.org 2006-12-13 18:19:57 Modified files: rgmanager/src/daemons: rg_forward.c resrules.c rg_thread.c reslist.c rg_state.c main.c rgmanager/init.d: rgmanager rgmanager/src/clulib: vft.c rgmanager/src/utils: clusvcadm.c clustat.c rgmanager/src/resources: ip.sh rgmanager/include: resgroup.h Log message: Fix #193603 (part 2; return error code if rgmanager start fails), #210455, #212110, #216774, #212634/#218112. Fix bug in ip.sh allowing start of the IP if the link was down, preventing failover (linux-cluster reported). Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/rg_forward.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.2.2.1&r2=1.2.2.2 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/resrules.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.9.2.4&r2=1.9.2.5 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/rg_thread.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.7.2.7&r2=1.7.2.8 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/reslist.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.6.2.6&r2=1.6.2.7 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/rg_state.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.4.2.16&r2=1.4.2.17 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/main.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.9.2.20&r2=1.9.2.21 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/init.d/rgmanager.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.3.2.3&r2=1.3.2.4 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/clulib/vft.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.7.2.6&r2=1.7.2.7 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/utils/clusvcadm.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.2.2.6&r2=1.2.2.7 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/utils/clustat.c.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.5.2.14&r2=1.5.2.15 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/resources/ip.sh.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.5.2.15&r2=1.5.2.16 http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/include/resgroup.h.diff?cvsroot=cluster&only_with_tag=RHEL4&r1=1.3.2.7&r2=1.3.2.8 --- cluster/rgmanager/src/daemons/rg_forward.c 2006/01/20 16:25:25 1.2.2.1 +++ cluster/rgmanager/src/daemons/rg_forward.c 2006/12/13 18:19:56 1.2.2.2 @@ -97,7 +97,7 @@ msg_close(fd); swab_SmMessageSt(&msg); - send_response(msg.sm_data.d_ret, req); + send_response(msg.sm_data.d_ret, req->rr_target, req); rq_free(req); --- cluster/rgmanager/src/daemons/resrules.c 2006/10/20 20:57:19 1.9.2.4 +++ cluster/rgmanager/src/daemons/resrules.c 2006/12/13 18:19:56 1.9.2.5 @@ -248,17 +248,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; @@ -274,17 +293,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; @@ -297,6 +337,7 @@ } + void _get_actions(xmlDocPtr doc, xmlXPathContextPtr ctx, char *base, resource_rule_t *rr) @@ -324,8 +365,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); } @@ -352,9 +393,8 @@ } if (store_action(&rr->rr_actions, act, depth, timeout, - interval) < 0) + interval) != 0) free(act); - } while (1); @@ -946,6 +986,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) --- cluster/rgmanager/src/daemons/rg_thread.c 2006/11/03 16:26:18 1.7.2.7 +++ cluster/rgmanager/src/daemons/rg_thread.c 2006/12/13 18:19:56 1.7.2.8 @@ -145,7 +145,7 @@ list_remove(list, curr); dprintf("Removed request %d\n", curr->rr_request); if (curr->rr_resp_fd != -1) { - send_response(RG_EABORT, curr); + send_response(RG_EABORT, NODE_ID_NONE, curr); } rq_free(curr); } @@ -412,9 +412,8 @@ if (ret != RG_NONE && rg_initialized() && (req->rr_resp_fd >= 0)) { - send_response(error, req); + send_response(error, newowner, req); } - rq_free(req); } @@ -611,7 +610,7 @@ case RG_START: case RG_ENABLE: send_ret(response_fd, resgroup->rt_name, RG_EDEADLCK, - request); + request, NODE_ID_NONE); break; } fprintf(stderr, "Failed to queue request: Would block\n"); --- cluster/rgmanager/src/daemons/reslist.c 2005/10/17 20:23:52 1.6.2.6 +++ cluster/rgmanager/src/daemons/reslist.c 2006/12/13 18:19:56 1.6.2.7 @@ -523,6 +523,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, @@ -628,12 +705,12 @@ } if (!found) { - //printf("No attributes found for %s\n", base); destroy_resource(res); return NULL; } res->r_actions = act_dup(rule->rr_actions); + _get_actions_ccs(ccsfd, base, res); return res; } @@ -660,7 +737,7 @@ for (resID = 1; ; resID++) { snprintf(tok, sizeof(tok), RESOURCE_BASE "/%s[%d]", currule->rr_type, resID); - + newres = load_resource(ccsfd, currule, tok); if (!newres) break; --- cluster/rgmanager/src/daemons/rg_state.c 2006/09/28 20:02:07 1.4.2.16 +++ cluster/rgmanager/src/daemons/rg_state.c 2006/12/13 18:19:56 1.4.2.17 @@ -111,123 +111,6 @@ int -clu_lock_verbose(char *resource, int dflt_flags, void **lockpp) -{ - int ret, timed_out = 0; - struct timeval start, now; - uint64_t nodeid, *p; - int flags; - int conv = 0, err; - int block = !(dflt_flags & CLK_NOWAIT); - - /* Holder not supported for this call */ - dflt_flags &= ~CLK_HOLDER; - - flags = dflt_flags; - - if (block) { - gettimeofday(&start, NULL); - start.tv_sec += 30; - } - - /* Ripped from global.c in magma */ - if (!(dflt_flags & CLK_CONVERT) && - (block || ((dflt_flags & CLK_EX) == 0))) { - /* Acquire NULL lock */ - ret = clu_lock(resource, CLK_NULL, lockpp); - err = errno; - if (ret == 0) { - if ((flags & CLK_EX) == 0) { - /* User only wanted a NULL lock... */ - return 0; - } - /* - Ok, NULL lock was taken, rest of blocking - call should be done using lock conversions. - */ - flags |= CLK_CONVERT; - conv = 1; - } else { - switch(err) { - case EINVAL: - /* Oops, null locks don't work on this - plugin; use normal spam mode */ - break; - default: - errno = err; - return -1; - } - } - } - - while (1) { - if (block) { - gettimeofday(&now, NULL); - - if ((now.tv_sec > start.tv_sec) || - ((now.tv_sec == start.tv_sec) && - (now.tv_usec >= start.tv_usec))) { - - gettimeofday(&start, NULL); - start.tv_sec += 30; - - timed_out = 1; - flags |= CLK_HOLDER; - } - } - - *lockpp = NULL; - - /* Take the lock (convert if possible). */ - ret = clu_lock(resource, flags | CLK_NOWAIT | - ((conv && !timed_out) ? CLK_CONVERT : 0), - lockpp); - err = errno; - - if ((ret != 0) && (err == EAGAIN) && block) { - if (timed_out) { - p = (uint64_t *)*lockpp; - if (p) { - nodeid = *p; - clulog(LOG_WARNING, "Node ID:%08x%08x" - " stuck with lock %s\n", - (uint32_t)(nodeid>>32&0xffffffff), - (uint32_t)nodeid&0xffffffff, - resource); - free(p); - } else { - clulog(LOG_WARNING, "Starving for lock" - " %s\n", resource); - } - flags = dflt_flags; - timed_out = 0; - } - usleep(random()&32767<<1); - continue; - - } else if (ret == 0) { - /* Success */ - return 0; - } - - break; - } - - /* Fatal error. If we took an automatic NL lock with the hopes of - converting it, release the lock before returning */ - if (conv == 1 && ret < 0) { - clu_unlock(resource, *lockpp); - *lockpp = NULL; - } - - if (ret < 0) - errno = err; - - return ret; -} - - -int #ifdef DEBUG _rg_lock(char *name, void **p) #else @@ -237,7 +120,7 @@ char res[256]; snprintf(res, sizeof(res), "usrm::rg=\"%s\"", name); - return clu_lock_verbose(res, CLK_EX, p); + return clu_lock(res, CLK_EX, p); } @@ -277,7 +160,7 @@ void -send_ret(int fd, char *name, int ret, int orig_request) +send_ret(int fd, char *name, int ret, int orig_request, uint64_t newowner) { SmMessageSt msg, *msgp = &msg; if (fd < 0) @@ -289,7 +172,11 @@ msgp->sm_data.d_action = orig_request; strncpy(msgp->sm_data.d_svcName, name, sizeof(msgp->sm_data.d_svcName)); - msgp->sm_data.d_svcOwner = my_id(); /* XXX Broken */ + if (newowner == NODE_ID_NONE) { + msgp->sm_data.d_svcOwner = my_id(); /* XXX Broken */ + } else { + msgp->sm_data.d_svcOwner = newowner; + } msgp->sm_data.d_ret = ret; swab_SmMessageSt(msgp); @@ -301,7 +188,7 @@ void -send_response(int ret, request_t *req) +send_response(int ret, uint64_t newowner, request_t *req) { SmMessageSt msg, *msgp = &msg; @@ -314,7 +201,11 @@ msgp->sm_data.d_action = req->rr_orig_request; strncpy(msgp->sm_data.d_svcName, req->rr_group, sizeof(msgp->sm_data.d_svcName)); - msgp->sm_data.d_svcOwner = my_id(); /* XXX Broken */ + if (newowner == NODE_ID_NONE) { + msgp->sm_data.d_svcOwner = my_id(); /* XXX Broken */ + } else { + msgp->sm_data.d_svcOwner = newowner; + } msgp->sm_data.d_ret = ret; swab_SmMessageSt(msgp); @@ -594,6 +485,7 @@ * 1 = START service - return whatever it returns. * 2 = DO NOT start service, return 0 * 3 = DO NOT start service, return RG_EAGAIN + * 4 = DO NOT start servuce, return RG_ERUN */ int svc_advise_start(rg_state_t *svcStatus, char *svcName, int req) @@ -618,7 +510,7 @@ clulog(LOG_DEBUG, "RG %s is already running locally\n", svcName); */ - ret = 2; + ret = 4; break; } @@ -630,7 +522,7 @@ svcName, memb_id_to_name(membership,svcStatus->rs_owner)); */ - ret = 2; + ret = 4; break; } @@ -688,6 +580,7 @@ break; case RG_STATE_STOPPED: + case RG_STATE_ERROR: /* Don't actually enable if the RG is locked! */ if (rg_locked()) { ret = 3; @@ -719,7 +612,6 @@ svcName); break; - case RG_STATE_ERROR: default: clulog(LOG_ERR, "#44: Cannot start RG %s: Invalid State %d\n", @@ -771,6 +663,9 @@ case 3: rg_unlock(svcName, lockp); return RG_EAGAIN; + case 4: + rg_unlock(svcName, lockp); + return RG_ERUN; default: break; } @@ -1404,8 +1299,8 @@ /* If services are locked, return the error */ - if (ret == RG_EAGAIN) - return RG_EAGAIN; + if (ret == RG_EAGAIN || ret == RG_ERUN) + return ret; /* * If we succeeded, then we're done. --- cluster/rgmanager/src/daemons/main.c 2006/10/05 17:52:27 1.9.2.20 +++ cluster/rgmanager/src/daemons/main.c 2006/12/13 18:19:56 1.9.2.21 @@ -426,6 +426,7 @@ sizeof (SmMessageSt)) clulog(LOG_ERR, "#40: Error replying to " "action request.\n"); + break; } /* Queue request */ --- cluster/rgmanager/init.d/rgmanager 2006/09/07 18:39:45 1.3.2.3 +++ cluster/rgmanager/init.d/rgmanager 2006/12/13 18:19:56 1.3.2.4 @@ -96,10 +96,14 @@ [ -z "$RGMGR_OPTS" ] && RGMGR_OPTS="-t 30" echo -n $"Starting $ID: " daemon $RGMGRD $RGMGR_OPTS + rv=$? echo # To be consistent... - touch /var/lock/subsys/rgmanager + if [ $ret -eq 0 ]; then + touch /var/lock/subsys/rgmanager + fi + exit $rv ;; restart) --- cluster/rgmanager/src/clulib/vft.c 2006/05/12 21:28:31 1.7.2.6 +++ cluster/rgmanager/src/clulib/vft.c 2006/12/13 18:19:56 1.7.2.7 @@ -44,8 +44,6 @@ #include -int clu_lock_verbose(char *lockname, int flags, void **lockpp); - static int vf_lfds[2]; static int vf_lfd = 0; static key_node_t *key_list = NULL; /** List of key nodes. */ @@ -1187,7 +1185,7 @@ pthread_mutex_lock(&vf_mutex); /* Obtain cluster lock on it. */ snprintf(lock_name, sizeof(lock_name), "usrm::vf"); - l = clu_lock_verbose(lock_name, CLK_EX, &lockp); + l = clu_lock(lock_name, CLK_EX, &lockp); if (l < 0) { clu_unlock(lock_name, lockp); pthread_mutex_unlock(&vf_mutex); @@ -1524,7 +1522,7 @@ /* Obtain cluster lock on it. */ pthread_mutex_lock(&vf_mutex); snprintf(lock_name, sizeof(lock_name), "usrm::vf"); - l = clu_lock_verbose(lock_name, CLK_EX, &lockp); + l = clu_lock(lock_name, CLK_EX, &lockp); if (l < 0) { clu_unlock(lock_name, lockp); pthread_mutex_unlock(&vf_mutex); --- cluster/rgmanager/src/utils/clusvcadm.c 2006/05/12 21:28:31 1.2.2.6 +++ cluster/rgmanager/src/utils/clusvcadm.c 2006/12/13 18:19:56 1.2.2.7 @@ -153,7 +153,7 @@ printf("Resource Group Control Commands:\n"); printf(" %s -v Display version and exit\n",name); printf(" %s -d Disable \n", name); -printf(" %s -e Enable \n", +printf(" %s -e Enable on the local node\n", name); printf(" %s -e -m Enable " " on \n", name); @@ -317,12 +317,31 @@ fprintf(stderr, "Error receiving reply!\n"); return 1; } - + /* Decode */ swab_SmMessageSt(&msg); switch (msg.sm_data.d_ret) { case SUCCESS: printf("success\n"); + + /* Non-start/relo request: done */ + if (action != RG_RELOCATE && action != RG_ENABLE) + break; + + if (svctarget != NODE_ID_NONE && + msg.sm_data.d_svcOwner != svctarget) { + /* Service running somewhere besides where requested */ + printf("Warning: Service %s is running on %s " + "instead of %s\n", svcname, + memb_id_to_name(membership, + msg.sm_data.d_svcOwner), + memb_id_to_name(membership, svctarget)); + break; + } + + /* No node specified or service running where requested */ + printf("Service %s is now running on %s\n", svcname, + memb_id_to_name(membership, msg.sm_data.d_svcOwner)); break; case RG_EFAIL: printf("failed\n"); @@ -339,6 +358,10 @@ case RG_EAGAIN: printf("failed: Try again (resource groups locked)\n"); break; + case RG_ERUN: + printf("failed: Service is already running\n"); + return 0; + break; default: printf("failed: unknown reason %d\n", msg.sm_data.d_ret); break; --- cluster/rgmanager/src/utils/clustat.c 2006/09/07 18:39:45 1.5.2.14 +++ cluster/rgmanager/src/utils/clustat.c 2006/12/13 18:19:56 1.5.2.15 @@ -358,14 +358,14 @@ } -void +int txt_rg_states(rg_state_list_t *rgl, cluster_member_list_t *members, char *svcname, int flags) { - int x; + int x, ret = 0; if (!rgl || !members) - return; + return -1; if (!(flags & RG_VERBOSE)) { printf(" %-20.20s %-30.30s %-14.14s\n", @@ -382,18 +382,31 @@ strcmp(rgl->rgl_states[x].rs_name, svcname)) continue; txt_rg_state(&rgl->rgl_states[x], members, flags); + if (svcname) { + switch (rgl->rgl_states[x].rs_state) { + case RG_STATE_STARTING: + case RG_STATE_STARTED: + case RG_STATE_STOPPING: + break; + default: + ret = rgl->rgl_states[x].rs_state; + } + } } + + return ret; } -void +int xml_rg_states(rg_state_list_t *rgl, cluster_member_list_t *members, char *svcname) { int x; + int ret = 0; if (!rgl || !members) - return; + return -1; printf(" \n"); @@ -401,14 +414,23 @@ if (svcname && strcmp(rgl->rgl_states[x].rs_name, svcname)) continue; - xml_rg_state(&rgl->rgl_states[x], members, 0); + if (svcname) { + switch (rgl->rgl_states[x].rs_state) { + case RG_STATE_STARTING: + case RG_STATE_STARTED: + case RG_STATE_STOPPING: + break; + default: + ret = rgl->rgl_states[x].rs_state; + } + } } printf(" \n"); + return ret; } - void txt_quorum_state(int qs) { @@ -481,14 +503,14 @@ } -void +int txt_member_states(cluster_member_list_t *membership, char *name) { - int x; + int x, ret = 0; if (!membership) { printf("Membership information not available\n"); - return; + return -1; } printf(" %-40.40s %s\n", "Member Name", "Status"); @@ -498,20 +520,22 @@ if (name && strcmp(membership->cml_members[x].cm_name, name)) continue; txt_member_state(&membership->cml_members[x]); + ret = !(membership->cml_members[x].cm_state & FLAG_UP); } printf("\n"); + return ret; } -void +int xml_member_states(cluster_member_list_t *membership, char *name) { - int x; + int x, ret = 0; if (!membership) { printf(" \n"); - return; + return -1; } printf(" \n"); @@ -519,16 +543,22 @@ if (name && strcmp(membership->cml_members[x].cm_name, name)) continue; xml_member_state(&membership->cml_members[x]); + if (name) + ret = !(membership->cml_members[x].cm_state & FLAG_UP); } printf(" \n"); + + return ret; } -void +int txt_cluster_status(int qs, cluster_member_list_t *membership, rg_state_list_t *rgs, char *name, char *svcname, int flags) { + int ret; + if (!svcname && !name) { txt_quorum_state(qs); if (!membership || !(qs & QF_GROUPMEMBER)) { @@ -538,50 +568,43 @@ } if (!svcname || (name && svcname)) - txt_member_states(membership, name); + ret = txt_member_states(membership, name); + if (name && !svcname) + return ret; if (!name || (name && svcname)) - txt_rg_states(rgs, membership, svcname, flags); + ret = txt_rg_states(rgs, membership, svcname, flags); + return ret; } -void +int xml_cluster_status(int qs, cluster_member_list_t *membership, rg_state_list_t *rgs, char *name, char *svcname, int flags) { + int ret1 = 0, ret2 = -1; + printf("\n"); printf("\n"); if (!svcname && !name) xml_quorum_state(qs); if (!svcname || (name && svcname)) - xml_member_states(membership, name); + ret1 = xml_member_states(membership, name); + if (rgs && (!name || (name && svcname))) - xml_rg_states(rgs, membership, svcname); + ret2 = xml_rg_states(rgs, membership, svcname); printf("\n"); + + if (name && ret1) + return ret1; + if (svcname && ret2) + return ret2; + return 0; } -void -dump_node(cluster_member_t *node) -{ - printf("Node %s state %02x\n", node->cm_name, node->cm_state); -} - - -void -dump_nodes(cluster_member_list_t *nodes) -{ - int x; - - for (x=0; xcml_count; x++) { - dump_node(&nodes->cml_members[x]); - } -} - - - cluster_member_list_t * build_member_list(uint64_t *lid) { @@ -778,11 +801,13 @@ } if (xml) - xml_cluster_status(qs, membership, rgs, member_name, - rg_name,flags); + ret = xml_cluster_status(qs, membership, rgs, + member_name, rg_name, + flags); else - txt_cluster_status(qs, membership, rgs, member_name, - rg_name,flags); + ret = txt_cluster_status(qs, membership, rgs, + member_name, rg_name, + flags); if (membership) cml_free(membership); --- cluster/rgmanager/src/resources/ip.sh 2006/05/16 20:03:04 1.5.2.15 +++ cluster/rgmanager/src/resources/ip.sh 2006/12/13 18:19:57 1.5.2.16 @@ -884,6 +884,9 @@ exit 0 fi ip_op ${OCF_RESKEY_family} add ${OCF_RESKEY_address} + if [ $? -ne 0 ]; then + exit $OCF_ERR_GENERIC + fi if [ $NFS_TRICKS -eq 0 ]; then if [ "$OCF_RESKEY_nfslock" = "yes" ] || \ --- cluster/rgmanager/include/resgroup.h 2006/05/12 21:28:30 1.3.2.7 +++ cluster/rgmanager/include/resgroup.h 2006/12/13 18:19:57 1.3.2.8 @@ -121,8 +121,8 @@ int rt_enqueue_request(const char *resgroupname, int request, int response_fd, int max, uint64_t target, int arg0, int arg1); -void send_response(int ret, request_t *req); -void send_ret(int fd, char *name, int ret, int req); +void send_response(int ret, uint64_t owner, request_t *req); +void send_ret(int fd, char *name, int ret, int req, uint64_t newowner); /* do this op on all resource groups. The handler for the request will sort out whether or not it's a valid request given the state */ @@ -156,12 +156,13 @@ cluster_member_list_t *member_list(void); uint64_t my_id(void); -#define RG_EAGAIN -6 -#define RG_EDEADLCK -5 -#define RG_ENOSERVICE -4 -#define RG_EFORWARD -3 -#define RG_EABORT -2 -#define RG_EFAIL -1 +#define RG_ERUN -7 /* Service is running already */ +#define RG_EAGAIN -6 /* Try again */ +#define RG_EDEADLCK -5 /* Operation would cause deadlock */ +#define RG_ENOSERVICE -4 /* Service does not exist */ +#define RG_EFORWARD -3 /* Ask current service owner to do this, please */ +#define RG_EABORT -2 /* Request cancelled */ +#define RG_EFAIL -1 /* Generic error */ #define RG_ESUCCESS 0