Complete removal of md/drbd 0.7 code
authorIustin Pop <iustin@google.com>
Fri, 30 May 2008 10:55:05 +0000 (10:55 +0000)
committerIustin Pop <iustin@google.com>
Fri, 30 May 2008 10:55:05 +0000 (10:55 +0000)
This patch removes the last of the md and drbd 0.7 code. Cluster which
have the old device types will be broken if they have this applied.

Reviewed-by: imsnah

lib/bdev.py
lib/cmdlib.py
lib/constants.py
lib/objects.py
scripts/gnt-backup
scripts/gnt-node

index 4dea377..d73d63f 100644 (file)
@@ -43,15 +43,14 @@ class BlockDev(object):
     - online (=used, or ready for use)
 
   A device can also be online but read-only, however we are not using
-  the readonly state (MD and LV have it, if needed in the future)
-  and we are usually looking at this like at a stack, so it's easier
-  to conceptualise the transition from not-existing to online and back
+  the readonly state (LV has it, if needed in the future) and we are
+  usually looking at this like at a stack, so it's easier to
+  conceptualise the transition from not-existing to online and back
   like a linear one.
 
   The many different states of the device are due to the fact that we
   need to cover many device types:
     - logical volumes are created, lvchange -a y $lv, and used
-    - md arrays are created or assembled and used
     - drbd devices are attached to a local disk/remote peer and made primary
 
   A block device is identified by three items:
@@ -61,15 +60,13 @@ class BlockDev(object):
 
   Not all devices implement both the first two as distinct items. LVM
   logical volumes have their unique ID (the pair volume group, logical
-  volume name) in a 1-to-1 relation to the dev path. For MD devices,
-  the /dev path is dynamic and the unique ID is the UUID generated at
-  array creation plus the slave list. For DRBD devices, the /dev path
-  is again dynamic and the unique id is the pair (host1, dev1),
-  (host2, dev2).
+  volume name) in a 1-to-1 relation to the dev path. For DRBD devices,
+  the /dev path is again dynamic and the unique id is the pair (host1,
+  dev1), (host2, dev2).
 
   You can get to a device in two ways:
     - creating the (real) device, which returns you
-      an attached instance (lvcreate, mdadm --create)
+      an attached instance (lvcreate)
     - attaching of a python instance to an existing (real) device
 
   The second point, the attachement to a device, is different
@@ -149,9 +146,9 @@ class BlockDev(object):
   def Remove(self):
     """Remove this device.
 
-    This makes sense only for some of the device types: LV and to a
-    lesser degree, md devices. Also note that if the device can't
-    attach, the removal can't be completed.
+    This makes sense only for some of the device types: LV and file
+    storeage. Also note that if the device can't attach, the removal
+    can't be completed.
 
     """
     raise NotImplementedError
@@ -523,1029 +520,167 @@ class LogicalVolume(BlockDev):
                                      result.output))
 
 
