-#!/usr/bin/python
+#
#
# Copyright (C) 2006, 2007 Google Inc.
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
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.
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,
[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:
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