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/storage/LV.cpp modules/sto ...
Date: 28 Jun 2006 20:09:11 -0000	[thread overview]
Message-ID: <20060628200911.4457.qmail@sourceware.org> (raw)

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@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>



                 reply	other threads:[~2006-06-28 20:09 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=20060628200911.4457.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.