diff --git a/crm/admin/crm_mon.c b/crm/admin/crm_mon.c index 5bb7fe594d..2feb4f0361 100644 --- a/crm/admin/crm_mon.c +++ b/crm/admin/crm_mon.c @@ -1,565 +1,566 @@ -/* $Id: crm_mon.c,v 1.7 2005/08/08 12:06:32 andrew Exp $ */ +/* $Id: crm_mon.c,v 1.8 2005/09/11 20:56:56 andrew Exp $ */ /* * Copyright (C) 2004 Andrew Beekhof * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef HAVE_GETOPT_H # include #endif #include /* GMainLoop *mainloop = NULL; */ const char *crm_system_name = "crm_mon"; #define OPTARGS "V?i:nrh:cdp:" #if CURSES_ENABLED void usage(const char *cmd, int exit_status); void blank_screen(void); int print_status(crm_data_t *cib); #define printw_at(line, fmt...) move(line, 0); printw(fmt); line++ void wait_for_refresh(int offset, const char *prefix, int seconds); int print_html_status(crm_data_t *cib, const char *filename); void make_daemon(gboolean daemonize, const char *pidfile); gboolean mon_timer_popped(gpointer data); void mon_update(const HA_Message*, int, int, crm_data_t*,void*); char *as_html_file = NULL; char *pid_file = NULL; gboolean as_console = FALSE; gboolean group_by_node = FALSE; gboolean inactive_resources = FALSE; int interval = 15; gboolean daemonize = FALSE; GMainLoop* mainloop = NULL; guint timer_id = 0; cib_t *cib_conn = NULL; int failed_connections = 0; int main(int argc, char **argv) { int argerr = 0; int flag; #ifdef HAVE_GETOPT_H int option_index = 0; static struct option long_options[] = { /* Top-level Options */ {"verbose", 0, 0, 'V'}, {"help", 0, 0, '?'}, {"interval", 1, 0, 'i'}, {"group-by-node", 0, 0, 'n'}, {"inactive", 0, 0, 'r'}, {"as-html", 1, 0, 'h'}, {"as-console", 0, 0, 'c'}, {"daemonize", 0, 0, 'd'}, {"pid-file", 0, 0, 'p'}, {0, 0, 0, 0} }; #endif pid_file = crm_strdup("/tmp/ClusterMon.pid"); crm_system_name = basename(argv[0]); crm_log_init(crm_system_name); crm_log_level = LOG_ERR -1; while (1) { #ifdef HAVE_GETOPT_H flag = getopt_long(argc, argv, OPTARGS, long_options, &option_index); #else flag = getopt(argc, argv, OPTARGS); #endif if (flag == -1) break; switch(flag) { case 'V': cl_log_enable_stderr(TRUE); alter_debug(DEBUG_INC); break; case 'i': interval = atoi(optarg); break; case 'n': group_by_node = TRUE; break; case 'r': inactive_resources = TRUE; break; case 'd': daemonize = TRUE; break; case 'p': pid_file = crm_strdup(optarg); break; case 'h': as_html_file = crm_strdup(optarg); break; case 'c': as_console = TRUE; break; default: printf("Argument code 0%o (%c) is not (?yet?) supported\n", flag, flag); ++argerr; break; } } if (optind < argc) { printf("non-option ARGV-elements: "); while (optind < argc) printf("%s ", argv[optind++]); printf("\n"); } if (argerr) { usage(crm_system_name, LSB_EXIT_GENERIC); } if(as_html_file == NULL) { as_console = TRUE; } if(daemonize) { as_console = FALSE; } if(daemonize && as_html_file == NULL) { usage(crm_system_name, LSB_EXIT_GENERIC); } make_daemon(daemonize, pid_file); if(as_console) { initscr(); cbreak(); noecho(); } crm_info("Starting %s", crm_system_name); mainloop = g_main_new(FALSE); timer_id = Gmain_timeout_add(interval*1000, mon_timer_popped, NULL); g_main_run(mainloop); return_to_orig_privs(); crm_info("Exiting %s", crm_system_name); if(as_console) { echo(); nocbreak(); endwin(); } return 0; } gboolean mon_timer_popped(gpointer data) { int rc = cib_ok; int options = cib_scope_local; Gmain_timeout_remove(timer_id); if(as_console) { move(0, 0); printw("Updating..."); clrtoeol(); refresh(); } else { crm_notice("Updating..."); } - if(cib_conn == NULL || cib_conn->state != cib_connected_query){ - crm_free(cib_conn); + if(cib_conn == NULL) { crm_debug_4("Creating CIB connection"); cib_conn = cib_new(); - if(cib_conn != NULL) { - crm_debug_4("Connecting to the CIB"); - if(cib_ok == cib_conn->cmds->signon( - cib_conn, crm_system_name, cib_query)) { - failed_connections = 0; - } + CRM_DEV_ASSERT(cib_conn != NULL); + } + if(cib_conn != NULL && cib_conn->state != cib_connected_query){ + crm_debug_4("Connecting to the CIB"); + if(cib_ok == cib_conn->cmds->signon( + cib_conn, crm_system_name, cib_query)) { + failed_connections = 0; + + } else { + failed_connections++; + CRM_DEV_ASSERT(cib_conn->cmds->signoff(cib_conn) == cib_ok); + wait_for_refresh(0, "Not connected: ", 2*interval); + return FALSE; } + crm_err("Channel fd: %p", cib_conn->cmds->inputfd(cib_conn)); } if(as_console) { blank_screen(); } - if(cib_conn == NULL || cib_conn->state != cib_connected_query){ - failed_connections++; - wait_for_refresh(0, "Not connected: ", 2*interval); - return FALSE; - } - rc = cib_conn->cmds->query(cib_conn, NULL, NULL, options); add_cib_op_callback(rc, FALSE, NULL, mon_update); return FALSE; } void mon_update(const HA_Message *msg, int call_id, int rc, crm_data_t *output, void*user_data) { const char *prefix = NULL; if(rc == cib_ok) { crm_data_t *cib = NULL; cib = find_xml_node(output,XML_TAG_CIB,TRUE); if(as_html_file) { print_html_status(cib, as_html_file); } if(as_console) { print_status(cib); } - cib_conn->cmds->signoff(cib_conn); } else { + CRM_DEV_ASSERT(cib_conn->cmds->signoff(cib_conn) == cib_ok); crm_err("Query failed: %s", cib_error2string(rc)); prefix = "Query failed! "; } wait_for_refresh(0, prefix, interval); } void wait_for_refresh(int offset, const char *prefix, int seconds) { int lpc = seconds; if(as_console == FALSE) { timer_id = Gmain_timeout_add(seconds*1000, mon_timer_popped, NULL); return; } crm_notice("%sRefresh in %ds...", prefix?prefix:"", lpc); while(lpc > 0) { move(offset, 0); /* printw("%sRefresh in \033[01;32m%ds\033[00m...", prefix?prefix:"", lpc); */ printw("%sRefresh in %ds...", prefix?prefix:"", lpc); clrtoeol(); refresh(); lpc--; if(lpc == 0) { timer_id = Gmain_timeout_add( 1000, mon_timer_popped, NULL); } else { sleep(1); } } } int print_status(crm_data_t *cib) { static int updates = 0; int lpc = 0; pe_working_set_t data_set; node_t *dc = NULL; updates++; set_working_set_defaults(&data_set); data_set.input = cib; stage0(&data_set); dc = data_set.dc_node; lpc++; printw_at(lpc, "============"); if(dc == NULL) { printw_at(lpc, "Current DC: NONE"); } else { printw_at(lpc, "Current DC: %s (%s)", dc->details->uname, dc->details->id); } printw_at(lpc, "%d Nodes configured.", g_list_length(data_set.nodes)); printw_at(lpc, "%d Resources configured.", g_list_length(data_set.resources)); printw_at(lpc, "============"); lpc++; slist_iter(node, node_t, data_set.nodes, lpc2, printw_at(lpc, "Node: %s (%s): %s", node->details->uname, node->details->id, node->details->online?"online":"OFFLINE"); if(group_by_node) { slist_iter(rsc, resource_t, node->details->running_rsc, lpc2, common_printw(rsc, "\t", &lpc); /* rsc->fns->printw(rsc, "\t", &lpc); */ lpc++; ); } ); lpc++; if(group_by_node && inactive_resources) { printw_at(lpc, "Full list of resources:"); } if(group_by_node == FALSE || inactive_resources) { slist_iter(rsc, resource_t, data_set.resources, lpc2, rsc->fns->printw(rsc, NULL, &lpc); lpc++; ); } move(lpc, 0); refresh(); data_set.input = NULL; cleanup_calculations(&data_set); return lpc; } int print_html_status(crm_data_t *cib, const char *filename) { static int updates = 0; pe_working_set_t data_set; node_t *dc = NULL; FILE *stream = fopen(filename, "w"); if(stream == NULL) { return -1; } updates++; set_working_set_defaults(&data_set); data_set.input = cib; stage0(&data_set); dc = data_set.dc_node; fprintf(stream, ""); fprintf(stream, ""); fprintf(stream, "Cluster status"); /* content="%d;url=http://webdesign.about.com" */ fprintf(stream, "", interval); fprintf(stream, ""); /*** SUMMARY ***/ fprintf(stream, "