-class MDRaid1(BlockDev):
-  """raid1 device implemented via md.
-
-  """
-  def __init__(self, unique_id, children):
-    super(MDRaid1, self).__init__(unique_id, children)
-    self.major = 9
-    self.Attach()
-
-  def Attach(self):
-    """Find an array which matches our config and attach to it.
-
-    This tries to find a MD array which has the same UUID as our own.
-
-    """
-    minor = self._FindMDByUUID(self.unique_id)
-    if minor is not None:
-      self._SetFromMinor(minor)
-    else:
-      self.minor = None
-      self.dev_path = None
-
-    return (minor is not None)
-
-  @staticmethod
-  def _GetUsedDevs():
-    """Compute the list of in-use MD devices.
-
-    It doesn't matter if the used device have other raid level, just
-    that they are in use.
-
-    """
-    mdstat = open("/proc/mdstat", "r")
-    data = mdstat.readlines()
-    mdstat.close()
-
-    used_md = {}
-    valid_line = re.compile("^md([0-9]+) : .*$")
-    for line in data:
-      match = valid_line.match(line)
-      if match:
-        md_no = int(match.group(1))
-        used_md[md_no] = line
-
-    return used_md
-
-  @staticmethod
-  def _GetDevInfo(minor):
-    """Get info about a MD device.
-
-    Currently only uuid is returned.
-
-    """
-    result = utils.RunCmd(["mdadm", "-D", "/dev/md%d" % minor])
-    if result.failed:
-      logger.Error("Can't display md: %s - %s" %
-                   (result.fail_reason, result.output))
-      return None
-    retval = {}
-    for line in result.stdout.splitlines():
-      line = line.strip()
-      kv = line.split(" : ", 1)
-      if kv:
-        if kv[0] == "UUID":
-          retval["uuid"] = kv[1].split()[0]
-        elif kv[0] == "State":
-          retval["state"] = kv[1].split(", ")
-    return retval
-
-  @staticmethod
-  def _FindUnusedMinor():
-    """Compute an unused MD minor.
-
-    This code assumes that there are 256 minors only.
-
-    """
-    used_md = MDRaid1._GetUsedDevs()
-    i = 0
-    while i < 256:
-      if i not in used_md:
-        break
-      i += 1
-    if i == 256:
-      logger.Error("Critical: Out of md minor numbers.")
-      raise errors.BlockDeviceError("Can't find a free MD minor")
-    return i
-
-  @classmethod
-  def _FindMDByUUID(cls, uuid):
-    """Find the minor of an MD array with a given UUID.
-
-    """
-    md_list = cls._GetUsedDevs()
-    for minor in md_list:
-      info = cls._GetDevInfo(minor)
-      if info and info["uuid"] == uuid:
-        return minor
-    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(children, (tuple, list)):
-      raise ValueError("Invalid setup data for MDRaid1 dev: %s" %
-                       str(children))
-    for i in children:
-      if not isinstance(i, BlockDev):
-        raise ValueError("Invalid member in MDRaid1 dev: %s" % type(i))
-    for i in children:
-      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,
-                           "--auto=yes", "--force", "-l1",
-                           "-n%d" % len(children)] +
-                          [dev.dev_path for dev in children])
-
-    if result.failed:
-      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:
-      logger.Error("Wrong information returned from mdadm -D: %s" % str(info))
-      return None
-    return MDRaid1(info["uuid"], children)
-
-  def Remove(self):
-    """Stub remove function for MD RAID 1 arrays.
-
-    We don't remove the superblock right now. Mark a to do.
-
-    """
-    #TODO: maybe zero superblock on child devices?
-    return self.Shutdown()
-
-  def Rename(self, new_id):
-    """Rename a device.
-
-    This is not supported for md raid1 devices.
-
-    """
-    raise errors.ProgrammerError("Can't rename a md raid1 device")
-
-  def AddChildren(self, devices):
-    """Add new member(s) to the md raid1.
-
-    """
-    if self.minor is None and not self.Attach():
-      raise errors.BlockDeviceError("Can't attach to device")
-
-    args = ["mdadm", "-a", self.dev_path]
-    for dev in devices:
-      if dev.dev_path is None:
-        raise errors.BlockDeviceError("Child '%s' is not initialised" % dev)
-      dev.Open()
-      args.append(dev.dev_path)
-    result = utils.RunCmd(args)
-    if result.failed:
-      raise errors.BlockDeviceError("Failed to add new device to array: %s" %
-                                    result.output)
-    new_len = len(self._children) + len(devices)
-    result = utils.RunCmd(["mdadm", "--grow", self.dev_path, "-n", new_len])
-    if result.failed:
-      raise errors.BlockDeviceError("Can't grow md array: %s" %
-                                    result.output)
-    self._children.extend(devices)
-
-  def RemoveChildren(self, devices):
-    """Remove member(s) from the md raid1.
-
-    """
-    if self.minor is None and not self.Attach():
-      raise errors.BlockDeviceError("Can't attach to device")
-    new_len = len(self._children) - len(devices)
-    if new_len < 1:
-      raise errors.BlockDeviceError("Can't reduce to less than one child")
-    args = ["mdadm", "-f", self.dev_path]
-    orig_devs = []
-    for dev in devices:
-      args.append(dev)
-      for c in self._children:
-        if c.dev_path == dev:
-          orig_devs.append(c)
-          break
-      else:
-        raise errors.BlockDeviceError("Can't find device '%s' for removal" %
-                                      dev)
-    result = utils.RunCmd(args)
-    if result.failed:
-      raise errors.BlockDeviceError("Failed to mark device(s) as failed: %s" %
-                                    result.output)
-
-    # it seems here we need a short delay for MD to update its
-    # superblocks
-    time.sleep(0.5)
-    args[1] = "-r"
-    result = utils.RunCmd(args)
-    if result.failed:
-      raise errors.BlockDeviceError("Failed to remove device(s) from array:"
-                                    " %s" % result.output)
-    result = utils.RunCmd(["mdadm", "--grow", "--force", self.dev_path,
-                           "-n", new_len])
-    if result.failed:
-      raise errors.BlockDeviceError("Can't shrink md array: %s" %
-                                    result.output)
-    for dev in orig_devs:
-      self._children.remove(dev)
-
-  def _SetFromMinor(self, minor):
-    """Set our parameters based on the given minor.
-
-    This sets our minor variable and our dev_path.
-
-    """
-    self.minor = minor
-    self.dev_path = "/dev/md%d" % minor
-
-  def Assemble(self):
-    """Assemble the MD device.
-
-    At this point we should have:
-      - list of children devices
-      - uuid
-
-    """
-    result = super(MDRaid1, self).Assemble()
-    if not result:
-      return result
-    md_list = self._GetUsedDevs()
-    for minor in md_list:
-      info = self._GetDevInfo(minor)
-      if info and info["uuid"] == self.unique_id:
-        self._SetFromMinor(minor)
-        logger.Info("MD array %s already started" % str(self))
-        return True
-    free_minor = self._FindUnusedMinor()
-    result = utils.RunCmd(["mdadm", "-A", "--auto=yes", "--uuid",
-                           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: %s" %
-                   (result.fail_reason, result.output))
-      self.minor = None
-    else:
-      self.minor = free_minor
-    return not result.failed
-
-  def Shutdown(self):
-    """Tear down the MD array.
-
-    This does a 'mdadm --stop' so after this command, the array is no
-    longer available.
-
-    """
-    if self.minor is None and not self.Attach():
-      logger.Info("MD object not attached to a device")
-      return True
-
-    result = utils.RunCmd(["mdadm", "--stop", "/dev/md%d" % self.minor])
-    if result.failed:
-      logger.Error("Can't stop MD array: %s - %s" %
-                   (result.fail_reason, result.output))
-      return False
-    self.minor = None
-    self.dev_path = None
-    return True
-
-  def SetSyncSpeed(self, kbytes):
-    """Set the maximum sync speed for the MD array.
-
-    """
-    result = super(MDRaid1, self).SetSyncSpeed(kbytes)
-    if self.minor is None:
-      logger.Error("MD array not attached to a device")
-      return False
-    f = open("/sys/block/md%d/md/sync_speed_max" % self.minor, "w")
-    try:
-      f.write("%d" % kbytes)
-    finally:
-      f.close()
-    f = open("/sys/block/md%d/md/sync_speed_min" % self.minor, "w")
-    try:
-      f.write("%d" % (kbytes/2))
-    finally:
-      f.close()
-    return result
-
-  def GetSyncStatus(self):
-    """Returns the sync status of the device.
-
-    Returns:
-     (sync_percent, estimated_time, is_degraded, ldisk)
-
-    If sync_percent is None, it means all is ok
-    If estimated_time is None, it means we can't esimate
-    the time needed, otherwise it's the time left in seconds.
-
-    The ldisk parameter is always true for MD devices.
-
-    """
-    if self.minor is None and not self.Attach():
-      raise errors.BlockDeviceError("Can't attach to device in GetSyncStatus")
-    dev_info = self._GetDevInfo(self.minor)
-    is_clean = ("state" in dev_info and
-                len(dev_info["state"]) == 1 and
-                dev_info["state"][0] in ("clean", "active"))
-    sys_path = "/sys/block/md%s/md/" % self.minor
-    f = file(sys_path + "sync_action")
-    sync_status = f.readline().strip()
-    f.close()
-    if sync_status == "idle":
-      return None, None, not is_clean, False
-    f = file(sys_path + "sync_completed")
-    sync_completed = f.readline().strip().split(" / ")
-    f.close()
-    if len(sync_completed) != 2:
-      return 0, None, not is_clean, False
-    sync_done, sync_total = [float(i) for i in sync_completed]
-    sync_percent = 100.0*sync_done/sync_total
-    f = file(sys_path + "sync_speed")
-    sync_speed_k = int(f.readline().strip())
-    if sync_speed_k == 0:
-      time_est = None
-    else:
-      time_est = (sync_total - sync_done) / 2 / sync_speed_k
-    return sync_percent, time_est, not is_clean, False
-
-  def Open(self, force=False):
-    """Make the device ready for I/O.
-
-    This is a no-op for the MDRaid1 device type, although we could use
-    the 2.6.18's new array_state thing.
-
-    """
-    pass
-
-  def Close(self):
-    """Notifies that the device will no longer be used for I/O.
-
-    This is a no-op for the MDRaid1 device type, but see comment for
-    `Open()`.
-
-    """
-    pass
-
-
 class BaseDRBD(BlockDev):
   """Base DRBD class.
 
   This class contains a few bits of common functionality between the
   0.7 and 8.x versions of DRBD.
 
-  """
-  _VERSION_RE = re.compile(r"^version: (\d+)\.(\d+)\.(\d+)"
-                           r" \(api:(\d+)/proto:(\d+)(?:-(\d+))?\)")
-
-  _DRBD_MAJOR = 147
-  _ST_UNCONFIGURED = "Unconfigured"
-  _ST_WFCONNECTION = "WFConnection"
-  _ST_CONNECTED = "Connected"
-
-  @staticmethod
-  def _GetProcData():
-    """Return data from /proc/drbd.
-
-    """
-    stat = open("/proc/drbd", "r")
-    try:
-      data = stat.read().splitlines()
-    finally:
-      stat.close()
-    if not data:
-      raise errors.BlockDeviceError("Can't read any data from /proc/drbd")
-    return data
-
-  @staticmethod
-  def _MassageProcData(data):
-    """Transform the output of _GetProdData into a nicer form.
-
-    Returns:
-      a dictionary of minor: joined lines from /proc/drbd for that minor
-
-    """
-    lmatch = re.compile("^ *([0-9]+):.*$")
-    results = {}
-    old_minor = old_line = None
-    for line in data:
-      lresult = lmatch.match(line)
-      if lresult is not None:
-        if old_minor is not None:
-          results[old_minor] = old_line
-        old_minor = int(lresult.group(1))
-        old_line = line
-      else:
-        if old_minor is not None:
-          old_line += " " + line.strip()
-    # add last line
-    if old_minor is not None:
-      results[old_minor] = old_line
-    return results
-
-  @classmethod
-  def _GetVersion(cls):
-    """Return the DRBD version.
-
-    This will return a dict with keys:
-      k_major,
-      k_minor,
-      k_point,
-      api,
-      proto,
-      proto2 (only on drbd > 8.2.X)
-
-    """
-    proc_data = cls._GetProcData()
-    first_line = proc_data[0].strip()
-    version = cls._VERSION_RE.match(first_line)
-    if not version:
-      raise errors.BlockDeviceError("Can't parse DRBD version from '%s'" %
-                                    first_line)
-
-    values = version.groups()
-    retval = {'k_major': int(values[0]),
-              'k_minor': int(values[1]),
-              'k_point': int(values[2]),
-              'api': int(values[3]),
-              'proto': int(values[4]),
-             }
-    if values[5] is not None:
-      retval['proto2'] = values[5]
-
-    return retval
-
-  @staticmethod
-  def _DevPath(minor):
-    """Return the path to a drbd device for a given minor.
-
-    """
-    return "/dev/drbd%d" % minor
-
-  @classmethod
-  def _GetUsedDevs(cls):
-    """Compute the list of used DRBD devices.
-
-    """
-    data = cls._GetProcData()
-
-    used_devs = {}
-    valid_line = re.compile("^ *([0-9]+): cs:([^ ]+).*$")
-    for line in data:
-      match = valid_line.match(line)
-      if not match:
-        continue
-      minor = int(match.group(1))
-      state = match.group(2)
-      if state == cls._ST_UNCONFIGURED:
-        continue
-      used_devs[minor] = state, line
-
-    return used_devs
-
-  def _SetFromMinor(self, minor):
-    """Set our parameters based on the given minor.
-
-    This sets our minor variable and our dev_path.
-
-    """
-    if minor is None:
-      self.minor = self.dev_path = None
-    else:
-      self.minor = minor
-      self.dev_path = self._DevPath(minor)
-
-  @staticmethod
-  def _CheckMetaSize(meta_device):
-    """Check if the given meta device looks like a valid one.
-
-    This currently only check the size, which must be around
-    128MiB.
-
-    """
-    result = utils.RunCmd(["blockdev", "--getsize", meta_device])
-    if result.failed:
-      logger.Error("Failed to get device size: %s - %s" %
-                   (result.fail_reason, result.output))
-      return False
-    try:
-      sectors = int(result.stdout)
-    except ValueError:
-      logger.Error("Invalid output from blockdev: '%s'" % result.stdout)
-      return False
-    bytes = sectors * 512
-    if bytes < 128 * 1024 * 1024: # less than 128MiB
-      logger.Error("Meta device too small (%.2fMib)" % (bytes / 1024 / 1024))
-      return False
-    if bytes > (128 + 32) * 1024 * 1024: # account for an extra (big) PE on LVM
-      logger.Error("Meta device too big (%.2fMiB)" % (bytes / 1024 / 1024))
-      return False
-    return True
-
-  def Rename(self, new_id):
-    """Rename a device.
-
-    This is not supported for drbd devices.
-
-    """
-    raise errors.ProgrammerError("Can't rename a drbd device")
-
-
-class DRBDev(BaseDRBD):
-  """DRBD block device.
-
-  This implements the local host part of the DRBD device, i.e. it
-  doesn't do anything to the supposed peer. If you need a fully
-  connected DRBD pair, you need to use this class on both hosts.
-
-  The unique_id for the drbd device is the (local_ip, local_port,
-  remote_ip, remote_port) tuple, and it must have two children: the
-  data device and the meta_device. The meta device is checked for
-  valid size and is zeroed on create.
-
-  """
-  def __init__(self, unique_id, children):
-    super(DRBDev, self).__init__(unique_id, children)
-    self.major = self._DRBD_MAJOR
-    version = self._GetVersion()
-    if version['k_major'] != 0 and version['k_minor'] != 7:
-      raise errors.BlockDeviceError("Mismatch in DRBD kernel version and"
-                                    " requested ganeti usage: kernel is"
-                                    " %s.%s, ganeti wants 0.7" %
-                                    (version['k_major'], version['k_minor']))
-    if len(children) != 2:
-      raise ValueError("Invalid configuration data %s" % str(children))
-    if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 4:
-      raise ValueError("Invalid configuration data %s" % str(unique_id))
-    self._lhost, self._lport, self._rhost, self._rport = unique_id
-    self.Attach()
-
-  @classmethod
-  def _FindUnusedMinor(cls):
-    """Find an unused DRBD device.
-
-    """
-    data = cls._GetProcData()
-
-    valid_line = re.compile("^ *([0-9]+): cs:Unconfigured$")
-    for line in data:
-      match = valid_line.match(line)
-      if match:
-        return int(match.group(1))
-    logger.Error("Error: no free drbd minors!")
-    raise errors.BlockDeviceError("Can't find a free DRBD minor")
-
-  @classmethod
-  def _GetDevInfo(cls, minor):
-    """Get details about a given DRBD minor.
-
-    This return, if available, the local backing device in (major,
-    minor) formant and the local and remote (ip, port) information.
-
-    """
-    data = {}
-    result = utils.RunCmd(["drbdsetup", cls._DevPath(minor), "show"])
-    if result.failed:
-      logger.Error("Can't display the drbd config: %s - %s" %
-                   (result.fail_reason, result.output))
-      return data
-    out = result.stdout
-    if out == "Not configured\n":
-      return data
-    for line in out.splitlines():
-      if "local_dev" not in data:
-        match = re.match("^Lower device: ([0-9]+):([0-9]+) .*$", line)
-        if match:
-          data["local_dev"] = (int(match.group(1)), int(match.group(2)))
-          continue
-      if "meta_dev" not in data:
-        match = re.match("^Meta device: (([0-9]+):([0-9]+)|internal).*$", line)
-        if match:
-          if match.group(2) is not None and match.group(3) is not None:
-            # matched on the major/minor
-            data["meta_dev"] = (int(match.group(2)), int(match.group(3)))
-          else:
-            # matched on the "internal" string
-            data["meta_dev"] = match.group(1)
-            # in this case, no meta_index is in the output
-            data["meta_index"] = -1
-          continue
-      if "meta_index" not in data:
-        match = re.match("^Meta index: ([0-9]+).*$", line)
-        if match:
-          data["meta_index"] = int(match.group(1))
-          continue
-      if "local_addr" not in data:
-        match = re.match("^Local address: ([0-9.]+):([0-9]+)$", line)
-        if match:
-          data["local_addr"] = (match.group(1), int(match.group(2)))
-          continue
-      if "remote_addr" not in data:
-        match = re.match("^Remote address: ([0-9.]+):([0-9]+)$", line)
-        if match:
-          data["remote_addr"] = (match.group(1), int(match.group(2)))
-          continue
-    return data
-
-  def _MatchesLocal(self, info):
-    """Test if our local config matches with an existing device.
-
-    The parameter should be as returned from `_GetDevInfo()`. This
-    method tests if our local backing device is the same as the one in
-    the info parameter, in effect testing if we look like the given
-    device.
-
-    """
-    if not ("local_dev" in info and "meta_dev" in info and
-            "meta_index" in info):
-      return False
-
-    backend = self._children[0]
-    if backend is not None:
-      retval = (info["local_dev"] == (backend.major, backend.minor))
-    else:
-      retval = (info["local_dev"] == (0, 0))
-    meta = self._children[1]
-    if meta is not None:
-      retval = retval and (info["meta_dev"] == (meta.major, meta.minor))
-      retval = retval and (info["meta_index"] == 0)
-    else:
-      retval = retval and (info["meta_dev"] == "internal" and
-                           info["meta_index"] == -1)
-    return retval
-
-  def _MatchesNet(self, info):
-    """Test if our network config matches with an existing device.
-
-    The parameter should be as returned from `_GetDevInfo()`. This
-    method tests if our network configuration is the same as the one
-    in the info parameter, in effect testing if we look like the given
-    device.
-
-    """
-    if (((self._lhost is None and not ("local_addr" in info)) and
-         (self._rhost is None and not ("remote_addr" in info)))):
-      return True
-
-    if self._lhost is None:
-      return False
-
-    if not ("local_addr" in info and
-            "remote_addr" in info):
-      return False
-
-    retval = (info["local_addr"] == (self._lhost, self._lport))
-    retval = (retval and
-              info["remote_addr"] == (self._rhost, self._rport))
-    return retval
-
-  @classmethod
-  def _AssembleLocal(cls, minor, backend, meta):
-    """Configure the local part of a DRBD device.
-
-    This is the first thing that must be done on an unconfigured DRBD
-    device. And it must be done only once.
-
-    """
-    if not cls._CheckMetaSize(meta):
-      return False
-    result = utils.RunCmd(["drbdsetup", cls._DevPath(minor), "disk",
-                           backend, meta, "0", "-e", "detach"])
-    if result.failed:
-      logger.Error("Can't attach local disk: %s" % result.output)
-    return not result.failed
-
-  @classmethod
-  def _ShutdownLocal(cls, minor):
-    """Detach from the local device.
-
-    I/Os will continue to be served from the remote device. If we
-    don't have a remote device, this operation will fail.
-
-    """
-    result = utils.RunCmd(["drbdsetup", cls._DevPath(minor), "detach"])
-    if result.failed:
-      logger.Error("Can't detach local device: %s" % result.output)
-    return not result.failed
-
-  @staticmethod
-  def _ShutdownAll(minor):
-    """Deactivate the device.
-
-    This will, of course, fail if the device is in use.
-
-    """
-    result = utils.RunCmd(["drbdsetup", DRBDev._DevPath(minor), "down"])
-    if result.failed:
-      logger.Error("Can't shutdown drbd device: %s" % result.output)
-    return not result.failed
-
-  @classmethod
-  def _AssembleNet(cls, minor, net_info, protocol):
-    """Configure the network part of the device.
-
-    This operation can be, in theory, done multiple times, but there
-    have been cases (in lab testing) in which the network part of the
-    device had become stuck and couldn't be shut down because activity
-    from the new peer (also stuck) triggered a timer re-init and
-    needed remote peer interface shutdown in order to clear. So please
-    don't change online the net config.
-
-    """
-    lhost, lport, rhost, rport = net_info
-    result = utils.RunCmd(["drbdsetup", cls._DevPath(minor), "net",
-                           "%s:%s" % (lhost, lport), "%s:%s" % (rhost, rport),
-                           protocol])
-    if result.failed:
-      logger.Error("Can't setup network for dbrd device: %s - %s" %
-                   (result.fail_reason, result.output))
-      return False
-
-    timeout = time.time() + 10
-    ok = False
-    while time.time() < timeout:
-      info = cls._GetDevInfo(minor)
-      if not "local_addr" in info or not "remote_addr" in info:
-        time.sleep(1)
-        continue
-      if (info["local_addr"] != (lhost, lport) or
-          info["remote_addr"] != (rhost, rport)):
-        time.sleep(1)
-        continue
-      ok = True
-      break
-    if not ok:
-      logger.Error("Timeout while configuring network")
-      return False
-    return True
-
-  @classmethod
-  def _ShutdownNet(cls, minor):
-    """Disconnect from the remote peer.
-
-    This fails if we don't have a local device.
-
-    """
-    result = utils.RunCmd(["drbdsetup", cls._DevPath(minor), "disconnect"])
-    if result.failed:
-      logger.Error("Can't shutdown network: %s" % result.output)
-    return not result.failed
-
-  def Assemble(self):
-    """Assemble the drbd.
-
-    Method:
-      - if we have a local backing device, we bind to it by:
-        - checking the list of used drbd devices
-        - check if the local minor use of any of them is our own device
-        - if yes, abort?
-        - if not, bind
-      - if we have a local/remote net info:
-        - redo the local backing device step for the remote device
-        - check if any drbd device is using the local port,
-          if yes abort
-        - check if any remote drbd device is using the remote
-          port, if yes abort (for now)
-        - bind our net port
-        - bind the remote net port
-
-    """
-    self.Attach()
-    if self.minor is not None:
-      logger.Info("Already assembled")
-      return True
-
-    result = super(DRBDev, self).Assemble()
-    if not result:
-      return result
+  """
+  _VERSION_RE = re.compile(r"^version: (\d+)\.(\d+)\.(\d+)"
+                           r" \(api:(\d+)/proto:(\d+)(?:-(\d+))?\)")
 
-    minor = self._FindUnusedMinor()
-    need_localdev_teardown = False
-    if self._children[0]:
-      result = self._AssembleLocal(minor, self._children[0].dev_path,
-                                   self._children[1].dev_path)
-      if not result:
-        return False
-      need_localdev_teardown = True
-    if self._lhost and self._lport and self._rhost and self._rport:
-      result = self._AssembleNet(minor,
-                                 (self._lhost, self._lport,
-                                  self._rhost, self._rport),
-                                 "C")
-      if not result:
-        if need_localdev_teardown:
-          # we will ignore failures from this
-          logger.Error("net setup failed, tearing down local device")
-          self._ShutdownAll(minor)
-        return False
-    self._SetFromMinor(minor)
-    return True
+  _DRBD_MAJOR = 147
+  _ST_UNCONFIGURED = "Unconfigured"
+  _ST_WFCONNECTION = "WFConnection"
+  _ST_CONNECTED = "Connected"
 
-  def Shutdown(self):
-    """Shutdown the DRBD device.
+  @staticmethod
+  def _GetProcData():
+    """Return data from /proc/drbd.
 
     """
-    if self.minor is None and not self.Attach():
-      logger.Info("DRBD device not attached to a device during Shutdown")
-      return True
-    if not self._ShutdownAll(self.minor):
-      return False
-    self.minor = None
-    self.dev_path = None
-    return True
+    stat = open("/proc/drbd", "r")
+    try:
+      data = stat.read().splitlines()
+    finally:
+      stat.close()
+    if not data:
+      raise errors.BlockDeviceError("Can't read any data from /proc/drbd")
+    return data
 
-  def Attach(self):
-    """Find a DRBD device which matches our config and attach to it.
+  @staticmethod
+  def _MassageProcData(data):
+    """Transform the output of _GetProdData into a nicer form.
 
-    In case of partially attached (local device matches but no network
-    setup), we perform the network attach. If successful, we re-test
-    the attach if can return success.
+    Returns:
+      a dictionary of minor: joined lines from /proc/drbd for that minor
 
     """
-    for minor in self._GetUsedDevs():
-      info = self._GetDevInfo(minor)
-      match_l = self._MatchesLocal(info)
-      match_r = self._MatchesNet(info)
-      if match_l and match_r:
-        break
-      if match_l and not match_r and "local_addr" not in info:
-        res_r = self._AssembleNet(minor,
-                                  (self._lhost, self._lport,
-                                   self._rhost, self._rport),
-                                  "C")
-        if res_r and self._MatchesNet(self._GetDevInfo(minor)):
-          break
-    else:
-      minor = None
-
-    self._SetFromMinor(minor)
-    return minor is not None
+    lmatch = re.compile("^ *([0-9]+):.*$")
+    results = {}
+    old_minor = old_line = None
+    for line in data:
+      lresult = lmatch.match(line)
+      if lresult is not None:
+        if old_minor is not None:
+          results[old_minor] = old_line
+        old_minor = int(lresult.group(1))
+        old_line = line
+      else:
+        if old_minor is not None:
+          old_line += " " + line.strip()
+    # add last line
+    if old_minor is not None:
+      results[old_minor] = old_line
+    return results
 
-  def Open(self, force=False):
-    """Make the local state primary.
+  @classmethod
+  def _GetVersion(cls):
+    """Return the DRBD version.
 
-    If the 'force' parameter is given, the '--do-what-I-say' parameter
-    is given. Since this is a pottentialy dangerous operation, the
-    force flag should be only given after creation, when it actually
-    has to be given.
+    This will return a dict with keys:
+      k_major,
+      k_minor,
+      k_point,
+      api,
+      proto,
+      proto2 (only on drbd > 8.2.X)
 
     """
-    if self.minor is None and not self.Attach():
-      logger.Error("DRBD cannot attach to a device during open")
-      return False
-    cmd = ["drbdsetup", self.dev_path, "primary"]
-    if force:
-      cmd.append("--do-what-I-say")
-    result = utils.RunCmd(cmd)
-    if result.failed:
-      msg = ("Can't make drbd device primary: %s" % result.output)
-      logger.Error(msg)
-      raise errors.BlockDeviceError(msg)
+    proc_data = cls._GetProcData()
+    first_line = proc_data[0].strip()
+    version = cls._VERSION_RE.match(first_line)
+    if not version:
+      raise errors.BlockDeviceError("Can't parse DRBD version from '%s'" %
+                                    first_line)
 
-  def Close(self):
-    """Make the local state secondary.
+    values = version.groups()
+    retval = {'k_major': int(values[0]),
+              'k_minor': int(values[1]),
+              'k_point': int(values[2]),
+              'api': int(values[3]),
+              'proto': int(values[4]),
+             }
+    if values[5] is not None:
+      retval['proto2'] = values[5]
 
-    This will, of course, fail if the device is in use.
+    return retval
+
+  @staticmethod
+  def _DevPath(minor):
+    """Return the path to a drbd device for a given minor.
 
     """
-    if self.minor is None and not self.Attach():
-      logger.Info("Instance not attached to a device")
-      raise errors.BlockDeviceError("Can't find device")
-    result = utils.RunCmd(["drbdsetup", self.dev_path, "secondary"])
-    if result.failed:
-      msg = ("Can't switch drbd device to"
-             " secondary: %s" % result.output)
-      logger.Error(msg)
-      raise errors.BlockDeviceError(msg)
+    return "/dev/drbd%d" % minor
 
-  def SetSyncSpeed(self, kbytes):
-    """Set the speed of the DRBD syncer.
+  @classmethod
+  def _GetUsedDevs(cls):
+    """Compute the list of used DRBD devices.
 
     """
-    children_result = super(DRBDev, self).SetSyncSpeed(kbytes)
-    if self.minor is None:
-      logger.Info("Instance not attached to a device")
-      return False
-    result = utils.RunCmd(["drbdsetup", self.dev_path, "syncer", "-r", "%d" %
-                           kbytes])
-    if result.failed:
-      logger.Error("Can't change syncer rate: %s - %s" %
-                   (result.fail_reason, result.output))
-    return not result.failed and children_result
+    data = cls._GetProcData()
 
-  def GetSyncStatus(self):
-    """Returns the sync status of the device.
+    used_devs = {}
+    valid_line = re.compile("^ *([0-9]+): cs:([^ ]+).*$")
+    for line in data:
+      match = valid_line.match(line)
+      if not match:
+        continue
+      minor = int(match.group(1))
+      state = match.group(2)
+      if state == cls._ST_UNCONFIGURED:
+        continue
+      used_devs[minor] = state, line
 
-    Returns:
-     (sync_percent, estimated_time, is_degraded, ldisk)
+    return used_devs
 
-    If sync_percent is None, it means all is ok
-    If estimated_time is None, it means we can't esimate
-    the time needed, otherwise it's the time left in seconds.
+  def _SetFromMinor(self, minor):
+    """Set our parameters based on the given minor.
 
-    The ldisk parameter will be returned as True, since the DRBD7
-    devices have not been converted.
+    This sets our minor variable and our dev_path.
 
     """
-    if self.minor is None and not self.Attach():
-      raise errors.BlockDeviceError("Can't attach to device in GetSyncStatus")
-    proc_info = self._MassageProcData(self._GetProcData())
-    if self.minor not in proc_info:
-      raise errors.BlockDeviceError("Can't find myself in /proc (minor %d)" %
-                                    self.minor)
-    line = proc_info[self.minor]
-    match = re.match("^.*sync'ed: *([0-9.]+)%.*"
-                     " finish: ([0-9]+):([0-9]+):([0-9]+) .*$", line)
-    if match:
-      sync_percent = float(match.group(1))
-      hours = int(match.group(2))
-      minutes = int(match.group(3))
-      seconds = int(match.group(4))
-      est_time = hours * 3600 + minutes * 60 + seconds
+    if minor is None:
+      self.minor = self.dev_path = None
     else:
-      sync_percent = None
-      est_time = None
-    match = re.match("^ *[0-9]+: cs:([^ ]+).*$", line)
-    if not match:
-      raise errors.BlockDeviceError("Can't find my data in /proc (minor %d)" %
-                                    self.minor)
-    client_state = match.group(1)
-    is_degraded = client_state != "Connected"
-    return sync_percent, est_time, is_degraded, False
+      self.minor = minor
+      self.dev_path = self._DevPath(minor)
 
   @staticmethod
-  def _ZeroDevice(device):
-    """Zero a device.
+  def _CheckMetaSize(meta_device):
+    """Check if the given meta device looks like a valid one.
 
-    This writes until we get ENOSPC.
+    This currently only check the size, which must be around
+    128MiB.
 
     """
-    f = open(device, "w")
-    buf = "\0" * 1048576
+    result = utils.RunCmd(["blockdev", "--getsize", meta_device])
+    if result.failed:
+      logger.Error("Failed to get device size: %s - %s" %
+                   (result.fail_reason, result.output))
+      return False
     try:
-      while True:
-        f.write(buf)
-    except IOError, err:
-      if err.errno != errno.ENOSPC:
-        raise
-
-  @classmethod
-  def Create(cls, unique_id, children, size):
-    """Create a new DRBD device.
-
-    Since DRBD devices are not created per se, just assembled, this
-    function just zeroes the meta device.
+      sectors = int(result.stdout)
+    except ValueError:
+      logger.Error("Invalid output from blockdev: '%s'" % result.stdout)
+      return False
+    bytes = sectors * 512
+    if bytes < 128 * 1024 * 1024: # less than 128MiB
+      logger.Error("Meta device too small (%.2fMib)" % (bytes / 1024 / 1024))
+      return False
+    if bytes > (128 + 32) * 1024 * 1024: # account for an extra (big) PE on LVM
+      logger.Error("Meta device too big (%.2fMiB)" % (bytes / 1024 / 1024))
+      return False
+    return True
 
-    """
-    if len(children) != 2:
-      raise errors.ProgrammerError("Invalid setup for the drbd device")
-    meta = children[1]
-    meta.Assemble()
-    if not meta.Attach():
-      raise errors.BlockDeviceError("Can't attach to meta device")
-    if not cls._CheckMetaSize(meta.dev_path):
-      raise errors.BlockDeviceError("Invalid meta device")
-    logger.Info("Started zeroing device %s" % meta.dev_path)
-    cls._ZeroDevice(meta.dev_path)
-    logger.Info("Done zeroing device %s" % meta.dev_path)
-    return cls(unique_id, children)
+  def Rename(self, new_id):
+    """Rename a device.
 
-  def Remove(self):
-    """Stub remove for DRBD devices.
+    This is not supported for drbd devices.
 
     """
-    return self.Shutdown()
+    raise errors.ProgrammerError("Can't rename a drbd device")
 
 
 class DRBD8(BaseDRBD):
@@ -2198,11 +1333,11 @@ class DRBD8(BaseDRBD):
 
 class FileStorage(BlockDev):
   """File device.
-  
+
   This class represents the a file storage backend device.
 
   The unique_id for the file device is a (file_driver, file_path) tuple.
-  
+
   """
   def __init__(self, unique_id, children):
     """Initalizes a file device backend.
@@ -2310,8 +1445,6 @@ class FileStorage(BlockDev):
 
 DEV_MAP = {
   constants.LD_LV: LogicalVolume,
-  constants.LD_MD_R1: MDRaid1,
-  constants.LD_DRBD7: DRBDev,
   constants.LD_DRBD8: DRBD8,
   constants.LD_FILE: FileStorage,
   }
index 4fc15dd..dc213b3 100644 (file)
@@ -2872,7 +2872,7 @@ class LUFailoverInstance(LogicalUnit):
     secondary_nodes = instance.secondary_nodes
     if not secondary_nodes:
       raise errors.ProgrammerError("no secondary node but using "
-                                   "DT_REMOTE_RAID1 template")
+                                   "a mirrored disk template")
 
     target_node = secondary_nodes[0]
     # check memory requirements on the secondary node
