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 11-30-2007, 08:36 PM
 
Default cluster/rgmanager ChangeLog TODO include/resgr ...

CVSROOT: /cvs/cluster
Module name: cluster
Changes by: lhh@sourceware.org 2007-11-30 21:36:29

Modified files:
rgmanager : ChangeLog TODO
rgmanager/include: resgroup.h reslist.h restart_counter.h
rg_locks.h rg_queue.h
rgmanager/src/clulib: Makefile members.c rg_strings.c vft.c
rgmanager/src/daemons: Makefile fo_domain.c groups.c main.c
restree.c rg_event.c rg_forward.c
rg_state.c rg_thread.c test.c
rgmanager/src/resources: Makefile
Added files:
rgmanager : event-script.txt
rgmanager/include: event.h
rgmanager/src/clulib: sets.c
rgmanager/src/daemons: event_config.c service_op.c slang_event.c
rgmanager/src/resources: default_event_script.sl
Removed files:
rgmanager/src/daemons: nodeevent.c

Log message:
Add centralized S/Lang event script engine v0.8.1

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/event-script.txt.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/ChangeLog.diff?cvsroot=cluster&r1=1.61&r2=1.62
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/TODO.diff?cvsroot=cluster&r1=1.8&r2=1.9
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/include/event.h.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/include/resgroup.h.diff?cvsroot=cluster&r1=1.24&r2=1.25
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/include/reslist.h.diff?cvsroot=cluster&r1=1.24&r2=1.25
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/include/restart_counter.h.diff?cvsroot=cluster&r1=1.2&r2=1 .3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/include/rg_locks.h.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/include/rg_queue.h.diff?cvsroot=cluster&r1=1.6&r2=1.7
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/clulib/sets.c.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/clulib/Makefile.diff?cvsroot=cluster&r1=1.18&r2=1.19
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/clulib/members.c.diff?cvsroot=cluster&r1=1.4&r2=1.5
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/clulib/rg_strings.c.diff?cvsroot=cluster&r1=1.10&r2=1.11
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/clulib/vft.c.diff?cvsroot=cluster&r1=1.22&r2=1.23
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/event_config.c.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/service_op.c.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/slang_event.c.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/Makefile.diff?cvsroot=cluster&r1=1.24&r2=1.25
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/fo_domain.c.diff?cvsroot=cluster&r1=1.14&r2=1.15
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/groups.c.diff?cvsroot=cluster&r1=1.40&r2=1.41
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/main.c.diff?cvsroot=cluster&r1=1.45&r2=1.46
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/restree.c.diff?cvsroot=cluster&r1=1.39&r2=1.40
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/rg_event.c.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/rg_forward.c.diff?cvsroot=cluster&r1=1.11&r2=1.12
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/rg_state.c.diff?cvsroot=cluster&r1=1.41&r2=1.42
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/rg_thread.c.diff?cvsroot=cluster&r1=1.24&r2=1.25
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/test.c.diff?cvsroot=cluster&r1=1.13&r2=1.14
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/daemons/nodeevent.c.diff?cvsroot=cluster&r1=1.9&r2=NONE
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/resources/default_event_script.sl.diff?cvsroot=cluster&r1=NO NE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/cluster/rgmanager/src/resources/Makefile.diff?cvsroot=cluster&r1=1.20&r2=1.21

