diff --git a/crm/admin/Makefile.am b/crm/admin/Makefile.am index 3706ad8c86..b169caa6c5 100644 --- a/crm/admin/Makefile.am +++ b/crm/admin/Makefile.am @@ -1,87 +1,92 @@ # # 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 # of the License, or (at your option) any later version. # # This program 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 program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # MAINTAINERCLEANFILES = Makefile.in INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include \ -I$(top_builddir)/libltdl -I$(top_srcdir)/libltdl \ -I$(top_builddir)/linux-ha -I$(top_srcdir)/linux-ha \ -I$(top_builddir) -I$(top_srcdir) hadir = $(sysconfdir)/ha.d halibdir = $(libdir)/@HB_PKG@ commmoddir = $(halibdir)/modules/comm havarlibdir = $(localstatedir)/lib/@HB_PKG@ XML_FLAGS = `xml2-config --cflags` XML_LIBS = `xml2-config --libs` # sockets with path crmdir = $(havarlibdir)/crm apigid = @HA_APIGID@ crmuid = @HA_CCMUID@ COMMONLIBS = $(CRM_DEBUG_LIBS) \ $(top_builddir)/lib/clplumbing/libplumb.la \ $(top_builddir)/lib/crm/common/libcrmcommon.la \ $(top_builddir)/lib/crm/cib/libcib.la \ $(top_builddir)/lib/apphb/libapphb.la \ $(top_builddir)/lib/hbclient/libhbclient.la \ $(GLIBLIB) \ $(LIBRT) LIBRT = @LIBRT@ AM_CFLAGS = @CFLAGS@ \ $(CRM_DEBUG_FLAGS) ## libraries lib_LTLIBRARIES = ## binary progs -halib_PROGRAMS = crmadmin cibadmin ccm_tool crm_diff +halib_PROGRAMS = crmadmin cibadmin ccm_tool crm_diff crm_mon ## SOURCES #noinst_HEADERS = config.h control.h crmd.h noinst_HEADERS = crmadmin_SOURCES = crmadmin.c crmadmin_CFLAGS = $(XML_FLAGS) -DHA_VARLIBDIR='"@HA_VARLIBDIR@"' crmadmin_LDFLAGS = $(XML_LIBS) crmadmin_LDADD = $(COMMONLIBS) cibadmin_SOURCES = cibadmin.c cibadmin_CFLAGS = $(XML_FLAGS) -DHA_VARLIBDIR='"@HA_VARLIBDIR@"' cibadmin_LDFLAGS = $(XML_LIBS) cibadmin_LDADD = $(COMMONLIBS) ccm_tool_SOURCES = ccm_epoche.c ccm_tool_CFLAGS = -DHA_VARLIBDIR='"@HA_VARLIBDIR@"' ccm_tool_LDADD = $(COMMONLIBS) \ $(top_builddir)/membership/ccm/libccmclient.la crm_diff_SOURCES = xml_diff.c crm_diff_CFLAGS = -DHA_VARLIBDIR='"@HA_VARLIBDIR@"' crm_diff_LDADD = $(COMMONLIBS) +crm_mon_SOURCES = crm_mon.c +crm_mon_CFLAGS = -DHA_VARLIBDIR='"@HA_VARLIBDIR@"' +crm_mon_LDADD = $(COMMONLIBS) \ + $(top_builddir)/crm/pengine/libpengine.la + clean-generic: rm -f *.log *.debug *.xml *~ install-exec-local: uninstall-local: diff --git a/crm/admin/crm_mon.c b/crm/admin/crm_mon.c new file mode 100644 index 0000000000..3bb470386b --- /dev/null +++ b/crm/admin/crm_mon.c @@ -0,0 +1,308 @@ +/* $Id: crm_mon.c,v 1.1 2005/06/29 11:02:58 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 + +#ifdef HAVE_GETOPT_H +# include +#endif + +#include + +/* GMainLoop *mainloop = NULL; */ +const char *crm_system_name = "crm_mon"; + +#define OPTARGS "V?i:nr" + +#if HAVE_LIBNCURSES +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); + +gboolean group_by_node = FALSE; +gboolean inactive_resources = FALSE; + +int +main(int argc, char **argv) +{ + int interval = 15; + int failed_connections = 0; + int options = cib_scope_local|cib_sync_call; + crm_data_t *xml_frag = NULL; + cib_t *cib_conn = NULL; + 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'}, + + {0, 0, 0, 0} + }; +#endif + + crm_system_name = basename(argv[0]); + crm_log_init(crm_system_name); + crm_log_level = 0; + + 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': + alter_debug(DEBUG_INC); + break; + case 'i': + interval = atoi(optarg); + break; + case 'n': + group_by_node = TRUE; + break; + case 'r': + inactive_resources = 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); + } + + initscr(); + cbreak(); + noecho(); + while(1) { + int offset = 0; + const char *prefix = NULL; + int rc = cib_ok; + if(cib_conn == NULL || cib_conn->state != cib_connected_query){ + crm_free(cib_conn); + 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; + } + } + } + blank_screen(); + if(cib_conn == NULL || cib_conn->state != cib_connected_query){ + failed_connections++; + refresh(); + wait_for_refresh(0, "Not connected: ", 2*interval); + continue; + } + + rc = cib_conn->cmds->query(cib_conn, NULL, &xml_frag, options); +/* add_cib_op_callback(rc, FALSE, crm_strdup(max_generation_from), */ +/* finalize_sync_callback); */ + if(rc == cib_ok) { + crm_data_t *cib = NULL; + cib = find_xml_node(xml_frag,XML_TAG_CIB,TRUE); + offset = print_status(cib); + free_xml(xml_frag); + + cib_conn->cmds->signoff(cib_conn); + + } else { + crm_err("Query failed: %s", cib_error2string(rc)); + prefix = "Query failed! "; + + } + wait_for_refresh(0, prefix, interval); + } + echo(); + nocbreak(); + endwin(); + + return 0; +} + +void +wait_for_refresh(int offset, const char *prefix, int seconds) +{ + int lpc = seconds; + 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--; + sleep(1); + } + move(offset, 0); + printw("Updating..."); + clrtoeol(); + refresh(); +} + + +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(); + cleanup_calculations(&data_set); + return lpc; +} + + +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); + fflush(stream); + + exit(exit_status); +} + +#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