From mboxrd@z Thu Jan 1 00:00:00 1970 From: rmccabe@sourceware.org Date: 9 Oct 2007 19:58:32 -0000 Subject: [Cluster-devel] conga ./clustermon.spec.in.in ricci/modules/cl ... Message-ID: <20071009195832.11139.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: conga Changes by: rmccabe at sourceware.org 2007-10-09 19:58:30 Modified files: . : clustermon.spec.in.in ricci/modules/cluster: ClusterStatus.cpp ricci/modules/cluster/clumon/src/cim-provider: Makefile ricci/modules/cluster/clumon/src/common: Cluster.cpp ricci/modules/cluster/clumon/src/daemon: Makefile Monitor.cpp Monitor.h main.cpp ricci/modules/cluster/clumon/src/snmp-agent: Makefile Log message: use libcman wherever possible instead of fork/exec and parsing stdout Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/conga/clustermon.spec.in.in.diff?cvsroot=cluster&r1=1.32&r2=1.33 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/ClusterStatus.cpp.diff?cvsroot=cluster&r1=1.23&r2=1.24 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/cim-provider/Makefile.diff?cvsroot=cluster&r1=1.7&r2=1.8 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/common/Cluster.cpp.diff?cvsroot=cluster&r1=1.8&r2=1.9 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/daemon/Makefile.diff?cvsroot=cluster&r1=1.8&r2=1.9 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/daemon/Monitor.cpp.diff?cvsroot=cluster&r1=1.18&r2=1.19 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/daemon/Monitor.h.diff?cvsroot=cluster&r1=1.8&r2=1.9 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/daemon/main.cpp.diff?cvsroot=cluster&r1=1.8&r2=1.9 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/snmp-agent/Makefile.diff?cvsroot=cluster&r1=1.6&r2=1.7 --- conga/clustermon.spec.in.in 2007/09/20 05:36:13 1.32 +++ conga/clustermon.spec.in.in 2007/10/09 19:58:29 1.33 @@ -27,6 +27,7 @@ Source0: %{name}-%{version}.tar.gz Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +BuildRequires: cman-devel BuildRequires: glibc-devel gcc-c++ libxml2-devel BuildRequires: openssl-devel dbus-devel pam-devel pkgconfig BuildRequires: net-snmp-devel tog-pegasus-devel --- conga/ricci/modules/cluster/ClusterStatus.cpp 2007/09/28 04:47:56 1.23 +++ conga/ricci/modules/cluster/ClusterStatus.cpp 2007/10/09 19:58:29 1.24 @@ -150,7 +150,8 @@ { XMLObject s(*iter); if (s.tag() == "service") - s.set_attr("vm", (is_service_vm(cluster_conf, s.get_attr("name"))) ? "true" : "false"); + s.set_attr("vm", (is_service_vm(cluster_conf, + s.get_attr("name"))) ? "true" : "false"); status_new.add_child(s); } return status_new; --- conga/ricci/modules/cluster/clumon/src/cim-provider/Makefile 2007/09/18 21:21:52 1.7 +++ conga/ricci/modules/cluster/clumon/src/cim-provider/Makefile 2007/10/09 19:58:30 1.8 @@ -57,7 +57,7 @@ INCLUDE += -I ../include CXXFLAGS += $(PEGASUS_CXXFLAGS) -DPARANOIA=$(PARANOID) -LDFLAGS += -shared -ldl -lcrypt +LDFLAGS += -shared -ldl -lcrypt -lcman ifeq ($(PARANOID), 1) LDFLAGS += ${top_srcdir}/common/paranoid/*.o @@ -88,7 +88,7 @@ rebuild: clean all $(TARGET): $(OBJECTS) - $(CXX) $(LDFLAGS) -o $@ $(OBJECTS) + $(CXX) -o $@ $(OBJECTS) $(LDFLAGS) $(TARGET_TEST): clusterCIM_test.* $(CXX) $(CXXFLAGS) -lpegcommon -lpegclient -lpthread -lcrypt -o $@ $@.cpp --- conga/ricci/modules/cluster/clumon/src/common/Cluster.cpp 2007/09/18 20:16:26 1.8 +++ conga/ricci/modules/cluster/clumon/src/common/Cluster.cpp 2007/10/09 19:58:30 1.9 @@ -24,6 +24,10 @@ #include +extern "C" { +# include +} + using namespace std; using namespace ClusterMonitoring; @@ -65,6 +69,19 @@ unsigned int Cluster::votes() { + cman_handle_t ch = cman_init(NULL); + if (ch != NULL) { + char info[PIPE_BUF]; + cman_extra_info_t *cman_ei = (cman_extra_info_t *) info; + unsigned int total_votes = 0; + + if (cman_get_extra_info(ch, cman_ei, sizeof(info)) == 0) + total_votes = cman_ei->ei_total_votes; + cman_finish(ch); + if (total_votes > 0) + return (total_votes); + } + unsigned int votes = 0; for (map >::iterator iter = _nodes.begin() ; @@ -81,6 +98,20 @@ unsigned int Cluster::minQuorum() { + cman_handle_t ch = cman_init(NULL); + if (ch != NULL) { + char info[PIPE_BUF]; + cman_extra_info_t *cman_ei = (cman_extra_info_t *) info; + int minq = -1; + + if (cman_get_extra_info(ch, cman_ei, sizeof(info)) == 0) + minq = cman_ei->ei_quorum; + cman_finish(ch); + + if (minq != -1) + return minq; + } + if (_minQuorum != 0) return _minQuorum; else { @@ -101,6 +132,13 @@ bool Cluster::quorate() { + cman_handle_t ch = cman_init(NULL); + if (ch != NULL) { + int quorate = cman_is_quorate(ch); + cman_finish(ch); + return quorate; + } + return votes() >= minQuorum(); } --- conga/ricci/modules/cluster/clumon/src/daemon/Makefile 2007/09/11 02:42:50 1.8 +++ conga/ricci/modules/cluster/clumon/src/daemon/Makefile 2007/10/09 19:58:30 1.9 @@ -20,7 +20,7 @@ Peer.o \ Communicator.o -INCLUDE += -I ../include +INCLUDE += -I../include CXXFLAGS += -DPARANOIA=$(PARANOID) LDFLAGS += ../common/*.o @@ -30,6 +30,8 @@ LDFLAGS += ${top_srcdir}/common/*.o endif +LDFLAGS += -lcman + all: ${TARGET} install: @@ -49,4 +51,4 @@ *.o: *.h $(TARGET): $(OBJECTS) - $(CXX) -o $@ $(LDFLAGS) $(OBJECTS) + $(CXX) -o $@ $(OBJECTS) $(LDFLAGS) --- conga/ricci/modules/cluster/clumon/src/daemon/Monitor.cpp 2007/09/18 20:16:27 1.18 +++ conga/ricci/modules/cluster/clumon/src/daemon/Monitor.cpp 2007/10/09 19:58:30 1.19 @@ -25,7 +25,6 @@ #include "Logger.h" #include "Time.h" #include "utils.h" -#include "Network.h" #include #include @@ -54,9 +53,9 @@ static String cluster_version(); static String get_cman_tool_path(); -Monitor::Monitor(unsigned short port) : +Monitor::Monitor(unsigned short port, const String& ver) : _comm(port, *this), - _cl_version(cluster_version()), + _cl_version(ver.size() ? ver : cluster_version()), _cman_tool_path(get_cman_tool_path()), _cman_locking(_cl_version == "5") { @@ -550,44 +549,53 @@ } */ -/* -** FIXME: rewrite this to use libcman. -*/ vector Monitor::clustered_nodes() { vector running; if (_cman_locking) { - String out, err; - int status; - vector args; - args.push_back("nodes"); - - if (execute(_cman_tool_path, args, out, err, status, EXECUTE_TIMEOUT)) - throw String("clustered_nodes(): missing cman_tool"); - if (status) - return vector(); + int ret_nodes = -1; + int ret; + cman_node_t *node_array; + + cman_handle_t ch = cman_init(NULL); + if (ch == NULL) + throw String("Unable to communicate with cman"); + + ret = cman_get_node_count(ch); + if (ret <= 0) { + cman_finish(ch); + throw String("Unable to communicate with cman"); + } + + node_array = (cman_node_t *) malloc(sizeof(*node_array) * ret); + if (node_array == NULL) { + cman_finish(ch); + throw String("Out of memory"); + } + + if (cman_get_nodes(ch, ret, &ret_nodes, node_array) != 0) { + cman_finish(ch); + free(node_array); + throw String("Unable to communicate with cman"); + } + cman_finish(ch); - vector::size_type Sts_idx = 0; - vector lines = utils::split(out, "\n"); - for (vector::iterator - iter = lines.begin() ; - iter != lines.end() ; - iter++) - { - vector words = utils::split(utils::strip(*iter)); - if (words.size() < Sts_idx+1) - continue; - if (words[0] == "Node") { - // update Sts_idx - for (vector::size_type i = 0 ; i < words.size() ; i++) { - if (words[i] == "Sts") - Sts_idx = i; + try { + for (int i = 0 ; i < ret_nodes ; i++) { + if (node_array[i].cn_nodeid == 0) { + /* qdisk */; + continue; } - } else if (words[Sts_idx] == "M") - running.push_back(words.back()); + if (node_array[i].cn_member) + running.push_back(String(node_array[i].cn_name)); + } + } catch (...) { + free(node_array); + throw; } + free(node_array); } else if (_cl_version == "4") { String out, err; int status; @@ -625,61 +633,56 @@ String Monitor::nodename(const vector& nodenames) { - if (_cman_locking) { - String out, err; - int status; - - vector args(1, "status"); - if (execute(_cman_tool_path, args, out, err, status, EXECUTE_TIMEOUT)) - throw String("nodename(): missing ") + _cman_tool_path; - - if (status) { - // cman not running, match using address - out.clear(); - } + struct ifaddrs *if_list = NULL; + struct addrinfo hints; - vector lines = utils::split(utils::strip(out), "\n"); - for (vector::const_iterator - iter = lines.begin() ; - iter != lines.end() ; - iter++) - { - vector words = utils::split(utils::strip(*iter)); - if (words.size() != 3) - continue; - - if (words[0] + " " + words[1] == "Node name:") - return words[2]; + if (_cman_locking) { + cman_handle_t ch = cman_init(NULL); + if (ch != NULL) { + cman_node_t this_node; + if (cman_get_node(ch, CMAN_NODEID_US, &this_node) == 0) { + cman_finish(ch); + return String(this_node.cn_name); + } + cman_finish(ch); } } - /* FIXME: REWRITE THIS. */ - String out, err; - int status; - if (execute("/sbin/ifconfig", vector(), out, err, - status, EXECUTE_TIMEOUT)) - { - throw String("nodename(): missing ifconfig"); - } - if (status) - throw String("nodename(): ifconfig failed"); + if (getifaddrs(&if_list) != 0) + throw ("Unable to determine local node name"); + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_INET; for (vector::const_iterator iter = nodenames.begin() ; iter != nodenames.end() ; iter++) { - const String& nodename = *iter; - vector ips = Network::name2IP(nodename); - for (vector::iterator - iter_ip = ips.begin() ; - iter_ip != ips.end() ; - iter_ip++) - { - if (out.find(*iter_ip) != out.npos) - return nodename; + struct addrinfo *res; + if (getaddrinfo(iter->c_str(), NULL, &hints, &res) == 0) { + struct addrinfo *ai; + for (ai = res ; ai != NULL ; ai = ai->ai_next) { + struct ifaddrs *cur; + + for (cur = if_list ; cur != NULL ; cur = cur->ifa_next) { + if (!cur->ifa_addr || !(cur->ifa_flags & IFF_UP)) + continue; + if (cur->ifa_flags & IFF_LOOPBACK) + continue; + if (cur->ifa_addr->sa_family != AF_INET) + continue; + if (!memcmp(cur->ifa_addr, ai->ai_addr, ai->ai_addrlen)) { + freeaddrinfo(res); + freeifaddrs(if_list); + return *iter; + } + } + } + freeaddrinfo(res); } } + freeifaddrs(if_list); return ""; } @@ -802,31 +805,24 @@ } String -Monitor::probe_quorum() const +Monitor::probe_quorum() { if (_cman_locking) { - int status; - String out, err; - vector args; - - args.push_back("status"); - if (execute(_cman_tool_path, args, out, err, status, EXECUTE_TIMEOUT)) - throw _cman_tool_path + " status failed"; - if (status) - throw _cman_tool_path + " status failed"; + String ret; - vector lines = utils::split(out, "\n"); - for (vector::const_iterator - iter = lines.begin() ; - iter != lines.end() ; - iter++) - { - vector words = utils::split(*iter); - if (words.size() < 2) - continue; - if (words[0] == "Quorum:") - return words[1]; + cman_handle_t ch = cman_init(NULL); + if (ch == NULL) { + cman_finish(ch); + throw String("quorum not found"); } + + if (cman_is_quorate(ch)) + ret = "Quorate"; + else + ret = "Not Quorate"; + + cman_finish(ch); + return ret; } else { // TODO: implement quorum detection on GULM clusters throw String("GULM quorum detection not yet implemented"); @@ -837,6 +833,32 @@ String cluster_version() { + cman_handle_t ch = cman_init(NULL); + + if (ch != NULL) { + int ret; + cman_version_t cman_version; + char *clu_version = ""; + + ret = cman_get_version(ch, &cman_version); + if (ret >= 0) { + if (cman_version.cv_major == 6) + clu_version = "5"; + else if (cman_version.cv_major == 5) + clu_version = "4"; + else { + char version[32]; + snprintf(version, sizeof(version), "%d.%d.%d", + cman_version.cv_major, cman_version.cv_minor, + cman_version.cv_patch); + cman_finish(ch); + throw "unsupported cluster version: " + String(version); + } + } + cman_finish(ch); + return (clu_version); + } + int status; String out, err; vector args; --- conga/ricci/modules/cluster/clumon/src/daemon/Monitor.h 2007/09/18 20:16:27 1.8 +++ conga/ricci/modules/cluster/clumon/src/daemon/Monitor.h 2007/10/09 19:58:30 1.9 @@ -35,11 +35,19 @@ namespace ClusterMonitoring { +extern "C" { +# include +# include +# include +# include +# include +# include +} class Monitor : public Thread, public CommDP { public: - Monitor(unsigned short port); + Monitor(unsigned short port, const String& cluster_version); virtual ~Monitor(); String request(const String&); @@ -74,12 +82,12 @@ XMLObject parse_cluster_conf(); //bool clustered(); //bool quorate(); + String probe_quorum(); String nodename(const std::vector& nodenames); std::vector clustered_nodes(); std::vector services_info(); String uptime() const; - String probe_quorum() const; }; --- conga/ricci/modules/cluster/clumon/src/daemon/main.cpp 2007/09/26 21:35:20 1.8 +++ conga/ricci/modules/cluster/clumon/src/daemon/main.cpp 2007/10/09 19:58:30 1.9 @@ -27,6 +27,8 @@ #include #include +#include + typedef struct pollfd poll_fd; extern "C" { @@ -71,9 +73,20 @@ bool debug = false, foreground = false; int v_level = -1; int rv; + String clu_version(""); - while ((rv = getopt(argc, argv, "fdv:")) != EOF) { + while ((rv = getopt(argc, argv, "c:fdv:")) != EOF) { switch (rv) { + case 'c': { + char *p; + long cv = strtol(optarg, &p, 10); + if (*p != '\0' || cv < 3 || cv > 5) { + fprintf(stderr, "Invalid cluster version: %s\n", optarg); + exit(-1); + } + clu_version = String(optarg); + } + case 'd': debug = true; break; @@ -112,7 +125,8 @@ try { ServerSocket server(MONITORING_CLIENT_SOCKET); server.nonblocking(true); - Monitor monitor(COMMUNICATION_PORT); + + Monitor monitor(COMMUNICATION_PORT, clu_version); if (!foreground && (geteuid() == 0)) daemon_init(argv[0]); --- conga/ricci/modules/cluster/clumon/src/snmp-agent/Makefile 2007/09/11 02:42:50 1.6 +++ conga/ricci/modules/cluster/clumon/src/snmp-agent/Makefile 2007/10/09 19:58:30 1.7 @@ -27,6 +27,8 @@ LDFLAGS += ${top_srcdir}/common/*.o endif +LDFLAGS += -lcman + OBJECTS = clusterMonitorSnmp.o \ clusterMIB.o \ nodesMIB.o \