[Cluster-devel] conga/ricci/modules/cluster/clumon/src common/ ...
kupcevic at sourceware.org
kupcevic at sourceware.org
Tue Aug 15 00:12:34 UTC 2006
CVSROOT: /cvs/cluster
Module name: conga
Changes by: kupcevic at sourceware.org 2006-08-15 00:12:33
Modified files:
ricci/modules/cluster/clumon/src/common: Cluster.cpp
ricci/modules/cluster/clumon/src/daemon: Makefile Monitor.cpp
Monitor.h
ricci/modules/cluster/clumon/src/include: Cluster.h
Log message:
modclusterd: add support for CS5, fix clustered_nodes() probe if not quorate
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/common/Cluster.cpp.diff?cvsroot=cluster&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/daemon/Makefile.diff?cvsroot=cluster&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/daemon/Monitor.cpp.diff?cvsroot=cluster&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/daemon/Monitor.h.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/clumon/src/include/Cluster.h.diff?cvsroot=cluster&r1=1.5&r2=1.6
--- conga/ricci/modules/cluster/clumon/src/common/Cluster.cpp 2006/08/10 22:53:08 1.5
+++ conga/ricci/modules/cluster/clumon/src/common/Cluster.cpp 2006/08/15 00:12:32 1.6
@@ -29,9 +29,13 @@
using namespace ClusterMonitoring;
-Cluster::Cluster(const String &name, const String &alias, unsigned int minQuorum) :
+Cluster::Cluster(const String &name,
+ const String &alias,
+ const String &cluster_version,
+ unsigned int minQuorum) :
_name(name),
_alias(alias),
+ _cl_version(cluster_version),
_minQuorum(minQuorum)
{
// add no-node node
@@ -55,6 +59,12 @@
return _alias;
}
+String
+Cluster::version()
+{
+ return _cl_version;
+}
+
unsigned int
Cluster::votes()
{
@@ -240,6 +250,7 @@
XMLObject clu("cluster");
clu.set_attr("name", cluster.name());
clu.set_attr("alias", cluster.alias());
+ clu.set_attr("cluster_version", cluster.version());
sprintf(buff, "%u", cluster.votes());
clu.set_attr("votes", buff);
sprintf(buff, "%u", cluster.minQuorum());
@@ -299,7 +310,11 @@
if (sscanf(clu.get_attr("minQuorum").c_str(), "%u", &minQuorum) != 1)
throw String("xml2cluster(): invalid value for cluster's minQuorum");
String alias = clu.get_attr("alias");
- counting_auto_ptr<Cluster> cluster(new Cluster(name, alias, minQuorum));
+ String cl_version = clu.get_attr("cluster_version");
+ counting_auto_ptr<Cluster> cluster(new Cluster(name,
+ alias,
+ cl_version,
+ minQuorum));
// nodes
for (list<XMLObject>::const_iterator iter = clu.children().begin();
--- conga/ricci/modules/cluster/clumon/src/daemon/Makefile 2006/08/09 20:53:22 1.5
+++ conga/ricci/modules/cluster/clumon/src/daemon/Makefile 2006/08/15 00:12:33 1.6
@@ -40,6 +40,7 @@
rebuild: clean all
+*.o: *.h
$(TARGET): $(OBJECTS)
$(CXX) -o $@ $(LDFLAGS) $(OBJECTS)
--- conga/ricci/modules/cluster/clumon/src/daemon/Monitor.cpp 2006/08/10 22:53:08 1.5
+++ conga/ricci/modules/cluster/clumon/src/daemon/Monitor.cpp 2006/08/15 00:12:33 1.6
@@ -31,6 +31,7 @@
#include <sys/sysinfo.h>
#include <algorithm>
+#include <fstream>
using namespace ClusterMonitoring;
@@ -53,15 +54,23 @@
#define EXECUTE_TIMEOUT 3000
+#define CCS_TOOL_PATH "/sbin/ccs_tool"
static XMLObject
merge_xmls(const XMLObject& what, const XMLObject& with);
+static String
+cluster_version();
+static String
+get_cman_tool_path();
Monitor::Monitor(unsigned short port) :
- _comm(port, *this)
+ _comm(port, *this),
+ _cl_version(cluster_version()),
+ _cman_tool_path(get_cman_tool_path()),
+ _cman_locking(_cl_version == "5")
{
log("Monitor created", LogMonitor);
}
@@ -159,7 +168,7 @@
_cache[hostname] = data;
}
}
- // TODO other msgs
+ // TODO: other msgs
}
} catch ( ... ) {}
}
@@ -189,6 +198,8 @@
cluster.set_attr("minQuorum", probe_quorum());
} catch ( ... ) {}
+ cluster.set_attr("cluster_version", _cl_version);
+
// insert current node info
const vector<String> clustered_nodes = this->clustered_nodes();
for (list<XMLObject>::const_iterator iter = cluster.children().begin();
@@ -244,25 +255,38 @@
XMLObject
Monitor::parse_cluster_conf()
{
- int status;
- String out, err;
- vector<String> args;
- args.push_back("/etc/cluster/cluster.conf");
- if (execute("/bin/cat", args, out, err, status, EXECUTE_TIMEOUT))
- throw String("parse_cluster_conf(): missing cluster.conf");
- if (status)
- throw String("parse_cluster_conf(): missing cluster.conf");
+ XMLObject cluster_conf;
+ char* buff = 0;
+ try {
+ if (access("/etc/cluster/cluster.conf", R_OK))
+ throw String("missing /etc/cluster/cluster.conf");
+ ifstream is("/etc/cluster/cluster.conf");
+ is.seekg(0, ios::end);
+ unsigned int length = is.tellg();
+ is.seekg(0, ios::beg);
+ if (length < 5)
+ throw String("cluster.conf too short");
+ buff = new char[length];
+ is.read(buff, length);
+ String conf(buff, length);
+ delete [] buff; buff = 0;
+ cluster_conf = parseXML(conf);
+ if (cluster_conf.tag() != "cluster" ||
+ utils::strip(cluster_conf.get_attr("name")).empty())
+ throw String("parse_cluster_conf(): invalid cluster.conf");
+ } catch ( ... ) {
+ delete [] buff;
+ throw;
+ }
- XMLObject cluster_conf = parseXML(out);
- if (cluster_conf.tag() != "cluster")
- throw String("parse_cluster_conf(): invalid cluster.conf");
XMLObject cluster("cluster");
- cluster.set_attr("alias", "");
for (map<String, String>::const_iterator iter = cluster_conf.attrs().begin();
iter != cluster_conf.attrs().end();
iter++)
cluster.set_attr(iter->first, iter->second);
+ if (utils::strip(cluster.get_attr("alias")).empty())
+ cluster.set_attr("alias", cluster.get_attr("name"));
for (list<XMLObject>::const_iterator iter = cluster_conf.children().begin();
iter != cluster_conf.children().end();
@@ -305,6 +329,10 @@
}
}
+ if (_cl_version == "5")
+ cluster.set_attr("locking", "cman");
+ _cman_locking = (cluster.get_attr("locking") == "cman");
+
return cluster;
}
@@ -355,11 +383,12 @@
counting_auto_ptr<Cluster> cluster_ret;
String name = cluster.get_attr("name");
String alias = cluster.get_attr("alias");
+ String clu_version = cluster.get_attr("cluster_version");
unsigned int minQuorum = 0;
if (sscanf(cluster.get_attr("minQuorum").c_str(), "%u", &minQuorum) != 1)
- cluster_ret = counting_auto_ptr<Cluster> (new Cluster(name, alias));
+ cluster_ret = counting_auto_ptr<Cluster> (new Cluster(name, alias, clu_version));
else
- cluster_ret = counting_auto_ptr<Cluster> (new Cluster(name, alias, minQuorum));
+ cluster_ret = counting_auto_ptr<Cluster> (new Cluster(name, alias, clu_version, minQuorum));
// nodes
for (list<XMLObject>::const_iterator iter = cluster.children().begin();
iter != cluster.children().end();
@@ -454,46 +483,87 @@
vector<String>
Monitor::clustered_nodes()
{
- String out, err;
- int status;
- vector<String> args;
- args.push_back("members");
- if (execute("/sbin/magma_tool", args, out, err, status, EXECUTE_TIMEOUT))
- throw String("clustered_nodes(): missing magma_tool");
- if (status)
- return vector<String>();
-
- // split out by lines
- vector<String> lines;
- while (out.size()) {
- String::size_type idx = out.find('\n');
- lines.push_back(out.substr(0, idx));
- if (idx == out.npos)
- out = "";
- else
- out = out.substr(idx+1);
- }
-
vector<String> running;
- for (vector<String>::iterator iter = lines.begin();
- iter != lines.end();
- iter++) {
- String& line = *iter;
- if (line.find("Member ID") != line.npos) {
- String t = line.substr(line.find(": ") + 2);
- String::size_type idx = t.find(',');
- String name = t.substr(0, idx);
- String rest = t.substr(idx);
- if (rest.find("UP") != rest.npos)
- running.push_back(name);
+
+ 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>();
+ 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;
+ } else if (words[Sts_idx] == "M")
+ running.push_back(words.back());
}
- }
+ } else if (_cl_version == "4") {
+ String out, err;
+ int status;
+ vector<String> args;
+ args.push_back("members");
+ if (execute("/sbin/magma_tool", args, out, err, status, EXECUTE_TIMEOUT))
+ throw String("clustered_nodes(): missing magma_tool");
+ if (status)
+ return vector<String>();
+ vector<String> lines = utils::split(out, "\n");
+ for (vector<String>::iterator iter = lines.begin();
+ iter != lines.end();
+ iter++) {
+ String line = utils::strip(*iter);
+ if (line.find("Member ID") != line.npos) {
+ String t = line.substr(line.find(": ") + 2);
+ String::size_type idx = t.find(',');
+ String name = t.substr(0, idx);
+ String rest = t.substr(idx);
+ if (rest.find("UP") != rest.npos)
+ running.push_back(name);
+ }
+ }
+ } else
+ throw String("cluster version ") + _cl_version + " not supported";
+
return running;
}
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();
+
+ 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];
+ }
+ }
+
String out, err;
int status;
if (execute("/sbin/ifconfig", vector<String>(), out, err, status, EXECUTE_TIMEOUT))
@@ -513,6 +583,7 @@
return nodename;
}
}
+
return "";
}
@@ -531,7 +602,7 @@
if (execute("/usr/sbin/clustat", args, out, err, status, EXECUTE_TIMEOUT))
throw String("services_info(): missing clustat");
if (status)
- return vector<XMLObject>();
+ throw String("services_info(): `clustat -h` failed");
if (out.find("-f") != out.npos)
fast_available = true;
@@ -542,7 +613,7 @@
if (execute("/usr/sbin/clustat", args, out, err, status, EXECUTE_TIMEOUT))
throw String("services_info(): missing clustat");
if (status)
- return vector<XMLObject>();
+ throw String("services_info(): `clustat -x` failed");
XMLObject clustat = parseXML(out);
for (list<XMLObject>::const_iterator iter_c = clustat.children().begin();
@@ -619,32 +690,63 @@
String
Monitor::probe_quorum() const
{
+ 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";
+
+ 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];
+ }
+ } else {
+ // TODO: implement quorum detection on GULM clusters
+ throw String("GULM quorum detection not yet implemented");
+ }
+ throw String("quorum not found");
+}
+
+
+String
+cluster_version()
+{
int status;
String out, err;
vector<String> args;
- args.push_back("/proc/cluster/status");
- if (execute("/bin/cat", args, out, err, status, EXECUTE_TIMEOUT))
- throw String("no /proc/cluster/status");
+ args.push_back("-V");
+ if (execute(CCS_TOOL_PATH, args, out, err, status, EXECUTE_TIMEOUT))
+ throw String("missing ") + CCS_TOOL_PATH;
if (status)
- throw String("no /proc/cluster/status");
+ throw String(CCS_TOOL_PATH) + " -V failed";
- 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];
- }
- throw String("quorum not found");
+ vector<String> words = utils::split(utils::strip(out));
+ if (words.size() < 2)
+ throw String(CCS_TOOL_PATH) + " -V failed";
+ if (utils::strip(words[0]) != CCS_TOOL_PATH)
+ throw String(CCS_TOOL_PATH) + " -V failed";
+ String version = utils::strip(words[1]);
+ if (version.size() < 5)
+ throw String(CCS_TOOL_PATH) + ": unrecognizable version format";
+ if (version[0] == '1')
+ return "4";
+ else if (version[0] == '2')
+ return "5";
+ else
+ throw String(CCS_TOOL_PATH) + ": unsupported version";
}
-
-
-
XMLObject
merge_xmls(const XMLObject& what, const XMLObject& with)
{
@@ -690,3 +792,14 @@
return new_xml;
}
+
+
+
+String
+get_cman_tool_path()
+{
+ String path = "/sbin/cman_tool";
+ if (access(path.c_str(), X_OK))
+ path = "/usr/sbin/cman_tool";
+ return path;
+}
--- conga/ricci/modules/cluster/clumon/src/daemon/Monitor.h 2006/08/10 22:53:08 1.3
+++ conga/ricci/modules/cluster/clumon/src/daemon/Monitor.h 2006/08/15 00:12:33 1.4
@@ -58,10 +58,22 @@
Communicator _comm;
+ /*
+ cluster versions:
+ RHEL3 = "3"
+ RHEL4, FC4, FC5 = "4"
+ RHEL5, FC6 = "5"
+ */
+ const String _cl_version;
+
+ const String _cman_tool_path;
+
+ bool _cman_locking;
+
// return (nodenames - my_nodename)
std::vector<String> get_local_info(String& nodename,
- String& clustername,
- String& msg);
+ String& clustername,
+ String& msg);
counting_auto_ptr<Cluster> merge_data(const String& clustername);
XMLObject parse_cluster_conf();
--- conga/ricci/modules/cluster/clumon/src/include/Cluster.h 2006/08/10 22:53:08 1.5
+++ conga/ricci/modules/cluster/clumon/src/include/Cluster.h 2006/08/15 00:12:33 1.6
@@ -48,11 +48,15 @@
class Cluster
{
public:
- Cluster(const String& name, const String& alias, unsigned int minQuorum=0);
+ Cluster(const String& name,
+ const String& alias,
+ const String& cluster_version,
+ unsigned int minQuorum=0);
virtual ~Cluster();
String name();
String alias();
+ String version();
unsigned int votes();
unsigned int minQuorum();
bool quorate();
@@ -81,6 +85,7 @@
private:
String _name;
String _alias;
+ String _cl_version;
unsigned int _minQuorum;
std::map<String, counting_auto_ptr<Node> > _nodes;
More information about the Cluster-devel
mailing list