FAQ Search Today's Posts Mark Forums Read
» Video Reviews

» Linux Archive

Linux-archive is a website aiming to archive linux email lists and to make them easily accessible for linux users/developers.


» Sponsor

» Partners

» Sponsor

Go Back   Linux Archive > Redhat > Cluster Development

 
 
LinkBack Thread Tools
 
Old 04-15-2008, 03:03 PM
 
Default Cluster Project branch, RHEL4, updated. gfs-kernel_2_6_9_76-42-g69a3d82

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "Cluster Project".

http://sources.redhat.com/git/gitweb.cgi?p=cluster.git;a=commitdiff;h=69a3d82a66 1d0c67dadfc0c02a6839c94ab0cdfb

The branch, RHEL4 has been updated
via 69a3d82a661d0c67dadfc0c02a6839c94ab0cdfb (commit)
via 24945860f4de6118437688aa3e4b7bb3e3edbbf0 (commit)
via 070de9cc3db1a66d427a2aaaef0dbf71d4d404b9 (commit)
via 179da28103b843845cad5eaec61a48855b5cf807 (commit)
via 7c3f3ad887d460c2bd92a7a398048be58f1b4a07 (commit)
via d35287124adf15a981703c3e0785fa7c644223c1 (commit)
via fed6e7804f9b092b09a1d243abd03eb87747e566 (commit)
via 71a51fb8ed4c91c5963665940afca5fc44f42559 (commit)
via 652fe516bfa1efd5ceff9e1551e8dabc573e294d (commit)
via 0d3a7a758217efbfec3a662269856a30d68fdd63 (commit)
via 00a395dd63da4728c30b61a04a71224a4f05b82d (commit)
from 5f03c06d964894819c182b5112af75e5ee44a256 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 69a3d82a661d0c67dadfc0c02a6839c94ab0cdfb
Author: Lon Hohberger <lhh@redhat.com>
Date: Tue Apr 15 11:02:33 2008 -0400

[rgmanager] Fix several bugzillas (see below)

- 245381 - restart counter/thresholds before switching to
relocation during service recovery
- 247772 - one service following another (event scripting
ability). This isn't fixed in the usual way, as
this feature has limited use. Instead, we allow
an alternative method of operation for rgmanager
in which administrators can define event triggers
for whatever they would like. (Called "RIND")
- 247945 - rgmanager restarting services when noncritical
parameters are changed
- 247980 - strong / weak service dependencies. These are
trivial. Weak dependencies are only allowed with
the event scripting as noted for 247772
- 250101 - RG event API (internals change). This was
required for RIND to operate as well as 247980
- 439948 - clushutdown reference in clusvcadm man page
- 440006 - rgmanager stuck on stop in some cases
- 440645 - quotaoff causes hanges in some circumstances
- 441577 - Symlinks in mount point path cause erroneous failures

commit 24945860f4de6118437688aa3e4b7bb3e3edbbf0
Author: Lon Hohberger <lhh@redhat.com>
Date: Tue Apr 8 00:32:04 2008 -0400

[rgmanager] Fix minor crash bug

commit 070de9cc3db1a66d427a2aaaef0dbf71d4d404b9
Author: Lon Hohberger <lhh@redhat.com>
Date: Fri Apr 4 13:54:28 2008 -0400

[rgmanager] Fixes for RIND

commit 179da28103b843845cad5eaec61a48855b5cf807
Author: Lon Hohberger <lhh@redhat.com>
Date: Fri Apr 4 11:20:09 2008 -0400

[rgmanager] More RIND merges.

commit 7c3f3ad887d460c2bd92a7a398048be58f1b4a07
Author: Lon Hohberger <lhh@redhat.com>
Date: Tue Apr 1 16:25:08 2008 -0400

[rgmanager] Fix clusvcadm build

commit d35287124adf15a981703c3e0785fa7c644223c1
Author: Lon Hohberger <lhh@redhat.com>
Date: Tue Apr 1 16:23:17 2008 -0400

[rgmanager] Fix build

commit fed6e7804f9b092b09a1d243abd03eb87747e566
Author: Lon Hohberger <lhh@redhat.com>
Date: Tue Apr 1 16:22:15 2008 -0400

[rgmanager] Remove extraneous copy of event_script.txt

commit 71a51fb8ed4c91c5963665940afca5fc44f42559
Author: Lon Hohberger <lhh@redhat.com>
Date: Tue Apr 1 16:17:55 2008 -0400

[rgmanager] Misc fixes. Update auto testing

commit 652fe516bfa1efd5ceff9e1551e8dabc573e294d
Author: Lon Hohberger <lhh@redhat.com>
Date: Tue Apr 1 12:54:15 2008 -0400

[rgmanager] Make RIND build on RHEL4 branch

commit 0d3a7a758217efbfec3a662269856a30d68fdd63
Author: Lon Hohberger <lhh@redhat.com>
Date: Mon Mar 10 09:58:08 2008 -0400

Merge, part 2

commit 00a395dd63da4728c30b61a04a71224a4f05b82d
Author: Lon Hohberger <lhh@redhat.com>
Date: Mon Mar 10 09:56:40 2008 -0400

Commit phase 1 of update from rhel5 branch

-----------------------------------------------------------------------

Summary of changes:
rgmanager/event-script.txt | 311 +++++
rgmanager/include/clulog.h | 2 +-
rgmanager/include/event.h | 147 +++
rgmanager/include/res-ocf.h | 20 +
rgmanager/include/resgroup.h | 60 +-
rgmanager/include/reslist.h | 64 +-
rgmanager/include/restart_counter.h | 32 +
rgmanager/include/rg_queue.h | 24 +-
rgmanager/include/sets.h | 39 +
rgmanager/man/clusvcadm.8 | 13 +-
rgmanager/src/clulib/Makefile | 3 +-
rgmanager/src/clulib/rg_strings.c | 208 +++-
rgmanager/src/clulib/sets.c | 370 ++++++
rgmanager/src/clulib/signals.c | 18 +
rgmanager/src/clulib/tmgr.c | 128 ++
rgmanager/src/clulib/vft.c | 87 +-
rgmanager/src/daemons/Makefile | 11 +-
rgmanager/src/daemons/event_config.c | 540 ++++++++
rgmanager/src/daemons/fo_domain.c | 117 ++-
rgmanager/src/daemons/groups.c | 575 ++++++++--
rgmanager/src/daemons/main.c | 167 ++--
rgmanager/src/daemons/members.c | 41 +
rgmanager/src/daemons/reslist.c | 94 ++-
rgmanager/src/daemons/resrules.c | 143 ++-
rgmanager/src/daemons/restart_counter.c | 205 ++++
rgmanager/src/daemons/restree.c | 542 ++++-----
rgmanager/src/daemons/rg_event.c | 500 ++++++++
rgmanager/src/daemons/rg_forward.c | 110 ++
rgmanager/src/daemons/rg_state.c | 427 +++++---
rgmanager/src/daemons/rg_thread.c | 5 +
rgmanager/src/daemons/service_op.c | 207 ++++
rgmanager/src/daemons/slang_event.c | 1286 ++++++++++++++++++++
rgmanager/src/daemons/test.c | 101 ++-
.../daemons/tests/delta-test001-test002.expected | 34 +
.../daemons/tests/delta-test002-test003.expected | 48 +-
.../daemons/tests/delta-test003-test004.expected | 52 +-
.../daemons/tests/delta-test004-test005.expected | 53 +-
.../daemons/tests/delta-test005-test006.expected | 56 +-
.../daemons/tests/delta-test006-test007.expected | 56 +-
.../daemons/tests/delta-test007-test008.expected | 68 +-
.../daemons/tests/delta-test008-test009.expected | 89 +-
.../daemons/tests/delta-test009-test010.expected | 98 +-
.../daemons/tests/delta-test010-test011.expected | 135 ++-
.../daemons/tests/delta-test011-test012.expected | 157 ++-
.../daemons/tests/delta-test012-test013.expected | 160 ++-
.../daemons/tests/delta-test013-test014.expected | 224 +++--
.../daemons/tests/delta-test014-test015.expected | 264 +++--
.../daemons/tests/delta-test015-test016.expected | 256 +++--
.../daemons/tests/delta-test016-test017.expected | 309 ++++--
.../daemons/tests/delta-test017-test018.expected | 558 +++++++++
rgmanager/src/daemons/tests/runtests.sh | 6 +-
rgmanager/src/daemons/tests/test001.expected | 21 +
rgmanager/src/daemons/tests/test002.expected | 21 +
rgmanager/src/daemons/tests/test003.expected | 33 +-
rgmanager/src/daemons/tests/test004.expected | 33 +-
rgmanager/src/daemons/tests/test005.expected | 36 +-
rgmanager/src/daemons/tests/test006.expected | 36 +-
rgmanager/src/daemons/tests/test007.expected | 36 +-
rgmanager/src/daemons/tests/test008.expected | 52 +-
rgmanager/src/daemons/tests/test009.expected | 53 +-
rgmanager/src/daemons/tests/test010.expected | 63 +-
rgmanager/src/daemons/tests/test011.expected | 88 +-
rgmanager/src/daemons/tests/test012.expected | 89 +-
rgmanager/src/daemons/tests/test013.expected | 89 +-
rgmanager/src/daemons/tests/test014.expected | 147 ++-
rgmanager/src/daemons/tests/test015.expected | 147 ++-
rgmanager/src/daemons/tests/test016.expected | 147 ++-
rgmanager/src/daemons/tests/test017.expected | 176 ++-
rgmanager/src/daemons/tests/test018.expected | 291 +++++
rgmanager/src/resources/Makefile | 9 +-
rgmanager/src/resources/clusterfs.sh | 61 +-
rgmanager/src/resources/default_event_script.sl | 314 +++++
rgmanager/src/resources/fs.sh | 53 +-
rgmanager/src/resources/netfs.sh | 2 +-
rgmanager/src/resources/ocf-shellfuncs | 4 +
rgmanager/src/resources/script.sh | 2 +-
rgmanager/src/resources/service.sh | 104 ++-
rgmanager/src/resources/svclib_nfslock | 28 +
.../src/resources/utils/named-parse-config.pl | 26 +
rgmanager/src/resources/utils/ra-skelet.sh | 2 +-
rgmanager/src/utils/clusvcadm.c | 45 +-
81 files changed, 9563 insertions(+), 1865 deletions(-)
create mode 100644 rgmanager/event-script.txt
create mode 100644 rgmanager/include/event.h
create mode 100644 rgmanager/include/restart_counter.h
create mode 100644 rgmanager/include/sets.h
create mode 100644 rgmanager/src/clulib/sets.c
create mode 100644 rgmanager/src/clulib/tmgr.c
create mode 100644 rgmanager/src/daemons/event_config.c
create mode 100644 rgmanager/src/daemons/restart_counter.c
create mode 100644 rgmanager/src/daemons/rg_event.c
create mode 100644 rgmanager/src/daemons/service_op.c
create mode 100644 rgmanager/src/daemons/slang_event.c
create mode 100644 rgmanager/src/daemons/tests/delta-test017-test018.expected
create mode 100644 rgmanager/src/daemons/tests/test018.expected
create mode 100644 rgmanager/src/resources/default_event_script.sl
create mode 100644 rgmanager/src/resources/utils/named-parse-config.pl

