sun.com | docs.sun.com | How To Buy | My Sun | Worldwide Sites |  |

| Previous Contents Index Next
### The `cmm_node_getid()` Function The code provided by Example A-7 displays information about the current node by using the `cmm_node_getid()` function. Example A-7 The `smpl_cmm_node_getid.c` Program
    /*********************************************************
    * Copyright (c) 2002 by Sun Microsystems, Inc.
    * All rights reserved.
    *
    *
    * ident  "@(#)smpl_cmm_node_getid.c 1.2     02/06/05 SMI"
    *
    **********************************************************/

    #include <stdio.h>
    #include <cmm.h>

    int main(int argc , char **argv) {
      cmm_nodeid_t nodeid;
      cmm_error_t cmm_diag;

      cmm_diag = cmm_node_getid(&nodeid);
      switch (cmm_diag) {
      case CMM_OK:
        {
          printf("The node id of this node is: %d\n",nodeid);
          exit(0);
        }
      case CMM_ETIMEDOUT:
        {
          fprintf(stderr,"Cmm didn't give us reponse within delay\n");
          exit(1);
        }
      case CMM_ECONN:
        {
          fprintf(stderr,"Cannot reach the CMM\n");
          exit(1);
        }
      default:
        fprintf(stderr,"call returned an error. CR=%d\n",cmm_diag);
        exit(1);
      }

      /*NOTREACHED*/
      exit(0);
    }