/cvs/cluster/cluster/rgmanager/event-script.txt,v --> standard output
revision 1.1
--- cluster/rgmanager/event-script.txt
+++ - 2007-11-30 21:36:29.524613000 +0000
@@ -0,0 +1,305 @@
+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.
+
+ 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);
+
+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>
+
+
--- cluster/rgmanager/ChangeLog 2007/11/30 20:36:17 1.61
+++ cluster/rgmanager/ChangeLog 2007/11/30 21:36:28 1.62
@@ -1,8 +1,58 @@
2007-11-30 Lon Hohberger <lhh at redhat.com>
- * src/resources/*: Merge misc. updates from RHEL5 branch.
- * src/utils/*: Merge misc. updates from RHEL5 branch.
- * include/*.h, src/daemons/*: Merge status-counter patch
- from RHEL5 branch.
+ * Commit RIND / S-Lang script engine [untested]
+
+[RHEL5 merged ChangeLog Entries]
+2007-11-30 Lon Hohberger <lhh at redhat.com>
+ * src/resources/clusterfs.sh: Retry mount up to 3 times to avoid
+ race condition during another process mounting a GFS volume
+ * src/resources/vm.sh, service.sh: Add defaults for values.
+ Make vm.sh work with more service attrs (max restarts)
+ * src/utils/clustat.c: Make output of clustat terminal-width
+ dependent
+
+2007-11-26 Lon Hohberger <lhh at redhat.com>
+ * include/reslist.h: Add restart counters to resource node structure
+ (intended for top-level resources, i.e. services, vms...)
+ * include/restart_counter.h: Add header file for restart counter
+ * src/daemons/Makefile: Fix build to include restart counters
+ * src/daemons/restart_counter.c: Implement restart counters #247139
+ * src/daemons/fo_domain.c, groups.c, restart_counter.c, resrules.c,
+ restree.c, test.c: Glue for restart counters.
+ * src/daemons/reslist.c: Glue for restart counters. Make expand_time
+ parser more robust to allow things like '1h30m' as a time value.
+ * src/daemons/main.c: Mark quorum disk offline in the correct
+ place to avoid extraneous log messages
+ * src/daemons/rg_state.c: Allow marking service as stopped if
+ stuck in recover state. Make service which failed to start
+ go to stopped state. Glue for restart counters.
+ * src/resources/service.sh, vm.sh: Add parameters for restart
+ counters #247139
+
+2007-11-14 Lon Hohberger <lhh at redhat.com>
+ * src/utils/clulog.c: Make clulog honor rgmanager log levels
+ (#289501)
+ * src/clulib/vft.c: Fix #303981 - crash on rgmanager restart in some
+ cases
+ * man/clusvcadm.8: Remove references to clushutdown from man page;
+ resolves #324151
+ * src/resources/netfs.sh: Apply patch from Marco Ceci to fix #358161
+ * src/resources/vm.sh: Make default migration policy live instead
+ of pause for Xen virtual machines. Also make it configurable instead
+ of static. Resolves #345871
+
+2007-11-13 Lon Hohberger <lhh at redhat.com>
+ * src/resources/clusterfs.sh: Add support for self_fence operation
+ to clusterfs resource agent
+ * src/resources/service.sh: Add default values to service.sh
+
+2007-10-26 Lon Hohberger <lhh at redhat.com>
+ * src/daemons/main.c, src/utils/clustat.c, clusvcadm.c:
+ Fix #354391
+
+2007-09-25 Lon Hohberger <lhh at redhat.com>
+ * src/daemons/restree.c: Apply patch to fix side case re: 229650
+ Patch from Simone Gotti. Resolves: #229650
+[End RHEL5 merged changes]

2007-08-30 Lon Hohberger <lhh at redhat.com>
* src/daemons/restree.c, rg_state.c: Fix tree-restart bug
--- cluster/rgmanager/TODO 2006/07/19 18:43:32 1.8
+++ cluster/rgmanager/TODO 2007/11/30 21:36:28 1.9
@@ -1,5 +0,0 @@
-* Make live-migration of resources work; preferrably so that admins
-can manually migrate Xen VMs to other nodes without telling the cluster
-about it. That is, the cluster should be able to acquire running VMs
-and update its state accordingly.
-* Test against a working Xen build and shake out bugs
/cvs/cluster/cluster/rgmanager/include/event.h,v --> standard output
revision 1.1
--- cluster/rgmanager/include/event.h
+++ - 2007-11-30 21:36:29.926075000 +0000
@@ -0,0 +1,145 @@
+/*
+ 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 {
+ int ne_local;
+ int ne_nodeid;
+ int ne_state;
+ int ne_clean;
+} node_event_t;
+
+typedef struct __cfg_q {
+ int cfg_version;
+ int cfg_oldversion;
+} config_event_t;
+
+typedef struct __user_q {
+ char u_name[128];
+ msgctx_t *u_ctx;
+ int u_request;
+ int u_arg1;
+ int u_arg2;
+ int u_target; /* Node ID */
+} 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 {
+ uint32_t m_magic;
+ uint32_t m_nodeid;
+ uint64_t m_master_time;
+ uint8_t m_reserved[112];
+} event_master_t;
+
+#define swab_event_master_t(ptr)
+{
+ swab32((ptr)->m_nodeid);
+ swab32((ptr)->m_magic);
+ swab64((ptr)->m_master_time);
+}
+
+/* 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, int nodeID, int state, int clean);
+void rg_event_q(char *name, uint32_t state, int owner, int last);
+void user_event_q(char *svc, int request, int arg1, int arg2,
+ int target, msgctx_t *ctx);
+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 */
+int 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, int *target_list, int target_list_len,
+ int *new_owner);
+int service_op_stop(char *svcName, int do_disable, int event_type);
+
+
+#endif
--- cluster/rgmanager/include/resgroup.h 2007/11/30 20:36:17 1.24
+++ cluster/rgmanager/include/resgroup.h 2007/11/30 21:36:28 1.25
@@ -67,9 +67,16 @@


#define RG_PORT 177
+
+/* Constants moved to src/clulib/constants.c */
+/* DO NOT EDIT */
#define RG_MAGIC 0x11398fed

#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

/* Requests */
@@ -130,6 +137,7 @@
#define RG_FLAG_FROZEN (1<<0) /** Resource frozen */

const char *rg_state_str(int val);
+int rg_state_str_to_id(const char *val);
const char *rg_flags_str(char *flags_string, size_t size, int val, char *separator);
const char *agent_op_str(int val);

@@ -140,7 +148,7 @@
int group_op(char *rgname, int op);
void rg_init(void);

-/* FOOM */
+/* Basic service operations */
int svc_start(char *svcName, int req);
int svc_stop(char *svcName, int error);
int svc_status(char *svcName);
@@ -157,7 +165,8 @@
int max, uint32_t target, int arg0, int arg1);

void send_response(int ret, int node, request_t *req);
-void send_ret(msgctx_t *ctx, char *name, int ret, int req);
+void send_ret(msgctx_t *ctx, char *name, int ret, int orig_request,
+ int new_owner);

/* 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 */
@@ -168,6 +177,7 @@
/* from rg_state.c */
int set_rg_state(char *name, rg_state_t *svcblk);
int get_rg_state(char *servicename, rg_state_t *svcblk);
+int get_rg_state_local(char *servicename, rg_state_t *svcblk);
uint32_t best_target_node(cluster_member_list_t *allowed, uint32_t owner,
char *rg_name, int lock);

@@ -192,6 +202,10 @@
int my_id(void);

/* Return codes */
+#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_EFROZEN -11 /* Service is frozen */
@@ -209,6 +223,7 @@
#define RG_YES 1
#define RG_NO 2

+
const char *rg_strerror(int val);


--- cluster/rgmanager/include/reslist.h 2007/11/30 20:36:17 1.24
+++ cluster/rgmanager/include/reslist.h 2007/11/30 21:36:28 1.25
@@ -202,6 +202,8 @@
void print_domains(fod_t **domains);
int node_should_start(int nodeid, cluster_member_list_t *membership,
char *rg_name, fod_t **domains);
+int node_domain_set(fod_t *domain, int **ret, int *retlen);
+int node_domain_set_safe(char *domainname, int **ret, int *retlen, int *flags);


