X-Git-Url: https://code.grnet.gr/git/ganeti-local/blobdiff_plain/3ecf6786a731c0a467f0efcbf6346914e3824ec8..087b34fe1c67f0f50b60b15675ae2de527a3265b:/lib/bdev.py diff --git a/lib/bdev.py b/lib/bdev.py index 2162dff..94ce454 100644 --- a/lib/bdev.py +++ b/lib/bdev.py @@ -1,4 +1,4 @@ -#!/usr/bin/python +# # # Copyright (C) 2006, 2007 Google Inc. @@ -573,7 +573,7 @@ class MDRaid1(BlockDev): kv = line.split(" : ", 1) if kv: if kv[0] == "UUID": - retval["uuid"] = kv[1] + retval["uuid"] = kv[1].split()[0] elif kv[0] == "State": retval["state"] = kv[1].split(", ") return retval @@ -611,6 +611,49 @@ class MDRaid1(BlockDev): return None + @staticmethod + def _ZeroSuperblock(dev_path): + """Zero the possible locations for an MD superblock. + + The zero-ing can't be done via ``mdadm --zero-superblock`` as that + fails in versions 2.x with the same error code as non-writable + device. + + The superblocks are located at (negative values are relative to + the end of the block device): + - -128k to end for version 0.90 superblock + - -8k to -12k for version 1.0 superblock (included in the above) + - 0k to 4k for version 1.1 superblock + - 4k to 8k for version 1.2 superblock + + To cover all situations, the zero-ing will be: + - 0k to 128k + - -128k to end + + As such, the minimum device size must be 128k, otherwise we'll get + I/O errors. + + Note that this function depends on the fact that one can open, + read and write block devices normally. + + """ + overwrite_size = 128 * 1024 + empty_buf = '\0' * overwrite_size + fd = open(dev_path, "r+") + try: + fd.seek(0, 0) + p1 = fd.tell() + fd.write(empty_buf) + p2 = fd.tell() + logger.Debug("Zeroed %s from %d to %d" % (dev_path, p1, p2)) + fd.seek(-overwrite_size, 2) + p1 = fd.tell() + fd.write(empty_buf) + p2 = fd.tell() + logger.Debug("Zeroed %s from %d to %d" % (dev_path, p1, p2)) + finally: + fd.close() + @classmethod def Create(cls, unique_id, children, size): """Create a new MD raid1 array. @@ -623,10 +666,11 @@ class MDRaid1(BlockDev): if not isinstance(i, BlockDev): raise ValueError("Invalid member in MDRaid1 dev: %s" % type(i)) for i in children: - result = utils.RunCmd(["mdadm", "--zero-superblock", "--force", - i.dev_path]) - if result.failed: - logger.Error("Can't zero superblock: %s" % result.fail_reason) + try: + cls._ZeroSuperblock(i.dev_path) + except EnvironmentError, err: + logger.Error("Can't zero superblock for %s: %s" % + (i.dev_path, str(err))) return None minor = cls._FindUnusedMinor() result = utils.RunCmd(["mdadm", "--create", "/dev/md%d" % minor, @@ -635,7 +679,8 @@ class MDRaid1(BlockDev): [dev.dev_path for dev in children]) if result.failed: - logger.Error("Can't create md: %s" % result.fail_reason) + logger.Error("Can't create md: %s: %s" % (result.fail_reason, + result.output)) return None info = cls._GetDevInfo(minor) if not info or not "uuid" in info: @@ -754,7 +799,8 @@ class MDRaid1(BlockDev): self.unique_id, "/dev/md%d" % free_minor] + [bdev.dev_path for bdev in self._children]) if result.failed: - logger.Error("Can't assemble MD array: %s" % result.fail_reason) + logger.Error("Can't assemble MD array: %s: %s" % + (result.fail_reason, result.output)) self.minor = None else: self.minor = free_minor