From 99e8295c8faf5fc6bcba1a5c79ff86b8f4ef1485 Mon Sep 17 00:00:00 2001 From: Iustin Pop <iustin@google.com> Date: Wed, 25 Jun 2008 06:45:19 +0000 Subject: [PATCH] Cleanup LV status computation Currently, when seeing if a LV is degraded or not (i.e. virtual volume), we first attach to the device (which does an lvdisplay), then do a lvs in order to display the lv_attr. This generates two external commands to do (almost) the same thing. This patch changes the Attach() method for LVs to call lvs and display both the major/minor (needed for attach) and the lv_status (needed for GetSyncStatus). Thus, later in GetSyncStatus, we don't need to run lvs again, and instead just return the value computed in Attach(). Reviewed-by: imsnah --- lib/bdev.py | 52 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/lib/bdev.py b/lib/bdev.py index dd35e36f9..b1deaf12c 100644 --- a/lib/bdev.py +++ b/lib/bdev.py @@ -287,6 +287,8 @@ class LogicalVolume(BlockDev): raise ValueError("Invalid configuration data %s" % str(unique_id)) self._vg_name, self._lv_name = unique_id self.dev_path = "/dev/%s/%s" % (self._vg_name, self._lv_name) + self._degraded = True + self.major = self.minor = None self.Attach() @classmethod @@ -392,19 +394,35 @@ class LogicalVolume(BlockDev): recorded. """ - result = utils.RunCmd(["lvdisplay", self.dev_path]) + result = utils.RunCmd(["lvs", "--noheadings", "--separator=,", + "-olv_attr,lv_kernel_major,lv_kernel_minor", + self.dev_path]) if result.failed: logger.Error("Can't find LV %s: %s, %s" % (self.dev_path, result.fail_reason, result.output)) return False - match = re.compile("^ *Block device *([0-9]+):([0-9]+).*$") - for line in result.stdout.splitlines(): - match_result = match.match(line) - if match_result: - self.major = int(match_result.group(1)) - self.minor = int(match_result.group(2)) - return True - return False + out = result.stdout.strip().rstrip(',') + out = out.split(",") + if len(out) != 3: + logger.Error("Can't parse LVS output, len(%s) != 3" % str(out)) + return False + + status, major, minor = out[:3] + if len(status) != 6: + logger.Error("lvs lv_attr is not 6 characters (%s)" % status) + return False + + try: + major = int(major) + minor = int(minor) + except ValueError, err: + logger.Error("lvs major/minor cannot be parsed: %s" % str(err)) + + self.major = major + self.minor = minor + self._degraded = status[0] == 'v' # virtual volume, i.e. doesn't backing + # storage + return True def Assemble(self): """Assemble the device. @@ -448,20 +466,10 @@ class LogicalVolume(BlockDev): physical disk failure and subsequent 'vgreduce --removemissing' on the volume group. + The status was already read in Attach, so we just return it. + """ - result = utils.RunCmd(["lvs", "--noheadings", "-olv_attr", self.dev_path]) - if result.failed: - logger.Error("Can't display lv: %s - %s" % - (result.fail_reason, result.output)) - return None, None, True, True - out = result.stdout.strip() - # format: type/permissions/alloc/fixed_minor/state/open - if len(out) != 6: - logger.Debug("Error in lvs output: attrs=%s, len != 6" % out) - return None, None, True, True - ldisk = out[0] == 'v' # virtual volume, i.e. doesn't have - # backing storage - return None, None, ldisk, ldisk + return None, None, self._degraded, self._degraded def Open(self, force=False): """Make the device ready for I/O. -- GitLab