/*
@@ -210,6 +212,7 @@
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.
--- cluster/rgmanager/include/restart_counter.h 2007/11/30 20:36:17 1.2
+++ cluster/rgmanager/include/restart_counter.h 2007/11/30 21:36:28 1.3
@@ -1,3 +1,22 @@
+/*
+ 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

--- cluster/rgmanager/include/rg_locks.h 2006/12/18 21:55:27 1.3
+++ cluster/rgmanager/include/rg_locks.h 2007/11/30 21:36:28 1.4
@@ -1,3 +1,20 @@
+/*
+ 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_LOCKS_H
#define __RG_LOCKS_H

--- cluster/rgmanager/include/rg_queue.h 2006/07/19 18:43:32 1.6
+++ cluster/rgmanager/include/rg_queue.h 2007/11/30 21:36:28 1.7
@@ -1,3 +1,20 @@
+/*
+ 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>
@@ -19,7 +36,7 @@
uint32_t rr_target; /** Target node */
uint32_t rr_arg0; /** Integer argument */
uint32_t rr_arg1; /** Integer argument */
- uint32_t rr_arg3; /** Integer argument */
+ uint32_t rr_arg2; /** Integer argument */
uint32_t rr_line; /** Line no */
msgctx_t * rr_resp_ctx; /** FD to send response */
char *rr_file; /** Who made req */
@@ -42,5 +59,7 @@
void rq_free(request_t *foo);

void forward_request(request_t *req);
+void forward_message(msgctx_t *ctx, void *msg, int nodeid);
+

#endif
/cvs/cluster/cluster/rgmanager/src/clulib/sets.c,v --> standard output
revision 1.1
--- cluster/rgmanager/src/clulib/sets.c
+++ - 2007-11-30 21:36:30.630539000 +0000
@@ -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
--- cluster/rgmanager/src/clulib/Makefile 2007/11/12 08:17:00 1.18
+++ cluster/rgmanager/src/clulib/Makefile 2007/11/30 21:36:28 1.19
@@ -19,7 +19,7 @@
OBJS1= clulog.o daemon_init.o signals.o msgsimple.o
gettid.o rg_strings.o message.o members.o fdops.o
lock.o cman.o vft.o msg_cluster.o msg_socket.o
- wrap_lock.o
+ wrap_lock.o sets.o

OBJS2= alloc.o

--- cluster/rgmanager/src/clulib/members.c 2006/09/27 16:28:41 1.4
+++ cluster/rgmanager/src/clulib/members.c 2007/11/30 21:36:28 1.5
@@ -233,6 +233,50 @@


