Revision ffa1c0dc

b/lib/bdev.py
804 804

  
805 805
    if len(children) not in (0, 2):
806 806
      raise ValueError("Invalid configuration data %s" % str(children))
807
    if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 4:
807
    if not isinstance(unique_id, (tuple, list)) or len(unique_id) != 5:
808 808
      raise ValueError("Invalid configuration data %s" % str(unique_id))
809
    self._lhost, self._lport, self._rhost, self._rport = unique_id
809
    (self._lhost, self._lport,
810
     self._rhost, self._rport,
811
     self._aminor) = unique_id
812
    if (self._lhost is not None and self._lhost == self._rhost and
813
        self._lport == self._rport):
814
      raise ValueError("Invalid configuration data, same local/remote %s" %
815
                       (unique_id,))
810 816
    self.Attach()
811 817

  
812 818
  @classmethod
b/lib/cmdlib.py
30 30
import tempfile
31 31
import re
32 32
import platform
33
import logging
33 34

  
34 35
from ganeti import rpc
35 36
from ganeti import ssh
......
2909 2910
  return results
2910 2911

  
2911 2912

  
2912
def _GenerateDRBD8Branch(cfg, primary, secondary, size, names, iv_name):
2913
def _GenerateDRBD8Branch(cfg, primary, secondary, size, names, iv_name,
2914
                         p_minor, s_minor):
2913 2915
  """Generate a drbd8 device complete with its children.
2914 2916

  
2915 2917
  """
......
2920 2922
  dev_meta = objects.Disk(dev_type=constants.LD_LV, size=128,
2921 2923
                          logical_id=(vgname, names[1]))
2922 2924
  drbd_dev = objects.Disk(dev_type=constants.LD_DRBD8, size=size,
2923
                          logical_id = (primary, secondary, port),
2924
                          children = [dev_data, dev_meta],
2925
                          logical_id=(primary, secondary, port,
2926
                                      p_minor, s_minor),
2927
                          children=[dev_data, dev_meta],
2925 2928
                          iv_name=iv_name)
2926 2929
  return drbd_dev
2927 2930

  
......
2954 2957
    if len(secondary_nodes) != 1:
2955 2958
      raise errors.ProgrammerError("Wrong template configuration")
2956 2959
    remote_node = secondary_nodes[0]
2960
    (minor_pa, minor_pb,
2961
     minor_sa, minor_sb) = [None, None, None, None]
2962

  
2957 2963
    names = _GenerateUniqueNames(cfg, [".sda_data", ".sda_meta",
2958 2964
                                       ".sdb_data", ".sdb_meta"])
2959 2965
    drbd_sda_dev = _GenerateDRBD8Branch(cfg, primary_node, remote_node,
2960
                                         disk_sz, names[0:2], "sda")
2966
                                        disk_sz, names[0:2], "sda",
2967
                                        minor_pa, minor_sa)
2961 2968
    drbd_sdb_dev = _GenerateDRBD8Branch(cfg, primary_node, remote_node,
2962
                                         swap_sz, names[2:4], "sdb")
2969
                                        swap_sz, names[2:4], "sdb",
2970
                                        minor_pb, minor_sb)
2963 2971
    disks = [drbd_sda_dev, drbd_sdb_dev]
2964 2972
  elif template_name == constants.DT_FILE:
2965 2973
    if len(secondary_nodes) != 0:
......
4003 4011
                                 pri_node)
4004 4012

  
4005 4013
    # Step: create new storage
4014

  
4015
    minors = [None for dev in instance.disks]
4016
    logging.debug("Allocated minors %s" % (minors,))
4006 4017
    self.proc.LogStep(3, steps_total, "allocate new storage")
4007
    for dev in instance.disks:
4018
    for idx, dev in enumerate(instance.disks):
4008 4019
      size = dev.size
4009 4020
      info("adding new local storage on %s for %s" % (new_node, dev.iv_name))
4010 4021
      # since we *always* want to create this LV, we use the
......
4017 4028
                                   " node '%s'" %
4018 4029
                                   (new_lv.logical_id[1], new_node))
4019 4030

  
4020
      iv_names[dev.iv_name] = (dev, dev.children)
4031
      iv_names[dev.iv_name] = (dev, dev.children, minors[idx])
4021 4032

  
4022 4033
    self.proc.LogStep(4, steps_total, "changing drbd configuration")
4023 4034
    for dev in instance.disks:
4024 4035
      size = dev.size
4025 4036
      info("activating a new drbd on %s for %s" % (new_node, dev.iv_name))
4026 4037
      # create new devices on new_node
4038
      new_minor = iv_names[dev.iv_name][2]
4039
      if pri_node == dev.logical_id[0]:
4040
        new_logical_id = (pri_node, new_node,
4041
                          dev.logical_id[2], dev.logical_id[3], new_minor)
4042
      else:
4043
        new_logical_id = (new_node, pri_node,
4044
                          dev.logical_id[2], new_minor, dev.logical_id[4])
4027 4045
      new_drbd = objects.Disk(dev_type=constants.LD_DRBD8,
4028
                              logical_id=(pri_node, new_node,
4029
                                          dev.logical_id[2]),
4046
                              logical_id=new_logical_id,
4030 4047
                              children=dev.children)
