BACK
This document describes the various components provided by the Cluster
Infrastructure (CI) package.


ICS CHANNELS (high-level and low-level)
========================================
An ICS channel is basically a TCP/IP connection which is established with
another node for intra-cluster communication.

Channels are the underlying transport through which cluster service 
messages/RPCS are sent.  Therefore, each cluster service needs to map to a 
specific ICS channel.  It is possible to group several cluster services 
together as subservices sharing the same ICS channel (Read more about 
subservices below).

Different ICS channels are created for purposes of flow control (also
known as throttling).  When the system is under high load, channels will be 
throttled according to their per-channel throttling variables.

Throttling does not occur on certain "priority" ICS channels.  These
priority channels exist to prevent deadlock situations.  Often times an
RPC message will be sent from Node A to Node B.  The server-side routine
on Node B will in turn send an RPC/message back to Node A.  However, Node
A's ICS channel could become throttled at this point.  This is unfortunate 
because the RPC/message sent by Node B would help free resources on Node A
but it cannot handle the message due to throttling.  To avoid this kind of
deadlock, the ICS code will automatically raise the priority of an outgoing
RPC/message if it is being sent within the server-side routine of an 
incoming RPC.

[ NOTE: In the current code version, ICS throttling is not fully implemented. ]

An ics_prio data member has been added to the task_struct structure to 
keep track of the current ICS priority.  A priority of 0 will
use the normal ICS channel mapped to that specific cluster service.  Any
priority above 0 will use one of the 4 ICS priority channels defined.

There are 2 ICS channels used for sending RPC replies.  The ics_reply_chan
is used for sending replies to non-priority RPC messages, while the 
ics_reply_prio_chan is used to reply to all high priority RPCs.  Like the
priority ICS channels, neither of these reply channels is ever throttled.

The current code defines a maximum of 12 ICS channels in a cluster.  This
can be increased by tuning ICS_MAX_CHANNELS in the header file ics.h.
The current CI code sets up 8 different ICS channels.  There are 4 priority 
channels and 2 low-level reply channels, as mentioned above.  In addition, 
there are 2 channels defined to support cluster services.  One of these 
supports the CLMS, cluster API, and ICS forwarding services, and the other 
is used specifically for probing the CLMS master on bootup.  To be precise,
the ics_clms_probe_chan is a transient channel that gets setup and torn down 
per probe sent. These probes are sent by coming-up nodes to query who the 
CLMS master is.

For more information on how to add your own ICS channel, please read the 
enhancing.txt document.



CLUSTER SERVICES
=================
A cluster service consists of "service routines" that are run on each node 
in the cluster and "service messages" that are sent amongst cluster nodes for
communication.

The current CI code defines 3 cluster services.  These include the CLMS 
service, the cluster API service, and the ICS signal forwarding service.
Each cluster service will need to send messages across the cluster and 
therefore needs to communicate over an ICS channel.

The 3 cluster services are multiplexed on top of one ICS channel, 
ics_clms_chan.  As mentioned above, it is possible for several cluster 
services to share one ICS channel and they will be flow-controlled as one 
unit.  There is a direct mapping from a cluster service to an ICS 
channel+subservice. Thus, every cluster service is designated to send messages 
over a specific ICS channel and it has a subservice number to distinguish its 
messages from other cluster service messages being sent on the same channel. 
The macro used to do this mapping is:

#define ICS_NSC_SVC(_chan,_subservice)  ((_chan << 16) + _subservice)

You can also determine the ICS service channel/subservice number given
the cluster service using these macros:

#define ICS_CHAN(_cluster_svc)          ((_cluster_svc) >> 16)
#define ICS_SSVC(_cluster_svc)          ((_clustersvc) & ((1 << 16) - 1))

There is a limit of 6 subservices per ICS service channel, set by 
ICS_NUM_SUBSERVICES in the header file ics.h.  Given that there are
6 ICS channels that can be used for regular cluster services 
(12 - 4 priority - 2 reply channels), this puts a limit of 36 cluster services 
(6 ICS service channels * 6 subservices/channel) that can be defined in a 
cluster.

Each cluster service needs to register with ICS so that it can callback the
stub routines.  ICS is also informed of the min/max number of available server
handles that should be maintained to handle incoming messages on this channel.

Icsgen is used to generate client/server stubs for the cluster service 
messages.  The stubs will insert the cluster service number in the ICS 
message headers.  Icsgen also generates a routine which registers the cluster
service with ICS for you.

Please read the ICSGEN document for more information.



CLMS SUBSYSTEMS
================
Cluster services may need to run cleanup or initialization code when nodes 
come up or go down in the cluster. This is done by registering a CLMS 
subsystem.  CLMS subsystems perform callbacks for a cluster service during 
cluster NODEUP and NODEDOWN events.

Each CLMS subsystem calls register_clms_subsys() to register itself with CLMS.
This registration call takes in the name of the CLMS subsystem, function 
pointers to the NODEUP and NODEDOWN callback routines, and the priority band 
of the subsystem.  During NODEUP/NODEDOWN events the subsystem
callbacks are performed (on each surviving cluster node) in order of priority 
band.  Subsystems within the same priority band are called in the order they
were registered with CLMS.  The CI code defines a maximum of 15 CLMS subystems
in a cluster.  This is can be tuned by modifying CLMS_MAX_SUBSYSTEMS in the
header file clms.h.

For more information on adding a subsystem to CLMS, please read the
enhancing.txt document.



CLMS KEY SERVICES
==================
CLMS key services are created for cluster services that need to be centralized.
A key service is designated to run on one node within the cluster at
any point in time. Cluster nodes specify in their boot entries whether or
not they are able to serve as key service nodes for a particular key
service.

Each key service registers a failover routine with CLMS by calling
clms_register_key_service(). When the node running the key service goes
down, CLMS will select another node to take over the key service and run
the registered failover callbacks on that new node. If the failover
key service node needs to pull data from the surviving nodes in the cluster,
it can do so if the key service has registered a pull_data routine. Once
the pulled data has been gathered, it runs a failover_data routine to
process this data. Finally, the key service is set to ready and the
whole cluster is notified of this new key service node.

Key services can be defined as either critical or non-critical. A critical
key service will delay the forming of a cluster until CLMS has designated a
key service node for it. Similarly, when a node serving a critical key service
goes does, the cluster will panic if CLMS cannot find a failover node for
that key service.

For more information on adding a key service to CLMS, please read the
enhancing.txt document.