Revision 1a87dca7

b/lib/bdev.py
611 611
    return None
612 612

  
613 613

  
614
  @staticmethod
615
  def _ZeroSuperblock(dev_path):
616
    """Zero the possible locations for an MD superblock.
617

  
618
    The zero-ing can't be done via ``mdadm --zero-superblock`` as that
619
    fails in versions 2.x with the same error code as non-writable
620
    device.
621

  
622
    The superblocks are located at (negative values are relative to
623
    the end of the block device):
624
      - -128k to end for version 0.90 superblock
625
      - -8k to -12k for version 1.0 superblock (included in the above)
626
      - 0k to 4k for version 1.1 superblock
627
      - 4k to 8k for version 1.2 superblock
628

  
629
    To cover all situations, the zero-ing will be:
630
      - 0k to 128k
631
      - -128k to end
632

  
633
    As such, the minimum device size must be 128k, otherwise we'll get
634
    I/O errors.
635

  
636
    Note that this function depends on the fact that one can open,
637
    read and write block devices normally.
638

  
639
    """
640
    overwrite_size = 128 * 1024
641
    empty_buf = '\0' * overwrite_size
642
    fd = open(dev_path, "r+")
643
    try:
644
      fd.seek(0, 0)
645
      p1 = fd.tell()
646
      fd.write(empty_buf)
647
      p2 = fd.tell()
648
      logger.Debug("Zeroed %s from %d to %d" % (dev_path, p1, p2))
649
      fd.seek(-overwrite_size, 2)
650
      p1 = fd.tell()
651
      fd.write(empty_buf)
652
      p2 = fd.tell()
653
      logger.Debug("Zeroed %s from %d to %d" % (dev_path, p1, p2))
654
    finally:
655
      fd.close()
656

  
614 657
  @classmethod
615 658
  def Create(cls, unique_id, children, size):
616 659
    """Create a new MD raid1 array.
......
623 666
      if not isinstance(i, BlockDev):
624 667
        raise ValueError("Invalid member in MDRaid1 dev: %s" % type(i))
625 668
    for i in children:
626
      result = utils.RunCmd(["mdadm", "--zero-superblock", "--force",
627
                             i.dev_path])
628
      if result.failed:
629
        logger.Error("Can't zero superblock: %s" % result.fail_reason)
669
      try:
670
        cls._ZeroSuperblock(i.dev_path)
671
      except EnvironmentError, err:
672
        logger.Error("Can't zero superblock for %s: %s" %
673
                     (i.dev_path, str(err)))
630 674
        return None
631 675
    minor = cls._FindUnusedMinor()
632 676
    result = utils.RunCmd(["mdadm", "--create", "/dev/md%d" % minor,
......
635 679
                          [dev.dev_path for dev in children])
636 680

  
637 681
    if result.failed:
638
      logger.Error("Can't create md: %s" % result.fail_reason)
682
      logger.Error("Can't create md: %s: %s" % (result.fail_reason,
683
                                                result.output))
639 684
      return None
640 685
    info = cls._GetDevInfo(minor)
641 686
    if not info or not "uuid" in info:

Also available in: Unified diff