### The `cmm_vicemaster_getinfo()` Function The code provided by Example A-8 displays information about the vice-master node by using the `cmm_vicemaster_getinfo()` function. Example A-8 The `smpl_cmm_vicemaster_getinfo.c` Program
    /***********************************************************
    * Copyright (c) 2002 by Sun Microsystems, Inc.
    * All rights reserved.
    *
    *
    * ident  "@(#)smpl_cmm_vicemaster_getinfo.c 1.2     02/06/05 SMI"
    *
    ************************************************************/

    #include <stdio.h>
    #include <cmm.h>

    int main(int argc , char **argv) {
      cmm_error_t  cmm_diag;
      cmm_member_t nodeInfo;

      cmm_diag = cmm_vicemaster_getinfo(&nodeInfo);

      if (cmm_diag != CMM_OK) {
        fprintf(stderr,"An error occured during
        cmm_member_getinfo call, CR=%d: %s\n",cmm_diag,cmm_strerror(cmm_diag));
        exit(1);
      }

      printf("Infornation on vice-master:\n");
      printf("\tName:               %s\n",nodeInfo.name);
      printf("\tAdress:             %s\n",nodeInfo.addr);
      printf("\tDomain Id:          %d\n",nodeInfo.domainid);
      printf("\tIncarnation number: %d\n",nodeInfo.incarnation_number);
      printf("\tSoftwareLoad id:    %s\n",nodeInfo.software_load_id);

      exit(0);
    }
## CMM API Extended Code Example In addition to the examples and Makefile outlined in CMM API Code Examples, the developer package subdirectory `opt/SUNWcgha/examples/` provides an extended code example, which uses many of the function calls of the CMM API. This program reacts to the `CMM_MASTER_ELECTED` and `CMM_MASTER_DEMOTED` notifications, as demonstrated in the Example A-9. Example A-9 The `smpl_cmm_notification.c` Program
    /******************************************************
    * Copyright (c) 2002 by Sun Microsystems, Inc.
    * All rights reserved.
    *
    *
    * ident  "@(#)smpl_cmm_notification.c 1.2     02/06/05 SMI"
    *
    ********************************************************/

    #include <stdio.h>
    #include <unistd.h>

    #include <pthread.h>
    #include <cmm.h>

    /*
     * create a pthread to receive events from CMM
     * the thread will be activated on vice-master election
     */

    typedef struct thrArg {
      int FilterChange;
      cmm_cmcfilter_t cmcFilter;
      cmm_cmchanges_t cmcChangeList[5];
      uint32_t        cmcChangeCount;
    } thrArg_t;

    void notification_thread_cb
    (const cmm_cmc_notification_t * change_notification,void *client_data);

    void CleanHandler(void *arg) {
      fprintf(stderr,"%d: I was cancelled\n",pthread_self());
      pthread_exit((void*)arg);
    }

    void *notification_thread(void*args) {
      struct pollfd pfd;
      int diag;
      cmm_error_t cmm_diag;

      thrArg_t *TArgs = (thrArg_t *)args;

      diag = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL);
      if (diag != 0) {
        fprintf(stderr,"%d:
         call of pthread_setcancelstate failed\n",pthread_self());
        pthread_exit((void*)NULL);
      }
      diag = pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL);
      if (diag != 0) {
      fprintf(stderr,"%d:
      call of pthread_setcanceltype failed\n",pthread_self());
        pthread_exit((void*)NULL);
      }

      pthread_cleanup_push(CleanHandler,NULL);

      /*register the callback, called after event are received*/

      diag = cmm_cmc_register(notification_thread_cb,NULL);
      if (diag != CMM_OK) {
        fprintf(stderr,"%d: error in
        cmm_cmc_register CR:%d:
        %s\n",pthread_self(),diag,cmm_strerror(cmm_diag));
        pthread_exit((void*)NULL);
      }

      diag = cmm_notify_getfd(&(pfd.fd));
      if (diag != CMM_OK) {
        fprintf(stderr,"%d: error in
        cmm_notify_getfd CR:%d:
        %s\n",pthread_self(),diag,cmm_strerror(cmm_diag));
        cmm_cmc_unregister();
        pthread_exit((void*)NULL);
      }

      pfd.events = POLLIN;

      while(1) {
        diag = poll(&pfd,1,1000);
        if (diag < 0) {
          fprintf(stderr,"%d:
          error during polling CR:%d\n",pthread_self(),diag);
          cmm_cmc_unregister();
          pthread_exit((void*)NULL);
        }

        /*we receive something*/
        if (pfd.revents == POLLIN) {
          cmm_diag = cmm_notify_dispatch();
          if (cmm_diag != CMM_OK) {
    	fprintf(stderr,"%d: error during
    	call of dispatch() CR:%d\n",pthread_self(),cmm_diag);
    	fprintf(stderr,"Details: %s\n",cmm_strerror(cmm_diag));
    	cmm_cmc_unregister();
    	pthread_exit((void*)NULL);
          }
        }
        if (TArgs->FilterChange) {
          /*we have to change the filter*/
          printf("%d: we have to update the filter\n",pthread_self());
          cmm_diag =
          cmm_cmc_filter(TArgs->cmcFilter,TArgs->
          cmcChangeList,TArgs->cmcChangeCount);
          if (cmm_diag != CMM_OK) {
    	fprintf(stderr,"%d: error during
      filter change CR:%d\n",pthread_self(),cmm_diag);
    	fprintf(stderr,"Details: %s\n",cmm_strerror(cmm_diag));
    	cmm_cmc_unregister();
    	pthread_exit((void*)NULL);
          }
          TArgs->FilterChange = 0;
        }

        pthread_testcancel();
      }

      /*NOTREACHED*/

      pthread_cleanup_pop(0);

      /*NOTREACHED*/
      pthread_exit((void*)NULL);

    }

    /*callback activated when event received*/

    void notification_thread_cb
    (const cmm_cmc_notification_t * change_notification,void *client_data) {

      printf("%d: notif thread received event (%d) for node %d\n",
    	 pthread_self(),
    	 change_notification->cmchange,
    	 change_notification->nodeid);
    }

    int main(int argc , char ** argv) {
      int diag;
      pthread_attr_t attr;
      cmm_error_t cmm_diag;
      pthread_t NotificationThread;
      thrArg_t targ;

      /*initialize notification thread*/
      diag = pthread_attr_init(&attr);
      if (diag != 0) {
        fprintf(stderr,"%d: attr init error\n",pthread_self());
        exit(1);
      }

      diag = pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_JOINABLE);
      if (diag != 0) {
        fprintf(stderr,"%d:
        pthread_attr_setdetachstate error\n",pthread_self());
        exit(1);
      }

      /*clear event filter*/
      targ.cmcFilter = CMM_CMC_NOTIFY_NONE;
      targ.cmcChangeCount = 0;

      cmm_diag =
      cmm_cmc_filter(targ.cmcFilter,targ.cmcChangeList,targ.cmcChangeCount);
      if (cmm_diag != CMM_OK) {
        fprintf(stderr,"%d: error during
        filter change CR:%d\n",pthread_self(),cmm_diag);
        fprintf(stderr,"Details: %s\n",cmm_strerror(cmm_diag));
        exit(1);
      }

      targ.FilterChange = 0;

      /*add "vice-master elected" event*/
      targ.cmcFilter      = CMM_CMC_NOTIFY_ADD;
      targ.cmcChangeCount = 1;
      targ.cmcChangeList[0]  = CMM_VICEMASTER_ELECTED;

      cmm_diag =
      cmm_cmc_filter(targ.cmcFilter,targ.cmcChangeList,targ.cmcChangeCount);
      if (cmm_diag != CMM_OK) {
        fprintf(stderr,"%d: error during
        filter change CR:%d\n",pthread_self(),cmm_diag);
        fprintf(stderr,"Details: %s\n",cmm_strerror(cmm_diag));
        exit(1);
      }

      /*launch notification thread*/

      diag = pthread_create
      (&NotificationThread,&attr,notification_thread,(void*)&targ);
      if (diag != 0) {
        fprintf(stderr,"pthread_create error\n");
        exit(1);
      }

      /*
       * ............
       */

      sleep(20);

      /*We can only register once, tha same thread has to be used*/
      /*to catch all events*/

      /*add CMM_MASTER_DEMOTED and CMM_MASTER_ELECTED events*/

      printf("%d: adding CMM_MASTER_ELECTED and
       CMM_MASTER_DEMOTED events..\n",pthread_self());

      targ.cmcFilter        = CMM_CMC_NOTIFY_ADD;
      targ.cmcChangeCount   = 2;
      targ.cmcChangeList[0] = CMM_MASTER_ELECTED;
      targ.cmcChangeList[1] = CMM_MASTER_DEMOTED;

      /*ask the notification thread to update the filter*/
      /*we don't want to stop it*/
      targ.FilterChange = 1;

      sleep(20);

      /*stop the notification thread*/

      pthread_cancel(NotificationThread);
      pthread_join(NotificationThread,NULL);

      exit (0);

    }
Previous Contents Index Next

Copyright 1994-2004 Sun Microsystems