[Cluster-devel] conga ./clustermon.spec.in.in ricci/modules/cl ...

rmccabe at sourceware.org rmccabe at sourceware.org
Tue Oct 9 19:58:32 UTC 2007


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 <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 \




More information about the Cluster-devel mailing list