This chapter describes how to use the TruCluster Production Server information services to obtain information about cluster members and services. It includes the following:
An overview of the TruCluster Production Server information services (Section 2.1).
Examples that show how to use the TruCluster Production Server information services (Section 2.2).
The TruCluster Production Server information services exist primarily to provide
an infrastructure for the cluster monitoring and administration utilities
(such as
cnxshow
and
drd_ivp) provided
with the Production Server product.
Other applications can use them as well.
Table 2-1
lists the functions provided by the TruCluster Production Server
information services.
These functions are available in the
libcnx
library for applications.
| Function | Description |
clu_get_ase_drdsvcs_byname |
Obtains the distributed raw disk (DRD) services list from the specified cluster node |
clu_get_ase_enabled |
Determines whether or not availability software is enabled on a specified cluster node |
clu_get_ase_id_byname |
Obtains the
ASE_ID
of
the specified cluster node |
clu_get_ase_nodes_byname |
Obtains the available server environment (ASE) member list from the specified cluster node |
clu_get_aseinfo_byname |
Obtains ASE-specific information from the specified cluster member system |
clu_get_cluster |
Obtains a description of a cluster and its member nodes |
clu_get_cluster_net |
Obtains the name of the cluster interconnect interface on the local node |
clu_get_cnxdirector |
Obtains the name of the node that is running
the connection manager director daemon (cnxmgrd) |
clu_get_nodebyname |
Obtains information about a named cluster node |
clu_get_nodebycsid |
Obtains information about the cluster node identified by the specified cluster ID (CSID) |
clu_get_qdisk |
Obtains information about each tie-breaker disk configured in the cluster |
The following examples show the use of the TruCluster Production Server information services.
The
cluinfo.c
program, listed in
Example 2-1
and available from the
/usr/examples/cluster
directory,
calls the
clu_get_cluster
and
clu_get_qdisk
functions to obtain information about the cluster configuration and the names
and status of the member systems.
It displays output similar to the following:
% cluinfo
-----------------------------------------------
Cluster summary
-----------------------------------------------
The director is : canarymc
suspended : no
Virtual hub is present
disks defined : 1
disks required: 1
Disks names:
/dev/rrz9a
The members are:
cluster node name : canarymc
host name : canary.sun.ra.com
node state is : clu_mem_member
incarnation : ccaf0
cluster system id : 0001,0001
cluster node name : cheatmc
host name : cheat.sun.ra.com
node state is : clu_mem_member
incarnation : d1730
cluster system id : 0001,0002
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/cluster_defs.h>
/* cluinfo.c
*
* A simple program to collect information about the cluster.
*
*/
/* Makefile
* cluinfo : cluinfo.c
* cc -o cluinfo cluinfo.c -lcnx
* chmod 555 cluinfo
* clean :
* -rm cluinfo
*/
/* Translate a Boolean value to yes or no */
#define xlate_bool(c)((c)? str_yes : str_no)
char str_yes[] = "yes";
char str_no[] = "no";
/* Buffers to receive the requested data */
clu_node_t nodebuf[MAX_CLUSTER_NODES];
clu_cluster_t clubuf;
clu_qdisk_t dbuf;
/* Format membership state into a readable string. */
char *
xlate_mbr_state(clu_mem_state_t m)
{
#define NUM_MBR_STATES 5
static char *unkn = "unknown_state";
static char *mbr[NUM_MBR_STATES] = {
"clu_mem_invalid",
"clu_mem_unknown",
"clu_mem_new",
"clu_mem_member",
"clu_mem_removed",
};
if (m > NUM_MBR_STATES - 1)
return unkn;
else
return mbr[m];
}
main(int arc, char **argv)
{
int clustatus, dskstatus;
/* Collect information about the cluster and its nodes */
clustatus = clu_get_cluster(&clubuf, nodebuf, MAX_CLUSTER_NODES);
/* Collect information about tie-breaker disks */
dskstatus = clu_get_qdisk(&dbuf);
if (clustatus == CLU_SUCCESS)
{
int i;
clu_node_t *p, *e;
/* Display the cluster summary */
(void) printf("-------------------------------------------\n");
(void) printf(" Cluster summary\n");
(void) printf("-------------------------------------------\n\n");
(void) printf("The director is : %s\n", clubuf.curr_direct_name);
(void) printf(" suspended : %s\n\n", xlate_bool(clubuf.suspended));
/* Display disk information */
if (dskstatus == CLU_SUCCESS)
{
/* Display disk information if there is a virtual hub present */
if (dbuf.have_vhub)
{
(void) printf("Virtual hub is present\n");
(void) printf(" disks defined : %d\n",
dbuf.num_qdisk_entries);
(void) printf(" disks required: %d\n",
dbuf.num_qdisk_access_rqd);
(void) printf(" Disks names:\n");
for (i = 0; i < MAX_QDSKS; i++)
{
if (dbuf.qdisk_vec[i].qdisk_name[0] != ' ')
(void) printf(" %s\n", dbuf.qdisk_vec[i].qdisk_name);
}
}
else
{
(void) printf("Virtual hub is not present.\n");
(void) printf(" Tie-breaker disks are not required.\n");
}
/* Display the membership list */
(void) printf("\nThe members are:\n\n");
for (p = nodebuf, e = &nodebuf[MAX_CLUSTER_NODES]; p < e; p++)
{
if (p->clu_node_name[0] != ' ')
{
/* Information about a single node */
(void) printf(" cluster node name : %s\n",
p->clu_node_name);
(void) printf(" host name : %s\n",
p->clu_hostname);
(void) printf(" node state is : %s\n",
xlate_mbr_state(p->clu_node_state));
(void) printf(" incarnation : %lx\n",
p->clu_node_incarnation);
(void) printf(" cluster system id : %04x,%04x\n",
CLU_CSID_SEQN(p->clu_node_csid),
CLU_CSID_IDX(p->clu_node_csid));
(void) printf("\n\n");
}
}
}
}
return 0;
}
The
cludo.c
program, listed in
Example 2-2
and available from the
/usr/examples/cluster
directory,
calls the
clu_get_cluster,
clu_get_nodebyname,
clu_get_ase_enabled,
clu_get_ase_id_byname, and
clu_get_ase_nodes_byname
functions to obtain
information about individual cluster member systems.
It displays output similar
to the following:
% cludo Contacting mcclu17 to collect the following cluster node name : mcclu17 host name : clu17.sun.ra.com ase enabled : no ase information not available Contacting mcclu5 to collect the following cluster node name : mcclu5 host name : clu5.sun.ra.com ase enabled : yes ase id : 5 ase nodes : mcclu5 mcclu8 Contacting mcclu8 to collect the following cluster node name : mcclu8 host name : clu8.sun.ra.com ase enabled : yes ase id : 5 ase nodes : mcclu5 mcclu8
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/cluster_defs.h>
/*
* cludo.c
*
* Determine membership and collect information from each node.
*
*/
/*
* cc -o cludo cludo.c -lcnx
*/
/* Translate a Boolean value to yes or no */
#define xlate_bool(c)((c)? str_yes : str_no)
char str_yes[] = "yes";
char str_no[] = "no";
/* Buffers to receive the requested data */
clu_node_t nodebuf[MAX_CLUSTER_NODES];
clu_cluster_t clubuf;
main(int arc, char **argv)
{
int clustatus;
clu_node_t *p, *e;
/*
* Collect information about the cluster and its nodes. This list will
* be used to communicate with each member node.
*/
clustatus = clu_get_cluster(&clubuf, nodebuf, MAX_CLUSTER_NODES);
if (clustatus != CLU_SUCCESS) {
printf("Error obtaining cluster information\n");
exit(1);
}
/*
* Contact each member node and request more information.
*/
p = nodebuf; /* mark the start */
e = &nodebuf[MAX_CLUSTER_NODES]; /* mark the end */
for (; p < e; p++) {
if (p->clu_node_name[0] != ' ') {
clu_node_t info;
int status;
int ase;
(void) printf("Contacting %s to collect the following\n",
p->clu_node_name);
status = clu_get_nodebyname(p->clu_node_name, &info);
ase = clu_get_ase_enabled(p->clu_node_name);
if (status != CLU_SUCCESS)
(void) printf("error contacting that node\n");
else {
/* Information about a single node */
(void) printf(" cluster node name : %s\n",
info.clu_node_name);
(void) printf(" host name : %s\n",
info.clu_hostname);
(void) printf(" ase enabled : %s\n", xlate_bool(ase));
/* If ASE is enabled, collect additional information */
if (ase) {
char buf[CLU_MAX_GETINFO_BUF_SIZE];
/* Collect the domain id */
status = clu_get_ase_id_byname(
info.clu_hostname, buf, CLU_MAX_GETINFO_BUF_SIZE);
if (status == CLU_SUCCESS)
printf(" ase id : %s", buf);
/* Collect the identity of nodes in the ase */
status = clu_get_ase_nodes_byname(
info.clu_hostname, buf, CLU_MAX_GETINFO_BUF_SIZE);
if (status == CLU_SUCCESS)
printf(" ase nodes : %s", buf);
} else
(void) printf(" ase information not available\n");
}
(void) printf("\n\n");
}
}
return 0;
}