Revision b6dd32db

b/lib/cmdlib/cluster.py
2294 2294
    groupinfo = self.cfg.GetAllNodeGroupsInfo()
2295 2295

  
2296 2296
    node_vol_should = {}
2297
    instance.MapLVsByNode(node_vol_should)
2297
    self.cfg.GetInstanceLVsByNode(instance, lvmap=node_vol_should)
2298 2298

  
2299 2299
    cluster = self.cfg.GetClusterInfo()
2300 2300
    ipolicy = ganeti.masterd.instance.CalculateGroupIPolicy(cluster,
......
3326 3326
          gnode.ghost = (nuuid not in self.all_node_info)
3327 3327
          node_image[nuuid] = gnode
3328 3328

  
3329
      instance.MapLVsByNode(node_vol_should)
3329
      self.cfg.GetInstanceLVsByNode(instance, lvmap=node_vol_should)
3330 3330

  
3331 3331
      pnode = instance.primary_node
3332 3332
      node_image[pnode].pinst.append(instance.uuid)
......
3523 3523
      for secondary in self.cfg.GetInstanceSecondaryNodes(instance):
3524 3524
        if (secondary in self.my_node_info
3525 3525
            and instance.name not in self.my_inst_info):
3526
          instance.MapLVsByNode(node_vol_should)
3526
          self.cfg.GetInstanceLVsByNode(instance, lvmap=node_vol_should)
3527 3527
          break
3528 3528

  
3529 3529
    self._VerifyOrphanVolumes(node_vol_should, node_image, reserved)
b/lib/cmdlib/common.py
918 918
  return op
919 919

  
920 920

  
921
def MapInstanceLvsToNodes(instances):
921
def MapInstanceLvsToNodes(cfg, instances):
922 922
  """Creates a map from (node, volume) to instance name.
923 923

  
924
  @type cfg: L{config.ConfigWriter}
925
  @param cfg: The cluster configuration
924 926
  @type instances: list of L{objects.Instance}
925 927
  @rtype: dict; tuple of (node uuid, volume name) as key, L{objects.Instance}
926 928
          object as value
......
928 930
  """
929 931
  return dict(((node_uuid, vol), inst)
930 932
              for inst in instances
931
              for (node_uuid, vols) in inst.MapLVsByNode().items()
933
              for (node_uuid, vols) in cfg.GetInstanceLVsByNode(inst).items()
932 934
              for vol in vols)
933 935

  
934 936

  
b/lib/cmdlib/group.py
874 874
  def _VerifyInstanceLvs(self, node_errors, offline_disk_instance_names,
875 875
                         missing_disks):
876 876
    node_lv_to_inst = MapInstanceLvsToNodes(
877
      self.cfg,
877 878
      [inst for inst in self.instances.values() if inst.disks_active])
878 879
    if node_lv_to_inst:
879 880
      node_uuids = utils.NiceSort(set(self.owned_locks(locking.LEVEL_NODE)) &
b/lib/cmdlib/node.py
1249 1249
    volumes = self.rpc.call_node_volumes(node_uuids)
1250 1250

  
1251 1251
    ilist = self.cfg.GetAllInstancesInfo()
1252
    vol2inst = MapInstanceLvsToNodes(ilist.values())
1252
    vol2inst = MapInstanceLvsToNodes(self.cfg, ilist.values())
1253 1253

  
1254 1254
    output = []
1255 1255
    for node_uuid in node_uuids:
b/lib/config.py
561 561
    """
562 562
    lvnames = set()
563 563
    for instance in self._config_data.instances.values():
564
      node_data = instance.MapLVsByNode()
564
      node_data = self._UnlockedGetInstanceLVsByNode(instance)
565 565
      for lv_list in node_data.values():
566 566
        lvnames.update(lv_list)
567 567
    return lvnames
......
1567 1567
      raise errors.ProgrammerError("Invalid type passed to AddInstance")
1568 1568

  
1569 1569
    if instance.disk_template != constants.DT_DISKLESS:
1570
      all_lvs = instance.MapLVsByNode()
1570
      all_lvs = self._UnlockedGetInstanceLVsByNode(instance)
1571 1571
      logging.info("Instance '%s' DISK_LAYOUT: %s", instance.name, all_lvs)
1572 1572

  
1573 1573
    all_macs = self._AllMACs()
b/lib/objects.py
1108 1108
    "serial_no",
1109 1109
    ] + _TIMESTAMPS + _UUID
1110 1110

  
1111
  def MapLVsByNode(self, lvmap=None, devs=None, node_uuid=None):
1112
    """Provide a mapping of nodes to LVs this instance owns.
1113

  
1114
    This function figures out what logical volumes should belong on
1115
    which nodes, recursing through a device tree.
1116

  
1117
    @type lvmap: dict
1118
    @param lvmap: optional dictionary to receive the
1119
        'node' : ['lv', ...] data.
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.
1126
    @return: None if lvmap arg is given, otherwise, a dictionary of
1127
        the form { 'node_uuid' : ['volume1', 'volume2', ...], ... };
1128
        volumeN is of the form "vg_name/lv_name", compatible with
1129
        GetVolumeList()
1130

  
1131
    """
1132
    if node_uuid is None:
1133
      node_uuid = self.primary_node
1134

  
1135
    if lvmap is None:
1136
      lvmap = {
1137
        node_uuid: [],
1138
        }
1139
      ret = lvmap
1140
    else:
1141
      if not node_uuid in lvmap:
1142
        lvmap[node_uuid] = []
1143
      ret = None
1144

  
1145
    if not devs:
1146
      devs = self.disks
1147

  
1148
    for dev in devs:
1149
      if dev.dev_type == constants.DT_PLAIN:
1150
        lvmap[node_uuid].append(dev.logical_id[0] + "/" + dev.logical_id[1])
1151

  
1152
      elif dev.dev_type in constants.DTS_DRBD:
1153
        if dev.children:
1154
          self.MapLVsByNode(lvmap, dev.children, dev.logical_id[0])
1155
          self.MapLVsByNode(lvmap, dev.children, dev.logical_id[1])
1156

  
1157
      elif dev.children:
1158
        self.MapLVsByNode(lvmap, dev.children, node_uuid)
1159

  
1160
    return ret
1161

  
1162 1111
  def FindDisk(self, idx):
1163 1112
    """Find a disk given having a specified index.
1164 1113

  

Also available in: Unified diff