Revision b5d48e87 lib/storage/bdev.py

b/lib/storage/bdev.py
172 172

  
173 173
  """
174 174
  _VALID_NAME_RE = re.compile("^[a-zA-Z0-9+_.-]*$")
175
  _PARSE_PV_DEV_RE = re.compile("^([^ ()]+)\([0-9]+\)$")
175 176
  _INVALID_NAMES = compat.UniqueFrozenset([".", "..", "snapshot", "pvmove"])
176 177
  _INVALID_SUBSTRINGS = compat.UniqueFrozenset(["_mlog", "_mimage"])
177 178

  
......
190 191
    self.dev_path = utils.PathJoin("/dev", self._vg_name, self._lv_name)
191 192
    self._degraded = True
192 193
    self.major = self.minor = self.pe_size = self.stripe_count = None
194
    self.pv_names = None
193 195
    self.Attach()
194 196

  
195 197
  @staticmethod
......
501 503

  
502 504
    """
503 505
    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))
506
    if len(elems) != 6:
507
      base.ThrowError("Can't parse LVS output, len(%s) != 6", str(elems))
506 508

  
507
    (status, major, minor, pe_size, stripes) = elems
509
    (status, major, minor, pe_size, stripes, pvs) = elems
508 510
    if len(status) < 6:
509 511
      base.ThrowError("lvs lv_attr is not at least 6 characters (%s)", status)
510 512

  
......
524 526
    except (TypeError, ValueError), err:
525 527
      base.ThrowError("Can't parse the number of stripes: %s", err)
526 528

  
527
    return (status, major, minor, pe_size, stripes)
529
    pv_names = []
530
    for pv in pvs.split(","):
531
      m = re.match(cls._PARSE_PV_DEV_RE, pv)
532
      if not m:
533
        base.ThrowError("Can't parse this device list: %s", pvs)
534
      pv_names.append(m.group(1))
535
    assert len(pv_names) > 0
536

  
537
    return (status, major, minor, pe_size, stripes, pv_names)
528 538

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

  
533 543
    """
534
    result = _run_cmd(["lvs", "--noheadings", "--separator=,",
544
    sep = "|"
545
    result = _run_cmd(["lvs", "--noheadings", "--separator=%s" % sep,
535 546
                       "--units=k", "--nosuffix",
536 547
                       "-olv_attr,lv_kernel_major,lv_kernel_minor,"
537
                       "vg_extent_size,stripes", dev_path])
548
                       "vg_extent_size,stripes,devices", dev_path])
538 549
    if result.failed:
539 550
      base.ThrowError("Can't find LV %s: %s, %s",
540 551
                      dev_path, result.fail_reason, result.output)
......
547 558
    if not out: # totally empty result? splitlines() returns at least
548 559
                # one line for any non-empty string
549 560
      base.ThrowError("Can't parse LVS output, no lines? Got '%s'", str(out))
550
    return cls._ParseLvInfoLine(out[-1], ",")
561
    pv_names = set()
562
    for line in out:
563
      (status, major, minor, pe_size, stripes, more_pvs) = \
564
        cls._ParseLvInfoLine(line, sep)
565
      pv_names.update(more_pvs)
566
    return (status, major, minor, pe_size, stripes, pv_names)
551 567

  
552 568
  def Attach(self):
553 569
    """Attach to an existing LV.
......
559 575
    """
560 576
    self.attached = False
561 577
    try:
562
      (status, major, minor, pe_size, stripes) = \
578
      (status, major, minor, pe_size, stripes, pv_names) = \
563 579
        self._GetLvInfo(self.dev_path)
564 580
    except errors.BlockDeviceError:
565 581
      return False
......
570 586
    self.stripe_count = stripes
571 587
    self._degraded = status[0] == "v" # virtual volume, i.e. doesn't backing
572 588
                                      # storage
589
    self.pv_names = pv_names
573 590
    self.attached = True
574 591
    return True
575 592

  

Also available in: Unified diff