[Contents] [Prev. Chapter] [Next Section] [Index] [Help]

2    Cluster Information Services

This chapter describes how to use the TruCluster Production Server information services to obtain information about cluster members and services. It includes the following:


[Contents] [Prev. Chapter] [Next Section] [Index] [Help]

2.1    Overview

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.

Table 2-1:  Cluster Information Services

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


[Contents] [Prev. Chapter] [Prev. Section] [Index] [Help]

2.2    Using the TruCluster Production Server Information Services

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

Example 2-1:  Using the clu_get_cluster and clu_get_qdisk Functions

#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

Example 2-2:  Obtaining Information from Cluster Member Systems

#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;
}


[Contents] [Prev. Chapter] [Prev. Section] [Index] [Help]