Revision 577d45d4

b/tools/lvmstrap
1 1
#!/usr/bin/python
2 2
#
3 3

  
4
# Copyright (C) 2006, 2007 Google Inc.
4
# Copyright (C) 2006, 2007, 2011 Google Inc.
5 5
#
6 6
# This program is free software; you can redistribute it and/or modify
7 7
# it under the terms of the GNU General Public License as published by
......
48 48
from ganeti.utils import RunCmd, ReadFile
49 49
from ganeti import constants
50 50
from ganeti import cli
51
from ganeti import compat
51 52

  
52 53
USAGE = ("\tlvmstrap diskinfo\n"
53 54
         "\tlvmstrap [--vgname=NAME] [--allow-removable]"
......
56 57

  
57 58
verbose_flag = False
58 59

  
60
#: Supported disk types (as prefixes)
61
SUPPORTED_TYPES = [
62
  "hd",
63
  "sd",
64
  "md",
65
  "ubd",
66
  ]
67

  
59 68

  
60 69
class Error(Exception):
61 70
  """Generic exception"""
......
169 178
  return options, args
170 179

  
171 180

  
181
def IsPartitioned(disk):
182
  """Returns whether a given disk should be used partitioned or as-is.
183

  
184
  Currently only md devices are used as is.
185

  
186
  """
187
  return not disk.startswith('md')
188

  
189

  
190
def DeviceName(disk):
191
  """Returns the appropriate device name for a disk.
192

  
193
  For non-partitioned devices, it returns the name as is, otherwise it
194
  returns the first partition.
195

  
196
  """
197
  if IsPartitioned(disk):
198
    device = '/dev/%s1' % disk
199
  else:
200
    device = '/dev/%s' % disk
201
  return device
202

  
203

  
172 204
def ExecCommand(command):
173 205
  """Executes a command.
174 206

  
......
379 411
  """
380 412
  dlist = []
381 413
  for name in os.listdir("/sys/block"):
382
    if (not name.startswith("hd") and
383
        not name.startswith("sd") and
384
        not name.startswith("ubd")):
414
    if not compat.any([name.startswith(pfx) for pfx in SUPPORTED_TYPES]):
385 415
      continue
386 416

  
387 417
    size = ReadSize("/sys/block/%s" % name)
......
534 564
def CheckReread(name):
535 565
  """Check to see if a block device is in use.
536 566

  
537
  Uses blockdev to reread the partition table of a block device, and
538
  thus compute the in-use status. See the discussion in GetDiskList
539
  about the meaning of 'in use'.
567
  Uses blockdev to reread the partition table of a block device (or
568
  fuser if the device is not partitionable), and thus compute the
569
  in-use status.  See the discussion in GetDiskList about the meaning
570
  of 'in use'.
540 571

  
541 572
  @rtype: boolean
542 573
  @return: the in-use status of the device
543 574

  
544 575
  """
576
  use_blockdev = IsPartitioned(name)
577
  if use_blockdev:
578
    cmd = "blockdev --rereadpt /dev/%s" % name
579
  else:
580
    cmd = "fuser -vam /dev/%s" % name
581

  
545 582
  for _ in range(3):
546
    result = ExecCommand("blockdev --rereadpt /dev/%s" % name)
547
    if not result.failed:
583
    result = ExecCommand(cmd)
584
    if not use_blockdev and result.failed:
585
      break
586
    elif not result.failed:
548 587
      break
549 588
    time.sleep(2)
550 589

  
551
  return not result.failed
590
  if use_blockdev:
591
    return not result.failed
592
  else:
593
    return result.failed
552 594

  
553 595

  
554 596
def WipeDisk(name):
......
623 665
  @param name: the device name, e.g. sda
624 666

  
625 667
  """
626
  result = ExecCommand("pvcreate -yff /dev/%s1 " % name)
668
  device = DeviceName(name)
669
  result = ExecCommand("pvcreate -yff %s" % device)
627 670
  if result.failed:
628 671
    raise OperationalError("I cannot create a physical volume on"
629
                           " partition /dev/%s1. Error message: %s."
672
                           " %s. Error message: %s."
630 673
                           " Please clean up yourself." %
631
                           (name, result.output))
674
                           (device, result.output))
632 675

  
633 676

  
634 677
def CreateVG(vgname, disks):
......
640 683
  @param disks: a list of disk names, e.g. ['sda','sdb']
641 684

  
642 685
  """
643
  pnames = ["'/dev/%s1'" % disk for disk in disks]
686
  pnames = [DeviceName(d) for d in disks]
644 687
  result = ExecCommand("vgcreate -s 64MB '%s' %s" % (vgname, " ".join(pnames)))
645 688
  if result.failed:
646 689
    raise OperationalError("I cannot create the volume group %s from"
......
718 761

  
719 762
  for disk in disklist:
720 763
    WipeDisk(disk)
721
    PartitionDisk(disk)
764
    if IsPartitioned(disk):
765
      PartitionDisk(disk)
722 766
  for disk in disklist:
723 767
    CreatePVOnDisk(disk)
724 768
  CreateVG(vgname, disklist)

Also available in: Unified diff