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 LVM.cpp
Date: 21 Aug 2006 15:44:43 -0000	[thread overview]
Message-ID: <20060821154443.24448.qmail@sourceware.org> (raw)

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 <vector>
 
-
-
-
-
-
 #include <iostream>
 
 
 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<String>
 vg_props(const String& vgname);
 
+static const map<String, PV_data>
+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<String> 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<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() < 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<String, PV_data> pvs(probe_pvs());
+  map<String, PV_data>::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<String> 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<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() < 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<String, PV_data> pvs(probe_pvs());
+  map<String, PV_data>::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<String, String> pv_to_vg;
-  vector<String> 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<String> lines = utils::split(out, "\n");
-  for (vector<String>::iterator iter = lines.begin();
-       iter != lines.end();
-       iter++) {
-    String& line = *iter;
-    vector<String> 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<String, PV_data> pvs_data(probe_pvs());
+  for (map<String, PV_data>::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<String> 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<String> lines = utils::split(out, "\n");
   for (vector<String>::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<String, PV_data>
+probe_pvs()
+{
+  map<String, PV_data> pvs;
+  
+  String out, err;
+  int status;
+  vector<String> 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<String> lines = utils::split(utils::strip(out), "\n");
+    for (vector<String>::iterator iter = lines.begin();
+	 iter != lines.end();
+	 iter++) {
+      vector<String> 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<String> lines = utils::split(utils::strip(out), "\n");
+    for (vector<String>::iterator iter = lines.begin();
+	 iter != lines.end();
+	 iter++) {
+      vector<String> 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;
+}
+



             reply	other threads:[~2006-08-21 15:44 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-21 15:44 kupcevic [this message]
  -- strict thread matches above, loose matches on Subject: below --
2006-11-01 21:27 [Cluster-devel] conga/ricci/modules/storage LVM.cpp kupcevic
2006-11-29 16:39 rmccabe
2007-01-16 17:05 kupcevic
2007-01-17 14:41 kupcevic

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=20060821154443.24448.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.