4031 4048
      if not _CreateBlockDevOnSecondary(cfg, new_node, instance,
4032 4049
                                        new_drbd, False,
......
4048 4065
      cfg.SetDiskID(dev, pri_node)
4049 4066
      # set the physical (unique in bdev terms) id to None, meaning
4050 4067
      # detach from network
4051
      dev.physical_id = (None,) * len(dev.physical_id)
4068
      dev.physical_id = (None, None, None, None, dev.physical_id[4])
4052 4069
      # and 'find' the device, which will 'fix' it to match the
4053 4070
      # standalone state
4054 4071
      if rpc.call_blockdev_find(pri_node, dev):
......
4078 4095
      # it will automatically activate the network, if the physical_id
4079 4096
      # is correct
4080 4097
      cfg.SetDiskID(dev, pri_node)
4098
      logging.debug("Disk to attach: %s", dev)
4081 4099
      if not rpc.call_blockdev_find(pri_node, dev):
4082 4100
        warning("can't attach drbd %s to new secondary!" % dev.iv_name,
4083 4101
                "please do a gnt-instance info to see the status of disks")
......
4089 4107
    _WaitForSync(cfg, instance, self.proc, unlock=True)
4090 4108

  
4091 4109
    # so check manually all the devices
4092
    for name, (dev, old_lvs) in iv_names.iteritems():
4110
    for name, (dev, old_lvs, _) in iv_names.iteritems():
4093 4111
      cfg.SetDiskID(dev, pri_node)
4094 4112
      is_degr = rpc.call_blockdev_find(pri_node, dev)[5]
4095 4113
      if is_degr:
4096 4114
        raise errors.OpExecError("DRBD device %s is degraded!" % name)
4097 4115

  
4098 4116
    self.proc.LogStep(6, steps_total, "removing old storage")
4099
    for name, (dev, old_lvs) in iv_names.iteritems():
4117
    for name, (dev, old_lvs, _) in iv_names.iteritems():
4100 4118
      info("remove logical volumes for %s" % name)
4101 4119
      for lv in old_lvs:
4102 4120
        cfg.SetDiskID(lv, old_node)
b/lib/config.py
229 229

  
230 230
    if disk.logical_id is None and disk.physical_id is not None:
231 231
      return
232
    if disk.dev_type in constants.LDS_DRBD:
233
      pnode, snode, port = disk.logical_id
232
    if disk.dev_type == constants.LD_DRBD8:
233
      pnode, snode, port, pminor, sminor = disk.logical_id
234 234
      if node_name not in (pnode, snode):
235 235
        raise errors.ConfigurationError("DRBD device not knowing node %s" %
236 236
                                        node_name)
......
239 239
      if pnode_info is None or snode_info is None:
240 240
        raise errors.ConfigurationError("Can't find primary or secondary node"
241 241
                                        " for %s" % str(disk))
242
      p_data = (pnode_info.secondary_ip, port)
243
      s_data = (snode_info.secondary_ip, port)
242 244
      if pnode == node_name:
243
        disk.physical_id = (pnode_info.secondary_ip, port,
244
                            snode_info.secondary_ip, port)
245
        disk.physical_id = p_data + s_data + (pminor,)
245 246
      else: # it must be secondary, we tested above
246
        disk.physical_id = (snode_info.secondary_ip, port,
247
                            pnode_info.secondary_ip, port)
247
        disk.physical_id = s_data + p_data + (sminor,)
248 248
    else:
249 249
      disk.physical_id = disk.logical_id
250 250
    return
b/lib/objects.py
412 412
    if self.logical_id is None and self.physical_id is not None:
413 413
      return
414 414
    if self.dev_type in constants.LDS_DRBD:
415
      pnode, snode, port = self.logical_id
415
      pnode, snode, port, pminor, sminor = self.logical_id
416 416
      if target_node not in (pnode, snode):
417 417
        raise errors.ConfigurationError("DRBD device not knowing node %s" %
418 418
                                        target_node)
......
421 421
      if pnode_ip is None or snode_ip is None:
422 422
        raise errors.ConfigurationError("Can't find primary or secondary node"
423 423
                                        " for %s" % str(self))
424
      p_data = (pnode_ip, port)
425
      s_data = (snode_ip, port)
424 426
      if pnode == target_node:
425
        self.physical_id = (pnode_ip, port,
426
                            snode_ip, port)
427
        self.physical_id = p_data + s_data + (pminor,)
427 428
      else: # it must be secondary, we tested above
428
        self.physical_id = (snode_ip, port,
429
                            pnode_ip, port)
429
        self.physical_id = s_data + p_data + (sminor,)
430 430
    else:
431 431
      self.physical_id = self.logical_id
432 432
    return
......
458 458
      obj.logical_id = tuple(obj.logical_id)
459 459
    if obj.physical_id and isinstance(obj.physical_id, list):
460 460
      obj.physical_id = tuple(obj.physical_id)
461
    if obj.dev_type in constants.LDS_DRBD and len(obj.logical_id) == 3:
462
      # old non-minor based disk type
463
      obj.logical_id += (None, None)
461 464
    return obj
462 465

  
463 466
  def __str__(self):
......
529 532
    def _Helper(primary, sec_nodes, device):
530 533
      """Recursively computes secondary nodes given a top device."""
531 534
      if device.dev_type in constants.LDS_DRBD:
532
        nodea, nodeb, dummy = device.logical_id
535
        nodea, nodeb, dummy = device.logical_id[:3]
533 536
        if nodea == primary:
534 537
          candidate = nodeb
535 538
        else:

Also available in: Unified diff