Revision 235a6b29 lib/cmdlib/group.py
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) |
Also available in: Unified diff