From f4d377e7fe5989b2102e7d8712b8e19c1fcd163b Mon Sep 17 00:00:00 2001
From: Iustin Pop <iustin@google.com>
Date: Sun, 20 Jan 2008 22:13:16 +0000
Subject: [PATCH] Make backend._GetVGInfo check the validity of 'vgs'

Currently, the function backend._GetVGInfo only checks for errors via
the exit code of the 'vgs' command. However, there are other ways of
failure so we need to also check for valid output before parsing.

Furthermore, the checks on the exit code were reported via a 'raise
LVMError', however this exception is not handled anywhere and so the
remote caller will not get reasonable data.

This patch does two main things:
  - change the calling protocol for this function to not raise an error,
    and instead return the same type of argument always (dict) with the
    requested keys but values changed into None; this allows in the
    parent rpc call node_info to have valid memory information but
    "error" value for disk space, if there's an error with disks
  - check the validity of the output so that in case we fail to parse
    it, we don't abort with a backtrace in the node daemon but instead
    return the default result value (containing errors), and log these
    cases in the node daemon log file

We also bump the protocol version to 11.

Reviewed-by: ultrotter
---
 lib/backend.py   | 24 ++++++++++++++++++------
 lib/constants.py |  2 +-
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/lib/backend.py b/lib/backend.py
index 8b6291a0a..007852dd0 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -491,20 +491,32 @@ def _GetVGInfo(vg_name):
     vg_free is the free size of the volume group in MiB
     pv_count are the number of physical disks in that vg
 
+  If an error occurs during gathering of data, we return the same dict
+  with keys all set to None.
+
   """
+  retdic = dict.fromkeys(["vg_size", "vg_free", "pv_count"])
+
   retval = utils.RunCmd(["vgs", "-ovg_size,vg_free,pv_count", "--noheadings",
                          "--nosuffix", "--units=m", "--separator=:", vg_name])
 
   if retval.failed:
     errmsg = "volume group %s not present" % vg_name
     logger.Error(errmsg)
-    raise errors.LVMError(errmsg)
+    return retdic
   valarr = retval.stdout.strip().split(':')
-  retdic = {
-    "vg_size": int(round(float(valarr[0]), 0)),
-    "vg_free": int(round(float(valarr[1]), 0)),
-    "pv_count": int(valarr[2]),
-    }
+  if len(valarr) == 3:
+    try:
+      retdic = {
+        "vg_size": int(round(float(valarr[0]), 0)),
+        "vg_free": int(round(float(valarr[1]), 0)),
+        "pv_count": int(valarr[2]),
+        }
+    except ValueError, err:
+      logger.Error("Fail to parse vgs output: %s" % str(err))
+  else:
+    logger.Error("vgs output has the wrong number of fields (expected"
+                 " three): %s" % str(valarr))
   return retdic
 
 
diff --git a/lib/constants.py b/lib/constants.py
index 3b764e261..de40522b2 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -25,7 +25,7 @@ from ganeti import _autoconf
 
 # various versions
 CONFIG_VERSION = 3
-PROTOCOL_VERSION = 10
+PROTOCOL_VERSION = 11
 RELEASE_VERSION = _autoconf.PACKAGE_VERSION
 OS_API_VERSION = 5
 EXPORT_VERSION = 0
-- 
GitLab