Revision 235a6b29

b/lib/backend.py
3801 3801
  shutil.rmtree(status_dir, ignore_errors=True)
3802 3802

  
3803 3803

  
3804
def _FindDisks(target_node_uuid, nodes_ip, disks):
3805
  """Sets the physical ID on disks and returns the block devices.
3804
def _SetPhysicalId(target_node_uuid, nodes_ip, disks):
3805
  """Sets the correct physical ID on all passed disks.
3806 3806

  
3807 3807
  """
3808
  # set the correct physical ID
3809 3808
  for cf in disks:
3810 3809
    cf.SetPhysicalID(target_node_uuid, nodes_ip)
3811 3810

  
3811

  
3812
def _FindDisks(target_node_uuid, nodes_ip, disks):
3813
  """Sets the physical ID on disks and returns the block devices.
3814

  
3815
  """
3816
  _SetPhysicalId(target_node_uuid, nodes_ip, disks)
3817

  
3812 3818
  bdevs = []
3813 3819

  
3814 3820
  for cf in disks:
......
3927 3933
  return (alldone, min_resync)
3928 3934

  
3929 3935

  
3936
def DrbdNeedsActivation(target_node_uuid, nodes_ip, disks):
3937
  """Checks which of the passed disks needs activation and returns their UUIDs.
3938

  
3939
  """
3940
  _SetPhysicalId(target_node_uuid, nodes_ip, disks)
3941
  faulty_disks = []
3942

  
3943
  for disk in disks:
3944
    rd = _RecursiveFindBD(disk)
3945
    if rd is None:
3946
      faulty_disks.append(disk)
3947
      continue
3948

  
3949
    stats = rd.GetProcStatus()
3950
    if stats.is_standalone or stats.is_diskless:
3951
      faulty_disks.append(disk)
3952

  
3953
  return [disk.uuid for disk in faulty_disks]
3954

  
3955

  
3930 3956
def GetDrbdUsermodeHelper():
3931 3957
  """Returns DRBD usermode helper currently configured.
3932 3958

  
b/lib/cmdlib/group.py
21 21

  
22 22
"""Logical units dealing with node groups."""
23 23

  
24
import itertools
24 25
import logging
25 26

  
26 27
from ganeti import constants
......
902 903
    CheckInstancesNodeGroups(self.cfg, self.instances,
903 904
                             owned_groups, owned_node_uuids, self.group_uuid)
904 905

  
905
  def Exec(self, feedback_fn):
906
    """Verify integrity of cluster disks.
907

  
908
    @rtype: tuple of three items
909
    @return: a tuple of (dict of node-to-node_error, list of instances
910
        which need activate-disks, dict of instance: (node, volume) for
911
        missing volumes
912

  
913
    """
914
    node_errors = {}
915
    offline_lv_instance_names = set()
916
    missing_lvs = {}
917

  
906
  def _VerifyInstanceLvs(self, node_errors, offline_disk_instance_names,
907
                         missing_disks):
918 908
    node_lv_to_inst = MapInstanceLvsToNodes(
919 909
      [inst for inst in self.instances.values() if inst.disks_active])
920

  
921 910
    if node_lv_to_inst:
922 911
      node_uuids = utils.NiceSort(set(self.owned_locks(locking.LEVEL_NODE)) &
923 912
                                  set(self.cfg.GetVmCapableNodeList()))
......
938 927
        for lv_name, (_, _, lv_online) in node_res.payload.items():
939 928
          inst = node_lv_to_inst.pop((node_uuid, lv_name), None)
940 929
          if not lv_online and inst is not None:
941
            offline_lv_instance_names.add(inst.name)
930
            offline_disk_instance_names.add(inst.name)
942 931

  
943 932
      # any leftover items in nv_dict are missing LVs, let's arrange the data
944 933
      # better
945 934
      for key, inst in node_lv_to_inst.iteritems():
946
        missing_lvs.setdefault(inst.name, []).append(list(key))
935
        missing_disks.setdefault(inst.name, []).append(list(key))
936

  
937
  def _VerifyDrbdStates(self, node_errors, offline_disk_instance_names):
938
    node_to_inst = {}
939
    for inst in self.instances.values():
940
      if not inst.disks_active or inst.disk_template != constants.DT_DRBD8:
941
        continue
942

  
943
      for node_uuid in itertools.chain([inst.primary_node],
944
                                       inst.secondary_nodes):
945
        node_to_inst.setdefault(node_uuid, []).append(inst)
946

  
947
    nodes_ip = dict((uuid, node.secondary_ip) for (uuid, node)
948
                    in self.cfg.GetMultiNodeInfo(node_to_inst.keys()))
949
    for (node_uuid, insts) in node_to_inst.items():
