From mboxrd@z Thu Jan 1 00:00:00 1970 From: rmccabe@sourceware.org Date: 23 Aug 2007 15:30:33 -0000 Subject: [Cluster-devel] conga/ricci/modules/cluster ClusterConf.cpp Cl ... Message-ID: <20070823153033.26467.qmail@sourceware.org> List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit CVSROOT: /cvs/cluster Module name: conga Changes by: rmccabe at sourceware.org 2007-08-23 15:30:29 Modified files: ricci/modules/cluster: ClusterConf.cpp ClusterConf.h ClusterModule.h ClusterStatus.cpp ClusterStatus.h Clusvcadm.cpp Clusvcadm.h Fence.cpp Fence.h NoServiceManager.h Virt.cpp Virt.h main.cpp Log message: - Return more useful error messages in responses for failed commands - Readability/formatting/whitespace fixes. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/ClusterConf.cpp.diff?cvsroot=cluster&r1=1.10&r2=1.11 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/ClusterConf.h.diff?cvsroot=cluster&r1=1.3&r2=1.4 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/ClusterModule.h.diff?cvsroot=cluster&r1=1.1&r2=1.2 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/ClusterStatus.cpp.diff?cvsroot=cluster&r1=1.20&r2=1.21 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/ClusterStatus.h.diff?cvsroot=cluster&r1=1.4&r2=1.5 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/Clusvcadm.cpp.diff?cvsroot=cluster&r1=1.14&r2=1.15 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/Clusvcadm.h.diff?cvsroot=cluster&r1=1.3&r2=1.4 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/Fence.cpp.diff?cvsroot=cluster&r1=1.5&r2=1.6 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/Fence.h.diff?cvsroot=cluster&r1=1.2&r2=1.3 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/NoServiceManager.h.diff?cvsroot=cluster&r1=1.1&r2=1.2 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/Virt.cpp.diff?cvsroot=cluster&r1=1.4&r2=1.5 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/Virt.h.diff?cvsroot=cluster&r1=1.3&r2=1.4 http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/cluster/main.cpp.diff?cvsroot=cluster&r1=1.4&r2=1.5 --- conga/ricci/modules/cluster/ClusterConf.cpp 2007/08/22 18:47:19 1.10 +++ conga/ricci/modules/cluster/ClusterConf.cpp 2007/08/23 15:30:27 1.11 @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -33,131 +33,151 @@ using namespace std; -#define CLUSTER_CONF_DIR String("/etc/cluster/") -#define CLUSTER_CONF_NAME String("cluster.conf") -#define CLUSTER_CONF_PATH (CLUSTER_CONF_DIR + CLUSTER_CONF_NAME) +#define CLUSTER_CONF_DIR String("/etc/cluster/") +#define CLUSTER_CONF_NAME String("cluster.conf") +#define CLUSTER_CONF_PATH (CLUSTER_CONF_DIR + CLUSTER_CONF_NAME) -#define CCS_TOOL_PATH "/sbin/ccs_tool" +#define CCS_TOOL_PATH "/sbin/ccs_tool" -static void -set_CMAN_TOOL_PATH(); +static void set_CMAN_TOOL_PATH(); static String CMAN_TOOL_PATH; - XMLObject ClusterConf::get() { - return readXML(CLUSTER_CONF_PATH); + return readXML(CLUSTER_CONF_PATH); } void -ClusterConf::set(const XMLObject& xml, - bool propagate) -{ - set_CMAN_TOOL_PATH(); - - // sanity check - if (xml.tag() != "cluster") - throw String("invalid cluster.conf: no cluster tag"); - if (xml.get_attr("name").empty()) - throw String("invalid cluster.conf: no cluster name attribute"); - long long conf_version = utils::to_long(xml.get_attr("config_version")); - if (conf_version == 0) - throw String("invalid cluster.conf: no config_version attribute"); - - // create dir, if not existing - DIR* dir = opendir(CLUSTER_CONF_DIR.c_str()); - if (dir) - closedir(dir); - else { - if (errno == ENOENT) { - if (mkdir(CLUSTER_CONF_DIR.c_str(), - S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)) - throw String("failed to create ") + CLUSTER_CONF_DIR + ": " + String(strerror(errno)); - } else - throw String("opendir() error: ") + String(strerror(errno)); - } - - // save tmp cluster.conf - String tmp_path(CLUSTER_CONF_PATH + ".tmp_ricci"); - fstream fs(tmp_path.c_str(), - ios_base::out | ios_base::trunc); - fs << generateXML(xml); - fs.close(); - - // propagate/move to proper place - if (propagate) { - try { - String out, err; - int status; - vector args; - args.push_back("update"); - args.push_back(tmp_path); - if (utils::execute(CCS_TOOL_PATH, args, out, err, status, false)) - throw command_not_found_error_msg(CCS_TOOL_PATH); - if (status != 0) - throw String("ccs_tool failed: ") + err; - - if (is_cman(xml)) { - args.clear(); - args.push_back("version"); - args.push_back("-r"); - args.push_back(utils::to_string(conf_version)); - if (utils::execute(CMAN_TOOL_PATH, args, out, err, status, false)) - throw command_not_found_error_msg(CMAN_TOOL_PATH); - if (status != 0) - throw String("cman_tool failed: ") + err; - } - - unlink(tmp_path.c_str()); - } catch ( ... ) { - unlink(tmp_path.c_str()); - throw; - } - } else { - if (rename(tmp_path.c_str(), CLUSTER_CONF_PATH.c_str())) { - int errnold = errno; - unlink(tmp_path.c_str()); - throw String("failed to rename cluster.conf: ") + String(strerror(errnold)); - } - } +ClusterConf::set(const XMLObject& xml, bool propagate) { + set_CMAN_TOOL_PATH(); + char cconf_path[] = "/etc/cluster/cluster.conf.tmp.ricciXXXXXX"; + int err = 0; + + // sanity check + if (xml.tag() != "cluster") + throw String("invalid cluster.conf: no cluster tag"); + if (xml.get_attr("name").empty()) + throw String("invalid cluster.conf: no cluster name attribute"); + + long long conf_version = utils::to_long(xml.get_attr("config_version")); + if (conf_version == 0) + throw String("invalid cluster.conf: no config_version attribute"); + + // create dir, if it doesn't exist + DIR *dir = opendir(CLUSTER_CONF_DIR.c_str()); + if (dir) + closedir(dir); + else { + if (errno == ENOENT) { + if (mkdir(CLUSTER_CONF_DIR.c_str(), 0755)) + throw String("failed to create " + CLUSTER_CONF_DIR + + ": " + String(strerror(errno))); + } else + throw String("opendir() error: ") + String(strerror(errno)); + } + + mode_t old_umask = umask(0077); + int conf_fd = mkstemp(cconf_path); + err = errno; + umask(old_umask); + + if (conf_fd < 0) { + throw String("error creating temporary cluster.conf: " + + String(strerror(err))); + } + + String conf_xml(generateXML(xml)); + ssize_t ret = write(conf_fd, conf_xml.c_str(), conf_xml.size()); + err = errno; + close(conf_fd); + + if (ret != (ssize_t) conf_xml.size()) { + throw String("error creating temporary cluster.conf: " + + String(strerror(err))); + } + + // propagate/move to proper place + if (propagate) { + try { + String out, err; + int status; + vector args; + + args.push_back("update"); + args.push_back(cconf_path); + + if (utils::execute(CCS_TOOL_PATH, args, out, err, status, false)) + throw command_not_found_error_msg(CCS_TOOL_PATH); + if (status != 0) + throw String("ccs_tool failed to propagate conf: ") + err; + + if (is_cman(xml)) { + args.clear(); + args.push_back("version"); + args.push_back("-r"); + args.push_back(utils::to_string(conf_version)); + + if (utils::execute(CMAN_TOOL_PATH, args, out, + err, status, false)) + { + throw command_not_found_error_msg(CMAN_TOOL_PATH); + } + + if (status != 0) + throw String("cman_tool failed to update version: ") + err; + } + + unlink(cconf_path); + } catch ( ... ) { + unlink(cconf_path); + throw; + } + } else { + if (rename(cconf_path, CLUSTER_CONF_PATH.c_str())) { + int errnold = errno; + unlink(cconf_path); + throw String("failed to rename cluster.conf: ") + + String(strerror(errnold)); + } + } } -void +void ClusterConf::purge_conf() { - unlink(CLUSTER_CONF_PATH.c_str()); + unlink(CLUSTER_CONF_PATH.c_str()); } bool ClusterConf::is_gulm(const XMLObject& cluster_conf) { - for (list::const_iterator iter = cluster_conf.children().begin(); - iter != cluster_conf.children().end(); - iter++) - if (iter->tag() == "gulm") - return true; - return false; + for (list::const_iterator iter = cluster_conf.children().begin(); + iter != cluster_conf.children().end(); + iter++) + { + if (iter->tag() == "gulm") + return true; + } + return false; } bool ClusterConf::is_cman(const XMLObject& cluster_conf) { - return !is_gulm(cluster_conf); + return !is_gulm(cluster_conf); } - - -void +void set_CMAN_TOOL_PATH() { - static bool path_set = false; - if (!path_set) { - CMAN_TOOL_PATH = "/sbin/cman_tool"; - if (access(CMAN_TOOL_PATH.c_str(), X_OK)) - CMAN_TOOL_PATH = "/usr/sbin/cman_tool"; - path_set = true; - } + static bool path_set = false; + if (!path_set) { + CMAN_TOOL_PATH = "/sbin/cman_tool"; + if (access(CMAN_TOOL_PATH.c_str(), X_OK)) + CMAN_TOOL_PATH = "/usr/sbin/cman_tool"; + path_set = true; + } } --- conga/ricci/modules/cluster/ClusterConf.h 2006/10/05 17:38:01 1.3 +++ conga/ricci/modules/cluster/ClusterConf.h 2007/08/23 15:30:27 1.4 @@ -1,5 +1,5 @@ /* - Copyright Red Hat, Inc. 2005 + Copyright Red Hat, Inc. 2005-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -26,19 +26,15 @@ #include "XML.h" - class ClusterConf { - public: - static XMLObject get(); - static void set(const XMLObject& xml, - bool propagate=true); - static void purge_conf(); - - static bool is_gulm(const XMLObject& cluster_conf); - static bool is_cman(const XMLObject& cluster_conf); - -}; + public: + static XMLObject get(); + static void set(const XMLObject& xml, bool propagate=true); + static void purge_conf(); + static bool is_gulm(const XMLObject& cluster_conf); + static bool is_cman(const XMLObject& cluster_conf); +}; -#endif // ClusterConf_h +#endif // ClusterConf_h --- conga/ricci/modules/cluster/ClusterModule.h 2006/04/07 16:42:39 1.1 +++ conga/ricci/modules/cluster/ClusterModule.h 2007/08/23 15:30:27 1.2 @@ -1,5 +1,5 @@ /* - Copyright Red Hat, Inc. 2006 + Copyright Red Hat, Inc. 2006-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -26,16 +26,13 @@ #include "Module.h" - class ClusterModule : public Module { - public: - ClusterModule(); - virtual ~ClusterModule(); - - private: - -}; + public: + ClusterModule(); + virtual ~ClusterModule(); + private: +}; -#endif // ClusterModule_h +#endif // ClusterModule_h --- conga/ricci/modules/cluster/ClusterStatus.cpp 2007/08/22 18:47:19 1.20 +++ conga/ricci/modules/cluster/ClusterStatus.cpp 2007/08/23 15:30:27 1.21 @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -34,20 +34,18 @@ using namespace std; -static void -set_CMAN_TOOL_PATH(); +static void set_CMAN_TOOL_PATH(); static String CMAN_TOOL_PATH; -#define INITD_DIR_PATH "/etc/init.d/" -#define LSMOD_PATH "/sbin/lsmod" -#define MODPROBE_PATH "/sbin/modprobe" -#define CHKCONFIG_PATH "/sbin/chkconfig" -#define LVMCONF_PATH "/usr/sbin/lvmconf" - -#define CMAN_LEAVE_TIMEOUT "120" // seconds (string) -#define CLUMON_SYNC_TIME 8 // seconds -#define CMAN_SETTLE_TIME 3 // seconds - +#define INITD_DIR_PATH "/etc/init.d/" +#define LSMOD_PATH "/sbin/lsmod" +#define MODPROBE_PATH "/sbin/modprobe" +#define CHKCONFIG_PATH "/sbin/chkconfig" +#define LVMCONF_PATH "/usr/sbin/lvmconf" + +#define CMAN_LEAVE_TIMEOUT "120" // seconds (string) +#define CLUMON_SYNC_TIME 8 // seconds +#define CMAN_SETTLE_TIME 3 // seconds static void run_initd(const String& servname, bool start, bool fail); @@ -56,401 +54,410 @@ static void gulm_leave(); - - bool is_service_vm(const XMLObject& cluster_conf, const String& name) { - for (list::const_iterator iter = cluster_conf.children().begin(); - iter != cluster_conf.children().end(); - iter++) { - const XMLObject& kid = *iter; - if (kid.tag() == "rm") - for (list::const_iterator iter_s = kid.children().begin(); - iter_s != kid.children().end(); - iter_s++) { - const XMLObject& service_conf = *iter_s; - if (iter_s->tag() == "vm") - if (iter_s->get_attr("name") == name) - return true;; - } - } - return false; + for (list::const_iterator + iter = cluster_conf.children().begin() ; + iter != cluster_conf.children().end() ; + iter++) + { + const XMLObject& kid = *iter; + if (kid.tag() == "rm") { + for (list::const_iterator + iter_s = kid.children().begin() ; + iter_s != kid.children().end() ; + iter_s++) + { + if (iter_s->tag() == "vm") { + if (iter_s->get_attr("name") == name) + return true; + } + } + } + } + return false; } - - -XMLObject +XMLObject Cluster::status() { - ClientSocket sock; - - try { - ClientSocket s("/var/run/clumond.sock"); - sock = s; - } catch ( ... ) { - // start clumon - run_initd("modclusterd", true, true); - - // wait for it to come up and sync - sleep_sec(CLUMON_SYNC_TIME); - - // try again - ClientSocket s("/var/run/clumond.sock"); - sock = s; - } - sock.nonblocking(true); - - // send status request - int beg = int(time_sec()); - String request("GET"); - while ((int(time_sec()) < beg + 5)) { - bool read = false, write = true; - sock.ready(read, write, 500); - if (write) - if ((request = sock.send(request)).empty()) - break; - } - - // receive status report - beg = int(time_sec()); - String xml_in; - while ((int(time_sec()) < beg + 5)) { - bool read = true, write = false; - sock.ready(read, write, 500); - if (read) - xml_in += sock.recv(); - try { - parseXML(xml_in); - break; - } catch ( ... ) {} - } - - const XMLObject status_xml(parseXML(xml_in)); - - const XMLObject cluster_conf(ClusterConf::get()); - if (cluster_conf.get_attr("name") != status_xml.get_attr("name")) - throw String("cluster names mismatch"); - - // add "vm" attr to services - XMLObject status_new(status_xml.tag()); - for (map::const_iterator iter = status_xml.attrs().begin(); - iter != status_xml.attrs().end(); - iter++) - status_new.set_attr(iter->first, iter->second); - for (list::const_iterator iter = status_xml.children().begin(); - iter != status_xml.children().end(); - iter++) { - XMLObject s(*iter); - if (s.tag() == "service") - s.set_attr("vm", - (is_service_vm(cluster_conf, s.get_attr("name"))) ? "true" : "false"); - status_new.add_child(s); - } - return status_new; + ClientSocket sock; + + try { + ClientSocket s("/var/run/clumond.sock"); + sock = s; + } catch ( ... ) { + // start clumon + run_initd("modclusterd", true, true); + + // wait for it to come up and sync + sleep_sec(CLUMON_SYNC_TIME); + + // try again + ClientSocket s("/var/run/clumond.sock"); + sock = s; + } + sock.nonblocking(true); + + // send status request + int beg = int(time_sec()); + String request("GET"); + + while ((int(time_sec()) < beg + 5)) { + bool read = false, write = true; + sock.ready(read, write, 500); + if (write) { + if ((request = sock.send(request)).empty()) + break; + } + } + + // receive status report + beg = int(time_sec()); + String xml_in; + + while ((int(time_sec()) < beg + 5)) { + bool read = true, write = false; + sock.ready(read, write, 500); + if (read) + xml_in += sock.recv(); + try { + parseXML(xml_in); + break; + } catch ( ... ) {} + } + + const XMLObject status_xml(parseXML(xml_in)); + const XMLObject cluster_conf(ClusterConf::get()); + + if (cluster_conf.get_attr("name") != status_xml.get_attr("name")) + throw String("cluster names mismatch"); + + // add "vm" attr to services + XMLObject status_new(status_xml.tag()); + for (map::const_iterator + iter = status_xml.attrs().begin() ; + iter != status_xml.attrs().end() ; + iter++) + { + status_new.set_attr(iter->first, iter->second); + } + + for (list::const_iterator + iter = status_xml.children().begin() ; + iter != status_xml.children().end() ; + iter++) + { + XMLObject s(*iter); + if (s.tag() == "service") + s.set_attr("vm", (is_service_vm(cluster_conf, s.get_attr("name"))) ? "true" : "false"); + status_new.add_child(s); + } + return status_new; } -void +void Cluster::start_node(bool cluster_startup) { - XMLObject cluster_conf(ClusterConf::get()); // bailout if cluster.conf not present - XMLObject stat = status(); - bool cman_cluster = ClusterConf::is_cman(cluster_conf); - - if (stat.get_attr("cluster_version") == "4") { - run_initd("ccsd", true, false); - if (cman_cluster) - try { - run_initd("cman", true, true); - } catch ( ... ) { - // try again - run_initd("cman", true, true); - } - else - run_initd("lock_gulmd", true, true); - - if (cluster_startup) { - // wait for all nodes to join -> avoid fencing - bool all_in = false; - while (all_in == false) { - all_in = true; + // bail out if cluster.conf is not present + XMLObject cluster_conf(ClusterConf::get()); XMLObject stat = status(); - for (list::const_iterator iter = stat.children().begin(); - iter != stat.children().end(); - iter++) - if (iter->tag() == "node") - if (iter->get_attr("clustered") == "false") - all_in = false; - if (all_in == false) - sleep_sec(CLUMON_SYNC_TIME); - } - } - - bool use_qdisk = false; - cluster_conf = ClusterConf::get(); // ccsd should bring newest cluster.conf - for (list::const_iterator iter = cluster_conf.children().begin(); - iter != cluster_conf.children().end(); - iter++) - if (iter->tag() == "quorumd") - use_qdisk = true; - - if (use_qdisk) - run_initd("qdiskd", true, false); - if (cman_cluster) - run_initd("fenced", true, false); - run_initd("clvmd", true, false); - run_initd("gfs", true, false); - run_initd("rgmanager", true, true); - - // enable them on boot - - run_chkconfig("ccsd", true); - if (cman_cluster) { - run_chkconfig("cman", true); - run_chkconfig("lock_gulmd", false); - run_chkconfig("fenced", true); - } else { - run_chkconfig("cman", false); - run_chkconfig("fenced", false); - run_chkconfig("lock_gulmd", true); - } - if (use_qdisk) - run_chkconfig("qdiskd", true); - else - run_chkconfig("qdiskd", false); - run_chkconfig("clvmd", true); - run_chkconfig("gfs", true); - run_chkconfig("rgmanager", true); - - } else if (stat.get_attr("cluster_version") == "5") { - try { - run_initd("cman", true, true); - } catch ( ... ) { - // try again - run_initd("cman", true, true); - } - - if (cluster_startup) { - // wait for all nodes to join -> avoid fencing - // trouble: fenced started from within cman!!! - /* - bool all_in = false; - while (all_in == false) { - all_in = true; - XMLObject stat = status(); - for (list::const_iterator iter = stat.children().begin(); - iter != stat.children().end(); - iter++) - if (iter->tag() == "node") - if (iter->get_attr("clustered") == "false") - all_in = false; - if (all_in == false) - sleep_sec(CLUMON_SYNC_TIME); - } - */ - } - - bool use_qdisk = false; - cluster_conf = ClusterConf::get(); // ccsd should bring newest cluster.conf - for (list::const_iterator iter = cluster_conf.children().begin(); - iter != cluster_conf.children().end(); - iter++) - if (iter->tag() == "quorumd") - use_qdisk = true; - - if (use_qdisk) - run_initd("qdiskd", true, false); - run_initd("clvmd", true, false); - run_initd("gfs", true, false); - run_initd("gfs2", true, false); - run_initd("rgmanager", true, true); - - // enable them on boot - - run_chkconfig("cman", true); - if (use_qdisk) - run_chkconfig("qdiskd", true); - else - run_chkconfig("qdiskd", false); - run_chkconfig("clvmd", true); - run_chkconfig("gfs", true); - run_chkconfig("gfs2", true); - run_chkconfig("rgmanager", true); - } else { - throw String("unsupported cluster version ") + stat.get_attr("cluster_version"); - } -} + bool cman_cluster = ClusterConf::is_cman(cluster_conf); -void -Cluster::stop_node(bool cluster_shutdown, - bool purge_conf) -{ - XMLObject stat = status(); - - if (cluster_shutdown) { - // stop all services, so they don't bounce around - for (list::const_iterator iter = stat.children().begin(); - iter != stat.children().end(); - iter++) - if (iter->tag() == "service") - if (iter->get_attr("running") == "true") - try { - Clusvcadm::stop(iter->get_attr("name")); - } catch ( ... ) {} - } - - if (stat.get_attr("cluster_version") == "4") { - run_initd("rgmanager", false, true); - run_initd("gfs", false, false); - run_initd("clvmd", false, false); - run_initd("fenced", false, false); - run_initd("qdiskd", false, false); - if (ClusterConf::is_cman(ClusterConf::get())) - cman_leave(); - else - gulm_leave(); - run_initd("ccsd", false, false); - - // disable them on boot - - run_chkconfig("ccsd", false); - run_chkconfig("cman", false); - run_chkconfig("lock_gulmd", false); - run_chkconfig("qdiskd", false); - run_chkconfig("fenced", false); - run_chkconfig("clvmd", false); - run_chkconfig("gfs", false); - run_chkconfig("rgmanager", false); - - } else if (stat.get_attr("cluster_version") == "5") { - run_initd("rgmanager", false, true); - run_initd("gfs2", false, false); - run_initd("gfs", false, false); - run_initd("clvmd", false, false); - run_initd("qdiskd", false, false); - run_initd("cman", false, true); - - // disable them on boot - - run_chkconfig("cman", false); - run_chkconfig("qdiskd", false); - run_chkconfig("clvmd", false); - run_chkconfig("gfs", false); - run_chkconfig("gfs2", false); - run_chkconfig("rgmanager", false); - } else { - throw String("unsupported cluster version ") + stat.get_attr("cluster_version"); - } - - if (purge_conf) { - ClusterConf::purge_conf(); - - // disable LVM cluster locking - try { - String out, err; - int status; - vector args; - args.push_back("--disable-cluster"); - utils::execute(LVMCONF_PATH, args, out, err, status, false); - } catch ( ... ) {} - } + if (stat.get_attr("cluster_version") == "4") { + run_initd("ccsd", true, false); + if (cman_cluster) { + try { + run_initd("cman", true, true); + } catch ( ... ) { + // try again + run_initd("cman", true, true); + } + } else + run_initd("lock_gulmd", true, true); + + if (cluster_startup) { + // wait for all nodes to join -> avoid fencing + bool all_in = false; + while (all_in == false) { + all_in = true; + XMLObject stat = status(); + for (list::const_iterator + iter = stat.children().begin() ; + iter != stat.children().end() ; + iter++) + { + if (iter->tag() == "node") + if (iter->get_attr("clustered") == "false") + all_in = false; + if (all_in == false) + sleep_sec(CLUMON_SYNC_TIME); + } + } + } + + bool use_qdisk = false; + + // ccsd should bring newest cluster.conf + cluster_conf = ClusterConf::get(); + for (list::const_iterator + iter = cluster_conf.children().begin() ; + iter != cluster_conf.children().end() ; + iter++) + { + if (iter->tag() == "quorumd") + use_qdisk = true; + } + + if (use_qdisk) + run_initd("qdiskd", true, false); + + if (cman_cluster) + run_initd("fenced", true, false); + run_initd("clvmd", true, false); + run_initd("gfs", true, false); + run_initd("rgmanager", true, true); + + // enable them on boot + run_chkconfig("ccsd", true); + if (cman_cluster) { + run_chkconfig("cman", true); + run_chkconfig("fenced", true); + run_chkconfig("lock_gulmd", false); + } else { + run_chkconfig("cman", false); + run_chkconfig("fenced", false); + run_chkconfig("lock_gulmd", true); + } + + if (use_qdisk) + run_chkconfig("qdiskd", true); + else + run_chkconfig("qdiskd", false); + run_chkconfig("clvmd", true); + run_chkconfig("gfs", true); + run_chkconfig("rgmanager", true); + } else if (stat.get_attr("cluster_version") == "5") { + try { + run_initd("cman", true, true); + } catch ( ... ) { + // try again + run_initd("cman", true, true); + } + + bool use_qdisk = false; + // ccsd should bring newest cluster.conf + cluster_conf = ClusterConf::get(); + + for (list::const_iterator + iter = cluster_conf.children().begin() ; + iter != cluster_conf.children().end() ; + iter++) + { + if (iter->tag() == "quorumd") + use_qdisk = true; + } + + if (use_qdisk) + run_initd("qdiskd", true, false); + run_initd("clvmd", true, false); + run_initd("gfs", true, false); + run_initd("gfs2", true, false); + run_initd("rgmanager", true, true); + + // enable them on boot + run_chkconfig("cman", true); + if (use_qdisk) + run_chkconfig("qdiskd", true); + else + run_chkconfig("qdiskd", false); + run_chkconfig("clvmd", true); + run_chkconfig("gfs", true); + run_chkconfig("gfs2", true); + run_chkconfig("rgmanager", true); + } else { + throw String("unsupported cluster version ") + + stat.get_attr("cluster_version"); + } } +void +Cluster::stop_node(bool cluster_shutdown, bool purge_conf) +{ + XMLObject stat = status(); + if (cluster_shutdown) { + // stop all services, so they don't bounce around + for (list::const_iterator + iter = stat.children().begin() ; + iter != stat.children().end() ; + iter++) + { + if (iter->tag() == "service") { + if (iter->get_attr("running") == "true") { + try { + Clusvcadm::stop(iter->get_attr("name")); + } catch ( ... ) {} + } + } + } + } + + if (stat.get_attr("cluster_version") == "4") { + run_initd("rgmanager", false, true); + run_initd("gfs", false, false); + run_initd("clvmd", false, false); + run_initd("fenced", false, false); + run_initd("qdiskd", false, false); + + if (ClusterConf::is_cman(ClusterConf::get())) + cman_leave(); + else + gulm_leave(); + run_initd("ccsd", false, false); + + // disable them on boot + run_chkconfig("ccsd", false); + run_chkconfig("cman", false); + run_chkconfig("lock_gulmd", false); + run_chkconfig("qdiskd", false); + run_chkconfig("fenced", false); + run_chkconfig("clvmd", false); + run_chkconfig("gfs", false); + run_chkconfig("rgmanager", false); + } else if (stat.get_attr("cluster_version") == "5") { + run_initd("rgmanager", false, true); + run_initd("gfs2", false, false); + run_initd("gfs", false, false); + run_initd("clvmd", false, false); + run_initd("qdiskd", false, false); + run_initd("cman", false, true); + + // disable them on boot + run_chkconfig("cman", false); + run_chkconfig("qdiskd", false); + run_chkconfig("clvmd", false); + run_chkconfig("gfs", false); + run_chkconfig("gfs2", false); + run_chkconfig("rgmanager", false); + } else { + throw String("unsupported cluster version ") + + stat.get_attr("cluster_version"); + } + + if (purge_conf) { + ClusterConf::purge_conf(); + + // disable LVM cluster locking + try { + String out, err; + int status; + vector args; + + args.push_back("--disable-cluster"); + utils::execute(LVMCONF_PATH, args, out, err, status, false); + } catch ( ... ) {} + } +} -void -run_chkconfig(const String& servname, - bool on) +void +run_chkconfig(const String& servname, bool on) { - String out, err; - int status; - vector args; - args.push_back(servname); - if (on) - args.push_back("on"); - else - args.push_back("off"); - utils::execute(CHKCONFIG_PATH, args, out, err, status, false); + String out, err; + int status; + vector args; + + args.push_back(servname); + if (on) + args.push_back("on"); + else + args.push_back("off"); + utils::execute(CHKCONFIG_PATH, args, out, err, status, false); } -void +void run_initd(const String& servname, bool start, bool fail) { - String path(INITD_DIR_PATH); - path += servname; - - String out, err; - int status; - vector args; - if (start) - args.push_back("start"); - else - args.push_back("stop"); - bool failed = true; - if (utils::execute(path, args, out, err, status, false) == 0) - if (status == 0) - failed = false; - if (fail && failed) - throw String("service ") + servname + " " + String(start?"start":"stop") + " failed: " + err; + String path(INITD_DIR_PATH); + path += servname; + + String out, err; + int status; + vector args; + + if (start) + args.push_back("start"); + else + args.push_back("stop"); + bool failed = true; + + if (utils::execute(path, args, out, err, status, false) == 0) { + if (status == 0) + failed = false; + } + + if (fail && failed) { + throw String("service ") + servname + " " + + String(start ? "start" : "stop") + " failed: " + err; + } } -void +void cman_leave() { - set_CMAN_TOOL_PATH(); - - // when bz179627 gets fixed, just call service cman stop, but for now ... - String out, err; - int status; - vector args; - if (utils::execute(LSMOD_PATH, args, out, err, status, false)) - throw command_not_found_error_msg(LSMOD_PATH); - bool cman_loaded = (out.find("cman") != out.npos); - - if (cman_loaded) { - // wait until things settle down - sleep_sec(CMAN_SETTLE_TIME); - - args.clear(); - args.push_back("leave"); - args.push_back("-t"); - args.push_back(CMAN_LEAVE_TIMEOUT); - args.push_back("-w"); - args.push_back("remove"); - utils::execute(CMAN_TOOL_PATH, args, out, err, status, false); - - // bz149282 - sleep_sec(CMAN_SETTLE_TIME); - - args.clear(); - args.push_back("-r"); - args.push_back("dlm"); - args.push_back("cman"); - if (utils::execute(MODPROBE_PATH, args, out, err, status, false)) - throw command_not_found_error_msg(MODPROBE_PATH); - if (status != 0) - throw String("modprobe -r failed: ") + err; - } + set_CMAN_TOOL_PATH(); + + // when bz179627 gets fixed, just call service cman stop, but for now ... + String out, err; + int status; + vector args; + + if (utils::execute(LSMOD_PATH, args, out, err, status, false)) + throw command_not_found_error_msg(LSMOD_PATH); + + bool cman_loaded = (out.find("cman") != out.npos); + if (cman_loaded) { + // wait until things settle down + sleep_sec(CMAN_SETTLE_TIME); + + args.clear(); + args.push_back("leave"); + args.push_back("-t"); + args.push_back(CMAN_LEAVE_TIMEOUT); + args.push_back("-w"); + args.push_back("remove"); + utils::execute(CMAN_TOOL_PATH, args, out, err, status, false); + + // bz149282 + sleep_sec(CMAN_SETTLE_TIME); + + args.clear(); + args.push_back("-r"); + args.push_back("dlm"); + args.push_back("cman"); + if (utils::execute(MODPROBE_PATH, args, out, err, status, false)) + throw command_not_found_error_msg(MODPROBE_PATH); + if (status != 0) + throw String("modprobe -r failed: ") + err; + } } -void +void gulm_leave() { - // TODO: implement me - - run_initd("lock_gulmd", false, true); + // TODO: implement me + run_initd("lock_gulmd", false, true); } - - -void +void set_CMAN_TOOL_PATH() { - static bool path_set = false; - if (!path_set) { - CMAN_TOOL_PATH = "/sbin/cman_tool"; - if (access(CMAN_TOOL_PATH.c_str(), X_OK)) - CMAN_TOOL_PATH = "/usr/sbin/cman_tool"; - path_set = true; - } + static bool path_set = false; + if (!path_set) { + CMAN_TOOL_PATH = "/sbin/cman_tool"; + if (access(CMAN_TOOL_PATH.c_str(), X_OK)) + CMAN_TOOL_PATH = "/usr/sbin/cman_tool"; + path_set = true; + } } --- conga/ricci/modules/cluster/ClusterStatus.h 2006/10/05 17:38:01 1.4 +++ conga/ricci/modules/cluster/ClusterStatus.h 2007/08/23 15:30:27 1.5 @@ -1,5 +1,5 @@ /* - Copyright Red Hat, Inc. 2005 + Copyright Red Hat, Inc. 2005-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -26,17 +26,13 @@ #include "XML.h" - class Cluster { - public: - static XMLObject status(); - - static void start_node(bool cluster_startup = false); - static void stop_node(bool cluster_shutdown = false, - bool purge_conf = false); - + public: + static XMLObject status(); + static void start_node(bool cluster_startup = false); + static void stop_node( bool cluster_shutdown = false, + bool purge_conf = false); }; - -#endif // ClusterStatus_h +#endif // ClusterStatus_h --- conga/ricci/modules/cluster/Clusvcadm.cpp 2007/08/22 18:47:19 1.14 +++ conga/ricci/modules/cluster/Clusvcadm.cpp 2007/08/23 15:30:27 1.15 @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -29,336 +29,408 @@ using namespace std; - -#define CLUSTAT_TOOL_PATH "/usr/sbin/clustat" -#define CLUSVCADM_TOOL_PATH "/usr/sbin/clusvcadm" - +#define CLUSTAT_TOOL_PATH "/usr/sbin/clustat" +#define CLUSVCADM_TOOL_PATH "/usr/sbin/clusvcadm" class ServiceStatus { -public: - enum state { - RG_STATE_STOPPED = 110, // Resource group is stopped - RG_STATE_STARTING = 111, // Resource is starting - RG_STATE_STARTED = 112, // Resource is started - RG_STATE_STOPPING = 113, // Resource is stopping - RG_STATE_FAILED = 114, // Resource has failed - RG_STATE_UNINITIALIZED = 115, // Thread not running yet - RG_STATE_CHECK = 116, // Checking status - RG_STATE_ERROR = 117, // Recoverable error - RG_STATE_RECOVER = 118, // Pending recovery - RG_STATE_DISABLED = 119, // Resource not allowd to run - RG_STATE_MIGRATE = 120 // Resource migrating - }; - - ServiceStatus(const String& name, - const String& node, - state status, - bool vm) : - name(name), - node(node), - status(status), - vm(vm) {} - virtual ~ServiceStatus() {} - - String name; - String node; - state status; - bool vm; + public: + enum state { + RG_STATE_STOPPED = 110, // Resource group is stopped + RG_STATE_STARTING = 111, // Resource is starting + RG_STATE_STARTED = 112, // Resource is started + RG_STATE_STOPPING = 113, // Resource is stopping + RG_STATE_FAILED = 114, // Resource has failed + RG_STATE_UNINITIALIZED = 115, // Thread not running yet + RG_STATE_CHECK = 116, // Checking status + RG_STATE_ERROR = 117, // Recoverable error + RG_STATE_RECOVER = 118, // Pending recovery + RG_STATE_DISABLED = 119, // Resource not allowd to run + RG_STATE_MIGRATE = 120 // Resource migrating + }; + + ServiceStatus(const String& name, + const String& node, state status, bool vm) : + name(name), + node(node), + status(status), + vm(vm) {} + virtual ~ServiceStatus() {} + + String name; + String node; + state status; + bool vm; }; +static pair, list > service_states(); -static pair, list > -service_states(); +void +Clusvcadm::start(const String& servicename, const String& nodename) +{ + pair, list > info = service_states(); + list nodes = info.first; + list services = info.second; + + // check if node can run services + bool node_found = false; + + for (list::const_iterator + iter = nodes.begin() ; + iter != nodes.end() ; + iter++) + { + if (*iter == nodename) { + node_found = true; + break; + } + } + if (!node_found && nodename.size()) { + throw String("Node " + nodename + + " is unable to run cluster services. Check whether the rgmanager service is running on that node."); + } + // start + for (list::const_iterator + iter = services.begin() ; + iter != services.end() ; + iter++) + { + if (iter->name != servicename) + continue; + String flag; + + if (iter->status == ServiceStatus::RG_STATE_MIGRATE) + throw String(servicename + " is in the process of being migrated"); + + /* + ** Failed services must be disabled before they can be + ** started again. + */ + if (iter->status == ServiceStatus::RG_STATE_FAILED) { + try { + Clusvcadm::stop(servicename); + } catch (String e) { + throw String("Unable to disable failed service " + + servicename + " before starting it: " + e); + } catch ( ... ) { + throw String("Unable to disable failed service " + + servicename + " before starting it"); + } + flag = "-e"; + } else if ( iter->status == ServiceStatus::RG_STATE_STOPPED || + iter->status == ServiceStatus::RG_STATE_STOPPING || + iter->status == ServiceStatus::RG_STATE_ERROR || + iter->status == ServiceStatus::RG_STATE_DISABLED) + { + flag = "-e"; + } else if ( iter->status == ServiceStatus::RG_STATE_STARTED || + iter->status == ServiceStatus::RG_STATE_STARTING) + { + flag = "-r"; + } + + if (flag.size() < 1) { + throw String(servicename + " is in unknown state " + + utils::to_string(iter->status)); + } + + String out, err; + int status; + vector args; + + args.push_back(flag); + if (iter->vm) + args.push_back("vm:" + servicename); + else + args.push_back(servicename); + + if (nodename.size()) { + args.push_back("-m"); + args.push_back(nodename); + } + + if (utils::execute(CLUSVCADM_TOOL_PATH, args, out, err, status, false)) + throw command_not_found_error_msg(CLUSVCADM_TOOL_PATH); + + if (status != 0) { + throw String("clusvcadm start failed to start " + + servicename + ": " + err); + } + return; + } + throw String(servicename + ": no such cluster service"); +} -void -Clusvcadm::start(const String& servicename, - const String& nodename) +void +Clusvcadm::migrate(const String& servicename, const String& nodename) { - pair, list > info = service_states(); - list nodes = info.first; - list services = info.second; - - // check if node can run services - bool node_found = false; - for (list::const_iterator iter = nodes.begin(); - iter != nodes.end(); - iter++) - if (*iter == nodename) - node_found = true; - if (!node_found && nodename.size()) - throw String("Node " + nodename + " is unable to run cluster services. Check whether the rgmanager service is running"); - - // start - for (list::const_iterator iter = services.begin(); - iter != services.end(); - iter++) - if (iter->name == servicename) { - String flag; - - if (iter->status == ServiceStatus::RG_STATE_MIGRATE) - throw String(servicename + " is in the process of being migrated"); - - /* - ** Failed services must be disabled before they can be - ** started again. - */ - if (iter->status == ServiceStatus::RG_STATE_FAILED) { - try { - Clusvcadm::stop(servicename); - } catch ( ... ) { - throw String("Unable to disable failed service " + servicename + " before starting it"); - } - flag = "-e"; - } else if (iter->status == ServiceStatus::RG_STATE_STOPPED || - iter->status == ServiceStatus::RG_STATE_STOPPING || - iter->status == ServiceStatus::RG_STATE_ERROR || - iter->status == ServiceStatus::RG_STATE_DISABLED) - flag = "-e"; - else if (iter->status == ServiceStatus::RG_STATE_STARTED || - iter->status == ServiceStatus::RG_STATE_STARTING) - flag = "-r"; - - if (flag.size()) { - String out, err; - int status; - vector args; - args.push_back(flag); - if (iter->vm) + pair, list > info = service_states(); + list nodes = info.first; + list services = info.second; + + // check if node can run services + bool node_found = false; + for (list::const_iterator + iter = nodes.begin() ; + iter != nodes.end() ; + iter++) + { + if (*iter == nodename) { + node_found = true; + break; + } + } + + if (!node_found && nodename.size()) + throw String("Node " + nodename + " is unable to run cluster services. Check whether the rgmanager service is running on that node."); + + // start + for (list::const_iterator + iter = services.begin() ; + iter != services.end() ; + iter++) + { + if (!iter->vm) + continue; + if (iter->name != servicename) + continue; + + String flag; + if (iter->status == ServiceStatus::RG_STATE_MIGRATE) + throw String(servicename + + " is already in the process of being migrated"); + + if (iter->status == ServiceStatus::RG_STATE_FAILED) { + try { + Clusvcadm::stop(servicename); + } catch (String e) { + throw String("Unable to disable failed service " + + servicename + " before starting it: " + e); + } catch ( ... ) { + throw String("Unable to disable failed service " + + servicename + " before starting it"); + } + flag = "-e"; + } else if ( iter->status == ServiceStatus::RG_STATE_STOPPED || + iter->status == ServiceStatus::RG_STATE_STOPPING || + iter->status == ServiceStatus::RG_STATE_ERROR || + iter->status == ServiceStatus::RG_STATE_DISABLED) + { + flag = "-e"; + } else if ( iter->status == ServiceStatus::RG_STATE_STARTED || + iter->status == ServiceStatus::RG_STATE_STARTING) + { + flag = "-M"; + } + + if (flag.size() < 1) { + throw String(servicename + " is in unknown state " + + utils::to_string(iter->status)); + } + + String out, err; + int status; + vector args; + + args.push_back(flag); args.push_back("vm:" + servicename); - else - args.push_back(servicename); - if (nodename.size()) { - args.push_back("-m"); - args.push_back(nodename); + + if (nodename.size()) { + args.push_back("-m"); + args.push_back(nodename); + } + + if (utils::execute(CLUSVCADM_TOOL_PATH, args, out, err, status, false)) + throw command_not_found_error_msg(CLUSVCADM_TOOL_PATH); + + if (status != 0) { + throw String("clusvcadm failed to migrate " + + servicename + ": " + err); + } + return; } - if (utils::execute(CLUSVCADM_TOOL_PATH, args, out, err, status, false)) - throw command_not_found_error_msg(CLUSVCADM_TOOL_PATH); - if (status != 0) - throw String("clusvcadm failed to start " + servicename); - } - return; - } - - throw String(servicename + ": no such cluster service"); + + throw String(servicename + ": no such virtual machine service"); } -void -Clusvcadm::migrate(const String& servicename, const String& nodename) +void +Clusvcadm::stop(const String& servicename) { - pair, list > info = service_states(); - list nodes = info.first; - list services = info.second; - - // check if node can run services - bool node_found = false; - for (list::const_iterator iter = nodes.begin(); - iter != nodes.end(); - iter++) - if (*iter == nodename) - node_found = true; - if (!node_found && nodename.size()) - throw String("Node " + nodename + " is unable to run cluster services. Check whether the rgmanager service is running"); - - // start - for (list::const_iterator iter = services.begin(); - iter != services.end(); - iter++) { - if (!iter->vm) - continue; - if (iter->name == servicename) { - String flag; - if (iter->status == ServiceStatus::RG_STATE_MIGRATE) - throw String(servicename + " is already in the process of being migrated"); - - if (iter->status == ServiceStatus::RG_STATE_FAILED) { - try { - Clusvcadm::stop(servicename); - } catch ( ... ) { - throw String("Unable to disable failed service " + servicename + " before starting it"); - } - flag = "-e"; - } else if (iter->status == ServiceStatus::RG_STATE_STOPPED || - iter->status == ServiceStatus::RG_STATE_STOPPING || - iter->status == ServiceStatus::RG_STATE_ERROR || - iter->status == ServiceStatus::RG_STATE_DISABLED) - flag = "-e"; - else if (iter->status == ServiceStatus::RG_STATE_STARTED || - iter->status == ServiceStatus::RG_STATE_STARTING) - flag = "-M"; - - if (flag.size()) { - String out, err; - int status; - vector args; - args.push_back(flag); - args.push_back("vm:" + servicename); - if (nodename.size()) { - args.push_back("-m"); - args.push_back(nodename); + pair, list > info = service_states(); + list nodes = info.first; + list services = info.second; + + for (list::const_iterator + iter = services.begin() ; + iter != services.end() ; + iter++) + { + if (iter->name != servicename) + continue; + + if (iter->status == ServiceStatus::RG_STATE_STARTING || + iter->status == ServiceStatus::RG_STATE_FAILED || + iter->status == ServiceStatus::RG_STATE_STARTED) + { + String out, err; + int status; + vector args; + + args.push_back("-d"); + if (iter->vm) + args.push_back("vm:" + servicename); + else + args.push_back(servicename); + + if (utils::execute(CLUSVCADM_TOOL_PATH, args, out, err, status, false)) + throw command_not_found_error_msg(CLUSVCADM_TOOL_PATH); + + if (status != 0) { + throw String("clusvcadm failed to stop " + + servicename + ": " + err); + } + return; + } } - if (utils::execute(CLUSVCADM_TOOL_PATH, args, out, err, status, false)) - throw command_not_found_error_msg(CLUSVCADM_TOOL_PATH); - if (status != 0) - throw String("clusvcadm failed to migrate " + servicename + ": " + err); - } - return; - } - } - - throw String(servicename + ": no such virtual machine service"); + + throw String(servicename + ": no such cluster service"); } -void -Clusvcadm::stop(const String& servicename) +void +Clusvcadm::restart(const String& servicename) { - pair, list > info = service_states(); - list nodes = info.first; - list services = info.second; - - for (list::const_iterator iter = services.begin(); - iter != services.end(); - iter++) - if (iter->name == servicename) { - if (iter->status == ServiceStatus::RG_STATE_STARTING || - iter->status == ServiceStatus::RG_STATE_FAILED || - iter->status == ServiceStatus::RG_STATE_STARTED) { - String out, err; - int status; - vector args; - args.push_back("-d"); - if (iter->vm) - args.push_back("vm:" + servicename); - else - args.push_back(servicename); - if (utils::execute(CLUSVCADM_TOOL_PATH, args, out, err, status, false)) - throw command_not_found_error_msg(CLUSVCADM_TOOL_PATH); - if (status != 0) - throw String("clusvcadm failed to stop " + servicename + ": " + err); - } - return; - } - - throw String(servicename + ": no such cluster service"); + pair, list > info = service_states(); + list nodes = info.first; + list services = info.second; + + for (list::const_iterator + iter = services.begin() ; + iter != services.end() ; + iter++) + { + if (iter->name != servicename) + continue; + if (iter->status == ServiceStatus::RG_STATE_MIGRATE) + throw String(servicename + " is in the process of being migrated"); + if (iter->status == ServiceStatus::RG_STATE_STARTING) + throw String(servicename + " is in the process of being started"); + + String flag; + if (iter->status == ServiceStatus::RG_STATE_FAILED) { + try { + Clusvcadm::stop(servicename); + } catch (String e) { + throw String("Unable to disable failed service " + + servicename + " before starting it: " + e); + } catch ( ... ) { + throw String("Unable to disable failed service " + + servicename + " before starting it"); + } + flag = "-e"; + } else if ( iter->status == ServiceStatus::RG_STATE_STOPPED || + iter->status == ServiceStatus::RG_STATE_STOPPING || + iter->status == ServiceStatus::RG_STATE_ERROR || + iter->status == ServiceStatus::RG_STATE_DISABLED) + { + flag = "-e"; + } else if (iter->status == ServiceStatus::RG_STATE_STARTED) + flag = "-R"; + + if (flag.size() < 1) { + throw String(servicename + " is in unknown state " + + utils::to_string(iter->status)); + } + + String out, err; + int status; + vector args; + args.push_back(flag); + + if (iter->vm) + args.push_back("vm:" + servicename); + else + args.push_back(servicename); + + if (utils::execute(CLUSVCADM_TOOL_PATH, args, out, err, status, false)) + throw command_not_found_error_msg(CLUSVCADM_TOOL_PATH); + if (status != 0) + throw String("clusvcadm failed to restart cluster service " + servicename + ": " + err); + return; + } + + throw String(servicename + ": no such cluster service"); } -void -Clusvcadm::restart(const String& servicename) +pair, list > service_states() { - pair, list > info = service_states(); - list nodes = info.first; - list services = info.second; - - for (list::const_iterator iter = services.begin(); - iter != services.end(); - iter++) - if (iter->name == servicename) { - String flag; - if (iter->status == ServiceStatus::RG_STATE_MIGRATE) - throw String(servicename + " is in the process of being migrated"); - if (iter->status == ServiceStatus::RG_STATE_STARTING) - throw String(servicename + " is in the process of being started"); - - if (iter->status == ServiceStatus::RG_STATE_FAILED) { - try { - Clusvcadm::stop(servicename); - } catch ( ... ) { - throw String("Unable to disable failed service " + servicename + " before starting it"); - } - flag = "-e"; - } else if (iter->status == ServiceStatus::RG_STATE_STOPPED || - iter->status == ServiceStatus::RG_STATE_STOPPING || - iter->status == ServiceStatus::RG_STATE_ERROR || - iter->status == ServiceStatus::RG_STATE_DISABLED) - flag = "-e"; - else if (iter->status == ServiceStatus::RG_STATE_STARTED) - flag = "-R"; - - if (flag.size()) { String out, err; int status; vector args; - args.push_back(flag); - if (iter->vm) - args.push_back("vm:" + servicename); - else - args.push_back(servicename); - if (utils::execute(CLUSVCADM_TOOL_PATH, args, out, err, status, false)) - throw command_not_found_error_msg(CLUSVCADM_TOOL_PATH); - if (status != 0) - throw String("clusvcadm failed to restart cluster service " + servicename + ": " + err); - } - return; - } - - throw String(servicename + ": no such cluster service"); -} + args.clear(); + args.push_back("-f"); + args.push_back("-x"); + if (utils::execute(CLUSTAT_TOOL_PATH, args, out, err, status, false)) + throw command_not_found_error_msg(CLUSTAT_TOOL_PATH); + if (status) + throw String("clustat -fx failed: " + err); + + XMLObject xml = parseXML(out); + if (xml.tag() != "clustat") + throw String("invalid clustat output (expecting 'clustat' tag)"); + + XMLObject nodes_xml("noname"), groups_xml("noname"), quorum_xml("noname"); + for (list::const_iterator + iter = xml.children().begin() ; + iter != xml.children().end() ; + iter++) + { + if (iter->tag() == "nodes") + nodes_xml = *iter; + else if (iter->tag() == "groups") + groups_xml = *iter; + else if (iter->tag() == "quorum") + quorum_xml = *iter; + } + if (quorum_xml.get_attr("groupmember") != "1") + throw NoServiceManager(); + list nodes; + for (list::const_iterator + iter = nodes_xml.children().begin() ; + iter != nodes_xml.children().end() ; + iter++) + { + if (iter->tag() == "node") + nodes.push_back(iter->get_attr("name")); + } -pair, list > -service_states() -{ - String out, err; - int status; - vector args; - - args.clear(); - args.push_back("-f"); - args.push_back("-x"); - if (utils::execute(CLUSTAT_TOOL_PATH, args, out, err, status, false)) - throw command_not_found_error_msg(CLUSTAT_TOOL_PATH); - if (status) - throw String("clustat failed: ") + err; - - XMLObject xml = parseXML(out); - if (xml.tag() != "clustat") - throw String("invalid clustat output: no clustat tag"); - - XMLObject nodes_xml("noname"), groups_xml("noname"), quorum_xml("noname"); - for (list::const_iterator iter = xml.children().begin(); - iter != xml.children().end(); - iter++) - if (iter->tag() == "nodes") - nodes_xml = *iter; - else if (iter->tag() == "groups") - groups_xml = *iter; - else if (iter->tag() == "quorum") - quorum_xml = *iter; - - if (quorum_xml.get_attr("groupmember") != "1") - throw NoServiceManager(); - - list nodes; - for (list::const_iterator iter = nodes_xml.children().begin(); - iter != nodes_xml.children().end(); - iter++) - if (iter->tag() == "node") - nodes.push_back(iter->get_attr("name")); - - list services; - for (list::const_iterator iter = groups_xml.children().begin(); - iter != groups_xml.children().end(); - iter++) - if (iter->tag() == "group") { - bool vm = false; - String name(iter->get_attr("name")); - String::size_type idx = name.find(":"); - if (idx != name.npos) { - if (name.substr(0, idx) == "vm") - vm = true; - name = name.substr(idx + 1); - } - String node(iter->get_attr("owner")); - ServiceStatus::state state = (ServiceStatus::state) - utils::to_long(iter->get_attr("state")); - services.push_back(ServiceStatus(name, node, state, vm)); - } - - return pair, list >(nodes, services); + list services; + for (list::const_iterator + iter = groups_xml.children().begin() ; + iter != groups_xml.children().end() ; + iter++) + { + if (iter->tag() == "group") { + bool vm = false; + String name(iter->get_attr("name")); + String::size_type idx = name.find(":"); + if (idx != name.npos) { + if (name.substr(0, idx) == "vm") + vm = true; + name = name.substr(idx + 1); + } + String node(iter->get_attr("owner")); + ServiceStatus::state state = + (ServiceStatus::state) utils::to_long(iter->get_attr("state")); + services.push_back(ServiceStatus(name, node, state, vm)); + } + } + + return pair, list >(nodes, services); } --- conga/ricci/modules/cluster/Clusvcadm.h 2007/03/09 22:48:20 1.3 +++ conga/ricci/modules/cluster/Clusvcadm.h 2007/08/23 15:30:27 1.4 @@ -1,5 +1,5 @@ /* - Copyright Red Hat, Inc. 2005 + Copyright Red Hat, Inc. 2005-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -13,28 +13,25 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * Author: Stanko Kupcevic */ - #ifndef Clusvcadm_h #define Clusvcadm_h #include "String.h" - class Clusvcadm { - public: - static void start(const String& servicename, const String& nodename); - static void migrate(const String& servicename, const String& nodename); - static void restart(const String& servicename); - static void stop(const String& servicename); + public: + static void start(const String& servicename, const String& nodename); + static void migrate(const String& servicename, const String& nodename); + static void restart(const String& servicename); + static void stop(const String& servicename); }; - -#endif // Clusvcadm_h +#endif // Clusvcadm_h --- conga/ricci/modules/cluster/Fence.cpp 2007/08/22 18:47:19 1.5 +++ conga/ricci/modules/cluster/Fence.cpp 2007/08/23 15:30:27 1.6 @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -27,23 +27,21 @@ using namespace std; +#define FENCE_NODE_TOOL_PATH "/sbin/fence_node" -#define FENCE_NODE_TOOL_PATH "/sbin/fence_node" - - +void +Fence::fence_node(const String& nodename) +{ + String out, err; + int status; + vector args; + args.push_back("-O"); + args.push_back(nodename); + if (utils::execute(FENCE_NODE_TOOL_PATH, args, out, err, status, false)) + throw command_not_found_error_msg(FENCE_NODE_TOOL_PATH); -void -Fence::fence_node(const String& nodename) -{ - String out, err; - int status; - vector args; - args.push_back("-O"); - args.push_back(nodename); - if (utils::execute(FENCE_NODE_TOOL_PATH, args, out, err, status, false)) - throw command_not_found_error_msg(FENCE_NODE_TOOL_PATH); - if (status != 0) - throw String("fence_node failed: ") + err; + if (status != 0) + throw String("fence_node failed: ") + err; } --- conga/ricci/modules/cluster/Fence.h 2006/08/10 22:53:08 1.2 +++ conga/ricci/modules/cluster/Fence.h 2007/08/23 15:30:27 1.3 @@ -1,5 +1,5 @@ /* - Copyright Red Hat, Inc. 2006 + Copyright Red Hat, Inc. 2006-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -29,10 +29,8 @@ class Fence { - public: - static void fence_node(const String& nodename); - + public: + static void fence_node(const String& nodename); }; - #endif // Fence_h --- conga/ricci/modules/cluster/NoServiceManager.h 2006/04/07 16:42:40 1.1 +++ conga/ricci/modules/cluster/NoServiceManager.h 2007/08/23 15:30:27 1.2 @@ -1,5 +1,5 @@ /* - Copyright Red Hat, Inc. 2005 + Copyright Red Hat, Inc. 2005-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -26,16 +26,12 @@ #include "Except.h" - class NoServiceManager : public Except { - public: - NoServiceManager() - : Except(1, "Service Manager not running on this node") {} - virtual ~NoServiceManager() - {} - + public: + NoServiceManager() + : Except(1, "Service Manager not running on this node") {} + virtual ~NoServiceManager() {} }; - -#endif // NoServiceManager_h +#endif // NoServiceManager_h --- conga/ricci/modules/cluster/Virt.cpp 2007/08/22 18:47:19 1.4 +++ conga/ricci/modules/cluster/Virt.cpp 2007/08/23 15:30:27 1.5 @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ @@ -33,21 +33,22 @@ using namespace std; bool Virt::virt_guest(void) { - try { - String out, err; - int status; - vector args; - if (utils::execute(DMIDECODE_PATH, args, out, err, status, false)) - throw command_not_found_error_msg(DMIDECODE_PATH); - if (status != 0) + try { + String out, err; + int status; + vector args; + + if (utils::execute(DMIDECODE_PATH, args, out, err, status, false)) + throw command_not_found_error_msg(DMIDECODE_PATH); + if (status != 0) throw String("dmidecode failed: " + err); - if (out.find("Vendor: Xen") != out.npos) - return true; - if (out.find("Manufacturer: Xen") != out.npos) - return true; - } catch ( ... ) {} + if (out.find("Vendor: Xen") != out.npos) + return true; + if (out.find("Manufacturer: Xen") != out.npos) + return true; + } catch ( ... ) {} - return false; + return false; } bool Virt::delete_xvm_key(void) { @@ -66,7 +67,7 @@ if (key_base64 == NULL) throw String("no key was given"); - + keylen = strlen(key_base64); if (keylen < 1) throw String("no key was given"); @@ -115,7 +116,6 @@ int fd; size_t ret; char buf[XVM_KEY_MAX_SIZE]; - struct stat stat; int err = 0; if (keylen < XVM_KEY_MIN_SIZE || keylen > XVM_KEY_MAX_SIZE) @@ -130,7 +130,6 @@ close(fd); if ((size_t) ret != keylen) throw String("error generating key: ") + String(strerror(err)); - fd = open(XVM_KEY_PATH, O_WRONLY | O_EXCL | O_CREAT, 0600); if (fd < 0) --- conga/ricci/modules/cluster/Virt.h 2007/07/23 18:47:50 1.3 +++ conga/ricci/modules/cluster/Virt.h 2007/08/23 15:30:27 1.4 @@ -1,5 +1,5 @@ /* - Copyright Red Hat, Inc. 2006 + Copyright Red Hat, Inc. 2006-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ @@ -30,12 +30,12 @@ #define DMIDECODE_PATH "/usr/sbin/dmidecode" class Virt { - public: - static bool virt_guest(void); - static bool delete_xvm_key(void); - static bool set_xvm_key(const char *key_base64); - static char *get_xvm_key(void); - static bool generate_xvm_key(size_t key_bytes); + public: + static bool virt_guest(void); + static bool delete_xvm_key(void); + static bool set_xvm_key(const char *key_base64); + static char *get_xvm_key(void); + static bool generate_xvm_key(size_t key_bytes); }; #endif --- conga/ricci/modules/cluster/main.cpp 2006/08/15 04:15:53 1.4 +++ conga/ricci/modules/cluster/main.cpp 2007/08/23 15:30:27 1.5 @@ -1,5 +1,5 @@ /* - Copyright Red Hat, Inc. 2005 + Copyright Red Hat, Inc. 2005-2007 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the @@ -13,7 +13,7 @@ You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the - Free Software Foundation, Inc., 675 Mass Ave, Cambridge, + Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* @@ -24,18 +24,18 @@ #include "ClusterModule.h" #include + using namespace std; int main(int argc, char** argv) { - try { - ClusterModule m; - return stdin_out_module_driver(m, - argc, - argv); - } catch (String e) { - cerr << e << endl; - return 1; - } + try { + ClusterModule m; + return stdin_out_module_driver(m, argc, argv); + } catch (String e) { + cerr << e << endl; + return 1; + } + return 1; }