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