## Revision 63c73073 lib/bdev.py

b/lib/bdev.py
29 29
```import pyparsing as pyp
```
30 30
```import os
```
31 31
```import logging
```
32
```import math
```
32 33

33 34
```from ganeti import utils
```
34 35
```from ganeti import errors
```
......
523 524
```    self.major = self.minor = self.pe_size = self.stripe_count = None
```
524 525
```    self.Attach()
```
525 526

527
```  @staticmethod
```
528
```  def _GetStdPvSize(pvs_info):
```
529
```    """Return the the standard PV size (used with exclusive storage).
```
530

531
```    @param pvs_info: list of objects.LvmPvInfo, cannot be empty
```
532
```    @rtype: float
```
533
```    @return: size in MiB
```
534

535
```    """
```
536
```    assert len(pvs_info) > 0
```
537
```    smallest = min([pv.size for pv in pvs_info])
```
538
```    return smallest / (1 + constants.PART_MARGIN + constants.PART_RESERVED)
```
539

540
```  @staticmethod
```
541
```  def _ComputeNumPvs(size, pvs_info):
```
542
```    """Compute the number of PVs needed for an LV (with exclusive storage).
```
543

544
```    @type size: float
```
545
```    @param size: LV size
```
546
```    @param pvs_info: list of objects.LvmPvInfo, cannot be empty
```
547
```    @rtype: integer
```
548
```    @return: number of PVs needed
```
549
```    """
```
550
```    assert len(pvs_info) > 0
```
551
```    pv_size = float(LogicalVolume._GetStdPvSize(pvs_info))
```
552
```    return int(math.ceil(float(size) / pv_size))
```
553

554
```  @staticmethod
```
555
```  def _GetEmptyPvNames(pvs_info, max_pvs=None):
```
556
```    """Return a list of empty PVs, by name.
```
557

558
```    """
```
559
```    empty_pvs = filter(objects.LvmPvInfo.IsEmpty, pvs_info)
```
560
```    if max_pvs is not None:
```
561
```      empty_pvs = empty_pvs[:max_pvs]
```
562
```    return map((lambda pv: pv.name), empty_pvs)
```
563

526 564
```  @classmethod
```
527 565
```  def Create(cls, unique_id, children, size, params, excl_stor):
```
528 566
```    """Create a new logical volume.
```
......
536 574
```    cls._ValidateName(lv_name)
```
537 575
```    pvs_info = cls.GetPVInfo([vg_name])
```
538 576
```    if not pvs_info:
```
539
```      _ThrowError("Can't compute PV info for vg %s", vg_name)
```
577
```      if excl_stor:
```
578
```        msg = "No (empty) PVs found"
```
579
```      else:
```
580
```        msg = "Can't compute PV info for vg %s" % vg_name
```
581
```      _ThrowError(msg)
```
540 582
```    pvs_info.sort(key=(lambda pv: pv.free), reverse=True)
```
541 583

542 584
```    pvlist = [pv.name for pv in pvs_info]
```
......
544 586
```      _ThrowError("Some of your PVs have the invalid character ':' in their"
```
545 587
```                  " name, this is not supported - please filter them out"
```
546 588
```                  " in lvm.conf using either 'filter' or 'preferred_names'")
```
547
```    free_size = sum([pv.free for pv in pvs_info])
```
589

548 590
```    current_pvs = len(pvlist)
```
549 591
```    desired_stripes = params[constants.LDP_STRIPES]
```
550 592
```    stripes = min(current_pvs, desired_stripes)
```
551
```    if stripes < desired_stripes:
```
552
```      logging.warning("Could not use %d stripes for VG %s, as only %d PVs are"
```
553
```                      " available.", desired_stripes, vg_name, current_pvs)
```
554 593

555
```    # The size constraint should have been checked from the master before
```
556
```    # calling the create function.
```
557
```    if free_size < size:
```
558
```      _ThrowError("Not enough free space: required %s,"
```
559
```                  " available %s", size, free_size)
```
560
```    cmd = ["lvcreate", "-L%dm" % size, "-n%s" % lv_name]
```
594
```    if excl_stor:
```
595
```      err_msgs = utils.LvmExclusiveCheckNodePvs(pvs_info)
```
596
```      if err_msgs:
```
597
```        for m in err_msgs:
```
598
```          logging.warning(m)
```
599
```      req_pvs = cls._ComputeNumPvs(size, pvs_info)
```
600
```      pvlist = cls._GetEmptyPvNames(pvs_info, req_pvs)
```
601
```      current_pvs = len(pvlist)
```
602
```      if current_pvs < req_pvs:
```
603
```        _ThrowError("Not enough empty PVs to create a disk of %d MB:"
```
604
```                    " %d available, %d needed", size, current_pvs, req_pvs)
```
605
```      assert current_pvs == len(pvlist)
```
606
```      if stripes > current_pvs:
```
607
```        # No warning issued for this, as it's no surprise
```
608
```        stripes = current_pvs
```
609

610
```    else:
```
611
```      if stripes < desired_stripes:
```
612
```        logging.warning("Could not use %d stripes for VG %s, as only %d PVs are"
```
613
```                        " available.", desired_stripes, vg_name, current_pvs)
```
614
```      free_size = sum([pv.free for pv in pvs_info])
```
615
```      # The size constraint should have been checked from the master before
```
616
```      # calling the create function.
```
617
```      if free_size < size:
```
618
```        _ThrowError("Not enough free space: required %s,"
```
619
```                    " available %s", size, free_size)
```
620

561 621
```    # If the free space is not well distributed, we won't be able to
```
562 622
```    # create an optimally-striped volume; in that case, we want to try
```
563 623
```    # with N, N-1, ..., 2, and finally 1 (non-stripped) number of
```
564 624
```    # stripes
```
625
```    cmd = ["lvcreate", "-L%dm" % size, "-n%s" % lv_name]
```
565 626
```    for stripes_arg in range(stripes, 0, -1):
```
566 627
```      result = utils.RunCmd(cmd + ["-i%d" % stripes_arg] + [vg_name] + pvlist)
```
567 628
```      if not result.failed:
```

Also available in: Unified diff