Revision 688b5752 lib/storage/bdev.py

b/lib/storage/bdev.py
495 495
    self._lv_name = new_name
496 496
    self.dev_path = utils.PathJoin("/dev", self._vg_name, self._lv_name)
497 497

  
498
  def Attach(self):
499
    """Attach to an existing LV.
500

  
501
    This method will try to see if an existing and active LV exists
502
    which matches our name. If so, its major/minor will be
503
    recorded.
498
  @classmethod
499
  def _ParseLvInfoLine(cls, line, sep):
500
    """Parse one line of the lvs output used in L{_GetLvInfo}.
504 501

  
505 502
    """
506
    self.attached = False
507
    result = utils.RunCmd(["lvs", "--noheadings", "--separator=,",
508
                           "--units=k", "--nosuffix",
509
                           "-olv_attr,lv_kernel_major,lv_kernel_minor,"
510
                           "vg_extent_size,stripes", self.dev_path])
511
    if result.failed:
512
      logging.error("Can't find LV %s: %s, %s",
513
                    self.dev_path, result.fail_reason, result.output)
514
      return False
515
    # the output can (and will) have multiple lines for multi-segment
516
    # LVs, as the 'stripes' parameter is a segment one, so we take
517
    # only the last entry, which is the one we're interested in; note
518
    # that with LVM2 anyway the 'stripes' value must be constant
519
    # across segments, so this is a no-op actually
520
    out = result.stdout.splitlines()
521
    if not out: # totally empty result? splitlines() returns at least
522
                # one line for any non-empty string
523
      logging.error("Can't parse LVS output, no lines? Got '%s'", str(out))
524
      return False
525
    out = out[-1].strip().rstrip(",")
526
    out = out.split(",")
527
    if len(out) != 5:
528
      logging.error("Can't parse LVS output, len(%s) != 5", str(out))
529
      return False
503
    elems = line.strip().rstrip(sep).split(sep)
504
    if len(elems) != 5:
505
      base.ThrowError("Can't parse LVS output, len(%s) != 5", str(elems))
530 506

  
531
    status, major, minor, pe_size, stripes = out
507
    (status, major, minor, pe_size, stripes) = elems
532 508
    if len(status) < 6:
533
      logging.error("lvs lv_attr is not at least 6 characters (%s)", status)
534
      return False
509
      base.ThrowError("lvs lv_attr is not at least 6 characters (%s)", status)
535 510

  
536 511
    try:
537 512
      major = int(major)
538 513
      minor = int(minor)
539 514
    except (TypeError, ValueError), err:
540
      logging.error("lvs major/minor cannot be parsed: %s", str(err))
515
      base.ThrowError("lvs major/minor cannot be parsed: %s", str(err))
541 516

  
542 517
    try:
543 518
      pe_size = int(float(pe_size))
544 519
    except (TypeError, ValueError), err:
545
      logging.error("Can't parse vg extent size: %s", err)
546
      return False
520
      base.ThrowError("Can't parse vg extent size: %s", err)
547 521

  
548 522
    try:
549 523
      stripes = int(stripes)
550 524
    except (TypeError, ValueError), err:
551
      logging.error("Can't parse the number of stripes: %s", err)
525
      base.ThrowError("Can't parse the number of stripes: %s", err)
526

  
527
    return (status, major, minor, pe_size, stripes)
528

  
529
  @classmethod
530
  def _GetLvInfo(cls, dev_path, _run_cmd=utils.RunCmd):
531
    """Get info about the given existing LV to be used.
532

  
533
    """
534
    result = _run_cmd(["lvs", "--noheadings", "--separator=,",
535
                       "--units=k", "--nosuffix",
536
                       "-olv_attr,lv_kernel_major,lv_kernel_minor,"
537
                       "vg_extent_size,stripes", dev_path])
538
    if result.failed:
539
      base.ThrowError("Can't find LV %s: %s, %s",
540
                      dev_path, result.fail_reason, result.output)
541
    # the output can (and will) have multiple lines for multi-segment
542
    # LVs, as the 'stripes' parameter is a segment one, so we take
543
    # only the last entry, which is the one we're interested in; note
544
    # that with LVM2 anyway the 'stripes' value must be constant
545
    # across segments, so this is a no-op actually
546
    out = result.stdout.splitlines()
547
    if not out: # totally empty result? splitlines() returns at least
548
                # one line for any non-empty string
549
      base.ThrowError("Can't parse LVS output, no lines? Got '%s'", str(out))
550
    return cls._ParseLvInfoLine(out[-1], ",")
551

  
552
  def Attach(self):
553
    """Attach to an existing LV.
554

  
555
    This method will try to see if an existing and active LV exists
556
    which matches our name. If so, its major/minor will be
557
    recorded.
558

  
559
    """
560
    self.attached = False
561
    try:
562
      (status, major, minor, pe_size, stripes) = \
563
        self._GetLvInfo(self.dev_path)
564
    except errors.BlockDeviceError:
552 565
      return False
553 566

  
554 567
    self.major = major

Also available in: Unified diff