Cluster summary

"); { char *now_str = NULL; time_t now = time(NULL); now_str = ctime(&now); now_str[24] = EOS; /* replace the newline */ fprintf(stream, "Last updated: %s
\n", now_str); } if(dc == NULL) { fprintf(stream, "Current DC: NONE
"); } else { fprintf(stream, "Current DC: %s (%s)
", dc->details->uname, dc->details->id); } fprintf(stream, "%d Nodes configured.
", g_list_length(data_set.nodes)); fprintf(stream, "%d Resources configured.
", g_list_length(data_set.resources)); /*** CONFIG ***/ fprintf(stream, "

Config Options

\n"); fprintf(stream, "\n"); fprintf(stream, "\n", data_set.default_resource_stickiness); fprintf(stream, "\n", data_set.stonith_enabled?"enabled":"disabled"); fprintf(stream, "\n", data_set.symmetric_cluster?"":"a-"); fprintf(stream, "\n
Default resource stickiness:%d
STONITH of failed nodes:%s
Cluster is:%ssymmetric
No Quorum Policy:"); switch (data_set.no_quorum_policy) { case no_quorum_freeze: fprintf(stream, "Freeze resources"); break; case no_quorum_stop: fprintf(stream, "Stop ALL resources"); break; case no_quorum_ignore: fprintf(stream, "Ignore"); break; } fprintf(stream, "\n
\n"); /*** NODE LIST ***/ fprintf(stream, "

