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