CVSROOT:        /cvs/cluster
Module name:    conga
Changes by:     [EMAIL PROTECTED]       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 $@ 
[EMAIL PROTECTED]
--- 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 <stdio.h>
 
+extern "C" {
+#      include <libcman.h>
+}
+
 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<String, counting_auto_ptr<Node> >::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 <sys/poll.h>
 #include <sys/sysinfo.h>
@@ -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<String>
 Monitor::clustered_nodes()
 {
        vector<String> running;
 
        if (_cman_locking) {
-               String out, err;
-               int status;
-               vector<String> 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<String>();
+               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<String>::size_type Sts_idx = 0;
-               vector<String> lines = utils::split(out, "\n");
-               for (vector<String>::iterator
-                               iter = lines.begin() ;
-                               iter != lines.end() ;
-                               iter++)
-               {
-                       vector<String> words = 
utils::split(utils::strip(*iter));
-                       if (words.size() < Sts_idx+1)
-                               continue;
-                       if (words[0] == "Node") {
-                               // update Sts_idx
-                               for (vector<String>::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<String>& nodenames)
 {
-       if (_cman_locking) {
-               String out, err;
-               int status;
-
-               vector<String> 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<String> lines = utils::split(utils::strip(out), "\n");
-               for (vector<String>::const_iterator
-                               iter = lines.begin() ;
-                               iter != lines.end() ;
-                               iter++)
-               {
-                       vector<String> 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<String>(), 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<String>::const_iterator
                        iter = nodenames.begin() ;
                        iter != nodenames.end() ;
                        iter++)
        {
-               const String& nodename = *iter;
-               vector<String> ips = Network::name2IP(nodename);
-               for (vector<String>::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<String> 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<String> lines = utils::split(out, "\n");
-               for (vector<String>::const_iterator
-                       iter = lines.begin() ;
-                       iter != lines.end() ;
-                       iter++)
-               {
-                       vector<String> 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<String> 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 <sys/socket.h>
+#      include <netdb.h>
+#      include <arpa/inet.h>
+#      include <net/if.h>
+#      include <ifaddrs.h>
+#      include <libcman.h>
+}
 
 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<String>& nodenames);
                std::vector<String> clustered_nodes();
                std::vector<XMLObject> 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 <sys/poll.h>
 #include <errno.h>
+#include <libcman.h>
+
 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 \

Reply via email to