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.