Revision fdbd668d

b/lib/bdev.py
122 122
      status = status and child.Assemble()
123 123
      if not status:
124 124
        break
125
      status = status and child.Open()
125

  
126
      try:
127
        child.Open()
128
      except errors.BlockDeviceError:
129
        for child in self._children:
130
          child.Shutdown()
131
        raise
126 132

  
127 133
    if not status:
128 134
      for child in self._children:
......
502 508
    This is a no-op for the LV device type.
503 509

  
504 510
    """
505
    return True
511
    pass
506 512

  
507 513
  def Close(self):
508 514
    """Notifies that the device will no longer be used for I/O.
......
510 516
    This is a no-op for the LV device type.
511 517

  
512 518
    """
513
    return True
519
    pass
514 520

  
515 521
  def Snapshot(self, size):
516 522
    """Create a snapshot copy of an lvm block device.
......
954 960
    the 2.6.18's new array_state thing.
955 961

  
956 962
    """
957
    return True
963
    pass
958 964

  
959 965
  def Close(self):
960 966
    """Notifies that the device will no longer be used for I/O.
......
963 969
    `Open()`.
964 970

  
965 971
    """
966
    return True
972
    pass
967 973

  
968 974

  
969 975
class BaseDRBD(BlockDev):
......
1456 1462
      cmd.append("--do-what-I-say")
1457 1463
    result = utils.RunCmd(cmd)
1458 1464
    if result.failed:
1459
      logger.Error("Can't make drbd device primary: %s" % result.output)
1460
      return False
1461
    return True
1465
      msg = ("Can't make drbd device primary: %s" % result.output)
1466
      logger.Error(msg)
1467
      raise errors.BlockDeviceError(msg)
1462 1468

  
1463 1469
  def Close(self):
1464 1470
    """Make the local state secondary.
......
1471 1477
      raise errors.BlockDeviceError("Can't find device")
1472 1478
    result = utils.RunCmd(["drbdsetup", self.dev_path, "secondary"])
1473 1479
    if result.failed:
1474
      logger.Error("Can't switch drbd device to secondary: %s" % result.output)
1475
      raise errors.BlockDeviceError("Can't switch drbd device to secondary")
1480
      msg = ("Can't switch drbd device to"
1481
             " secondary: %s" % result.output)
1482
      logger.Error(msg)
1483
      raise errors.BlockDeviceError(msg)
1476 1484

  
1477 1485
  def SetSyncSpeed(self, kbytes):
1478 1486
    """Set the speed of the DRBD syncer.
......
2068 2076
      cmd.append("-o")
2069 2077
    result = utils.RunCmd(cmd)
2070 2078
    if result.failed:
2071
      logger.Error("Can't make drbd device primary: %s" % result.output)
2072
      return False
2073
    return True
2079
      msg = ("Can't make drbd device primary: %s" % result.output)
2080
      logger.Error(msg)
2081
      raise errors.BlockDeviceError(msg)
2074 2082

  
2075 2083
  def Close(self):
2076 2084
    """Make the local state secondary.
......
2083 2091
      raise errors.BlockDeviceError("Can't find device")
2084 2092
    result = utils.RunCmd(["drbdsetup", self.dev_path, "secondary"])
2085 2093
    if result.failed:
2086
      logger.Error("Can't switch drbd device to secondary: %s" % result.output)
2087
      raise errors.BlockDeviceError("Can't switch drbd device to secondary")
2094
      msg = ("Can't switch drbd device to"
2095
             " secondary: %s" % result.output)
2096
      logger.Error(msg)
2097
      raise errors.BlockDeviceError(msg)
2088 2098

  
2089 2099
  def Attach(self):
2090 2100
    """Find a DRBD device which matches our config and attach to it.
b/lib/cmdlib.py
1860 1860
  """
1861 1861
  device_info = []
1862 1862
  disks_ok = True
1863
  iname = instance.name
1864
  # With the two passes mechanism we try to reduce the window of
1865
  # opportunity for the race condition of switching DRBD to primary
1866
  # before handshaking occured, but we do not eliminate it
1867

  
1868
  # The proper fix would be to wait (with some limits) until the
1869
  # connection has been made and drbd transitions from WFConnection
1870
  # into any other network-connected state (Connected, SyncTarget,
1871
  # SyncSource, etc.)
1872

  
1873
  # 1st pass, assemble on all nodes in secondary mode
1863 1874
  for inst_disk in instance.disks:
1864
    master_result = None
1865 1875
    for node, node_disk in inst_disk.ComputeNodeTree(instance.primary_node):
1866 1876
      cfg.SetDiskID(node_disk, node)
1867
      is_primary = node == instance.primary_node
1868
      result = rpc.call_blockdev_assemble(node, node_disk,
1869
                                          instance.name, is_primary)
1877
      result = rpc.call_blockdev_assemble(node, node_disk, iname, False)
1870 1878
      if not result:
1871 1879
        logger.Error("could not prepare block device %s on node %s"
1872
                     " (is_primary=%s)" %
1873
                     (inst_disk.iv_name, node, is_primary))
1874
        if is_primary or not ignore_secondaries:
1880
                     " (is_primary=False, pass=1)" % (inst_disk.iv_name, node))
1881
        if not ignore_secondaries:
1875 1882
          disks_ok = False
1876
      if is_primary:
1877
        master_result = result
1878
    device_info.append((instance.primary_node, inst_disk.iv_name,
1879
                        master_result))
1883

  
1884
  # FIXME: race condition on drbd migration to primary
1885

  
1886
  # 2nd pass, do only the primary node
1887
  for inst_disk in instance.disks:
1888
    for node, node_disk in inst_disk.ComputeNodeTree(instance.primary_node):
1889
      if node != instance.primary_node:
1890
        continue
1891
      cfg.SetDiskID(node_disk, node)
1892
      result = rpc.call_blockdev_assemble(node, node_disk, iname, True)
1893
      if not result:
1894
        logger.Error("could not prepare block device %s on node %s"
1895
                     " (is_primary=True, pass=2)" % (inst_disk.iv_name, node))
1896
        disks_ok = False
1897
    device_info.append((instance.primary_node, inst_disk.iv_name, result))
1880 1898

  
1881 1899
  # leave the disks configured for the primary node
1882 1900
  # this is a workaround that would be fixed better by

Also available in: Unified diff