All of lore.kernel.org
 help / color / mirror / Atom feed
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.