@@ -2902,7 +2902,7 @@ class LUFailoverInstance(LogicalUnit):
 
     feedback_fn("* checking disk consistency between source and target")
     for dev in instance.disks:
-      # for remote_raid1, these are md over drbd
+      # for drbd, these are drbd over lvm
       if not _CheckDiskConsistency(self.cfg, dev, target_node, False):
         if instance.status == "up" and not self.op.ignore_consistency:
           raise errors.OpExecError("Disk %s is degraded on target node,"
@@ -3751,13 +3751,6 @@ class LUReplaceDisks(LogicalUnit):
         # replacement as for drbd7 (no different port allocated)
         raise errors.OpPrereqError("Same secondary given, cannot execute"
                                    " replacement")
-      # the user gave the current secondary, switch to
-      # 'no-replace-secondary' mode for drbd7
-      remote_node = None
-    if (instance.disk_template == constants.DT_REMOTE_RAID1 and
-        self.op.mode != constants.REPLACE_DISK_ALL):
-      raise errors.OpPrereqError("Template 'remote_raid1' only allows all"
-                                 " disks replacement, not individual ones")
     if instance.disk_template == constants.DT_DRBD8:
       if (self.op.mode == constants.REPLACE_DISK_ALL and
           remote_node is not None):
@@ -3789,101 +3782,6 @@ class LUReplaceDisks(LogicalUnit):
                                    (name, instance.name))
     self.op.remote_node = remote_node
 
