Revision b496abdb lib/bdev.py

b/lib/bdev.py
666 666
    return data
667 667

  
668 668
  @classmethod
669
  def GetPVInfo(cls, vg_names, filter_allocatable=True):
669
  def GetPVInfo(cls, vg_names, filter_allocatable=True, include_lvs=False):
670 670
    """Get the free space info for PVs in a volume group.
671 671

  
672 672
    @param vg_names: list of volume group names, if empty all will be returned
673 673
    @param filter_allocatable: whether to skip over unallocatable PVs
674
    @param include_lvs: whether to include a list of LVs hosted on each PV
674 675

  
675 676
    @rtype: list
676 677
    @return: list of objects.LvmPvInfo objects
677 678

  
678 679
    """
680
    # We request "lv_name" field only if we care about LVs, so we don't get
681
    # a long list of entries with many duplicates unless we really have to.
682
    # The duplicate "pv_name" field will be ignored.
683
    if include_lvs:
684
      lvfield = "lv_name"
685
    else:
686
      lvfield = "pv_name"
679 687
    try:
680 688
      info = cls._GetVolumeInfo("pvs", ["pv_name", "vg_name", "pv_free",
681
                                        "pv_attr", "pv_size"])
689
                                        "pv_attr", "pv_size", lvfield])
682 690
    except errors.GenericError, err:
683 691
      logging.error("Can't get PV information: %s", err)
684 692
      return None
685 693

  
694
    # When asked for LVs, "pvs" may return multiple entries for the same PV-LV
695
    # pair. We sort entries by PV name and then LV name, so it's easy to weed
696
    # out duplicates.
697
    if include_lvs:
698
      info.sort(key=(lambda i: (i[0], i[5])))
686 699
    data = []
687
    for (pv_name, vg_name, pv_free, pv_attr, pv_size) in info:
700
    lastpvi = None
701
    for (pv_name, vg_name, pv_free, pv_attr, pv_size, lv_name) in info:
688 702
      # (possibly) skip over pvs which are not allocatable
689 703
      if filter_allocatable and pv_attr[0] != "a":
690 704
        continue
691 705
      # (possibly) skip over pvs which are not in the right volume group(s)
692 706
      if vg_names and vg_name not in vg_names:
693 707
        continue
694
      pvi = objects.LvmPvInfo(name=pv_name, vg_name=vg_name,
695
                              size=float(pv_size), free=float(pv_free),
696
                              attributes=pv_attr)
697
      data.append(pvi)
708
      # Beware of duplicates (check before inserting)
709
      if lastpvi and lastpvi.name == pv_name:
710
        if include_lvs and lv_name:
711
          if not lastpvi.lv_list or lastpvi.lv_list[-1] != lv_name:
712
            lastpvi.lv_list.append(lv_name)
713
      else:
714
        if include_lvs and lv_name:
715
          lvl = [lv_name]
716
        else:
717
          lvl = []
718
        lastpvi = objects.LvmPvInfo(name=pv_name, vg_name=vg_name,
719
                                    size=float(pv_size), free=float(pv_free),
720
                                    attributes=pv_attr, lv_list=lvl)
721
        data.append(lastpvi)
698 722

  
699 723
    return data
700 724

  

Also available in: Unified diff