950
      node_disks = [(inst.disks, inst) for inst in insts]
951
      node_res = self.rpc.call_drbd_needs_activation(node_uuid, nodes_ip,
952
                                                     node_disks)
953
      msg = node_res.fail_msg
954
      if msg:
955
        logging.warning("Error getting DRBD status on node %s: %s",
956
                        self.cfg.GetNodeName(node_uuid), msg)
957
        node_errors[node_uuid] = msg
958
        continue
959

  
960
      faulty_disk_uuids = set(node_res.payload)
961
      for inst in self.instances.values():
962
        inst_disk_uuids = set([disk.uuid for disk in inst.disks])
963
        if inst_disk_uuids.intersection(faulty_disk_uuids):
964
          offline_disk_instance_names.add(inst.name)
965

  
966
  def Exec(self, feedback_fn):
967
    """Verify integrity of cluster disks.
968

  
969
    @rtype: tuple of three items
970
    @return: a tuple of (dict of node-to-node_error, list of instances
971
        which need activate-disks, dict of instance: (node, volume) for
972
        missing volumes
973

  
974
    """
975
    node_errors = {}
976
    offline_disk_instance_names = set()
977
    missing_disks = {}
978

  
979
    self._VerifyInstanceLvs(node_errors, offline_disk_instance_names,
980
                            missing_disks)
981
    self._VerifyDrbdStates(node_errors, offline_disk_instance_names)
947 982

  
948
    return (node_errors, list(offline_lv_instance_names), missing_lvs)
983
    return (node_errors, list(offline_disk_instance_names), missing_disks)
b/lib/rpc.py
837 837

  
838 838
      # Encoders annotating disk parameters
839 839
      rpc_defs.ED_DISKS_DICT_DP: self._DisksDictDP,
840
      rpc_defs.ED_MULTI_DISKS_DICT_DP: self._MultiDiskDictDP,
840 841
      rpc_defs.ED_SINGLE_DISK_DICT_DP: self._SingleDiskDictDP,
841 842

  
842 843
      # Encoders with special requirements
......
935 936
            for disk in AnnotateDiskParams(instance.disk_template,
936 937
                                           disks, diskparams)]
937 938

  
939
  def _MultiDiskDictDP(self, disks_insts):
940
    """Wrapper for L{AnnotateDiskParams}.
941

  
942
    Supports a list of (disk, instance) tuples.
943
    """
944
    return [disk for disk_inst in disks_insts
945
            for disk in self._DisksDictDP(disk_inst)]
946

  
938 947
  def _SingleDiskDictDP(self, (disk, instance)):
939 948
    """Wrapper for L{AnnotateDiskParams}.
940 949

  
b/lib/rpc_defs.py
70 70
 ED_COMPRESS,
71 71
 ED_BLOCKDEV_RENAME,
72 72
 ED_DISKS_DICT_DP,
73
 ED_MULTI_DISKS_DICT_DP,
73 74
 ED_SINGLE_DISK_DICT_DP,
74
 ED_NIC_DICT) = range(1, 15)
75
 ED_NIC_DICT) = range(1, 16)
75 76

  
76 77

  
77 78
def _Prepare(calls):
......
412 413
    ("disks", ED_DISKS_DICT_DP, None),
413 414
    ], _DrbdCallsPreProc, None,
414 415
   "Waits for the synchronization of drbd devices is complete"),
416
  ("drbd_needs_activation", SINGLE, None, constants.RPC_TMO_NORMAL, [
417
    ("nodes_ip", None, None),
418
    ("disks", ED_MULTI_DISKS_DICT_DP, None),
419
    ], _DrbdCallsPreProc, None,
420
   "Returns the drbd disks which need activation"),
415 421
  ("blockdev_grow", SINGLE, None, constants.RPC_TMO_NORMAL, [
416 422
    ("cf_bdev", ED_SINGLE_DISK_DICT_DP, None),
417 423
    ("amount", None, None),
b/lib/server/noded.py
445 445
    return backend.DrbdWaitSync(target_node_uuid, nodes_ip, disks)
446 446

  
447 447
  @staticmethod
448
  def perspective_drbd_needs_activation(params):
449
    """Checks if the drbd devices need activation
450

  
451
    Note that this is only valid for drbd disks, so the members of the
452
    disk list must all be drbd devices.
453

  
454
    """
455
    nodes_ip, disks, target_node_uuid = params
456
    disks = [objects.Disk.FromDict(cf) for cf in disks]
457
    return backend.DrbdNeedsActivation(target_node_uuid, nodes_ip, disks)
458

  
459
  @staticmethod
448 460
  def perspective_drbd_helper(params):
449 461
    """Query drbd helper.
450 462

  

Also available in: Unified diff