[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Cluster-devel] conga/ricci/modules/storage LVM.cpp



CVSROOT:	/cvs/cluster
Module name:	conga
Changes by:	kupcevic 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;
+}
+


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]