diff --git a/rgmanager/event-script.txt b/rgmanager/event-script.txt
new file mode 100644
index 0000000..00a8b4c
--- /dev/null
+++ b/rgmanager/event-script.txt
@@ -0,0 +1,311 @@
+TODO:
+* Return correct error codes to clusvcadm (currently it always returns
+ "Unknown")
+* Write glue for 'migrate' operations and migrate-enabled services
+
+Basic configuration specification:
+
+ <rm>
+ <events>
+ <event class="node"/> <!-- all node events -->
+ <event class="node"
+ node="bar"/> <!-- events concerning 'bar' -->
+ <event class="node"
+ node="foo"
+ node_state="up"/> <!-- 'up' events for 'foo' -->
+ <event class="node"
+ node_id="3"
+ node_state="down"/> <!-- 'down' events for node ID 3 -->
+
+ (note, all service ops and such deal with node ID, not
+ with node names)
+
+ <event class="service"/> <!-- all service events-->
+ <event class="service"
+ service_name="A"/> <!-- events concerning 'A' -->
+ <event class="service"
+ service_name="B"
+ service_state="started"/> <!-- when 'B' is started... -->
+ <event class="service"
+ service_name="B"
+ service_state="started"/>
+ service_owner="3"/> <!-- when 'B' is started on node 3... -->
+
+ <event class="service"
+ priority="1"
+ service_state="started"/>
+ service_owner="3"/> <!-- when 'B' is started on node 3, do this
+ before the other event handlers ... -->
+
+
+ </events>
+ ...
+ </rm>
+
+General globals available from all scripts:
+
+ node_self - local node ID
+ event_type - event class, either:
+ EVENT_NONE - unspecified / unknown
+ EVENT_NODE - node transition
+ EVENT_SERVICE - service transition
+ EVENT_USER - a user-generated request
+ EVENT_CONFIG - [NOT CONFIGURABLE]
+
+Node event globals (i.e. when event_type == EVENT_NODE):
+
+ node_id - node ID which is transitioning
+ node_name - name of node which is transitioning
+ node_state - new node state (NODE_ONLINE or NODE_OFFLINE, or if you prefer,
+ 1 or 0, respectively)
+ node_clean - 0 if the node has not been fenced, 1 if the node has been
+ fenced
+
+Service event globals (i.e. when event_type == EVENT_SERVICE):
+
+ service_name - Name of service which transitioned
+ service_state - new state of service
+ service_owner - new owner of service (or <0 if service is no longer
+ running)
+ service_last_owner - Last owner of service if known. Used for when
+ service_state = "recovering" generally, in order to
+ apply restart/relocate/disable policy.
+
+User event globals (i.e. when event_type == EVENT_USER):
+
+ service_name - service to perform request upon
+ user_request - request to perform (USER_ENABLE, USER_DISABLE,
+ USER_STOP, USER_RELOCATE, [TODO] USER_MIGRATE)
+ user_target - target node ID if applicable
+
+
+Scripting functions - Informational:
+
+ node_list = nodes_online();
+
+ Returns a list of all online nodes.
+
+ service_list = service_list();
+
+ Returns a list of all configured services.
+
+ (restarts, last_owner, owner, state) = service_status(service_name);
+
+ Returns the state, owner, last_owner, and restarts. Note that
+ all return values are optional, but are right-justified per S-Lang
+ specification. This means if you only want the 'state', you can use:
+
+ (state) = service_status(service_name);
+
+ However, if you need the restart count, you must provide all four
+ return values as above.
+
+ (nofailback, restricted, ordered, node_list) =
+ service_domain_info(service_name);
+
+ Returns the failover domain specification, if it exists, for the
+ specified service name. The node list returned is an ordered list
+ according to priority levels. In the case of unordered domains,
+ the ordering of the returned list is pseudo-random.
+
+Scripting functions - Operational:
+
+ err = service_start(service_name, node_list, [avoid_list]);
+
+ Start a non-running, (but runnable, i.e. not failed)
+ service on the first node in node_list. Failing that, start it on
+ the second node in node_list and so forth. One may also specify
+ an avoid list, but it's better to just use the subtract() function
+ below. If the start is successful, the node ID running the service
+ is returned. If the start is unsuccessful, a value < 0 is returned.
+
+ err = service_stop(service_name, [0 = stop, 1 = disable]);
+
+ Stop a running service. The second parameter is optional, and if
+ non-zero is specified, the service will enter the disabled state.
+
+ ... stuff that's not done but needs to be:
+
+ err = service_relocate(service_name, node_list);
+
+ Move a running service to the specified node_list in order of
+ preference. In the case of VMs, this is actually a migrate-or-
+ relocate operation.
+
+Utility functions - Node list manipulation
+
+ node_list = union(left_node_list, right_node_list);
+
+ Calculates the union between the two node list, removing duplicates
+ and preserving ordering according to left_node_list. Any added
+ values from right_node_list will appear in their order, but
+ after left_node_list in the returned list.
+
+ node_list = intersection(left_node_list, right_node_list);
+
+ Calculates the intersection (items in both lists) between the two
+ node lists, removing duplicates and preserving ordering according
+ to left_node_list. Any added values from right_node_list will
+ appear in their order, but after left_node_list in the returned list.
+
+ node_list = delta(left_node_list, right_node_list);
+
+ Calculates the delta (items not in both lists) between the two
+ node lists, removing duplicates and preserving ordering according
+ to left_node_list. Any added values from right_node_list will
+ appear in their order, but after left_node_list in the returned list.
+
+ node_list = subtract(left_node_list, right_node_list);
+
+ Removes any duplicates as well as items specified in right_node_list
+ from left_node_list. Example:
+
+ all_nodes = nodes_online();
+ allowed_nodes = subtract(nodes_online, node_to_avoid);
+
+ node_list = shuffle(node_list_old);
+
+ Rearranges the contents of node_list_old randomly and returns a
+ new node list.
+
+Utility functions - Logging:
+
+ debug(item1, item2, ...); LOG_DEBUG level
+ info(...); LOG_INFO level
+ notice(...); LOG_NOTICE level
+ warning(...); LOG_WARNING level
+ err(...); LOG_ERR level
+ crit(...); LOG_CRIT level
+ alert(...); LOG_ALERT level
+ emerg(...); LOG_EMERG level
+
+ items - These can be strings, integer lists, or integers. Logging
+ string lists is not supported.
+
+ level - the level is consistent with syslog(8)
+
+ stop_processing();
+
+ Calling this function will prevent further event scripts from being
+ executed on a particular event. Call this script if, for example,
+ you do not wish for the default event handler to process the event.
+
+ Note: This does NOT terminate the caller script; that is, the
+ script being executed will run to completion.
+
+Event scripts are written in a language called S-Lang; documentation specifics
+about the language are available at http://www.s-lang.org
+
+Example script (creating a follows-but-avoid-after-start behavior):
+%
+% If the main queue server and replication queue server are on the same
+% node, relocate the replication server somewhere else if possible.
+%
+define my_sap_event_trigger()
+{
+ variable state, owner_rep, owner_main;
+ variable nodes, allowed;
+
+ %
+ % If this was a service event, don't execute the default event
+ % script trigger after this script completes.
+ %
+ if (event_type == EVENT_SERVICE) {
+ stop_processing();
+ }
+
+ (owner_main, state) = service_status("service:main_queue");
+ (owner_rep, state) = service_status("service:replication_server");
+
+ if ((event_type == EVENT_NODE) and (owner_main == node_id) and
+ (node_state == NODE_OFFLINE) and (owner_rep >= 0)) {
+ %
+ % uh oh, the owner of the main server died. Restart it
+ % on the node running the replication server
+ %
+ notice("Starting Main Queue Server on node ", owner_rep);
+ ()=service_start("service:main_queue", owner_rep);
+ return;
+ }
+
+ %
+ % S-Lang doesn't short-circuit prior to 2.1.0
+ %
+ if ((owner_main >= 0) and
+ ((owner_main == owner_rep) or (owner_rep < 0))) {
+
+ %
+ % Get all online nodes
+ %
+ nodes = nodes_online();
+
+ %
+ % Drop out the owner of the main server
+ %
+ allowed = subtract(nodes, owner_main);
+ if ((owner_rep >= 0) and (length(allowed) == 0)) {
+ %
+ % Only one node is online and the rep server is
+ % already running. Don't do anything else.
+ %
+ return;
+ }
+
+ if ((length(allowed) == 0) and (owner_rep < 0)) {
+ %
+ % Only node online is the owner ... go ahead
+ % and start it, even though it doesn't increase
+ % availability to do so.
+ %
+ allowed = owner_main;
+ }
+
+ %
+ % Move the replication server off the node that is
+ % running the main server if a node's available.
+ %
+ if (owner_rep >= 0) {
+ ()=service_stop("service:replication_server");
+ }
+ ()=service_start("service:replication_server", allowed);
+ }
+
+ return;
+}
+
+my_sap_event_trigger();
+
+
+Relevant <rm> section from cluster.conf:
+
+ <rm central_processing="1">
+ <events>
+ <event name="main-start" class="service"
+ service="service:main_queue"
+ service_state="started"
+ file="/tmp/sap.sl"/>
+ <event name="rep-start" class="service"
+ service="service:replication_server"
+ service_state="started"
+ file="/tmp/sap.sl"/>
+ <event name="node-up" node_state="up"
+ class="node"
+ file="/tmp/sap.sl"/>
+
+ </events>
+ <failoverdomains>
+ <failoverdomain name="all" ordered="1" restricted="1">
+ <failoverdomainnode name="molly"
+priority="2"/>
+ <failoverdomainnode name="frederick"
+priority="1"/>
+ </failoverdomain>
+ </failoverdomains>
+ <resources/>
+ <service name="main_queue"/>
+ <service name="replication_server" autostart="0"/>
+ <!-- replication server is started when main-server start
+ event completes -->
+ </rm>
+
+
diff --git a/rgmanager/include/clulog.h b/rgmanager/include/clulog.h
index 856d83c..e6b7ff8 100644
--- a/rgmanager/include/clulog.h
+++ b/rgmanager/include/clulog.h
@@ -38,7 +38,7 @@ extern "C" {
#include <syslog.h>
#include <sys/types.h>

-#define LOGLEVEL_DFLT LOG_INFO
+#define LOGLEVEL_DFLT LOG_NOTICE
#define MAX_LOGMSG_LEN 512

/*
diff --git a/rgmanager/include/event.h b/rgmanager/include/event.h
new file mode 100644
index 0000000..bd8bc0a
--- /dev/null
+++ b/rgmanager/include/event.h
@@ -0,0 +1,147 @@
+/*
+ Copyright Red Hat, Inc. 2007
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 as published
+ by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+*/
+#ifndef _EVENT_H
+#define _EVENT_H
+
+/* 128 is a bit big, but it should be okay */
+typedef struct __rge_q {
+ char rg_name[128];
+ uint32_t rg_state;
+ uint32_t pad1;
+ int rg_owner;
+ int rg_last_owner;
+} group_event_t;
+
+typedef struct __ne_q {
+ uint64_t ne_nodeid;
+ int ne_local;
+ int ne_state;
+ int ne_clean;
+ int pad1;
+} node_event_t;
+
+typedef struct __cfg_q {
+ int cfg_version;
+ int cfg_oldversion;
+} config_event_t;
+
+typedef struct __user_q {
+ char u_name[128];
+ uint64_t u_target; /* Node ID */
+ int pad1;
+ int u_fd;
+ int u_request;
+ int u_arg1;
+ int u_arg2;
+} user_event_t;
+
+typedef enum {
+ EVENT_NONE=0,
+ EVENT_CONFIG,
+ EVENT_NODE,
+ EVENT_RG,
+ EVENT_USER
+} event_type_t;
+
+/* Data that's distributed which indicates which
+ node is the event master */
+typedef struct __rgm {
+ uint64_t m_nodeid;
+ uint64_t m_master_time;
+ uint32_t m_magic;
+ uint8_t m_reserved[108];
+} event_master_t;
+
+#define swab_event_master_t(ptr)
+{
+ swab64((ptr)->m_nodeid);
+ swab64((ptr)->m_master_time);
+ swab32((ptr)->m_magic);
+}
+
+/* Just a magic # to help us ensure we've got good
+ date from VF */
+#define EVENT_MASTER_MAGIC 0xfabab0de
+
+/* Event structure - internal to the event subsystem; use
+ the queueing functions below which allocate this struct
+ and pass it to the event handler */
+typedef struct _event {
+ /* Not used dynamically - part of config info */
+ list_head();
+ char *ev_name;
+ char *ev_script;
+ char *ev_script_file;
+ int ev_prio;
+ int ev_pad;
+ /* --- end config part */
+ int ev_type; /* config & generated by rgmanager*/
+ int ev_transaction;
+ union {
+ group_event_t group;
+ node_event_t node;
+ config_event_t config;
+ user_event_t user;
+ } ev;
+} event_t;
+
+#define EVENT_PRIO_COUNT 100
+
+typedef struct _event_table {
+ int max_prio;
+ int pad;
+ event_t *entries[0];
+} event_table_t;
+
+
+int construct_events(int ccsfd, event_table_t **);
+void deconstruct_events(event_table_t **);
+void print_events(event_table_t *);
+
+/* Does the event match a configured event? */
+int event_match(event_t *pattern, event_t *actual);
+
+/* Event queueing functions. */
+void node_event_q(int local, uint64_t nodeID, int state, int clean);
+void rg_event_q(char *name, uint32_t state, uint64_t owner, uint64_t last);
+void user_event_q(char *svc, int request, int arg1, int arg2,
+ uint64_t target, int fd);
+void config_event_q(int old_version, int new_version);
+
+/* Call this to see if there's a master. */
+int event_master_info_cached(event_master_t *);
+
+/* Call this to get the node ID of the current
+ master *or* become the master if none exists */
+uint64_t event_master(void);
+
+/* Setup */
+int central_events_enabled(void);
+void set_central_events(int flag);
+int slang_process_event(event_table_t *event_table, event_t *ev);
+
+/* For distributed events. */
+void set_transition_throttling(int nsecs);
+
+/* Simplified service start. */
+int service_op_start(char *svcName, uint64_t *target_list, int target_list_len,
+ uint64_t *new_owner);
+int service_op_stop(char *svcName, int do_disable, int event_type);
+
+
+#endif
diff --git a/rgmanager/include/res-ocf.h b/rgmanager/include/res-ocf.h
index 4459b67..b55bf44 100644
--- a/rgmanager/include/res-ocf.h
+++ b/rgmanager/include/res-ocf.h
@@ -31,6 +31,7 @@
#define OCF_RESOURCE_INSTANCE_STR "OCF_RESOURCE_INSTANCE"
#define OCF_CHECK_LEVEL_STR "OCF_CHECK_LEVEL"
#define OCF_RESOURCE_TYPE_STR "OCF_RESOURCE_TYPE"
+#define OCF_REFCNT_STR "OCF_RESKEY_RGMANAGER_meta_refcnt"

/*
LSB return codes
@@ -45,4 +46,23 @@
#define OCF_RA_NOT_RUNNING 7
#define OCF_RA_MAX 7

+/*
+ Resource operations - not ocf-specified
+ */
+#define RS_START (0)
+#define RS_STOP (1)
+#define RS_STATUS (2)
+#define RS_RESINFO (3)
+#define RS_RESTART (4)
+#define RS_RELOAD (5)
+#define RS_CONDRESTART (6)
+#define RS_RECOVER (7)
+#define RS_CONDSTART (8) /** Start if flagged with RF_NEEDSTART */
+#define RS_CONDSTOP (9) /** STOP if flagged with RF_NEEDSTOP */
+#define RS_MONITOR (10)
+#define RS_META_DATA (11)
+#define RS_VALIDATE (12)
+#define RS_MIGRATE (13)
+#define RS_RECONFIG (14)
+
#endif
diff --git a/rgmanager/include/resgroup.h b/rgmanager/include/resgroup.h
index 56f7f3c..c52dcc0 100644
--- a/rgmanager/include/resgroup.h
+++ b/rgmanager/include/resgroup.h
@@ -54,6 +54,11 @@ typedef struct {
#define RG_SERVICE_GROUP "usrm::manager"

#define RG_ACTION_REQUEST /* Message header */ 0x138582
+/* Argument to RG_ACTION_REQUEST */
+#define RG_ACTION_MASTER 0xfe0db143
+#define RG_ACTION_USER 0x3f173bfd
+/* */
+#define RG_EVENT 0x138583

#define RG_SUCCESS 0
#define RG_FAIL 1
@@ -67,7 +72,7 @@ typedef struct {
#define RG_EXITING 9
#define RG_INIT 10
#define RG_ENABLE 11
-#define RG_STATUS_INQUIRY 12
+#define RG_STATUS_NODE 12
#define RG_RELOCATE 13
#define RG_CONDSTOP 14
#define RG_CONDSTART 15
@@ -77,11 +82,12 @@ typedef struct {
#define RG_LOCK 19
#define RG_UNLOCK 20
#define RG_QUERY_LOCK 21
+/* #define RG_MIGRATE 22 */
+/* Compat: FREEZE = 23, UNFREEZE = 24 */
+/* #define RG_STATUS_INQUIRY 25 */
#define RG_NONE 999

-extern const char *rg_req_strings[];
-
-#define rg_req_str(req) (rg_req_strings[req])
+const char *rg_req_str(int req);

int handle_relocate_req(char *svcName, int request, uint64_t preferred_target,
uint64_t *new_owner);
@@ -101,23 +107,28 @@ int handle_start_remote_req(char *svcName, int req);
#define RG_STATE_ERROR 117 /** Recoverable error */
#define RG_STATE_RECOVER 118 /** Pending recovery */
#define RG_STATE_DISABLED 119 /** Resource not allowd to run */
+/* #define RG_STATE_MIGRATE 120 */

#define DEFAULT_CHECK_INTERVAL 10

-extern const char *rg_state_strings[];
+const char *rg_state_str(int val);
+int rg_state_str_to_id(const char *val);
+const char *agent_op_str(int val);

-#define rg_state_str(state) (rg_state_strings[state - RG_STATE_BASE])
+int eval_groups(int local, uint64_t nodeid, int nodeStatus);

int rg_status(const char *resgroupname);
int group_op(char *rgname, int op);
void rg_init(void);

-/* FOOM */
int svc_start(char *svcName, int req);
int svc_stop(char *svcName, int error);
int svc_status(char *svcName);
int svc_disable(char *svcName);
int svc_fail(char *svcName);
+int check_restart(char *svcName);
+int add_restart(char *svcName);
+
int rt_enqueue_request(const char *resgroupname, int request, int response_fd,
int max, uint64_t target, int arg0, int arg1);

@@ -135,6 +146,7 @@ int set_rg_state(char *name, rg_state_t *svcblk);
int get_rg_state(char *servicename, rg_state_t *svcblk);
uint64_t best_target_node(cluster_member_list_t *allowed, uint64_t owner,
char *rg_name, int lock);
+char *c_name(char *svcName);

#ifdef DEBUG
int _rg_lock_dbg(char *, void **, char *, int);
@@ -155,6 +167,24 @@ int rg_unlock(char *name, void *p);
void member_list_update(cluster_member_list_t *new_ml);
cluster_member_list_t *member_list(void);
uint64_t my_id(void);
+int member_online(uint64_t nid);
+void member_set_state(uint64_t nid, int state);
+
+
+/* Return codes */
+#define RG_EDEPEND -17 /* Dependency rule would be violated */
+#define RG_EEXCL -16 /* Service not runnable due to
+ the fact that it is tagged
+ exclusive and there are no
+ empty nodes. */
+#define RG_EDOMAIN -15 /* Service not runnable given the
+ set of nodes and its failover
+ domain */
+#define RG_ESCRIPT -14 /* S/Lang script failed */
+#define RG_EFENCE -13 /* Fencing operation pending */
+#define RG_ENODE -12 /* Node is dead/nonexistent */
+#define RG_EINVAL -11 /* Invalid operation for resource */
+#define RG_EQUORUM -10 /* Operation requires quorum */

#define RG_ERELO -9 /* Operation cannot complete here */
#define RG_ENODEDEATH -8 /* Processing node died */
@@ -166,14 +196,12 @@ uint64_t my_id(void);
#define RG_EABORT -2 /* Request cancelled */
#define RG_EFAIL -1 /* Generic error */
#define RG_ESUCCESS 0
+#define RG_YES 1
+#define RG_NO 2
+

+const char *rg_strerror(int val);

-#define FORWARD -3
-#define ABORT -2
-#define FAIL -1
-#define SUCCESS 0
-#define YES 1
-#define NO 2

/*
* Fail-over domain states
@@ -190,6 +218,12 @@ uint64_t my_id(void);
#define FOD_RESTRICTED (1<<1)
#define FOD_NOFAILBACK (1<<2)

+/*
+ Status tree flags
+ */
+#define SFL_FAILURE (1<<0)
+#define SFL_RECOVERABLE (1<<1)
+
//#define DEBUG
#ifdef DEBUG

diff --git a/rgmanager/include/reslist.h b/rgmanager/include/reslist.h
index 7b98f23..23129ff 100644
--- a/rgmanager/include/reslist.h
+++ b/rgmanager/include/reslist.h
@@ -25,31 +25,34 @@
#include <libxml/xpath.h>


+#define RA_PRIMARY (1<<0) /** Primary key */
+#define RA_UNIQUE (1<<1) /** Unique for given type */
+#define RA_REQUIRED (1<<2) /** Required (or an error if not present */
+#define RA_INHERIT (1<<3) /** Inherit a parent resource's attr */
+#define RA_RECONFIG (1<<4) /** Allow inline reconfiguration */
+
#define RF_INLINE (1<<0)
#define RF_DEFINED (1<<1)
#define RF_NEEDSTART (1<<2) /** Used when adding/changing resources */
#define RF_NEEDSTOP (1<<3) /** Used when deleting/changing resources */
#define RF_COMMON (1<<4) /** " */
+#define RF_INDEPENDENT (1<<5) /** Define this for a resource if it is
+ otherwise an independent subtree */
+#define RF_RECONFIG (1<<6)
+
+#define RF_INIT (1<<7) /** Resource rule: Initialize this resource
+ class on startup */
+#define RF_DESTROY (1<<8) /** Resource rule flag: Destroy this
+ resource class if you delete it from
+ the configuration */
+#define RF_ROOT (1<<9)
+
+

#define RES_STOPPED (0)
#define RES_STARTED (1)
#define RES_FAILED (2)

-/*
- Resource operations
- */
-#define RS_START (0)
-#define RS_STOP (1)
-#define RS_STATUS (2)
-#define RS_RESINFO (3)
-#define RS_RESTART (4)
-#define RS_RELOAD (5)
-#define RS_CONDRESTART (6)
-#define RS_RECOVER (7)
-#define RS_CONDSTART (8) /** Start if flagged with RF_NEEDSTART */
-#define RS_CONDSTOP (9) /** STOP if flagged with RF_NEEDSTOP */
-
-
#ifndef SHAREDIR
#define SHAREDIR "/usr/share/rgmanager"
#endif
@@ -65,33 +68,20 @@
#include <res-ocf.h>


-typedef enum {
-/*
-#define RA_PRIMARY (1<<0)
-#define RA_UNIQUE (1<<1)
-#define RA_REQUIRED (1<<2)
-#define RA_INHERIT (1<<3)
- */
- RA_PRIMARY = (1<<0),
- RA_UNIQUE = (1<<1),
- RA_REQUIRED= (1<<2),
- RA_INHERIT = (1<<3),
- RA_SPEC = (1<<4)
-} ra_flag_t;
-
typedef struct _resource_attribute {
char *ra_name;
char *ra_value;
- ra_flag_t ra_flags;
+ int ra_flags;
+ int _pad_;
} resource_attr_t;


typedef struct _resource_child {
+ char *rc_name;
int rc_startlevel;
int rc_stoplevel;
int rc_forbid;
int rc_flags;
- char *rc_name;
} resource_child_t;


@@ -110,7 +100,7 @@ typedef struct _resource_rule {
char * rr_type;
char * rr_agent;
char * rr_version; /** agent XML spec version; OCF-ism */
- int rr_root;
+ int rr_flags;
int rr_maxrefs;
resource_attr_t * rr_attrs;
resource_child_t * rr_childtypes;
@@ -137,6 +127,7 @@ typedef struct _rg_node {
struct _rg_node *rn_child, *rn_parent;
resource_t *rn_resource;
resource_act_t *rn_actions;
+ restart_counter_t rn_restart_counter;
int rn_state; /* State of this instance of rn_resource */
int rn_flags;
int rn_last_status;
@@ -149,7 +140,7 @@ typedef struct _fod_node {
list_head();
char *fdn_name;
int fdn_prio;
- int _pad_; /* align */
+ uint64_t fdn_nodeid; /* on rhel4 this will be 64-bit int */
} fod_node_t;

typedef struct _fod {
@@ -169,7 +160,11 @@ int res_stop(resource_node_t **tree, resource_t *res, void *ret);
int res_status(resource_node_t **tree, resource_t *res, void *ret);
int res_condstart(resource_node_t **tree, resource_t *res, void *ret);
int res_condstop(resource_node_t **tree, resource_t *res, void *ret);
+int res_exec(resource_node_t *node, int op, const char *arg, int depth);
/*int res_resinfo(resource_node_t **tree, resource_t *res, void *ret);*/
+int expand_time(char *val);
+int store_action(resource_act_t **actsp, char *name, int depth, int timeout, int interval);
+

/*
Calculate differences
@@ -208,6 +203,8 @@ void deconstruct_domains(fod_t **domains);
void print_domains(fod_t **domains);
int node_should_start(uint64_t nodeid, cluster_member_list_t *membership,
char *rg_name, fod_t **domains);
+int node_domain_set(fod_t *domain, uint64_t **ret, int *retlen);
+int node_domain_set_safe(char *domainname, uint64_t **ret, int *retlen, int *flags);


/*
@@ -216,6 +213,7 @@ int node_should_start(uint64_t nodeid, cluster_member_list_t *membership,
resource_t *find_resource_by_ref(resource_t **reslist, char *type, char *ref);
resource_t *find_root_by_ref(resource_t **reslist, char *ref);
resource_rule_t *find_rule_by_type(resource_rule_t **rulelist, char *type);
+void res_build_name(char *, size_t, resource_t *);

/*
Internal functions; shouldn't be needed.
diff --git a/rgmanager/include/restart_counter.h b/rgmanager/include/restart_counter.h
new file mode 100644
index 0000000..2f158ad
--- /dev/null
+++ b/rgmanager/include/restart_counter.h
@@ -0,0 +1,32 @@
+/*
+ Copyright Red Hat, Inc. 2007
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 as published
+ by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+*/
+/* Time-based restart counters for rgmanager */
+
+#ifndef _RESTART_COUNTER_H
+#define _RESTART_COUNTER_H
+
+typedef void *restart_counter_t;
+
+int restart_add(restart_counter_t arg);
+int restart_clear(restart_counter_t arg);
+int restart_count(restart_counter_t arg);
+int restart_treshold_exceeded(restart_counter_t arg);
+restart_counter_t restart_init(time_t expire_timeout, int max_restarts);
+int restart_cleanup(restart_counter_t arg);
+
+#endif
diff --git a/rgmanager/include/rg_queue.h b/rgmanager/include/rg_queue.h
index ac26ce8..d40793e 100644
--- a/rgmanager/include/rg_queue.h
+++ b/rgmanager/include/rg_queue.h
@@ -1,9 +1,27 @@
+/*
+ Copyright Red Hat, Inc. 2004-2007
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 as published
+ by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+*/
#ifndef _RG_QUEUE_H
#define _RG_QUEUE_H
#include <list.h>
#include <stdint.h>
#include <sys/time.h>
#include <unistd.h>
+#include <magmamsg.h>


/**
@@ -15,12 +33,12 @@ typedef struct _request {
uint32_t rr_request; /** Request */
uint32_t rr_errorcode; /** Error condition */
uint32_t rr_orig_request; /** Original request */
- uint32_t rr_resp_fd; /** FD to send response */
uint64_t rr_target; /** Target node */
uint32_t rr_arg0; /** Integer argument */
uint32_t rr_arg1; /** Integer argument */
+ uint32_t rr_arg2; /** Integer argument */
uint32_t rr_line; /** Line no */
- uint32_t _pad_; /** pad */
+ uint32_t rr_resp_fd; /** FD to send response */
char *rr_file; /** Who made req */
time_t rr_when; /** time to execute */
} request_t;
@@ -41,5 +59,7 @@ int rq_queue_empty(request_t **q);
void rq_free(request_t *foo);

void forward_request(request_t *req);
+void forward_message(int fd, void *msg, uint64_t nodeid);
+

#endif
diff --git a/rgmanager/include/sets.h b/rgmanager/include/sets.h
new file mode 100644
index 0000000..8cc271b
--- /dev/null
+++ b/rgmanager/include/sets.h
@@ -0,0 +1,39 @@
+/*
+ Copyright Red Hat, Inc. 2007
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 as published
+ by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+*/
+/**
+ @file sets.h - Header file for sets.c
+ @author Lon Hohberger <lhh at redhat.com>
+ */
+#ifndef _SETS_H
+#define _SETS_H
+
+#include <stdint.h>
+typedef uint64_t set_type_t;
+
+int s_add(set_type_t *, int *, set_type_t);
+int s_union(set_type_t *, int, set_type_t *,
+ int, set_type_t **, int *);
+
+int s_intersection(set_type_t *, int, set_type_t *,
+ int, set_type_t **, int *);
+int s_delta(set_type_t *, int, set_type_t *,
+ int, set_type_t **, int *);
+int s_subtract(set_type_t *, int, set_type_t *, int, set_type_t **, int *);
+int s_shuffle(set_type_t *, int);
+
+#endif
diff --git a/rgmanager/man/clusvcadm.8 b/rgmanager/man/clusvcadm.8
index dcc5691..20ae823 100644
--- a/rgmanager/man/clusvcadm.8
+++ b/rgmanager/man/clusvcadm.8
@@ -49,12 +49,8 @@ service
Lock the local resource group manager. This should only be used if the
administrator intends to perform a global, cluster-wide shutdown. This
prevents starting resource groups on the local node, allowing
-services will not fail over during the shutdown of the cluster. Generally,
-administrators should use the
-.B
-clushutdown(8)
-command to accomplish this. Once the cluster quorum is dissolved, this
-state is reset.
+services will not fail over during the shutdown of the cluster.
+Once the cluster quorum is dissolved, this state is reset.
.IP "-m <member>"
When used in conjunction with either the
.B
@@ -88,11 +84,10 @@ service
until a member transition or until it is enabled again.
.IP -u
Unlock the cluster's service managers. This allows services to transition
-again. It will be necessary to re-enable all services in the stopped state
-if this is run after fB clushutdown(8)fR.
+again.

.IP -v
Display version information and exit.

.SH "SEE ALSO"
-clustat(8), clushutdown(8)
+clustat(8)
diff --git a/rgmanager/src/clulib/Makefile b/rgmanager/src/clulib/Makefile
index 343c2e9..5531e82 100644
--- a/rgmanager/src/clulib/Makefile
+++ b/rgmanager/src/clulib/Makefile
@@ -30,7 +30,8 @@ install: all
uninstall:

libclulib.a: clulog.o daemon_init.o signals.o msgsimple.o
- vft.o gettid.o rg_strings.o wrap_lock.o
+ vft.o gettid.o rg_strings.o wrap_lock.o
+ sets.o
${AR} cru $@ $^
ranlib $@

diff --git a/rgmanager/src/clulib/rg_strings.c b/rgmanager/src/clulib/rg_strings.c
index 4728789..5d561b7 100644
--- a/rgmanager/src/clulib/rg_strings.c
+++ b/rgmanager/src/clulib/rg_strings.c
@@ -1,35 +1,179 @@
-const char *rg_state_strings[] = {
- "stopped",
- "starting",
- "started",
- "stopping",
- "failed",
- "uninitialized",
- "checking",
- "recoverable",
- "recovering",
- "disabled",
- ""
+/*
+ Copyright Red Hat, Inc. 2004-2006
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+*/
+#include <res-ocf.h>
+#include <resgroup.h>
+
+struct string_val {
+ int val;
+ char *str;
+};
+
+
+const struct string_val rg_error_strings[] = {
+ { RG_EEXCL, "Service not runnable: cannot run exclusive" },
+ { RG_EDOMAIN, "Service not runnable: restricted failover domain offline" },
+ { RG_ESCRIPT, "S/Lang Script Error" },
+ { RG_EFENCE, "Fencing operation pending; try again later" },
+ { RG_ENODE, "Target node dead / nonexistent" },
+ { RG_ERUN, "Service is already running" },
+ { RG_EQUORUM, "Operation requires quorum" },
+ { RG_EINVAL, "Invalid operation for resource" },
+ { RG_EDEPEND, "Operation violates dependency rule" },
+ { RG_EAGAIN, "Temporary failure; try again" },
+ { RG_EDEADLCK, "Operation would cause a deadlock" },
+ { RG_ENOSERVICE,"Service does not exist" },
+ { RG_EFORWARD, "Service not mastered locally" },
+ { RG_EABORT, "Aborted; service failed" },
+ { RG_EFAIL, "Failure" },
+ { RG_ESUCCESS, "Success" },
+ { RG_YES, "Yes" },
+ { RG_NO, "No" },
+ { 0, NULL }
+};
+
+
+const struct string_val rg_req_strings[] = {
+ {RG_SUCCESS, "success" },
+ {RG_FAIL, "fail"},
+ {RG_START, "start"},
+ {RG_STOP, "stop"},
+ {RG_STATUS, "status"},
+ {RG_DISABLE, "disable"},
+ {RG_STOP_RECOVER, "stop (recovery)"},
+ {RG_START_RECOVER, "start (recovery)"},
+ {RG_RESTART, "restart"},
+ {RG_EXITING, "exiting"},
+ {RG_INIT, "initialize"},
+ {RG_ENABLE, "enable"},
+ {RG_STATUS_NODE, "status inquiry"},
+ {RG_RELOCATE, "relocate"},
+ {RG_CONDSTOP, "conditional stop"},
+ {RG_CONDSTART, "conditional start"},
+ {RG_START_REMOTE,"remote start"},
+ {RG_STOP_USER, "user stop"},
+ {RG_STOP_EXITING, "stop (shutdown)"},
+ {RG_LOCK, "locking"},
+ {RG_UNLOCK, "unlocking"},
+ {RG_QUERY_LOCK, "lock status inquiry"},
+ //{RG_MIGRATE, "migrate"},
+ //{RG_STATUS_INQUIRY, "out of band service status inquiry"},
+ {RG_NONE, "none"},
+ {0, NULL}
+};
+
+
+const struct string_val rg_state_strings[] = {
+ {RG_STATE_STOPPED, "stopped"},
+ {RG_STATE_STARTING, "starting"},
+ {RG_STATE_STARTED, "started"},
+ {RG_STATE_STOPPING, "stopping"},
+ {RG_STATE_FAILED, "failed"},
+ {RG_STATE_UNINITIALIZED, "uninitialized"},
+ {RG_STATE_CHECK, "checking"},
+ {RG_STATE_ERROR, "recoverable"},
+ {RG_STATE_RECOVER, "recovering"},
+ {RG_STATE_DISABLED, "disabled"},
+ //{RG_STATE_MIGRATE, "migrating"},
+ {0, NULL}
};

-const char *rg_req_strings[] = {
- "success",
- "fail",
- "start",
- "stop",
- "status",
- "disable",
- "stop (recovery)",
- "start (recovery)",
- "restart",
- "exiting",
- "initialize",
- "enable",
- "status inquiry",
- "relocate",
- "conditional stop",
- "conditional start",
- "remote start",
- "user stop",
- ""
+
+const struct string_val agent_ops[] = {
+ {RS_START, "start"},
+ {RS_STOP, "stop"},
+ {RS_STATUS, "status"},
+ {RS_RESINFO, "resinfo"},
+ {RS_RESTART, "restart"},
+ {RS_RELOAD, "reload"},
+ {RS_CONDRESTART, "condrestart"}, /* Unused */
+ {RS_RECOVER, "recover"},
+ {RS_CONDSTART, "condstart"},
+ {RS_CONDSTOP, "condstop"},
+ {RS_MONITOR, "monitor"},
+ {RS_META_DATA, "meta-data"}, /* printenv */
+ {RS_VALIDATE, "validate-all"},
+ //{RS_MIGRATE, "migrate"},
+ {RS_RECONFIG, "reconfig"},
+ {0 , NULL}
};
+
+
+static inline const char *
+rg_search_table(const struct string_val *table, int val)
+{
+ int x;
+
+ for (x = 0; table[x].str != NULL; x++) {
+ if (table[x].val == val) {
+ return table[x].str;
+ }
+ }
+
+ return "Unknown";
+}
+
+
+static inline int
+rg_search_table_by_str(const struct string_val *table, const char *val)
+{
+ int x;
+
+ for (x = 0; table[x].str != NULL; x++) {
+ if (!strcasecmp(table[x].str, val))
+ return table[x].val;
+ }
+
+ return -1;
+}
+
+
+
+const char *
+rg_strerror(int val)
+{
+ return rg_search_table(rg_error_strings, val);
+}
+
+const char *
+rg_state_str(int val)
+{
+ return rg_search_table(rg_state_strings, val);
+}
+
+
+int
+rg_state_str_to_id(const char *val)
+{
+ return rg_search_table_by_str(rg_state_strings, val);
+}
+
+
+
+const char *
+rg_req_str(int val)
+{
+ return rg_search_table(rg_req_strings, val);
+}
+
+
+const char *
+agent_op_str(int val)
+{
+ return rg_search_table(agent_ops, val);
+}
diff --git a/rgmanager/src/clulib/sets.c b/rgmanager/src/clulib/sets.c
new file mode 100644
index 0000000..f734064
--- /dev/null
+++ b/rgmanager/src/clulib/sets.c
@@ -0,0 +1,370 @@
+/*
+ Copyright Red Hat, Inc. 2007
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License version 2 as published
+ by the Free Software Foundation.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+*/
+/**
+ @file sets.c - Order-preserving set functions (union / intersection / delta)
+ (designed for integer types; a la int, uint64_t, etc...)
+ @author Lon Hohberger <lhh at redhat.com>
+ */
+#include <stdio.h>
+#include <malloc.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sets.h>
+#include <sys/time.h>
+
+
+/**
+ Add a value to a set. This function disregards an add if the value is already
+ in the set. Note that the maximum length of set s must be preallocated; this
+ function doesn't do error or bounds checking.
+
+ @param s Set to modify
+ @param curlen Current length (modified if added)
+ @param val Value to add
+ @return 0 if not added, 1 if added
+ */
+int
+s_add(set_type_t *s, int *curlen, set_type_t val)
+{
+ int idx=0;
+
+ for (; idx < *curlen; idx++)
+ if (s[idx] == val)
+ return 0;
+ s[*curlen] = val;
+ ++(*curlen);
+ return 1;
+}
+
+
+/**
+ Union-set function. Allocates and returns a new set which is the union of
+ the two given sets 'left' and 'right'. Also returns the new set length.
+
+ @param left Left set - order is preserved on this set; that is,
+ this is the set where the caller cares about ordering.
+ @param ll Length of left set.
+ @param right Right set - order is not preserved on this set during
+ the union operation
+ @param rl Length of right set
+ @param ret Return set. Should * not * be preallocated.
+ @param retl Return set length. Should be ready to accept 1 integer
+ upon calling this function
+ @return 0 on success, -1 on error
+ */
+int
+s_union(set_type_t *left, int ll, set_type_t *right, int rl,
+ set_type_t **ret, int *retl)
+{
+ int l, r, cnt = 0, total;
+
+ total = ll + rl; /* Union will never exceed both sets */
+
+ *ret = malloc(sizeof(set_type_t)*total);
+ if (!*ret) {
+ return -1;
+ }
+ memset((void *)(*ret), 0, sizeof(set_type_t)*total);
+
+ cnt = 0;
+
+ /* Add all the ones on the left */
+ for (l = 0; l < ll; l++)
+ s_add(*ret, &cnt, left[l]);
+
+ /* Add the ones on the left */
+ for (r = 0; r < rl; r++)
+ s_add(*ret, &cnt, right[r]);
+
+ *retl = cnt;
+
+ return 0;
+}
+
+
+/**
+ Intersection-set function. Allocates and returns a new set which is the
+ intersection of the two given sets 'left' and 'right'. Also returns the new
+ set length.
+
+ @param left Left set - order is preserved on this set; that is,
+ this is the set where the caller cares about ordering.
+ @param ll Length of left set.
+ @param right Right set - order is not preserved on this set during
+ the union operation
+ @param rl Length of right set
+ @param ret Return set. Should * not * be preallocated.
+ @param retl Return set length. Should be ready to accept 1 integer
+ upon calling this function
+ @return 0 on success, -1 on error
+ */
+int
+s_intersection(set_type_t *left, int ll, set_type_t *right, int rl,
+ set_type_t **ret, int *retl)
+{
+ int l, r, cnt = 0, total;
+
+ total = ll; /* Intersection will never exceed one of the two set
+ sizes */
+
+ *ret = malloc(sizeof(set_type_t)*total);
+ if (!*ret) {
+ return -1;
+ }
+ memset((void *)(*ret), 0, sizeof(set_type_t)*total);
+
+ cnt = 0;
+ /* Find duplicates */
+ for (l = 0; l < ll; l++) {
+ for (r = 0; r < rl; r++) {
+ if (left[l] != right[r])
+ continue;
+ if (s_add(*ret, &cnt, right[r]))
+ break;
+ }
+ }
+
+ *retl = cnt;
+ return 0;
+}
+
+
+/**
+ Delta-set function. Allocates and returns a new set which is the delta (i.e.
+ numbers not in both sets) of the two given sets 'left' and 'right'. Also
+ returns the new set length.
+
+ @param left Left set - order is preserved on this set; that is,
+ this is the set where the caller cares about ordering.
+ @param ll Length of left set.
+ @param right Right set - order is not preserved on this set during
+ the union operation
+ @param rl Length of right set
+ @param ret Return set. Should * not * be preallocated.
+ @param retl Return set length. Should be ready to accept 1 integer
+ upon calling this function
+ @return 0 on success, -1 on error
+ */
+int
+s_delta(set_type_t *left, int ll, set_type_t *right, int rl,
+ set_type_t **ret, int *retl)
+{
+ int l, r, cnt = 0, total, found;
+
+ total = ll + rl; /* Union will never exceed both sets */
+
+ *ret = malloc(sizeof(set_type_t)*total);
+ if (!*ret) {
+ return -1;
+ }
+ memset((void *)(*ret), 0, sizeof(set_type_t)*total);
+
+ cnt = 0;
+
+ /* not efficient, but it works */
+ /* Add all the ones on the left */
+ for (l = 0; l < ll; l++) {
+ found = 0;
+ for (r = 0; r < rl; r++) {
+ if (right[r] == left[l]) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+ s_add(*ret, &cnt, left[l]);
+ }
+
+
+ /* Add all the ones on the right*/
+ for (r = 0; r < rl; r++) {
+ found = 0;
+ for (l = 0; l < ll; l++) {
+ if (right[r] == left[l]) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+ s_add(*ret, &cnt, right[r]);
+ }
+
+ *retl = cnt;
+
+ return 0;
+}
+
+
+/**
+ Subtract-set function. Allocates and returns a new set which is the
+ subtraction of the right set from the left set.
+ Also returns the new set length.
+
+ @param left Left set - order is preserved on this set; that is,
+ this is the set where the caller cares about ordering.
+ @param ll Length of left set.
+ @param right Right set - order is not preserved on this set during
+ the union operation
+ @param rl Length of right set
+ @param ret Return set. Should * not * be preallocated.
+ @param retl Return set length. Should be ready to accept 1 integer
+ upon calling this function
+ @return 0 on success, -1 on error
+ */
+int
+s_subtract(set_type_t *left, int ll, set_type_t *right, int rl,
+ set_type_t **ret, int *retl)
+{
+ int l, r, cnt = 0, total, found;
+
+ total = ll; /* Union will never exceed left set length*/
+
+ *ret = malloc(sizeof(set_type_t)*total);
+ if (!*ret) {
+ return -1;
+ }
+ memset((void *)(*ret), 0, sizeof(set_type_t)*total);
+
+ cnt = 0;
+
+ /* not efficient, but it works */
+ for (l = 0; l < ll; l++) {
+ found = 0;
+ for (r = 0; r < rl; r++) {
+ if (right[r] == left[l]) {
+ found = 1;
+ break;
+ }
+ }
+
+ if (found)
+ continue;
+ s_add(*ret, &cnt, left[l]);
+ }
+
+ *retl = cnt;
+
+ return 0;
+}
+
+
+/**
+ Shuffle-set function. Weakly randomizes ordering of a set in-place.
+
+ @param set Set to randomize
+ @param sl Length of set
+ @return 0
+ */
+int
+s_shuffle(set_type_t *set, int sl)
+{
+ int x, newidx;
+ unsigned r_state = 0;
+ set_type_t t;
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ r_state = (int)(tv.tv_usec);
+
+ for (x = 0; x < sl; x++) {
+ newidx = (rand_r(&r_state) % sl);
+ if (newidx == x)
+ continue;
+ t = set[x];
+ set[x] = set[newidx];
+ set[newidx] = t;
+ }
+
+ return 0;
+}
+
+
+#ifdef STANDALONE
+/* Testbed */
+/*
+ gcc -o sets sets.c -DSTANDALONE -ggdb -I../../include
+ -Wall -Werror -Wstrict-prototypes -Wextra
+ */
+int
+main(int __attribute__ ((unused)) argc, char __attribute__ ((unused)) **argv)
+{
+ set_type_t a[] = { 1, 2, 3, 3, 3, 2, 2, 3 };
+ set_type_t b[] = { 2, 3, 4 };
+ set_type_t *i;
+ int ilen = 0, x;
+
+ s_union(a, 8, b, 3, &i, &ilen);
+
+ /* Should return length of 4 - { 1 2 3 4 } */
+ printf("set_union [%d] = ", ilen);
+ for ( x = 0; x < ilen; x++) {
+ printf("%d ", (int)i[x]);
+ }
+ printf("
");
+
+ s_shuffle(i, ilen);
+ printf("shuffled [%d] = ", ilen);
+ for ( x = 0; x < ilen; x++) {
+ printf("%d ", (int)i[x]);
+ }
+ printf("
");
+
+
+ free(i);
+
+ /* Should return length of 2 - { 2 3 } */
+ s_intersection(a, 8, b, 3, &i, &ilen);
+
+ printf("set_intersection [%d] = ", ilen);
+ for ( x = 0; x < ilen; x++) {
+ printf("%d ", (int)i[x]);
+ }
+ printf("
");
+
+ free(i);
+
+ /* Should return length of 2 - { 1 4 } */
+ s_delta(a, 8, b, 3, &i, &ilen);
+
+ printf("set_delta [%d] = ", ilen);
+ for ( x = 0; x < ilen; x++) {
+ printf("%d ", (int)i[x]);
+ }
+ printf("
");
+
+ free(i);
+
+ /* Should return length of 1 - { 1 } */
+ s_subtract(a, 8, b, 3, &i, &ilen);
+
+ printf("set_subtract [%d] = ", ilen);
+ for ( x = 0; x < ilen; x++) {
+ printf("%d ", (int)i[x]);
+ }
+ printf("
");
+
+ free(i);
+
+
+ return 0;
+}
+#endif
diff --git a/rgmanager/src/clulib/signals.c b/rgmanager/src/clulib/signals.c
index 1d49ee5..fa9f4a6 100644
--- a/rgmanager/src/clulib/signals.c
+++ b/rgmanager/src/clulib/signals.c
@@ -1,3 +1,21 @@
+/*
+ Copyright Red Hat, Inc. 2003-2006
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+*/
#include <signal.h>
#include <stdlib.h>
#include <string.h>
diff --git a/rgmanager/src/clulib/tmgr.c b/rgmanager/src/clulib/tmgr.c
new file mode 100644
index 0000000..2565f26
--- /dev/null
+++ b/rgmanager/src/clulib/tmgr.c
@@ -0,0 +1,128 @@
+/*
+ Copyright Red Hat, Inc. 2007
+ Copyright Crosswalk 2006-2007
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU General Public License as published by the
+ Free Software Foundation; either version 2, or (at your option) any
+ later version.
+
+ This program is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; see the file COPYING. If not, write to the
+ Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
+ MA 02139, USA.
+*/
+#ifdef WRAP_THREADS
+#include <stdio.h>
+#include <sys/types.h>
+#include <gettid.h>
+#include <pthread.h>
+#include <string.h>
+#include <errno.h>
+#include <malloc.h>
+#include <string.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <pthread.h>
+#include <list.h>
+#include <execinfo.h>
+
+typedef struct _thr {
+ list_head();
+ void *(*fn)(void *arg);
+ char **name;
+ pthread_t th;
+} mthread_t;
+
+static mthread_t *_tlist = NULL;
+static int _tcount = 0;
+static pthread_rwlock_t _tlock = PTHREAD_RWLOCK_INITIALIZER;
+
+void
+dump_thread_states(FILE *fp)
+{
+ int x;
+ mthread_t *curr;
+ fprintf(fp, "Thread Information
");
+ pthread_rwlock_rdlock(&_tlock);
+ list_for(&_tlist, curr, x) {
+ fprintf(fp, " Thread #%d id: %d function: %s
",
+ x, (unsigned)curr->th, curr->name[0]);
+ }
+ pthread_rwlock_unlock(&_tlock);
+ fprintf(fp, "

");
+}
+
+
+int __real_pthread_create(pthread_t *, const pthread_attr_t *,
+ void *(*)(void*), void *);
+int
+__wrap_pthread_create(pthread_t *th, const pthread_attr_t *attr,
+ void *(*start_routine)(void*),
+ void *arg)
+{
+ void *fn = start_routine;
+ mthread_t *new;
+ int ret;
+
+ new = malloc(sizeof (*new));
+
+ ret = __real_pthread_create(th, attr, start_routine, arg);
+ if (ret) {
+ if (new)
+ free(new);
+ return ret;
+ }
+
+ if (new) {
+ new->th = *th;
+ new->fn = start_routine;
+ new->name = backtrace_symbols(&fn, 1);
+ pthread_rwlock_wrlock(&_tlock);
+ list_insert(&_tlist, new);
+ ++_tcount;
+ pthread_rwlock_unlock(&_tlock);
+ }
+
+ return ret;
+}
+
+
+void __real_pthread_exit(void *);
+void
+__wrap_pthread_exit(void *exitval)
+{
+ mthread_t *old;
+ int ret = 0, found = 0;
+ pthread_t me = pthread_self();
+
+ pthread_rwlock_rdlock(&_tlock);
+ list_for(&_tlist, old, ret) {
+ if (old->th == me) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ old = NULL;
+ pthread_rwlock_unlock(&_tlock);
+
+ if (!old)
+ __real_pthread_exit(exitval);
+
+ pthread_rwlock_wrlock(&_tlock);
+ list_remove(&_tlist, old);
+ --_tcount;
+ pthread_rwlock_unlock(&_tlock);
+
+ if (old->name)
+ free(old->name);
+ free(old);
+ __real_pthread_exit(exitval);
+}
+#endif
diff --git a/rgmanager/src/clulib/vft.c b/rgmanager/src/clulib/vft.c
index 859fc3e..29e51bc 100644
--- a/rgmanager/src/clulib/vft.c
+++ b/rgmanager/src/clulib/vft.c
@@ -187,6 +187,9 @@ static void
close_all(int *fds)
{
int x;
+
+ if (!fds)
+ return;
for (x = 0; fds[x] != -1; x++) {
msg_close(fds[x]);
}
@@ -1246,10 +1249,10 @@ vf_write(cluster_member_list_t *membership, uint32_t flags, char *keyid,
void *data, uint32_t datalen)
{
uint64_t nodeid;
- int *peer_fds;
+ int *peer_fds = NULL;
int count;
- key_node_t *key_node;
- vf_msg_t *join_view;
+ key_node_t *key_node = NULL;
+ vf_msg_t *join_view = NULL;
int remain = 0, x, y, rv = 1;
uint32_t totallen;
struct timeval start, end, dif;
@@ -1263,19 +1266,11 @@ vf_write(cluster_member_list_t *membership, uint32_t flags, char *keyid,
return -1;

pthread_mutex_lock(&vf_mutex);
- /* Obtain cluster lock on it. */
- snprintf(lock_name, sizeof(lock_name), "usrm::vf");
- l = clu_lock(lock_name, CLK_EX, &lockp);
- if (l < 0) {
- pthread_mutex_unlock(&vf_mutex);
- return l;
- }

/* set to -1 */
count = sizeof(int) * (membership->cml_count + 1);
peer_fds = malloc(count);
if(!peer_fds) {
- clu_unlock(lock_name, lockp);
pthread_mutex_unlock(&vf_mutex);
return -1;
}
@@ -1285,6 +1280,14 @@ vf_write(cluster_member_list_t *membership, uint32_t flags, char *keyid,
getuptime(&start);

retry_top:
+ /* Obtain cluster lock on it. */
+ snprintf(lock_name, sizeof(lock_name), "usrm::vf");
+ l = clu_lock(lock_name, CLK_EX, &lockp);
+ if (l < 0) {
+ pthread_mutex_unlock(&vf_mutex);
+ return l;
+ }
+
/*
* Connect to everyone, except ourself. We separate this from the
* initial send cycle because the connect cycle can cause timeouts
@@ -1316,29 +1319,40 @@ retry_top:
printf("VF: Connect to %d failed: %s
", (int)nodeid,
strerror(errno));
#endif
- if (flags & VFF_RETRY)
- goto retry_top;
if (flags & VFF_IGN_CONN_ERRORS)
continue;
- close_all(peer_fds);
- free(peer_fds);

- clu_unlock(lock_name, lockp);
- pthread_mutex_unlock(&vf_mutex);
- return -1;
+ if (flags & VFF_RETRY) {
+ clu_unlock(lock_name, lockp);
+ lockp = NULL;
+ usleep(20000); /* XXX */
+ goto retry_top;
+ }
+
+ /* No retry and no connection ignoring */
+ rv = -1;
+ goto out_cleanup;
}
++y;
}

+ if (y == 0) {
+ /* No hosts online / all refused connection (including
+ ourself) - guess we're good */
+ rv = 1;
+ goto out_cleanup;
+ }
+
pthread_mutex_lock(&key_list_mutex);
key_node = kn_find_key(keyid);
if (!key_node) {

if ((vf_key_init_nt(keyid, 10, NULL, NULL) < 0)) {
pthread_mutex_unlock(&key_list_mutex);
- clu_unlock(lock_name, lockp);
- pthread_mutex_unlock(&vf_mutex);
- return -1;
+ /* key_list_mutex is only held here; so we do
+ not put it in the cleanup section */
+ rv = -1;
+ goto out_cleanup;
}
key_node = kn_find_key(keyid);
assert(key_node);
@@ -1350,9 +1364,8 @@ retry_top:
pthread_mutex_unlock(&key_list_mutex);

if (!join_view) {
- clu_unlock(lock_name, lockp);
- pthread_mutex_unlock(&vf_mutex);
- return -1;
+ rv = -1;
+ goto out_cleanup;
}

#ifdef DEBUG
@@ -1386,11 +1399,8 @@ retry_top:
*/
if (ret_status == -1) {
vf_send_abort(peer_fds);
- close_all(peer_fds);
- free(join_view);
- clu_unlock(lock_name, lockp);
- pthread_mutex_unlock(&vf_mutex);
- return -1;
+ rv = -1;
+ goto out_cleanup;
}

#ifdef DEBUG
@@ -1408,21 +1418,28 @@ retry_top:
#endif
}

+
+out_cleanup:
/*
* Clean up
*/
- close_all(peer_fds);
+ if (peer_fds) {
+ close_all(peer_fds);
+ free(peer_fds);
+ }

/*
* unanimous returns 1 for true; 0 for false, so negate it and
* return our value...
*/
- free(join_view);
- free(peer_fds);
- clu_unlock(lock_name, lockp);
+ if (join_view)
+ free(join_view);
+ if (lockp)
+ clu_unlock(lock_name, lockp);
+
pthread_mutex_unlock(&vf_mutex);

- if (rv) {
+ if (rv >= 0) {
getuptime(&end);

dif.tv_usec = end.tv_usec - start.tv_usec;
@@ -1439,7 +1456,7 @@ retry_top:
#endif
}

- return (rv?0:-1);
+ return ((rv>=0)?0:-1);
}


diff --git a/rgmanager/src/daemons/Makefile b/rgmanager/src/daemons/Makefile
index f4413b7..55b37d5 100644
--- a/rgmanager/src/daemons/Makefile
+++ b/rgmanager/src/daemons/Makefile
@@ -17,12 +17,13 @@ include ${top_srcdir}/make/defines.mk
INCLUDE += -I $(top_srcdir)/include

CFLAGS+= -g -I${incdir} -I/usr/include/libxml2 -L${libdir}
+CFLAGS+= -I/usr/include/slang

CFLAGS+= -g -Wstrict-prototypes -Wshadow -fPIC -D_GNU_SOURCE

CFLAGS+= -L ../clulib

-LDFLAGS+= -lclulib -lxml2 -lmagmamsg -lmagma -lpthread -ldl
+LDFLAGS+= -lclulib -lxml2 -lmagmamsg -lmagma -lpthread -ldl -lslang
TARGETS=clurgmgrd clurmtabd rg_test

all: ${TARGETS}
@@ -40,8 +41,9 @@ uninstall:

clurgmgrd: rg_thread.o rg_locks.o main.o groups.o rg_state.o
rg_queue.o members.o rg_forward.o reslist.o
- resrules.o restree.o fo_domain.o nodeevent.o
- watchdog.o
+ resrules.o restree.o fo_domain.o
+ watchdog.o restart_counter.o event_config.o
+ slang_event.o rg_event.o service_op.o
$(CC) -o $@ $^ $(INCLUDE) $(CFLAGS) $(LDFLAGS) -lccs

#
@@ -59,7 +61,8 @@ clurgmgrd: rg_thread.o rg_locks.o main.o groups.o rg_state.o
# packages should run 'make check' as part of the build process.
#
rg_test: rg_locks-noccs.o test-noccs.o reslist-noccs.o
- resrules-noccs.o restree-noccs.o fo_domain-noccs.o
+ resrules-noccs.o restree-noccs.o
 

Thread Tools




All times are GMT. The time now is 04:20 AM.

VBulletin, Copyright ©2000 - 2014, Jelsoft Enterprises Ltd.
Content Relevant URLs by vBSEO ©2007, Crawlability, Inc.
Copyright 2007 - 2008, www.linux-archive.org