From: kupcevic@sourceware.org <kupcevic@sourceware.org>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] conga/ricci/modules/cluster/clumon/src common/ ...
Date: 15 Aug 2006 00:12:34 -0000 [thread overview]
Message-ID: <20060815001234.20531.qmail@sourceware.org> (raw)
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;
reply other threads:[~2006-08-15 0:12 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20060815001234.20531.qmail@sourceware.org \
--to=kupcevic@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.