-  def _ExecRR1(self, feedback_fn):
-    """Replace the disks of an instance.
-
-    """
-    instance = self.instance
-    iv_names = {}
-    # start of work
-    if self.op.remote_node is None:
-      remote_node = self.sec_node
-    else:
-      remote_node = self.op.remote_node
-    cfg = self.cfg
-    for dev in instance.disks:
-      size = dev.size
-      lv_names = [".%s_%s" % (dev.iv_name, suf) for suf in ["data", "meta"]]
-      names = _GenerateUniqueNames(cfg, lv_names)
-      new_drbd = _GenerateMDDRBDBranch(cfg, instance.primary_node,
-                                       remote_node, size, names)
-      iv_names[dev.iv_name] = (dev, dev.children[0], new_drbd)
-      logger.Info("adding new mirror component on secondary for %s" %
-                  dev.iv_name)
-      #HARDCODE
-      if not _CreateBlockDevOnSecondary(cfg, remote_node, instance,
-                                        new_drbd, False,
-                                        _GetInstanceInfoText(instance)):
-        raise errors.OpExecError("Failed to create new component on secondary"
-                                 " node %s. Full abort, cleanup manually!" %
-                                 remote_node)
-
-      logger.Info("adding new mirror component on primary")
-      #HARDCODE
-      if not _CreateBlockDevOnPrimary(cfg, instance.primary_node,
-                                      instance, new_drbd,
-                                      _GetInstanceInfoText(instance)):
-        # remove secondary dev
-        cfg.SetDiskID(new_drbd, remote_node)
-        rpc.call_blockdev_remove(remote_node, new_drbd)
-        raise errors.OpExecError("Failed to create volume on primary!"
-                                 " Full abort, cleanup manually!!")
-
-      # the device exists now
-      # call the primary node to add the mirror to md
-      logger.Info("adding new mirror component to md")
-      if not rpc.call_blockdev_addchildren(instance.primary_node, dev,
-                                           [new_drbd]):
-        logger.Error("Can't add mirror compoment to md!")
-        cfg.SetDiskID(new_drbd, remote_node)
-        if not rpc.call_blockdev_remove(remote_node, new_drbd):
-          logger.Error("Can't rollback on secondary")
-        cfg.SetDiskID(new_drbd, instance.primary_node)
-        if not rpc.call_blockdev_remove(instance.primary_node, new_drbd):
-          logger.Error("Can't rollback on primary")
-        raise errors.OpExecError("Full abort, cleanup manually!!")
-
-      dev.children.append(new_drbd)
-      cfg.AddInstance(instance)
-
-    # this can fail as the old devices are degraded and _WaitForSync
-    # does a combined result over all disks, so we don't check its
-    # return value
-    _WaitForSync(cfg, instance, self.proc, unlock=True)
-
-    # so check manually all the devices
-    for name in iv_names:
-      dev, child, new_drbd = iv_names[name]
-      cfg.SetDiskID(dev, instance.primary_node)
-      is_degr = rpc.call_blockdev_find(instance.primary_node, dev)[5]
-      if is_degr:
-        raise errors.OpExecError("MD device %s is degraded!" % name)
-      cfg.SetDiskID(new_drbd, instance.primary_node)
-      is_degr = rpc.call_blockdev_find(instance.primary_node, new_drbd)[5]
-      if is_degr:
-        raise errors.OpExecError("New drbd device %s is degraded!" % name)
-
-    for name in iv_names:
-      dev, child, new_drbd = iv_names[name]
-      logger.Info("remove mirror %s component" % name)
-      cfg.SetDiskID(dev, instance.primary_node)
-      if not rpc.call_blockdev_removechildren(instance.primary_node,
-                                              dev, [child]):
-        logger.Error("Can't remove child from mirror, aborting"
-                     " *this device cleanup*.\nYou need to cleanup manually!!")
-        continue
-
-      for node in child.logical_id[:2]:
-        logger.Info("remove child device on %s" % node)
-        cfg.SetDiskID(child, node)
-        if not rpc.call_blockdev_remove(node, child):
-          logger.Error("Warning: failed to remove device from node %s,"
-                       " continuing operation." % node)
-
-      dev.children.remove(child)
-
-      cfg.AddInstance(instance)
-
   def _ExecD8DiskOnly(self, feedback_fn):
     """Replace a disk on the primary or secondary for dbrd8.
 
@@ -4225,9 +4123,7 @@ class LUReplaceDisks(LogicalUnit):
 
     """
     instance = self.instance