Node List

\n"); fprintf(stream, "
    \n"); slist_iter(node, node_t, data_set.nodes, lpc2, fprintf(stream, "
  • "); fprintf(stream, "Node: %s (%s): %s", node->details->uname, node->details->id, node->details->online?"online\n":"OFFLINE\n"); if(group_by_node) { fprintf(stream, "
      \n"); slist_iter(rsc, resource_t, node->details->running_rsc, lpc2, fprintf(stream, "
    • "); common_html(rsc, "\t", stream); fprintf(stream, "
    • \n"); ); fprintf(stream, "
    \n"); } fprintf(stream, "
  • \n"); ); fprintf(stream, "
\n"); if(group_by_node && inactive_resources) { fprintf(stream, "

(Partially) Inactive Resources

\n"); } else if(group_by_node == FALSE) { fprintf(stream, "

Resource List

\n"); } if(group_by_node == FALSE || inactive_resources) { slist_iter(rsc, resource_t, data_set.resources, lpc2, if(group_by_node && rsc->fns->active(rsc, TRUE)) { continue; } rsc->fns->html(rsc, NULL, stream); ); } data_set.input = NULL; cleanup_calculations(&data_set); fprintf(stream, ""); fflush(stream); fclose(stream); return 0; } void blank_screen(void) { int lpc = 0; for(lpc = 0; lpc < LINES; lpc++) { move(lpc, 0); clrtoeol(); } move(0, 0); } void usage(const char *cmd, int exit_status) { FILE *stream; stream = exit_status ? stderr : stdout; fprintf(stream, "usage: %s [-%s]\n", cmd, OPTARGS); fprintf(stream, "\t--%s (-%c) \t: This text\n", "help", '?'); fprintf(stream, "\t--%s (-%c) \t: Increase the debug output\n", "verbose", 'V'); fprintf(stream, "\t--%s (-%c) \t: Update frequency\n", "interval", 'i'); fprintf(stream, "\t--%s (-%c) \t:Group resources by node\n", "group-by-node", 'n'); fprintf(stream, "\t--%s (-%c) \t:Display inactive resources\n", "inactive", 'r'); fprintf(stream, "\t--%s (-%c) \t: Display cluster status on the console\n", "as-console", 'c'); fprintf(stream, "\t--%s (-%c) \t: Write cluster status to the named file\n", "as-html", 'h'); fprintf(stream, "\t--%s (-%c) \t: Run in the background as a daemon\n", "daemonize", 'd'); fprintf(stream, "\t--%s (-%c) \t: Daemon pid file location\n", "pid-file", 'p'); fflush(stream); exit(exit_status); } void make_daemon(gboolean daemonize, const char *pidfile) { long pid; const char *devnull = "/dev/null"; if (daemonize == FALSE){ return; } pid = fork(); if (pid < 0) { fprintf(stderr, "%s: could not start daemon\n", crm_system_name); perror("fork"); exit(LSB_EXIT_GENERIC); } else if (pid > 0) { exit(LSB_EXIT_OK); } if (cl_lock_pidfile(pidfile) < 0 ){ pid = cl_read_pidfile(pidfile); fprintf(stderr, "%s: already running [pid %ld].\n", crm_system_name, pid); exit(LSB_EXIT_OK); } umask(022); close(FD_STDIN); (void)open(devnull, O_RDONLY); /* Stdin: fd 0 */ close(FD_STDOUT); (void)open(devnull, O_WRONLY); /* Stdout: fd 1 */ close(FD_STDERR); (void)open(devnull, O_WRONLY); /* Stderr: fd 2 */ } #else int main(int argc, char **argv) { fprintf(stderr, "The use of %s requires ncurses to be available" " during the build process\n", crm_system_name); exit(1); } #endif diff --git a/lib/crm/common/ipc.c b/lib/crm/common/ipc.c index 926c9076a3..2e2e3fa4b4 100644 --- a/lib/crm/common/ipc.c +++ b/lib/crm/common/ipc.c @@ -1,415 +1,416 @@ -/* $Id: ipc.c,v 1.12 2005/08/17 08:44:57 andrew Exp $ */ +/* $Id: ipc.c,v 1.13 2005/09/11 20:56:56 andrew Exp $ */ /* * Copyright (C) 2004 Andrew Beekhof * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include gboolean send_ha_message(ll_cluster_t *hb_conn, HA_Message *msg, const char *node, gboolean force_ordered) { gboolean all_is_good = TRUE; if (msg == NULL) { crm_err("cant send NULL message"); all_is_good = FALSE; } else if(hb_conn == NULL) { crm_err("No heartbeat connection specified"); all_is_good = FALSE; } else if(hb_conn->llc_ops->chan_is_connected(hb_conn) != HA_OK) { crm_err("Not connected to Heartbeat"); all_is_good = FALSE; } else if(get_stringlen(msg) >= MAXMSG) { crm_err("Message is too large to send"); all_is_good = FALSE; } else if(node != NULL) { if(hb_conn->llc_ops->send_ordered_nodemsg( hb_conn, msg, node) != HA_OK) { IPC_Channel *ipc = hb_conn->llc_ops->ipcchan(hb_conn); all_is_good = FALSE; crm_err("Send failed"); CRM_DEV_ASSERT(ipc->send_queue->current_qlen < ipc->send_queue->max_qlen); } else { crm_debug_2("Message sent..."); } } else if(force_ordered) { if(hb_conn->llc_ops->send_ordered_clustermsg(hb_conn, msg) != HA_OK) { IPC_Channel *ipc = hb_conn->llc_ops->ipcchan(hb_conn); all_is_good = FALSE; crm_err("Broadcast Send failed"); CRM_DEV_ASSERT(ipc->send_queue->current_qlen < ipc->send_queue->max_qlen); } else { crm_debug_2("Broadcast message sent..."); } } else { if(hb_conn->llc_ops->sendclustermsg(hb_conn, msg) != HA_OK) { IPC_Channel *ipc = hb_conn->llc_ops->ipcchan(hb_conn); all_is_good = FALSE; crm_err("Broadcast Send failed"); CRM_DEV_ASSERT(ipc->send_queue->current_qlen < ipc->send_queue->max_qlen); } else { crm_debug_2("Broadcast message sent..."); } } crm_log_message_adv(all_is_good?LOG_MSG:LOG_WARNING,"HA[outbound]",msg); return all_is_good; } #define ipc_log(fmt...) do_crm_log(server?LOG_WARNING:LOG_ERR, __FILE__, __FUNCTION__, fmt) /* frees msg */ gboolean crm_send_ipc_message(IPC_Channel *ipc_client, HA_Message *msg, gboolean server) { gboolean all_is_good = TRUE; if (msg == NULL) { crm_err("cant send NULL message"); all_is_good = FALSE; } else if (ipc_client == NULL) { crm_err("cant send message without an IPC Channel"); all_is_good = FALSE; } else if(ipc_client->ops->get_chan_status(ipc_client) != IPC_CONNECT) { ipc_log("IPC Channel is not connected"); all_is_good = FALSE; } else if(get_stringlen(msg) >= MAXMSG) { crm_err("Message is too large to send"); all_is_good = FALSE; } if(all_is_good && msg2ipcchan(msg, ipc_client) != HA_OK) { ipc_log("Could not send IPC, message"); all_is_good = FALSE; if(ipc_client->ops->get_chan_status(ipc_client) != IPC_CONNECT) { ipc_log("IPC Channel is no longer connected"); } else if(server == FALSE) { CRM_DEV_ASSERT(ipc_client->send_queue->current_qlen < ipc_client->send_queue->max_qlen); } } crm_log_message_adv(all_is_good?LOG_MSG:LOG_WARNING,"IPC[outbound]",msg); crm_msg_del(msg); return all_is_good; } void default_ipc_connection_destroy(gpointer user_data) { return; } int init_server_ipc_comms( char *channel_name, gboolean (*channel_client_connect)(IPC_Channel *newclient,gpointer user_data), void (*channel_connection_destroy)(gpointer user_data)) { /* the clients wait channel is the other source of events. * This source delivers the clients connection events. * listen to this source at a relatively lower priority. */ char commpath[SOCKET_LEN]; IPC_WaitConnection *wait_ch; sprintf(commpath, CRM_SOCK_DIR "/%s", channel_name); wait_ch = wait_channel_init(commpath); if (wait_ch == NULL) { return 1; } G_main_add_IPC_WaitConnection( G_PRIORITY_LOW, wait_ch, NULL, FALSE, channel_client_connect, channel_name, channel_connection_destroy); crm_debug_3("Listening on: %s", commpath); return 0; } GCHSource* init_client_ipc_comms(const char *channel_name, gboolean (*dispatch)( IPC_Channel* source_data, gpointer user_data), void *client_data, IPC_Channel **ch) { IPC_Channel *a_ch = NULL; GCHSource *the_source = NULL; void *callback_data = client_data; a_ch = init_client_ipc_comms_nodispatch(channel_name); if(ch != NULL) { *ch = a_ch; if(callback_data == NULL) { callback_data = a_ch; } } if(a_ch == NULL) { crm_warn("Setup of client connection failed," " not adding channel to mainloop"); return NULL; } if(dispatch == NULL) { crm_warn("No dispatch method specified..." "maybe you meant init_client_ipc_comms_nodispatch()?"); } else { crm_debug_3("Adding dispatch method to channel"); the_source = G_main_add_IPC_Channel( G_PRIORITY_HIGH, a_ch, FALSE, dispatch, callback_data, default_ipc_connection_destroy); } return the_source; } IPC_Channel * init_client_ipc_comms_nodispatch(const char *channel_name) { IPC_Channel *ch; GHashTable *attrs; static char path[] = IPC_PATH_ATTR; char *commpath = NULL; int local_socket_len = 2; /* 2 = '/' + '\0' */ local_socket_len += strlen(channel_name); local_socket_len += strlen(CRM_SOCK_DIR); crm_malloc0(commpath, sizeof(char)*local_socket_len); if(commpath != NULL) { sprintf(commpath, CRM_SOCK_DIR "/%s", channel_name); commpath[local_socket_len - 1] = '\0'; crm_debug_3("Attempting to talk on: %s", commpath); } attrs = g_hash_table_new(g_str_hash,g_str_equal); g_hash_table_insert(attrs, path, commpath); ch = ipc_channel_constructor(IPC_ANYTYPE, attrs); g_hash_table_destroy(attrs); if (ch == NULL) { crm_err("Could not access channel on: %s", commpath); return NULL; } else if (ch->ops->initiate_connection(ch) != IPC_OK) { crm_debug("Could not init comms on: %s", commpath); + ch->ops->destroy(ch); return NULL; } ch->ops->set_recv_qlen(ch, 100); ch->ops->set_send_qlen(ch, 100); /* ch->should_send_block = TRUE; */ crm_debug_3("Processing of %s complete", commpath); return ch; } IPC_WaitConnection * wait_channel_init(char daemonsocket[]) { IPC_WaitConnection *wait_ch; mode_t mask; char path[] = IPC_PATH_ATTR; GHashTable * attrs; attrs = g_hash_table_new(g_str_hash,g_str_equal); g_hash_table_insert(attrs, path, daemonsocket); mask = umask(0); wait_ch = ipc_wait_conn_constructor(IPC_ANYTYPE, attrs); if (wait_ch == NULL) { cl_perror("Can't create wait channel of type %s", IPC_ANYTYPE); exit(1); } mask = umask(mask); g_hash_table_destroy(attrs); return wait_ch; } longclock_t ipc_call_start = 0; longclock_t ipc_call_stop = 0; longclock_t ipc_call_diff = 0; gboolean subsystem_msg_dispatch(IPC_Channel *sender, void *user_data) { int lpc = 0; IPC_Message *msg = NULL; ha_msg_input_t *new_input = NULL; gboolean all_is_well = TRUE; const char *sys_to; const char *task; while(sender->ops->is_message_pending(sender)) { gboolean process = FALSE; if (sender->ch_status == IPC_DISCONNECT) { /* The message which was pending for us is that * the IPC status is now IPC_DISCONNECT */ crm_debug("Channel is disconnected"); break; } if (sender->ops->recv(sender, &msg) != IPC_OK) { perror("Receive failure:"); return !all_is_well; } if (msg == NULL) { crm_err("No message this time"); continue; } lpc++; new_input = new_ipc_msg_input(msg); msg->msg_done(msg); crm_log_message(LOG_MSG, new_input->msg); sys_to = cl_get_string(new_input->msg, F_CRM_SYS_TO); task = cl_get_string(new_input->msg, F_CRM_TASK); if(safe_str_eq(task, CRM_OP_HELLO)) { process = TRUE; } else if(sys_to == NULL) { crm_err("Value of %s was NULL!!", F_CRM_SYS_TO); } else if(task == NULL) { crm_err("Value of %s was NULL!!", F_CRM_TASK); } else { process = TRUE; } if(process){ gboolean (*process_function) (HA_Message *msg, crm_data_t *data, IPC_Channel *sender) = NULL; process_function = user_data; #ifdef MSG_LOG crm_log_message_adv( LOG_MSG, __FUNCTION__, new_input->msg); #endif if(ipc_call_diff_max_ms > 0) { ipc_call_start = time_longclock(); } if(FALSE == process_function( new_input->msg, new_input->xml, sender)) { crm_warn("Received a message destined for %s" " by mistake", sys_to); } if(ipc_call_diff_max_ms > 0) { unsigned int ipc_call_diff_ms = 0; ipc_call_stop = time_longclock(); ipc_call_diff = sub_longclock( ipc_call_stop, ipc_call_start); ipc_call_diff_ms = longclockto_ms( ipc_call_diff); if(ipc_call_diff_ms > ipc_call_diff_max_ms) { crm_err("%s took %dms to complete", sys_to, ipc_call_diff_ms); } } } else { #ifdef MSG_LOG crm_log_message_adv( LOG_ERR, NULL, new_input->msg); #endif } delete_ha_msg_input(new_input); msg = NULL; } /* clean up after a break */ if(msg != NULL) { msg->msg_done(msg); } crm_debug_2("Processed %d messages", lpc); if (sender->ch_status != IPC_CONNECT) { crm_err("The server has left us: Shutting down...NOW"); exit(1); /* shutdown properly later */ return !all_is_well; } return all_is_well; } gboolean is_ipc_empty(IPC_Channel *ch) { if(ch == NULL) { return TRUE; } else if(ch->send_queue->current_qlen == 0 && ch->recv_queue->current_qlen == 0) { return TRUE; } return FALSE; }