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