-    if instance.disk_template == constants.DT_REMOTE_RAID1:
-      fn = self._ExecRR1
-    elif instance.disk_template == constants.DT_DRBD8:
+    if instance.disk_template == constants.DT_DRBD8:
       if self.op.remote_node is None:
         fn = self._ExecD8DiskOnly
       else:
index 0f68b2f..a522ede 100644 (file)
@@ -101,21 +101,17 @@ HKR_SUCCESS = 2
 # disk template types
 DT_DISKLESS = "diskless"
 DT_PLAIN = "plain"
-DT_LOCAL_RAID1 = "local_raid1"
-DT_REMOTE_RAID1 = "remote_raid1"
 DT_DRBD8 = "drbd"
 DT_FILE = "file"
 
 # the set of network-mirrored disk templates
-DTS_NET_MIRROR = frozenset([DT_REMOTE_RAID1, DT_DRBD8])
+DTS_NET_MIRROR = frozenset([DT_DRBD8])
 
 # the set of non-lvm-based disk templates
 DTS_NOT_LVM = frozenset([DT_DISKLESS, DT_FILE])
 
 # logical disk types
 LD_LV = "lvm"
-LD_MD_R1 = "md_raid1"
-LD_DRBD7 = "drbd"
 LD_DRBD8 = "drbd8"
 LD_FILE = "file"
 
