static gboolean try_heartbeat(int command) { crm_debug("Attempting to process %c command", command); if(command == 'i') { if(read_local_hb_uuid()) { exit(0); } } else if(ccm_age_connect(&ccm_fd)) { int rc = 0; fd_set rset; while (1) { sleep(1); FD_ZERO(&rset); FD_SET(ccm_fd, &rset); errno = 0; rc = select(ccm_fd + 1, &rset, NULL,NULL,NULL); if(rc > 0 && oc_ev_handle_event(ccm_token) != 0) { crm_err("oc_ev_handle_event failed"); exit(1); } else if(rc < 0 && errno != EINTR) { crm_perror(LOG_ERR, "select failed"); exit(1); } } } return FALSE; }
SaErrorT saClmInitialize(SaClmHandleT *clmHandle, const SaClmCallbacksT *clmCallbacks, const SaVersionT *version) { int ret; oc_ev_t *ev_token; __clm_handle_t *hd; SaClmHandleT *hash_key; fd_set rset; struct timeval tv; SaErrorT rc; oc_ev_register(&ev_token); if ((ret = oc_ev_set_callback(ev_token, OC_EV_MEMB_CLASS , ccm_events, NULL)) != 0) { if (ret == ENOMEM){ rc = SA_ERR_NO_MEMORY; goto err_nomem_exit; } else{ assert(0); /* Never runs here */ } } /* We must call it to get non-quorum partition info */ oc_ev_special(ev_token, OC_EV_MEMB_CLASS, 0); clm_init(); hash_key = (SaClmHandleT *)g_malloc(sizeof(SaClmHandleT)); if (!hash_key){ rc = SA_ERR_NO_MEMORY; goto err_nomem_exit; } hd = (__clm_handle_t *)g_malloc(sizeof(__clm_handle_t)); if (!hd){ g_free(hash_key); rc = SA_ERR_NO_MEMORY; goto err_nomem_exit; } *clmHandle = __handle_counter++; *hash_key = *clmHandle; hd->ev_token = ev_token; hd->callbacks = *clmCallbacks; hd->trackflags = CLM_TRACK_STOP; cl_log(LOG_INFO, "g_hash_table_insert hd = [%p]", hd); g_hash_table_insert(__handle_hash, hash_key, hd); if ((ret = oc_ev_activate(hd->ev_token, &hd->fd)) != 0) { cl_log(LOG_ERR, "oc_ev_activate error [%d]", ret); rc = SA_ERR_LIBRARY; goto err_lib_exit; } /* Prepare information for saClmClusterNodeGet() series calls */ while (!__ccm_data) { FD_ZERO(&rset); FD_SET(hd->fd, &rset); tv.tv_sec = 2; tv.tv_usec = 0; if ((ret = select(hd->fd + 1, &rset, NULL, NULL, &tv)) == -1) { cl_log(LOG_ERR, "%s: select error [%d]" , __FUNCTION__, ret); rc = SA_ERR_LIBRARY; goto err_lib_exit; } else if (ret == 0) { cl_log(LOG_WARNING, "%s: select timeout", __FUNCTION__); rc = SA_ERR_TIMEOUT; goto err_lib_exit; } if ((ret = oc_ev_handle_event(hd->ev_token) != 0)) { cl_log(LOG_ERR, "%s: oc_ev_handle_event error [%d]" , __FUNCTION__, ret); rc = SA_ERR_LIBRARY; goto err_lib_exit; } } return SA_OK; err_lib_exit: g_hash_table_remove(__handle_hash, hash_key); g_free(hd); g_free(hash_key); err_nomem_exit: oc_ev_unregister(ev_token); return rc; }
SaErrorT saClmDispatch(const SaClmHandleT *clmHandle, SaDispatchFlagsT dispatchFlags) { int ret; const oc_ev_membership_t *oc; uint itemnum; __clm_handle_t *hd = GET_CLM_HANDLE(clmHandle); if (!hd){ return SA_ERR_BAD_HANDLE; } if ((ret = oc_ev_handle_event(hd->ev_token)) != 0) { if (ret == EINVAL){ return SA_ERR_BAD_HANDLE; } /* else we must be evicted */ } /* We did not lock for read here because other writers will set it * with the same value (if there really exist some). Otherwise we * need to lock here. */ if (__ccm_event == OC_EV_MS_EVICTED) { cl_log(LOG_WARNING , "This node is evicted from the current partition!"); return SA_ERR_LIBRARY; } if (__ccm_event == OC_EV_MS_NOT_PRIMARY || __ccm_event == OC_EV_MS_PRIMARY_RESTORED) { cl_log(LOG_DEBUG, "Received not interested event [%d]" , __ccm_event); return SA_OK; } if (!__ccm_data){ return SA_ERR_INIT; } oc = __ccm_data; if(CLM_TRACK_STOP == hd->trackflags){ return SA_OK; } /* SA_TRACK_CURRENT is cleared in saClmClusterTrackStart, hence we * needn't to deal with it now*/ if (hd->trackflags & SA_TRACK_CHANGES) { itemnum = oc->m_n_member + oc->m_n_out; if (itemnum > hd->itemnum) { hd->callbacks.saClmClusterTrackCallback(hd->nbuf , hd->itemnum, oc->m_n_member, oc->m_instance , SA_ERR_NO_SPACE); return SA_OK; } pthread_lock(); retrieve_changes_buffer(hd); pthread_unlock(); hd->callbacks.saClmClusterTrackCallback(hd->nbuf, itemnum , oc->m_n_member, oc->m_instance, SA_OK); } else if (hd->trackflags & SA_TRACK_CHANGES_ONLY) { itemnum = oc->m_n_in + oc->m_n_out; if (itemnum > hd->itemnum) { hd->callbacks.saClmClusterTrackCallback(hd->nbuf , hd->itemnum, oc->m_n_member, oc->m_instance , SA_ERR_NO_SPACE); return SA_OK; } pthread_lock(); retrieve_changes_only_buffer(hd); pthread_unlock(); hd->callbacks.saClmClusterTrackCallback(hd->nbuf, itemnum , oc->m_n_member, oc->m_instance, SA_OK); } else { assert(0); } /* unlock */ return SA_OK; }
int main(int argc, char ** argv) { int flag; int argerr = 0; int ccm_fd = 0; fd_set rset; oc_ev_t *ccm_token = NULL; crm_log_init(crm_system_name, LOG_INFO, FALSE, FALSE, 0, NULL); while ((flag = getopt(argc, argv, OPTARGS)) != EOF) { switch(flag) { case 'V': cl_log_enable_stderr(TRUE); alter_debug(DEBUG_INC); break; case 'h': /* Help message */ usage(crm_system_name, LSB_EXIT_OK); break; case 'p': case 'e': case 'q': command = flag; break; default: ++argerr; break; } } if (optind > argc) { ++argerr; } if (argerr) { usage(crm_system_name,LSB_EXIT_GENERIC); } if(ccm_age_connect(&ccm_fd)) { int rc = 0; int lpc = 0; for (;;lpc++) { FD_ZERO(&rset); FD_SET(ccm_fd, &rset); rc = select(ccm_fd + 1, &rset, NULL,NULL,NULL); if(rc == -1){ perror("select failed"); if(errno == EINTR) { crm_debug("Retry..."); continue; } } else if(oc_ev_handle_event(ccm_token) != 0){ crm_err("oc_ev_handle_event failed"); } return(1); } } return(1); }