Sun Microsystems
Products & Services
 
Support & Training
 
 

Previous Previous     Contents     Index     Next 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 Previous     Contents     Index     Next Next