int
+member_low_id(void)
+{
+ int x = 0, low = -1;
+
+ pthread_rwlock_wrlock(&memblock);
+ if (!membership) {
+ pthread_rwlock_unlock(&memblock);
+ return low;
+ }
+
+ for (x = 0; x < membership->cml_count; x++) {
+ if ((membership->cml_members[x].cn_member) &&
+ ((membership->cml_members[x].cn_nodeid < low) || (low == -1)))
+ low = membership->cml_members[x].cn_nodeid;
+ }
+ pthread_rwlock_unlock(&memblock);
+
+ return low;
+}
+
+
+int
+member_high_id(void)
+{
+ int x = 0, high = -1;
+
+ pthread_rwlock_wrlock(&memblock);
+ if (!membership) {
+ pthread_rwlock_unlock(&memblock);
+ return high;
+ }
+
+ for (x = 0; x < membership->cml_count; x++) {
+ if (membership->cml_members[x].cn_member &&
+ (membership->cml_members[x].cn_nodeid > high))
+ high = membership->cml_members[x].cn_nodeid;
+ }
+ pthread_rwlock_unlock(&memblock);
+
+ return high;
+}
+
+
+int
member_online(int nodeid)
{
int x = 0, ret = 0;
--- cluster/rgmanager/src/clulib/rg_strings.c 2007/07/31 18:00:25 1.10
+++ cluster/rgmanager/src/clulib/rg_strings.c 2007/11/30 21:36:28 1.11
@@ -26,6 +26,8 @@


const struct string_val rg_error_strings[] = {
+ { RG_EDOMAIN, "Service not runnable" },
+ { 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" },
@@ -147,6 +149,21 @@
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)
{
@@ -159,6 +176,14 @@
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_flags_str(char *flags_string, size_t size, int val, char *separator)
{
--- cluster/rgmanager/src/clulib/vft.c 2007/11/30 21:01:27 1.22
+++ cluster/rgmanager/src/clulib/vft.c 2007/11/30 21:36:28 1.23
@@ -1734,55 +1734,52 @@
}
msg_close(&ctx);
msg = (vf_msg_t *)gh;
- break;
- }
-
- if (x >= membership->cml_count)
- return VFR_ERROR;
-
- /* Uh oh */
- if (!msg || (msg == &rmsg)) {
- printf("VF: No valid message
");
- return VFR_ERROR;
- }
-
- swab_generic_msg_hdr(&(msg->vm_hdr));
- if (msg->vm_hdr.gh_command == VF_NACK) {
- free(msg);
- return VFR_NODATA;
- }

- if (msg->vm_hdr.gh_length < sizeof(vf_msg_t)) {
- fprintf(stderr, "VF: Short reply from %d
", x);
- free(msg);
- return VFR_ERROR;
- }
-
- if (msg->vm_hdr.gh_length > n) {
- fprintf(stderr,"VF: Size mismatch during decode (%d > %d)
",
- msg->vm_hdr.gh_length, n);
- free(msg);
- return VFR_ERROR;
- }
+ /* Uh oh */
+ if (!msg || (msg == &rmsg)) {
+ printf("VF: No valid message
");
+ return VFR_ERROR;
+ }
+ swab_generic_msg_hdr(&(msg->vm_hdr));
+ if (msg->vm_hdr.gh_command == VF_NACK) {
+ free(msg);
+ continue;
+ }
+ if (msg->vm_hdr.gh_length < sizeof(vf_msg_t)) {
+ fprintf(stderr, "VF: Short reply from %d
", x);
+ free(msg);
+ continue;
+ }
+ if (msg->vm_hdr.gh_length > n) {
+ fprintf(stderr,
+ "VF: Size mismatch during decode (%d > %d)
",
+ msg->vm_hdr.gh_length, n);
+ free(msg);
+ continue;
+ }

- swab_vf_msg_info_t(&(msg->vm_msg));
+ swab_vf_msg_info_t(&(msg->vm_msg));

- if (msg->vm_msg.vf_datalen != (n - sizeof(*msg))) {
- fprintf(stderr,"VF: Size mismatch during decode (
");
- free(msg);
- return VFR_ERROR;
- }
+ if (msg->vm_msg.vf_datalen != (n - sizeof(*msg))) {
+ fprintf(stderr,"VF: Size mismatch during decode (
");
+ free(msg);
+ continue;
+ }

- if (vf_set_current(keyid, msg->vm_msg.vf_view,
+ /* Ok... we've got data! */
+ if (vf_set_current(keyid, msg->vm_msg.vf_view,
msg->vm_msg.vf_data,
msg->vm_msg.vf_datalen) == VFR_ERROR) {
+ free(msg);
+ return VFR_ERROR;
+ }
+
free(msg);
- return VFR_ERROR;
- }

- free(msg);
+ return VFR_OK;
+ }

- return VFR_OK;
+ return VFR_NODATA;
}


/cvs/cluster/cluster/rgmanager/src/daemons/event_config.c,v --> standard output
revision 1.1
--- cluster/rgmanager/src/daemons/event_config.c
+++ - 2007-11-30 21:36:31.406600000 +0000
@@ -0,0 +1,541 @@
+/**
+ Copyright Red Hat, Inc. 2002-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
+ * CCS event parsing, based on failover domain parsing
+ */
+#include <string.h>
+#include <list.h>
+#include <clulog.h>
+#include <resgroup.h>
+#include <restart_counter.h>
+#include <reslist.h>
+#include <ccs.h>
+#include <pthread.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <members.h>
+#include <reslist.h>
+#include <ctype.h>
+#include <event.h>
+
+#define CONFIG_NODE_ID_TO_NAME
+ "/cluster/clusternodes/clusternode[@nodeid="%d"]/@name"
+#define CONFIG_NODE_NAME_TO_ID
+ "/cluster/clusternodes/clusternode[@name="%s"]/@nodeid"
+
+void deconstruct_events(event_table_t **);
+void print_event(event_t *ev);
+
+//#define DEBUG
+
+#ifdef DEBUG
+#define ENTER() clulog(LOG_DEBUG, "ENTER: %s
", __FUNCTION__)
+#define RETURN(val) {
+ clulog(LOG_DEBUG, "RETURN: %s line=%d value=%d
", __FUNCTION__,
+ __LINE__, (val));
+ return(val);
+}
+#else
+#define ENTER()
+#define RETURN(val) return(val)
+#endif
+
+#ifdef NO_CCS
+#define ccs_get(fd, query, ret) conf_get(query, ret)
+#endif
+
+/*
+ <events>
+ <event name="helpful_name_here" class="node"
+ node="nodeid|nodename" nodestate="up|down">
+ slang_script_stuff();
+ start_service();
+ </event>
+ </events>
+ */
+int
+event_match(event_t *pattern, event_t *actual)
+{
+ if (pattern->ev_type != EVENT_NONE &&
+ actual->ev_type != pattern->ev_type)
+ return 0;
+
+ /* If there's no event class specified, the rest is
+ irrelevant */
+ if (pattern->ev_type == EVENT_NONE)
+ return 1;
+
+ switch(pattern->ev_type) {
+ case EVENT_NODE:
+ if (pattern->ev.node.ne_nodeid >= 0 &&
+ actual->ev.node.ne_nodeid !=
+ pattern->ev.node.ne_nodeid) {
+ return 0;
+ }
+ if (pattern->ev.node.ne_local >= 0 &&
+ actual->ev.node.ne_local !=
+ pattern->ev.node.ne_local) {
+ return 0;
+ }
+ if (pattern->ev.node.ne_state >= 0 &&
+ actual->ev.node.ne_state !=
+ pattern->ev.node.ne_state) {
+ return 0;
+ }
+ if (pattern->ev.node.ne_clean >= 0 &&
+ actual->ev.node.ne_clean !=
+ pattern->ev.node.ne_clean) {
+ return 0;
+ }
+ return 1; /* All specified params match */
+ case EVENT_RG:
+ if (pattern->ev.group.rg_name[0] &&
+ strcasecmp(actual->ev.group.rg_name,
+ pattern->ev.group.rg_name)) {
+ return 0;
+ }
+ if (pattern->ev.group.rg_state != (uint32_t)-1 &&
+ actual->ev.group.rg_state !=
+ pattern->ev.group.rg_state) {
+ return 0;
+ }
+ if (pattern->ev.group.rg_owner >= 0 &&
+ actual->ev.group.rg_owner !=
+ pattern->ev.group.rg_owner) {
+ return 0;
+ }
+ return 1;
+ case EVENT_CONFIG:
+ if (pattern->ev.config.cfg_version >= 0 &&
+ actual->ev.config.cfg_version !=
+ pattern->ev.config.cfg_version) {
+ return 0;
+ }
+ if (pattern->ev.config.cfg_oldversion >= 0 &&
+ actual->ev.config.cfg_oldversion !=
+ pattern->ev.config.cfg_oldversion) {
+ return 0;
+ }
+ return 1;
+ case EVENT_USER:
+ if (pattern->ev.user.u_name[0] &&
+ strcasecmp(actual->ev.user.u_name,
+ pattern->ev.user.u_name)) {
+ return 0;
+ }
+ if (pattern->ev.user.u_request != 0 &&
+ actual->ev.user.u_request !=
+ pattern->ev.user.u_request) {
+ return 0;
+ }
+ if (pattern->ev.user.u_target != 0 &&
+ actual->ev.user.u_target !=
+ pattern->ev.user.u_target) {
+ return 0;
+ }
+ return 1;
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+
+char *
+ccs_node_id_to_name(int ccsfd, int nodeid)
+{
+ char xpath[256], *ret = 0;
+
+ snprintf(xpath, sizeof(xpath), CONFIG_NODE_ID_TO_NAME,
+ nodeid);
+ if (ccs_get(ccsfd, xpath, &ret) == 0)
+ return ret;
+ return NULL;
+}
+
+
+int
+ccs_node_name_to_id(int ccsfd, char *name)
+{
+ char xpath[256], *ret = 0;
+ int rv = 0;
+
+ snprintf(xpath, sizeof(xpath), CONFIG_NODE_NAME_TO_ID,
+ name);
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ rv = atoi(ret);
+ free(ret);
+ return rv;
+ }
+ return 0;
+}
+
+
+static void
+deconstruct_event(event_t *ev)
+{
+ if (ev->ev_script)
+ free(ev->ev_script);
+ if (ev->ev_name)
+ free(ev->ev_name);
+ free(ev);
+}
+
+
+static int
+get_node_event(int ccsfd, char *base, event_t *ev)
+{
+ char xpath[256], *ret = NULL;
+
+ /* Clear out the possibilitiies */
+ ev->ev.node.ne_nodeid = -1;
+ ev->ev.node.ne_local = -1;
+ ev->ev.node.ne_state = -1;
+ ev->ev.node.ne_clean = -1;
+
+ snprintf(xpath, sizeof(xpath), "%s/@node_id", base);
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ ev->ev.node.ne_nodeid = atoi(ret);
+ free(ret);
+ if (ev->ev.node.ne_nodeid <= 0)
+ return -1;
+ } else {
+ /* See if there's a node name */
+ snprintf(xpath, sizeof(xpath), "%s/@node", base);
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ ev->ev.node.ne_nodeid =
+ ccs_node_name_to_id(ccsfd, ret);
+ free(ret);
+ if (ev->ev.node.ne_nodeid <= 0)
+ return -1;
+ }
+ }
+
+ snprintf(xpath, sizeof(xpath), "%s/@node_state", base);
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ if (!strcasecmp(ret, "up")) {
+ ev->ev.node.ne_state = 1;
+ } else if (!strcasecmp(ret, "down")) {
+ ev->ev.node.ne_state = 0;
+ } else {
+ ev->ev.node.ne_state = !!atoi(ret);
+ }
+ free(ret);
+ }
+
+ snprintf(xpath, sizeof(xpath), "%s/@node_clean", base);
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ ev->ev.node.ne_clean = !!atoi(ret);
+ free(ret);
+ }
+
+ snprintf(xpath, sizeof(xpath), "%s/@node_local", base);
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ ev->ev.node.ne_local = !!atoi(ret);
+ free(ret);
+ }
+
+ return 0;
+}
+
+
+static int
+get_rg_event(int ccsfd, char *base, event_t *ev)
+{
+ char xpath[256], *ret = NULL;
+
+ /* Clear out the possibilitiies */
+ ev->ev.group.rg_name[0] = 0;
+ ev->ev.group.rg_state = (uint32_t)-1;
+ ev->ev.group.rg_owner = -1;
+
+ snprintf(xpath, sizeof(xpath), "%s/@service", base);
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ strncpy(ev->ev.group.rg_name, ret,
+ sizeof(ev->ev.group.rg_name));
+ free(ret);
+ if (!strlen(ev->ev.group.rg_name)) {
+ return -1;
+ }
+ }
+
+ snprintf(xpath, sizeof(xpath), "%s/@service_state", base);
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ if (!isdigit(ret[0])) {
+ ev->ev.group.rg_state =
+ rg_state_str_to_id(ret);
+ } else {
+ ev->ev.group.rg_state = atoi(ret);
+ }
+ free(ret);
+ }
+
+ snprintf(xpath, sizeof(xpath), "%s/@service_owner", base);
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ if (!isdigit(ret[0])) {
+ ev->ev.group.rg_owner =
+ ccs_node_name_to_id(ccsfd, ret);
+ } else {
+ ev->ev.group.rg_owner = !!atoi(ret);
+ }
+ free(ret);
+ }
+
+ return 0;
+}
+
+
+static int
+get_config_event(int __attribute__((unused)) ccsfd,
+ char __attribute__((unused)) *base,
+ event_t __attribute__((unused)) *ev)
+{
+ errno = ENOSYS;
+ return -1;
+}
+
+
+static event_t *
+get_event(int ccsfd, char *base, int idx, int *_done)
+{
+ event_t *ev;
+ char xpath[256];
+ char *ret = NULL;
+
+ *_done = 0;
+ snprintf(xpath, sizeof(xpath), "%s/event[%d]/@name",
+ base, idx);
+ if (ccs_get(ccsfd, xpath, &ret) != 0) {
+ *_done = 1;
+ return NULL;
+ }
+
+ ev = malloc(sizeof(*ev));
+ if (!ev)
+ return NULL;
+ memset(ev, 0, sizeof(*ev));
+ ev->ev_name = ret;
+
+ /* Get the script file / inline from config */
+ ret = NULL;
+ snprintf(xpath, sizeof(xpath), "%s/event[%d]/@file",
+ base, idx);
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ ev->ev_script_file = ret;
+ } else {
+ snprintf(xpath, sizeof(xpath), "%s/event[%d]",
+ base, idx);
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ ev->ev_script = ret;
+ } else {
+ goto out_fail;
+ }
+ }
+
+ /* Get the priority ordering (must be nonzero) */
+ ev->ev_prio = 99;
+ ret = NULL;
+ snprintf(xpath, sizeof(xpath), "%s/event[%d]/@priority",
+ base, idx);
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ ev->ev_prio = atoi(ret);
+ if (ev->ev_prio <= 0 || ev->ev_prio > EVENT_PRIO_COUNT) {
+ clulog(LOG_ERR,
+ "event %s: priority %s invalid
",
+ ev->ev_name, ret);
+ goto out_fail;
+ }
+ free(ret);
+ }
+
+ /* Get the event class */
+ snprintf(xpath, sizeof(xpath), "%s/event[%d]/@class",
+ base, idx);
+ ret = NULL;
+ if (ccs_get(ccsfd, xpath, &ret) == 0) {
+ snprintf(xpath, sizeof(xpath), "%s/event[%d]",
+ base, idx);
+ if (!strcasecmp(ret, "node")) {
+ ev->ev_type = EVENT_NODE;
+ if (get_node_event(ccsfd, xpath, ev) < 0)
+ goto out_fail;
+ } else if (!strcasecmp(ret, "service") ||
+ !strcasecmp(ret, "resource") ||
+ !strcasecmp(ret, "rg") ) {
+ ev->ev_type = EVENT_RG;
+ if (get_rg_event(ccsfd, xpath, ev) < 0)
+ goto out_fail;
+ } else if (!strcasecmp(ret, "config") ||
+ !strcasecmp(ret, "reconfig")) {
+ ev->ev_type = EVENT_CONFIG;
+ if (get_config_event(ccsfd, xpath, ev) < 0)
+ goto out_fail;
+ } else {
+ clulog(LOG_ERR,
+ "event %s: class %s unrecognized
",
+ ev->ev_name, ret);
+ goto out_fail;
+ }
+
+ free(ret);
+ ret = NULL;
+ }
+
+ return ev;
+out_fail:
+ if (ret)
+ free(ret);
+ deconstruct_event(ev);
+ return NULL;
+}
+
+
+static event_t *
+get_default_event(void)
+{
+ event_t *ev;
+ char xpath[1024];
+
+ ev = malloc(sizeof(*ev));
+ if (!ev)
+ return NULL;
+ memset(ev, 0, sizeof(*ev));
+ ev->ev_name = strdup("Default");
+
+ /* Get the script file / inline from config */
+ snprintf(xpath, sizeof(xpath), "%s/default_event_script.sl",
+ RESOURCE_ROOTDIR);
+
+ ev->ev_prio = 100;
+ ev->ev_type = EVENT_NONE;
+ ev->ev_script_file = strdup(xpath);
+ if (!ev->ev_script_file || ! ev->ev_name) {
+ deconstruct_event(ev);
+ return NULL;
+ }
+
+ return ev;
+}
+
+
+/**
+ * similar API to failover domain
+ */
+int
+construct_events(int ccsfd, event_table_t **events)
+{
+ char xpath[256];
+ event_t *ev;
+ int x = 1, done = 0;
+
+ /* Allocate the event list table */
+ *events = malloc(sizeof(event_table_t) +
+ sizeof(event_t) * (EVENT_PRIO_COUNT+1));
+ if (!*events)
+ return -1;
+ memset(*events, 0, sizeof(event_table_t) +
+ sizeof(event_t) * (EVENT_PRIO_COUNT+1));
+ (*events)->max_prio = EVENT_PRIO_COUNT;
+
+ snprintf(xpath, sizeof(xpath),
+ RESOURCE_TREE_ROOT "/events");
+
+ do {
+ ev = get_event(ccsfd, xpath, x++, &done);
+ if (ev)
+ list_insert(&((*events)->entries[ev->ev_prio]), ev);
+ } while (!done);
+
+ ev = get_default_event();
+ if (ev)
+ list_insert(&((*events)->entries[ev->ev_prio]), ev);
+
+ return 0;
+}
+
+
+void
+print_event(event_t *ev)
+{
+ printf(" Name: %s
", ev->ev_name);
+
+ switch(ev->ev_type) {
+ case EVENT_NODE:
+ printf(" Node %d State %d
", ev->ev.node.ne_nodeid,
+ ev->ev.node.ne_state);
+ break;
+ case EVENT_RG:
+ printf(" RG %s State %s
", ev->ev.group.rg_name,
+ rg_state_str(ev->ev.group.rg_state));
+ break;
+ case EVENT_CONFIG:
+ printf(" Config change - unsupported
");
+ break;
+ default:
+ printf(" (Any event)
");
+ break;
+ }
+
+ if (ev->ev_script) {
+ printf(" Inline script.
");
+ } else {
+ printf(" File: %s
", ev->ev_script_file);
+ }
+}
+
+
+void
+print_events(event_table_t *events)
+{
+ int x, y;
+ event_t *ev;
+
+ for (x = 0; x <= events->max_prio; x++) {
+ if (!events->entries[x])
+ continue;
+ printf("Event Priority Level %d:
", x);
+ list_for(&(events->entries[x]), ev, y) {
+ print_event(ev);
+ }
+ }
+}
+
+
+void
+deconstruct_events(event_table_t **eventsp)
+{
+ int x;
+ event_table_t *events = *eventsp;
+ event_t *ev = NULL;
+
+ if (!events)
+ return;
+
+ for (x = 0; x <= events->max_prio; x++) {
+ while ((ev = (events->entries[x]))) {
+ list_remove(&(events->entries[x]), ev);
+ deconstruct_event(ev);
+ }
+ }
+
+ free(events);
+ *eventsp = NULL;
+}
+
+
/cvs/cluster/cluster/rgmanager/src/daemons/service_op.c,v --> standard output
revision 1.1
--- cluster/rgmanager/src/daemons/service_op.c
+++ - 2007-11-30 21:36:31.603381000 +0000
@@ -0,0 +1,189 @@
+/*
+ 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.
+*/
+#include <assert.h>
+#include <platform.h>
+#include <message.h>
+#include <members.h>
+#include <stdio.h>
+#include <string.h>
+#include <resgroup.h>
+#include <clulog.h>
+#include <lock.h>
+#include <rg_locks.h>
+#include <ccs.h>
+#include <rg_queue.h>
+#include <msgsimple.h>
+#include <res-ocf.h>
+#include <event.h>
+
+
+/*
+ * Send a message to the target node to start the service.
+ */
+int svc_start_remote(char *svcName, int request, uint32_t target);
+void svc_report_failure(char *);
+int get_service_state_internal(char *svcName, rg_state_t *svcStatus);
+
+
+/**
+ *
+ */
+int
+service_op_start(char *svcName,
+ int *target_list,
+ int target_list_len,
+ int *new_owner)
+{
+ int target;
+ int ret, x;
+ rg_state_t svcStatus;
+
+ if (get_service_state_internal(svcName, &svcStatus) < 0) {
+ return RG_EFAIL;
+ }
+
+ if (svcStatus.rs_state == RG_STATE_FAILED ||
+ svcStatus.rs_state == RG_STATE_UNINITIALIZED)
+ return RG_EINVAL;
+
+ for (x = 0; x < target_list_len; x++) {
+
+ target = target_list[x];
+ ret = svc_start_remote(svcName, RG_START_REMOTE,
+ target);
+ switch (ret) {
+ case RG_ERUN:
+ /* Someone stole the service while we were
+ trying to start it */
+ get_rg_state_local(svcName, &svcStatus);
+ if (new_owner)
+ *new_owner = svcStatus.rs_owner;
+ return 0;
+ case RG_EDEPEND:
+ case RG_EFAIL:
+ continue;
+ case RG_EABORT:
+ svc_report_failure(svcName);
+ return RG_EFAIL;
+ default:
+ /* deliberate fallthrough */
+ clulog(LOG_ERR,
+ "#61: Invalid reply from member %d during"
+ " start operation!
", target);
+ case RG_NO:
+ /* state uncertain */
+ clulog(LOG_CRIT, "State Uncertain: svc:%s "
+ "nid:%d req:%s ret:%d
", svcName,
+ target, rg_req_str(RG_START_REMOTE), ret);
+ return 0;
+ case 0:
+ if (new_owner)
+ *new_owner = target;
+ clulog(LOG_NOTICE, "Service %s is now running "
+ "on member %d
", svcName, (int)target);
+ return 0;
+ }
+ }
+
+ return RG_EFAIL;
+}
+
+
+int
+service_op_stop(char *svcName, int do_disable, int event_type)
+{
+ SmMessageSt msg;
+ int msg_ret;
+ msgctx_t ctx;
+ rg_state_t svcStatus;
+ int msgtarget = my_id();
+
+ /* Build the message header */
+ msg.sm_hdr.gh_magic = GENERIC_HDR_MAGIC;
+ msg.sm_hdr.gh_command = RG_ACTION_REQUEST;
+ msg.sm_hdr.gh_arg1 = RG_ACTION_MASTER;
+ msg.sm_hdr.gh_length = sizeof (SmMessageSt);
+
+ msg.sm_data.d_action = ((!do_disable) ? RG_STOP:RG_DISABLE);
+
+ if (msg.sm_data.d_action == RG_STOP && event_type == EVENT_USER)
+ msg.sm_data.d_action = RG_STOP_USER;
+
+ strncpy(msg.sm_data.d_svcName, svcName,
+ sizeof(msg.sm_data.d_svcName));
+ msg.sm_data.d_ret = 0;
+ msg.sm_data.d_svcOwner = 0;
+
+ /* Open a connection to the local node - it will decide what to
+ do in this case. XXX inefficient; should queue requests
+ locally and immediately forward requests otherwise */
+
+ if (get_service_state_internal(svcName, &svcStatus) < 0)
+ return RG_EFAIL;
+ if (svcStatus.rs_owner > 0)
+ msgtarget = svcStatus.rs_owner;
+
+ if (msg_open(MSG_CLUSTER, msgtarget, RG_PORT, &ctx, 2)< 0) {
+ clulog(LOG_ERR,
+ "#58: Failed opening connection to member #%d
",
+ my_id());
+ return -1;
+ }
+
+ /* Encode */
+ swab_SmMessageSt(&msg);
+
+ /* Send stop message to the other node */
+ if (msg_send(&ctx, &msg, sizeof (SmMessageSt)) <
+ (int)sizeof (SmMessageSt)) {
+ clulog(LOG_ERR, "Failed to send complete message
");
+ msg_close(&ctx);
+ return -1;
+ }
+
+ /* Check the response */
+ do {
+ msg_ret = msg_receive(&ctx, &msg,
+ sizeof (SmMessageSt), 10);
+ if ((msg_ret == -1 && errno != ETIMEDOUT) ||
+ (msg_ret >= 0)) {
+ break;
+ }
+ } while(1);
+
+ if (msg_ret != sizeof (SmMessageSt)) {
+ clulog(LOG_WARNING, "Strange response size: %d vs %d
",
+ msg_ret, (int)sizeof(SmMessageSt));
+ return 0; /* XXX really UNKNOWN */
+ }
+
+ /* Got a valid response from other node. */
+ msg_close(&ctx);
+
+ /* Decode */
+ swab_SmMessageSt(&msg);
+
+ return msg.sm_data.d_ret;
+}
+
+
+/*
+ TODO
+ service_op_migrate()
+ */
+
/cvs/cluster/cluster/rgmanager/src/daemons/slang_event.c,v --> standard output
revision 1.1
--- cluster/rgmanager/src/daemons/slang_event.c
+++ - 2007-11-30 21:36:31.687551000 +0000
@@ -0,0 +1,1228 @@
+/*
+ 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 S/Lang event handling & intrinsic functions + vars
+ */
+#include <platform.h>
+#include <resgroup.h>
+#include <list.h>
+#include <restart_counter.h>
+#include <reslist.h>
+#include <clulog.h>
+#include <members.h>
+#include <assert.h>
+#include <event.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <slang/slang.h>
+#include <sys/syslog.h>
+#include <malloc.h>
+#include <clulog.h>
+#include <sets.h>
+
+static int __sl_initialized = 0;
+
+static char **_service_list = NULL;
+static int _service_list_len = 0;
+
+char **get_service_names(int *len); /* from groups.c */
+int get_service_property(char *rg_name, char *prop, char *buf, size_t buflen);
+void push_int_array(int *stuff, int len);
+
+
+/* ================================================== ==============
+ * Node states
+ * ================================================== ============== */
+static const int
+ _ns_online = 1,
+ _ns_offline = 0;
+
+/* ================================================== ==============
+ * Event information
+ * ================================================== ============== */
+static const int
+ _ev_none = EVENT_NONE,
+ _ev_node = EVENT_NODE,
+ _ev_service = EVENT_RG,
+ _ev_config = EVENT_CONFIG,
+ _ev_user = EVENT_USER;
+
+static const int
+ _rg_fail = RG_EFAIL,
+ _rg_success = RG_ESUCCESS,
+ _rg_edomain = RG_EDOMAIN,
+ _rg_edepend = RG_EDEPEND,
+ _rg_eabort = RG_EABORT,
+ _rg_einval = RG_EINVAL,
+ _rg_erun = RG_ERUN;
+
+static int
+ _stop_processing = 0,
+ _my_node_id = 0,
+ _node_state = 0,
+ _node_id = 0,
+ _node_clean = 0,
+ _service_owner = 0,
+ _service_last_owner = 0,
+ _user_request = 0,
+ _user_arg1 = 0,
+ _user_arg2 = 0,
+ _user_return = 0,
+ _rg_err = 0,
+ _event_type = 0;
+
+static char
+ *_node_name = NULL,
+ *_service_name = NULL,
+ *_service_state = NULL,
+ *_rg_err_str = "No Error";
+
+static int
+ _user_enable = RG_ENABLE,
+ _user_disable = RG_DISABLE,
+ _user_stop = RG_STOP_USER, /* From clusvcadm */
+ _user_relo = RG_RELOCATE,
+ _user_restart = RG_RESTART,
+ _user_migrate = RG_MIGRATE;
+
+
+SLang_Intrin_Var_Type rgmanager_vars[] =
+{
+ /* Log levels (constants) */
+
+ /* Node state information */
+ MAKE_VARIABLE("NODE_ONLINE", &_ns_online, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("NODE_OFFLINE", &_ns_offline, SLANG_INT_TYPE, 1),
+
+ /* Node event information */
+ MAKE_VARIABLE("node_self", &_my_node_id, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("node_state", &_node_state, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("node_id", &_node_id, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("node_name", &_node_name, SLANG_STRING_TYPE,1),
+ MAKE_VARIABLE("node_clean", &_node_clean, SLANG_INT_TYPE, 1),
+
+ /* Service event information */
+ MAKE_VARIABLE("service_name", &_service_name, SLANG_STRING_TYPE,1),
+ MAKE_VARIABLE("service_state", &_service_state,SLANG_STRING_TYPE,1),
+ MAKE_VARIABLE("service_owner", &_service_owner,SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("service_last_owner", &_service_last_owner,
+ SLANG_INT_TYPE, 1),
+
+ /* User event information */
+ MAKE_VARIABLE("user_request", &_user_request, SLANG_INT_TYPE,1),
+ MAKE_VARIABLE("user_arg1", &_user_arg1, SLANG_INT_TYPE,1),
+ MAKE_VARIABLE("user_arg2", &_user_arg2, SLANG_INT_TYPE,1),
+ MAKE_VARIABLE("user_service", &_service_name, SLANG_STRING_TYPE,1),
+ MAKE_VARIABLE("user_target", &_service_owner,SLANG_INT_TYPE, 1),
+ /* Return code to user requests; i.e. clusvcadm */
+ MAKE_VARIABLE("user_return", &_user_return, SLANG_INT_TYPE, 0),
+
+ /* General event information */
+ MAKE_VARIABLE("event_type", &_event_type, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("EVENT_NONE", &_ev_none, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("EVENT_NODE", &_ev_node, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("EVENT_CONFIG", &_ev_config, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("EVENT_SERVICE", &_ev_service, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("EVENT_USER", &_ev_user, SLANG_INT_TYPE, 1),
+
+ /* User request constants */
+ MAKE_VARIABLE("USER_ENABLE", &_user_enable, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("USER_DISABLE", &_user_disable, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("USER_STOP", &_user_stop, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("USER_RELOCATE", &_user_relo, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("USER_RESTART", &_user_restart, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("USER_MIGRATE", &_user_migrate, SLANG_INT_TYPE, 1),
+
+ /* Errors */
+ MAKE_VARIABLE("rg_error", &_rg_err, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("rg_error_string",&_rg_err_str, SLANG_STRING_TYPE,1),
+
+ /* From constants.c */
+ MAKE_VARIABLE("FAIL", &_rg_fail, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("SUCCESS", &_rg_success, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("ERR_ABORT", &_rg_eabort, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("ERR_INVALID", &_rg_einval, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("ERR_DEPEND", &_rg_edepend, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("ERR_DOMAIN", &_rg_edomain, SLANG_INT_TYPE, 1),
+ MAKE_VARIABLE("ERR_RUNNING", &_rg_erun, SLANG_INT_TYPE, 1),
+
+ SLANG_END_INTRIN_VAR_TABLE
+};
+
+
+#define rg_error(errortype)
 

Thread Tools




All times are GMT. The time now is 12:32 AM.

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