[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