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