[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