From mboxrd@z Thu Jan 1 00:00:00 1970 From: kupcevic@sourceware.org Date: 21 Aug 2006 15:44:43 -0000 Subject: [Cluster-devel] conga/ricci/modules/storage LVM.cpp Message-ID: <20060821154443.24448.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: kupcevic at sourceware.org 2006-08-21 15:44:42 Modified files: ricci/modules/storage: LVM.cpp Log message: storage module: use `pvdisplay -c` if `pvs` fails (`pvs` will fail if one of hard drives is not readable, while `pvdisplay -c` will give incomplete but usefull info) Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/conga/ricci/modules/storage/LVM.cpp.diff?cvsroot=cluster&r1=1.5&r2=1.6 --- conga/ricci/modules/storage/LVM.cpp 2006/08/10 22:53:09 1.5 +++ conga/ricci/modules/storage/LVM.cpp 2006/08/21 15:44:42 1.6 @@ -32,16 +32,42 @@ #include - - - - - #include using namespace std; +class PV_data +{ +public: + PV_data() {} + PV_data(const String& path, + const String& vgname, + long long extent_size, + long long size, + long long size_free, + const String& uuid, + const String& attrs, + const String& format) : + path(path), + vgname(vgname), + extent_size(extent_size), + size(size), + size_free(size_free), + uuid(uuid), + attrs(attrs), + format(format) {} + + String path; + String vgname; + long long extent_size; + long long size; + long long size_free; + String uuid; + String attrs; + String format; +}; + static String get_locking_type(); @@ -49,9 +75,12 @@ static vector vg_props(const String& vgname); +static const map +probe_pvs(); +// pvs static String PVS_OPTIONS = "pv_name,vg_name,pv_size,pv_free,pv_attr,pv_fmt,pv_uuid,vg_extent_size"; static unsigned int PVS_NAME_IDX = 0; static unsigned int PVS_VG_NAME_IDX = 1; @@ -64,6 +93,19 @@ static unsigned int PVS_OPTIONS_LENGTH = 8; // last +// pvdisplay -c +static unsigned int PVDISPLAY_c_NAME_IDX = 0; +static unsigned int PVDISPLAY_c_VG_NAME_IDX = 1; +static unsigned int PVDISPLAY_c_SIZE_IDX = 2; +static unsigned int PVDISPLAY_c_EXTENT_SIZE_IDX = 7; +static unsigned int PVDISPLAY_c_TOT_EXT_IDX = 8; +static unsigned int PVDISPLAY_c_FREE_EXT_IDX = 9; +static unsigned int PVDISPLAY_c_USED_EXT_IDX = 10; +static unsigned int PVDISPLAY_c_UUID_IDX = 11; +static unsigned int PVDISPLAY_c_OPTIONS_LENGTH = 12; // last + + +// lvs 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; @@ -86,7 +128,7 @@ static unsigned int LVS_OPTIONS_LENGTH = 15; // last - +// vgs static String VGS_OPTIONS_STRING = "vg_name,vg_attr,vg_size,vg_extent_size,vg_free_count,max_lv,max_pv,vg_uuid"; static unsigned int VGS_NAME_IDX = 0; static unsigned int VGS_ATTR_IDX = 1; @@ -134,40 +176,11 @@ { check_locking(); - vector args; - args.push_back("pvs"); - 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(PVS_OPTIONS); - String out, err; - int status; - if (utils::execute(LVM_BIN_PATH, args, out, err, status)) - throw String("execute failed"); - if (status != 0) - throw String("pvs failed"); - vector lines = utils::split(out, "\n"); - vector words; - for (vector::iterator iter = lines.begin(); - iter != lines.end(); - iter++) { - String line = utils::strip(*iter); - vector t_words = utils::split(line, ";"); - if (t_words.size() < PVS_OPTIONS_LENGTH) - continue; - if (t_words[PVS_NAME_IDX] == path) { - words = t_words; - break; - } - } - if (words.size() < PVS_OPTIONS_LENGTH) - throw String("no such pv"); - - return words[PVS_VG_NAME_IDX]; + map pvs(probe_pvs()); + map::const_iterator iter = pvs.find(path); + if (iter == pvs.end()) + throw String("no such pv: ") + path; + return iter->second.vgname; } @@ -274,56 +287,19 @@ { check_locking(); - vector args; - args.push_back("pvs"); - 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(PVS_OPTIONS); - String out, err; - int status; - if (utils::execute(LVM_BIN_PATH, args, out, err, status)) - throw String("execute failed"); - if (status != 0) - throw String("pvs failed"); - vector lines = utils::split(out, "\n"); - vector words; - for (vector::iterator iter = lines.begin(); - iter != lines.end(); - iter++) { - String line = utils::strip(*iter); - vector t_words = utils::split(line, ";"); - if (t_words.size() < PVS_OPTIONS_LENGTH) - continue; - if (t_words[PVS_NAME_IDX] == path) { - words = t_words; - break; - } - } - if (words.size() < PVS_OPTIONS_LENGTH) - throw String("no such pv"); - - String vgname(utils::strip(words[PVS_VG_NAME_IDX])); - props.set(Variable("vgname", vgname)); - - long long extent_size = utils::to_long(words[PVS_EXTENT_SIZE_IDX]); - props.set(Variable("extent_size", extent_size)); - - long long size = utils::to_long(words[PVS_SIZE_IDX]); - props.set(Variable("size", size)); - - long long free = utils::to_long(words[PVS_FREE_IDX]); - props.set(Variable("size_free", free)); - - props.set(Variable("attrs", words[PVS_ATTR_IDX])); - - props.set(Variable("format", words[PVS_FMT_IDX])); - - props.set(Variable("uuid", words[PVS_UUID_IDX])); + map pvs(probe_pvs()); + map::const_iterator iter = pvs.find(path); + if (iter == pvs.end()) + throw String("no such pv: ") + path; + const PV_data& data = iter->second; + + props.set(Variable("vgname", data.vgname)); + props.set(Variable("extent_size", data.extent_size)); + props.set(Variable("size", data.size)); + props.set(Variable("size_free", data.size_free)); + props.set(Variable("uuid", data.uuid)); + props.set(Variable("attrs", data.attrs)); + props.set(Variable("format", data.format)); } @@ -339,31 +315,11 @@ // pv to vg mappings map pv_to_vg; - vector args; - args.push_back("pvs"); - 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(PVS_OPTIONS); - String out, err; - int status; - if (utils::execute(LVM_BIN_PATH, args, out, err, status)) - throw String("execute failed"); - if (status != 0) - throw String("pvs failed"); - vector lines = utils::split(out, "\n"); - for (vector::iterator iter = lines.begin(); - iter != lines.end(); - iter++) { - String& line = *iter; - vector words = utils::split(utils::strip(line), ";"); - if (words.size() >= PVS_OPTIONS_LENGTH) - pv_to_vg[words[PVS_NAME_IDX]] = words[PVS_VG_NAME_IDX]; - } + map pvs_data(probe_pvs()); + for (map::const_iterator iter = pvs_data.begin(); + iter != pvs_data.end(); + iter++) + pv_to_vg[iter->first] = iter->second.vgname; // probe vg if (!vgname.empty()) { @@ -412,15 +368,16 @@ // LVS - args.clear(); + String out, err; + int status; + vector args; args.push_back("lvdisplay"); args.push_back("-c"); - out = err = ""; if (utils::execute(LVM_BIN_PATH, args, out, err, status)) throw String("execute failed"); if (status != 0) throw String("lvdisplay failed"); - lines = utils::split(out, "\n"); + vector lines = utils::split(out, "\n"); for (vector::iterator iter = lines.begin(); iter != lines.end(); iter++) { @@ -782,3 +739,112 @@ return false; return vg_props(vgname)[VGS_ATTR_IDX][5] == 'c'; } + + + +const map +probe_pvs() +{ + map pvs; + + String out, err; + int status; + vector args; + args.push_back("pvs"); + 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(PVS_OPTIONS); + if (utils::execute(LVM_BIN_PATH, args, out, err, status)) + throw String("execute failed"); + + bool use_pvdisplay = false; + if (status) + // wouldn't `pvdisplay -c` fail if `pvs` has already failed? + // `pvs` fails if it cannot read one hard drive (common in SANs), + // while pvdisplay reports without failure + use_pvdisplay = true; + + if (use_pvdisplay) { + args.clear(); + args.push_back("pvdisplay"); + args.push_back("-c"); + if (utils::execute(LVM_BIN_PATH, args, out, err, status)) + throw String("execute failed"); + if (status) + throw String("pvs and pvdisplay failed"); + + vector lines = utils::split(utils::strip(out), "\n"); + for (vector::iterator iter = lines.begin(); + iter != lines.end(); + iter++) { + vector words = utils::split(utils::strip(*iter), ":"); + if (words.size() >= PVDISPLAY_c_OPTIONS_LENGTH) { + String path(utils::strip(words[PVDISPLAY_c_NAME_IDX])); + String vgname(utils::strip(words[PVDISPLAY_c_VG_NAME_IDX])); + long long extent_size = utils::to_long(words[PVDISPLAY_c_EXTENT_SIZE_IDX]); + extent_size *= 1024; + long long size = utils::to_long(words[PVDISPLAY_c_SIZE_IDX]); + size = size / 2 * 1024; + long long size_free = utils::to_long(words[PVDISPLAY_c_FREE_EXT_IDX]); + size_free *= extent_size; + if (vgname.empty()) + size_free = size; + String uuid(words[PVDISPLAY_c_UUID_IDX]); + + // pvdisplay doesn't report attr and format + // guess + // FIXME: probe somewhere else + String attrs; + if (vgname.empty()) + attrs = "--"; + else + attrs = "a-"; + String format = "lvm2"; + + pvs[path] = PV_data(path, + vgname, + extent_size, + size, + size_free, + uuid, + attrs, + format); + } + } + + } else { + vector lines = utils::split(utils::strip(out), "\n"); + for (vector::iterator iter = lines.begin(); + iter != lines.end(); + iter++) { + vector words = utils::split(utils::strip(*iter), ";"); + if (words.size() >= PVS_OPTIONS_LENGTH) { + String path(utils::strip(words[PVS_NAME_IDX])); + String vgname(utils::strip(words[PVS_VG_NAME_IDX])); + long long extent_size = utils::to_long(words[PVS_EXTENT_SIZE_IDX]); + long long size = utils::to_long(words[PVS_SIZE_IDX]); + long long size_free = utils::to_long(words[PVS_FREE_IDX]); + String uuid(words[PVS_UUID_IDX]); + String attrs(words[PVS_ATTR_IDX]); + String format(words[PVS_FMT_IDX]); + + pvs[path] = PV_data(path, + vgname, + extent_size, + size, + size_free, + uuid, + attrs, + format); + } + } + } + + return pvs; +} +