[Cluster-devel] conga/ricci modules/storage/LV.cpp modules/sto ...

kupcevic at sourceware.org kupcevic at sourceware.org
Wed Jun 28 20:09:11 UTC 2006


CVSROOT:	/cvs/cluster
Module name:	conga
Changes by:	kupcevic at sourceware.org	2006-06-28 20:09:08

Modified files:
	ricci/modules/storage: LV.cpp LVM.cpp LVM.h PV.cpp VG.cpp 
	ricci/docs     : storage_api.html 
Added files:
	ricci/modules/storage: ClvmdError.h 

Log message:
	storage module: clvm support

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/ClvmdError.h.diff?cvsroot=cluster&r1=NONE&r2=1.1
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/LV.cpp.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/LVM.cpp.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/LVM.h.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/PV.cpp.diff?cvsroot=cluster&r1=1.2&r2=1.3
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/VG.cpp.diff?cvsroot=cluster&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/docs/storage_api.html.diff?cvsroot=cluster&r1=1.2&r2=1.3

/cvs/cluster/conga/ricci/modules/storage/ClvmdError.h,v  -->  standard output
revision 1.1
--- conga/ricci/modules/storage/ClvmdError.h
+++ -	2006-06-28 20:09:09.165044000 +0000
@@ -0,0 +1,41 @@
+/*
+  Copyright Red Hat, Inc. 2006
+
+  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
+  Free Software Foundation; either version 2, or (at your option) any
+  later version.
+
+  This program is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+  General Public License for more details.
+
+  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, 
+  MA 02139, USA.
+*/
+/*
+ * Author: Stanko Kupcevic <kupcevic at redhat.com>
+ */
+
+
+#ifndef ClvmdError_h
+#define ClvmdError_h
+
+#include "Except.h"
+
+
+class ClvmdError : public Except
+{
+ public:
+  ClvmdError()
+    : Except(4, std::string("clvmd required, but unable to start. Start cluster infrastructure.")) {}
+  virtual ~ClvmdError()
+    {}
+  
+};
+
+
+#endif  // ClvmdError_h
--- conga/ricci/modules/storage/LV.cpp	2006/03/10 17:50:11	1.2
+++ conga/ricci/modules/storage/LV.cpp	2006/06/28 20:09:08	1.3
@@ -29,6 +29,7 @@
 #include "utils.h"
 #include "ContentFactory.h"
 #include "ContentNone.h"
+#include "ClvmdError.h"
 
 
 using namespace std;
@@ -42,6 +43,13 @@
   
   string vgname = bd_temp.props.get("vgname").get_string();
   
+  
+  // if VG is marked as clustered, but cluster locking is not available, throw
+  if (!LVM::clustered_available() &&
+      bd_temp.props.get("clustered").get_bool())
+    throw ClvmdError();
+  
+  
   string lvname = bd_temp.props.get("lvname").get_string();
   long long size = bd_temp.props.get("size").get_int();
   