@@ -124,7 +120,7 @@ FD_LOOP = "loop"
 FD_BLKTAP = "blktap"
 
 # the set of drbd-like disk types
-LDS_DRBD = frozenset([LD_DRBD7, LD_DRBD8])
+LDS_DRBD = frozenset([LD_DRBD8])
 
 # disk replacement mode
 REPLACE_DISK_PRI = "replace_primary"
@@ -136,7 +132,6 @@ INSTANCE_CREATE = "create"
 INSTANCE_IMPORT = "import"
 
 DISK_TEMPLATES = frozenset([DT_DISKLESS, DT_PLAIN,
-                            DT_LOCAL_RAID1, DT_REMOTE_RAID1,
                             DT_DRBD8, DT_FILE])
 
 FILE_DRIVER = frozenset([FD_LOOP, FD_BLKTAP])
index 3d78b57..5f7a653 100644 (file)
@@ -342,12 +342,9 @@ class Disk(ConfigObject):
 
     This method, given the node on which the parent disk lives, will
     return the list of all (node, disk) pairs which describe the disk
-    tree in the most compact way. For example, a md/drbd/lvm stack
-    will be returned as (primary_node, md) and (secondary_node, drbd)
-    which represents all the top-level devices on the nodes. This
-    means that on the primary node we need to activate the the md (and
-    recursively all its children) and on the secondary node we need to
-    activate the drbd device (and its children, the two lvm volumes).
+    tree in the most compact way. For example, a drbd/lvm stack
+    will be returned as (primary_node, drbd) and (secondary_node, drbd)
+    which represents all the top-level devices on the nodes.
 
     """
     my_nodes = self.GetNodes(parent_node)
index c8a0f6b..1e1ba68 100755 (executable)
@@ -142,8 +142,8 @@ import_opts = [
   make_option("-p", "--cpu", dest="vcpus", help="Number of virtual CPUs",
               default=1, type="int", metavar="<PROC>"),
   make_option("-t", "--disk-template", dest="disk_template",
-              help="Custom disk setup (diskless, plain, local_raid1,"
-              " remote_raid1 or drbd)", default=None, metavar="TEMPL"),
+              help="Custom disk setup (diskless, file, plain, drbd)"
+              default=None, metavar="TEMPL"),
   make_option("-i", "--ip", dest="ip",
               help="IP address ('none' [default], 'auto', or specify address)",
               default='none', type="string", metavar="<ADDRESS>"),
index fb9eb91..3c2189a 100755 (executable)
@@ -300,8 +300,8 @@ commands = {
                [DEBUG_OPT, FORCE_OPT],
                "[-f] <src> <dst>",
                "Relocate the secondary instances from the first node"
-               " to the second one (only for instances of type remote_raid1"
-               " drbd)"),
+               " to the second one (only for instances with drbd disk template"
+               ),
   'failover': (FailoverNode, ARGS_ONE,
                [DEBUG_OPT, FORCE_OPT,
                 make_option("--ignore-consistency", dest="ignore_consistency",
@@ -311,7 +311,7 @@ commands = {
                 ],
                "[-f] <node>",
                "Stops the primary instances on a node and start them on their"
-               " secondary node (only for instances of type remote_raid1)"),
+               " secondary node (only for instances with drbd disk template)"),
   'info': (ShowNodeConfig, ARGS_ANY, [DEBUG_OPT],
            "[<node_name>...]", "Show information about the node(s)"),
   'list': (ListNodes, ARGS_NONE,