Revision 843094ad
b/lib/cmdlib/common.py | ||
---|---|---|
907 | 907 |
return op |
908 | 908 |
|
909 | 909 |
|
910 |
def MapInstanceDisksToNodes(instances):
|
|
910 |
def MapInstanceLvsToNodes(instances):
|
|
911 | 911 |
"""Creates a map from (node, volume) to instance name. |
912 | 912 |
|
913 | 913 |
@type instances: list of L{objects.Instance} |
914 |
@rtype: dict; tuple of (node uuid, volume name) as key, instance name as value |
|
914 |
@rtype: dict; tuple of (node uuid, volume name) as key, L{objects.Instance} |
|
915 |
object as value |
|
915 | 916 |
|
916 | 917 |
""" |
917 |
return dict(((node_uuid, vol), inst.name)
|
|
918 |
return dict(((node_uuid, vol), inst) |
|
918 | 919 |
for inst in instances |
919 | 920 |
for (node_uuid, vols) in inst.MapLVsByNode().items() |
920 | 921 |
for vol in vols) |
b/lib/cmdlib/group.py | ||
---|---|---|
37 | 37 |
MergeAndVerifyDiskState, GetWantedNodes, GetUpdatedParams, \ |
38 | 38 |
CheckNodeGroupInstances, GetUpdatedIPolicy, \ |
39 | 39 |
ComputeNewInstanceViolations, GetDefaultIAllocator, ShareAll, \ |
40 |
CheckInstancesNodeGroups, LoadNodeEvacResult, MapInstanceDisksToNodes
|
|
40 |
CheckInstancesNodeGroups, LoadNodeEvacResult, MapInstanceLvsToNodes
|
|
41 | 41 |
|
42 | 42 |
import ganeti.masterd.instance |
43 | 43 |
|
... | ... | |
911 | 911 |
missing volumes |
912 | 912 |
|
913 | 913 |
""" |
914 |
res_nodes = {}
|
|
915 |
res_instances = set()
|
|
916 |
res_missing = {}
|
|
914 |
node_errors = {}
|
|
915 |
offline_lv_instance_names = set()
|
|
916 |
missing_lvs = {}
|
|
917 | 917 |
|
918 |
nv_dict = MapInstanceDisksToNodes(
|
|
918 |
node_lv_to_inst = MapInstanceLvsToNodes(
|
|
919 | 919 |
[inst for inst in self.instances.values() if inst.disks_active]) |
920 | 920 |
|
921 |
if nv_dict:
|
|
921 |
if node_lv_to_inst:
|
|
922 | 922 |
node_uuids = utils.NiceSort(set(self.owned_locks(locking.LEVEL_NODE)) & |
923 | 923 |
set(self.cfg.GetVmCapableNodeList())) |
924 | 924 |
|
... | ... | |
932 | 932 |
if msg: |
933 | 933 |
logging.warning("Error enumerating LVs on node %s: %s", |
934 | 934 |
self.cfg.GetNodeName(node_uuid), msg) |
935 |
res_nodes[node_uuid] = msg
|
|
935 |
node_errors[node_uuid] = msg
|
|
936 | 936 |
continue |
937 | 937 |
|
938 | 938 |
for lv_name, (_, _, lv_online) in node_res.payload.items(): |
939 |
inst = nv_dict.pop((node_uuid, lv_name), None)
|
|
940 |
if not (lv_online or inst is None):
|
|
941 |
res_instances.add(inst)
|
|
939 |
inst = node_lv_to_inst.pop((node_uuid, lv_name), None)
|
|
940 |
if not lv_online and inst is not None:
|
|
941 |
offline_lv_instance_names.add(inst.name)
|
|
942 | 942 |
|
943 | 943 |
# any leftover items in nv_dict are missing LVs, let's arrange the data |
944 | 944 |
# better |
945 |
for key, inst in nv_dict.iteritems():
|
|
946 |
res_missing.setdefault(inst, []).append(list(key))
|
|
945 |
for key, inst in node_lv_to_inst.iteritems():
|
|
946 |
missing_lvs.setdefault(inst.name, []).append(list(key))
|
|
947 | 947 |
|
948 |
return (res_nodes, list(res_instances), res_missing) |
|
948 |
return (node_errors, list(offline_lv_instance_names), missing_lvs) |
b/lib/cmdlib/node.py | ||
---|---|---|
44 | 44 |
RedistributeAncillaryFiles, ExpandNodeUuidAndName, ShareAll, SupportsOob, \ |
45 | 45 |
CheckInstanceState, INSTANCE_DOWN, GetUpdatedParams, \ |
46 | 46 |
AdjustCandidatePool, CheckIAllocatorOrNode, LoadNodeEvacResult, \ |
47 |
GetWantedNodes, MapInstanceDisksToNodes, RunPostHook, \
|
|
47 |
GetWantedNodes, MapInstanceLvsToNodes, RunPostHook, \
|
|
48 | 48 |
FindFaultyInstanceDisks |
49 | 49 |
|
50 | 50 |
|
... | ... | |
1316 | 1316 |
volumes = self.rpc.call_node_volumes(node_uuids) |
1317 | 1317 |
|
1318 | 1318 |
ilist = self.cfg.GetAllInstancesInfo() |
1319 |
vol2inst = MapInstanceDisksToNodes(ilist.values())
|
|
1319 |
vol2inst = MapInstanceLvsToNodes(ilist.values())
|
|
1320 | 1320 |
|
1321 | 1321 |
output = [] |
1322 | 1322 |
for node_uuid in node_uuids: |
... | ... | |
1346 | 1346 |
elif field == "size": |
1347 | 1347 |
val = int(float(vol["size"])) |
1348 | 1348 |
elif field == "instance": |
1349 |
val = vol2inst.get((node_uuid, vol["vg"] + "/" + vol["name"]), "-") |
|
1349 |
inst = vol2inst.get((node_uuid, vol["vg"] + "/" + vol["name"]), |
|
1350 |
None) |
|
1351 |
if inst is not None: |
|
1352 |
val = inst.name |
|
1353 |
else: |
|
1354 |
val = "-" |
|
1350 | 1355 |
else: |
1351 | 1356 |
raise errors.ParameterError(field) |
1352 | 1357 |
node_output.append(str(val)) |
b/lib/objects.py | ||
---|---|---|
1108 | 1108 |
all_nodes = property(_ComputeAllNodes, None, None, |
1109 | 1109 |
"List of names of all the nodes of the instance") |
1110 | 1110 |
|
1111 |
def MapLVsByNode(self, lvmap=None, devs=None, node=None): |
|
1111 |
def MapLVsByNode(self, lvmap=None, devs=None, node_uuid=None):
|
|
1112 | 1112 |
"""Provide a mapping of nodes to LVs this instance owns. |
1113 | 1113 |
|
1114 | 1114 |
This function figures out what logical volumes should belong on |
1115 | 1115 |
which nodes, recursing through a device tree. |
1116 | 1116 |
|
1117 |
@type lvmap: dict |
|
1117 | 1118 |
@param lvmap: optional dictionary to receive the |
1118 | 1119 |
'node' : ['lv', ...] data. |
1119 |
|
|
1120 |
@type devs: list of L{Disk} |
|
1121 |
@param devs: disks to get the LV name for. If None, all disk of this |
|
1122 |
instance are used. |
|
1123 |
@type node_uuid: string |
|
1124 |
@param node_uuid: UUID of the node to get the LV names for. If None, the |
|
1125 |
primary node of this instance is used. |
|
1120 | 1126 |
@return: None if lvmap arg is given, otherwise, a dictionary of |
1121 | 1127 |
the form { 'node_uuid' : ['volume1', 'volume2', ...], ... }; |
1122 | 1128 |
volumeN is of the form "vg_name/lv_name", compatible with |
1123 | 1129 |
GetVolumeList() |
1124 | 1130 |
|
1125 | 1131 |
""" |
1126 |
if node is None: |
|
1127 |
node = self.primary_node |
|
1132 |
if node_uuid is None:
|
|
1133 |
node_uuid = self.primary_node
|
|
1128 | 1134 |
|
1129 | 1135 |
if lvmap is None: |
1130 | 1136 |
lvmap = { |
1131 |
node: [], |
|
1137 |
node_uuid: [],
|
|
1132 | 1138 |
} |
1133 | 1139 |
ret = lvmap |
1134 | 1140 |
else: |
1135 |
if not node in lvmap: |
|
1136 |
lvmap[node] = [] |
|
1141 |
if not node_uuid in lvmap:
|
|
1142 |
lvmap[node_uuid] = []
|
|
1137 | 1143 |
ret = None |
1138 | 1144 |
|
1139 | 1145 |
if not devs: |
... | ... | |
1141 | 1147 |
|
1142 | 1148 |
for dev in devs: |
1143 | 1149 |
if dev.dev_type == constants.LD_LV: |
1144 |
lvmap[node].append(dev.logical_id[0] + "/" + dev.logical_id[1]) |
|
1150 |
lvmap[node_uuid].append(dev.logical_id[0] + "/" + dev.logical_id[1])
|
|
1145 | 1151 |
|
1146 | 1152 |
elif dev.dev_type in constants.LDS_DRBD: |
1147 | 1153 |
if dev.children: |
... | ... | |
1149 | 1155 |
self.MapLVsByNode(lvmap, dev.children, dev.logical_id[1]) |
1150 | 1156 |
|
1151 | 1157 |
elif dev.children: |
1152 |
self.MapLVsByNode(lvmap, dev.children, node) |
|
1158 |
self.MapLVsByNode(lvmap, dev.children, node_uuid)
|
|
1153 | 1159 |
|
1154 | 1160 |
return ret |
1155 | 1161 |
|
Also available in: Unified diff