@@ -158,6 +166,11 @@
 counting_auto_ptr<BD> 
 LV::apply(const BDParsed& bd_parsed)
 {
+  // if VG is marked as clustered, but cluster locking is not available, throw
+  if (_props.get("clustered").get_bool() &&
+      !LVM::clustered_available())
+    throw ClvmdError();
+  
   // snapshots neither resize nor replace content, see LV()
   
   if (_props.get("snapshot").get_bool()) {
@@ -217,6 +230,11 @@
 void 
 LV::remove()
 {
+  // if VG is marked as clustered, but cluster locking is not available, throw
+  if (_props.get("clustered").get_bool() &&
+      !LVM::clustered_available())
+    throw ClvmdError();
+  
   content->remove();
   LVM::lvremove(path());
 }
--- conga/ricci/modules/storage/LVM.cpp	2006/03/10 17:50:11	1.2
+++ conga/ricci/modules/storage/LVM.cpp	2006/06/28 20:09:08	1.3
@@ -27,6 +27,7 @@
 #include "BDFactory.h"
 #include "LV.h"
 #include "defines.h"
+#include "ClvmdError.h"
 
 #include <vector>
 
@@ -41,6 +42,12 @@
 using namespace std;
 
 
+static string
+get_locking_type();
+
+static vector<string>
+vg_props(const string& vgname);
+
 
 
 
@@ -55,8 +62,8 @@
 static unsigned int PVS_EXTENT_SIZE_IDX  = 7;
 static unsigned int PVS_OPTIONS_LENGTH   = 8;  // last
 
-  
-static string LVS_OPTIONS_STRING = "lv_name,vg_name,stripes,stripesize,lv_attr,lv_uuid,devices,origin,snap_percent,seg_start,seg_size,vg_extent_size,lv_size,vg_free_count";
+
+static string LVS_OPTIONS_STRING = "lv_name,vg_name,stripes,stripesize,lv_attr,lv_uuid,devices,origin,snap_percent,seg_start,seg_size,vg_extent_size,lv_size,vg_free_count,vg_attr";
 static unsigned int LVS_NAME_IDX         = 0;
 static unsigned int LVS_VG_NAME_IDX      = 1;
 //static unsigned int LVS_STRIPES_NUM_IDX  = 2;
@@ -71,11 +78,12 @@
 static unsigned int LVS_EXTENT_SIZE_IDX  = 11;
 static unsigned int LVS_SIZE_IDX         = 12;
 static unsigned int LVS_VG_FREE_COUNT    = 13;
+static unsigned int LVS_VG_ATTR_IDX      = 14;
 //  if LVS_HAS_MIRROR_OPTIONS:
 //  LVS_OPTION_STRING += ",mirror_log";
 //static unsigned int LVS_MIRROR_LOG_IDX   = 13;
-static unsigned int LVS_OPTIONS_LENGTH   = 14;  // last
-  
+static unsigned int LVS_OPTIONS_LENGTH   = 15;  // last
+
 
 
 static string VGS_OPTIONS_STRING = "vg_name,vg_attr,vg_size,vg_extent_size,vg_free_count,max_lv,max_pv,vg_uuid";
@@ -95,6 +103,8 @@
 std::string 
 LVM::vgname_from_lvpath(const std::string& lvpath)
 {
+  check_locking();
+  
   vector<string> args;
   args.push_back("lvdisplay");
   args.push_back("-c");
@@ -121,6 +131,8 @@
 std::string 
 LVM::vgname_from_pvpath(const std::string& path)
 {
+  check_locking();
+  
   vector<string> args;
   args.push_back("pvs");
   args.push_back("--nosuffix");
@@ -161,6 +173,8 @@
 void 
 LVM::probe_lv(const std::string& lvpath, Props& props)
 {
+  check_locking();
+  
   vector<string> args;
   args.push_back("lvs");
   args.push_back("--nosuffix");
@@ -212,6 +226,10 @@
   
   props.set(Variable("mirrored", attrs[0] == 'm'));
   
+  // clustered
+  string vg_attrs = words[LVS_VG_ATTR_IDX];
+  props.set(Variable("clustered", vg_attrs[5] == 'c'));
+  
   // snapshots
   string origin = words[LVS_SNAP_ORIGIN_IDX];
   props.set(Variable("snapshot", origin != ""));
@@ -253,6 +271,8 @@
 void 
 LVM::probe_pv(const std::string& path, Props& props)
 {
+  check_locking();
+  
   vector<string> args;
   args.push_back("pvs");
   args.push_back("--nosuffix");
@@ -314,6 +334,8 @@
 	      list<counting_auto_ptr<BD> >& sources,
 	      list<counting_auto_ptr<BD> >& targets)
 {
+  check_locking();
+  
   // pv to vg mappings
   map<string, string> pv_to_vg;
   vector<string> args;
@@ -344,44 +366,13 @@
   
   // probe vg
   if (!vgname.empty()) {
-    args.clear();
-    args.push_back("vgs");
-    args.push_back("--nosuffix");
-    args.push_back("--noheadings");
-    args.push_back("--units");
-    args.push_back("b");
-    args.push_back("--separator");
-    args.push_back(";");
-    args.push_back("-o");
-    args.push_back(VGS_OPTIONS_STRING);
-    //    args.push_back(vgname);
-    out = err = "";
-    if (utils::execute(LVM_BIN_PATH, args, out, err, status))
-      throw string("execute failed");
-    if (status != 0)
-      throw string("vgs failed");
-    
     
-    
-    vector<string> lines = utils::split(out, "\n");
-    vector<string> words;
-    for (vector<string>::iterator iter = lines.begin();
-	 iter != lines.end();
-	 iter++) {
-      string line = utils::strip(*iter);
-      vector<string> t_words = utils::split(line, ";");
-      if (t_words.size() < VGS_OPTIONS_LENGTH)
-	continue;
-      if (t_words[VGS_NAME_IDX] == vgname) {
-	words = t_words;
-	break;
-      }
-    }
-    if (words.size() < VGS_OPTIONS_LENGTH)
-      throw string("no such vg");
+    vector<string> words = vg_props(vgname);
     
     props.set(Variable("vgname", words[VGS_NAME_IDX]));
-    props.set(Variable("attrs", words[VGS_ATTR_IDX]));
+    
+    string vg_attrs(words[VGS_ATTR_IDX]);
+    props.set(Variable("attrs", vg_attrs));
     
     long long size = utils::to_long(words[VGS_SIZE_IDX]);
     long long extent_size = utils::to_long(words[VGS_EXTENT_SIZE_IDX]);
@@ -404,26 +395,8 @@
     props.set(Variable("uuid", words[VGS_UUID_IDX]));
     
     // clustered
-    bool clustered = false;
-    args.clear();
-    args.push_back("vgdisplay");
-    args.push_back(vgname);
-    out = err = "";
-    if (utils::execute(LVM_BIN_PATH, args, out, err, status))
-      throw string("execute failed");
-    if (status != 0)
-      throw string("vgdisplay failed");
-    lines = utils::split(out, "\n");
-    for (vector<string>::iterator iter = lines.begin();
-	 iter != lines.end();
-	 iter++) {
-      string line = utils::strip(*iter);
-      vector<string> words = utils::split(line, " ");
-      if (words.size() == 2)
-	if (words[0] == "Clustered" && words[1] == "yes")
-	  clustered = true;
-    }
-    props.set(Variable("clustered", clustered));
+    bool clustered = (vg_attrs[5] == 'c');
+    props.set(Variable("clustered", clustered, true));
   }
   
   // PVS
@@ -497,14 +470,21 @@
 
 
 void 
-LVM::vgcreate(const std::string& vgname,
-	      long long extent_size,
+LVM::vgcreate(const std::string& vgname, 
+	      long long extent_size, 
+	      bool clustered, 
 	      const list<string>& pv_paths)
 {
+  if (clustered &&
+      !clustered_available())
+    throw ClvmdError();
+  
   vector<string> args;
   args.push_back("vgcreate");
   args.push_back("--physicalextentsize");
   args.push_back(utils::to_string(extent_size/1024) + "k");
+  args.push_back("-c");
+  args.push_back(clustered ? "y" : "n");
   args.push_back(vgname);
   for (list<string>::const_iterator iter = pv_paths.begin();
        iter != pv_paths.end();
@@ -574,6 +554,28 @@
   utils::clear_cache();
 }
 
+void 
+LVM::vgchange(const std::string& vgname,
+	      bool clustered)
+{
+  if (clustered &&
+      !clustered_available())
+    throw ClvmdError();
+  
+  vector<string> args;
+  args.push_back("vgchange");
+  args.push_back("-c");
+  args.push_back(clustered ? "y" : "n");
+  args.push_back(vgname);
+  string out, err;
+  int status;
+  if (utils::execute(LVM_BIN_PATH, args, out, err, status, false))
+    throw string("execute failed");
+  if (status != 0)
+    throw string("vgchange failed");
+  utils::clear_cache();
+}
+
 
 void 
 LVM::lvcreate(const std::string& vgname,
@@ -676,3 +678,96 @@
     throw string("lvextend failed");
   utils::clear_cache();
 }
+
+
+bool 
+LVM::clustered_available()
+{
+  return get_locking_type() == "2";
+}
+
+void 
+LVM::check_locking()
+{
+  if (get_locking_type() == "2") {
+    // try to start clvmd, if not running
+    string out, err;
+    int status;
+    vector<string> args;
+    args.push_back("clvmd");
+    args.push_back("start");
+    if (utils::execute("/sbin/service", args, out, err, status))
+      throw string("execute failed");
+    if (status)
+      throw ClvmdError();
+  }
+}
+
+string
+get_locking_type()
+{
+  string out, err;
+  int status;
+  vector<string> args;
+  args.push_back("locking_type");
+  args.push_back("/etc/lvm/lvm.conf");
+  if (utils::execute("/bin/grep", args, out, err, status))
+    throw string("execute failed");
+  vector<string> lines(utils::split(utils::strip(out), "\n"));
+  for (vector<string>::const_iterator line = lines.begin();
+       line != lines.end();
+       line++) {
+    vector<string> words(utils::split(utils::strip(*line)));
+    if (words.size() < 3)
+      continue;
+    if (words[0] == "locking_type" &&
+	words[1] == "=") {
+      return words[2];
+    }
+  }
+  throw string("locking_type not found in lvm.conf!!!");
+}
+
+vector<string>
+vg_props(const string& vgname)
+{
+  string out, err;
+  int status;
+  vector<string> args;
+  args.push_back("vgs");
+  args.push_back("--nosuffix");
+  args.push_back("--noheadings");
+  args.push_back("--units");
+  args.push_back("b");
+  args.push_back("--separator");
+  args.push_back(";");
+  args.push_back("-o");
+  args.push_back(VGS_OPTIONS_STRING);
+  //    args.push_back(vgname);
+  if (utils::execute(LVM_BIN_PATH, args, out, err, status))
+    throw string("execute failed");
+  if (status)
+    throw string("vgs failed");
+  
+  vector<string> lines = utils::split(out, "\n");
+  for (vector<string>::iterator iter = lines.begin();
+       iter != lines.end();
+       iter++) {
+    string line = utils::strip(*iter);
+    vector<string> words = utils::split(line, ";");
+    if (words.size() < VGS_OPTIONS_LENGTH)
+      continue;
+    if (words[VGS_NAME_IDX] == vgname) {
+      return words;
+    }
+  }
+  throw string("no such vg");
+}
+
+bool
+LVM::vg_clustered(const string& vgname)
+{
+  if (vgname.empty())
+    return false;
+  return vg_props(vgname)[VGS_ATTR_IDX][5] == 'c';
+}
--- conga/ricci/modules/storage/LVM.h	2006/03/10 17:50:11	1.2
+++ conga/ricci/modules/storage/LVM.h	2006/06/28 20:09:08	1.3
@@ -50,14 +50,17 @@
   static void pvcreate(const std::string& path);
   static void pvremove(const std::string& path);
   
-  static void vgcreate(const std::string& vgname,
-		       long long extent_size,
+  static void vgcreate(const std::string& vgname, 
+		       long long extent_size, 
+		       bool clustered, 
 		       const std::list<std::string>& pv_paths);
   static void vgremove(const std::string& vgname);
   static void vgextend(const std::string& vgname,
 		       const std::list<std::string>& pv_paths);
   static void vgreduce(const std::string& vgname,
 		       const std::string& pv_path);
+  static void vgchange(const std::string& vgname,
+		       bool clustered);
   
   static void lvcreate(const std::string& vgname,
 		       const std::string& lvname,
@@ -70,6 +73,10 @@
   static void lvreduce(const std::string& path, long long new_size);
   static void lvextend(const std::string& path, long long new_size);
   
+  static void check_locking();
+  static bool clustered_available();
+  static bool vg_clustered(const std::string& vgname);
+  
 };
 
 
--- conga/ricci/modules/storage/PV.cpp	2006/03/10 17:50:11	1.2
+++ conga/ricci/modules/storage/PV.cpp	2006/06/28 20:09:08	1.3
@@ -25,6 +25,7 @@
 #include "LVM.h"
 #include "MapperFactory.h"
 #include "utils.h"
+#include "ClvmdError.h"
 
 
 using namespace std;
@@ -91,6 +92,13 @@
   
   string vgname = _props.get("vgname").get_string();
   
+  
+  // if VG is marked as clustered, but cluster locking is not available, throw
+  if (!LVM::clustered_available() &&
+      LVM::vg_clustered(vgname))
+    throw ClvmdError();
+  
+  
   if (vg->sources.size() == 1) {
     if (vgname.size())
       LVM::vgremove(vgname);
@@ -111,6 +119,14 @@
   string vgname_old(_props.get("vgname").get_string());
   string vgname_new(new_props.get("vgname").get_string());
   
+  
+  // if VG is marked as clustered, but cluster locking is not available, throw
+  if (!LVM::clustered_available() &&
+      (LVM::vg_clustered(vgname_old) || 
+       LVM::vg_clustered(vgname_new)))
+    throw ClvmdError();
+  
+  
   counting_auto_ptr<Mapper> vg_old = 
     MapperFactory::get_mapper(_mapper_type,
 			      _mapper_id);
@@ -135,6 +151,13 @@
 {
   string vgname(templ->_props.get("vgname").get_string());
   
+  
+  // if VG is marked as clustered, but cluster locking is not available, throw
+  if (!LVM::clustered_available() &&
+      LVM::vg_clustered(vgname))
+    throw ClvmdError();
+  
+  
   LVM::pvcreate(path);
   try {
     if (vgname.size())
--- conga/ricci/modules/storage/VG.cpp	2006/05/16 20:10:39	1.3
+++ conga/ricci/modules/storage/VG.cpp	2006/06/28 20:09:08	1.4
@@ -28,6 +28,7 @@
 #include "defines.h"
 #include "utils.h"
 #include "MidAir.h"
+#include "ClvmdError.h"
 
 #include "Time.h"
 
@@ -41,6 +42,8 @@
 list<string> 
 get_VG_ids()
 {
+  LVM::check_locking();
+  
   list<string> vgids;
   
   vector<string> args;
@@ -148,6 +151,7 @@
     
     new_lv->props.set(Variable("vgname", _vgname));
     new_lv->props.set(Variable("snapshot", false));
+    new_lv->props.set(Variable("clustered", _props.get("clustered").get_bool()));
     new_targets.push_back(new_lv);
     
     // snapshots
@@ -183,14 +187,25 @@
 
 
 void 
-VG::apply(const MapperParsed&)
+VG::apply(const MapperParsed& mp)
 {
-  // nothing to do, for now
+  string vgname(mp.props.get("vgname").get_string());
+  
+  // clustered
+  bool clustered_old = _props.get("clustered").get_bool();
+  bool clustered_new = mp.props.get("clustered").get_bool();
+  if (clustered_old != clustered_new)
+    LVM::vgchange(vgname, clustered_new);
 }
 
 void 
 VG::__add_sources(const list<counting_auto_ptr<BD> >& bds)
 {
+  // if VG is marked as clustered, but cluster locking is not available, throw
+  if (_props.get("clustered").get_bool() &&
+      !LVM::clustered_available())
+    throw ClvmdError();
+  
   string vgname;
   try {
     vgname = _props.get("vgname").get_string();
@@ -231,6 +246,11 @@
 void 
 VG::__remove()
 {
+  // if VG is marked as clustered, but cluster locking is not available, throw
+  if (_props.get("clustered").get_bool() &&
+      !LVM::clustered_available())
+    throw ClvmdError();
+  
   string vgname = _props.get("vgname").get_string();
   LVM::vgremove(vgname);
   for (list<counting_auto_ptr<BD> >::const_iterator iter = sources.begin();
@@ -251,6 +271,11 @@
   
   string vgname = temp.props.get("vgname").get_string();
   long long extent_size = temp.props.get("extent_size").get_int();
+  bool clustered = temp.props.get("clustered").get_bool();
+  
+  if (clustered &&
+      !LVM::clustered_available())
+    throw ClvmdError();
   
   try {
     utils::clear_cache();
@@ -267,7 +292,7 @@
     }
     
     // create VG
-    LVM::vgcreate(vgname, extent_size, pv_paths);
+    LVM::vgcreate(vgname, extent_size, clustered, pv_paths);
   } catch ( ... ) {
     for (list<counting_auto_ptr<BD> >::const_iterator iter = temp.sources.begin();
 	 iter != temp.sources.end();
@@ -319,6 +344,9 @@
 		     4 * 1024 * 1024 /* 4 MB */,
 		     ext_sizes));
   
+  // clustered
+  props.set(Variable("clustered", false, true));
+  
   // new sources
   VG unused(VG_PREFIX);
   for (list<counting_auto_ptr<BD> >::iterator iter = unused.sources.begin();
--- conga/ricci/docs/storage_api.html	2006/04/13 18:06:14	1.2
+++ conga/ricci/docs/storage_api.html	2006/06/28 20:09:08	1.3
@@ -5,7 +5,7 @@
 	<TITLE>Storage Module</TITLE>
 	<META NAME="GENERATOR" CONTENT="OpenOffice.org 1.1.2  (Linux)">
 	<META NAME="CREATED" CONTENT="20060410;13011800">
-	<META NAME="CHANGED" CONTENT="20060413;13424800">
+	<META NAME="CHANGED" CONTENT="20060626;19014000">
 </HEAD>
 <BODY LANG="en-US" DIR="LTR">
 <P>Storage module manages all aspects of storage. Supports partition
@@ -66,6 +66,13 @@
 	<LI><P>3 – umount error<BR>It will happen in the case of umount
 	failure. 
 	</P>
+	<LI><P>4 – clvmd not running<BR>Clustered Volume Groups need clvmd
+	daemon running, and yet clvmd is not running. <BR>Storage module
+	will try to start it. On failure, this error will be raised. <BR>User
+	should either start clvmd, or mark VG non-clustered. <BR>In order to
+	start clvmd: <BR>1. lvm2-cluster needs to be installed<BR>2. cluster
+	infrastructure needs to be started<BR>3. clvmd should be started
+	(service clvmd start)</P>
 </UL>
 <P><BR><BR>
 </P>




More information about the Cluster-devel mailing list