Revision 39e9e213
b/lib/bdev.py | ||
---|---|---|
53 | 53 |
- md arrays are created or assembled and used |
54 | 54 |
- drbd devices are attached to a local disk/remote peer and made primary |
55 | 55 |
|
56 |
The status of the device can be examined by `GetStatus()`, which |
|
57 |
returns a numerical value, depending on the position in the |
|
58 |
transition stack of the device. |
|
59 |
|
|
60 | 56 |
A block device is identified by three items: |
61 | 57 |
- the /dev path of the device (dynamic) |
62 | 58 |
- a unique ID of the device (static) |
... | ... | |
82 | 78 |
after assembly we'll have our correct major/minor. |
83 | 79 |
|
84 | 80 |
""" |
85 |
STATUS_UNKNOWN = 0 |
|
86 |
STATUS_EXISTING = 1 |
|
87 |
STATUS_STANDBY = 2 |
|
88 |
STATUS_ONLINE = 3 |
|
89 |
|
|
90 |
STATUS_MAP = { |
|
91 |
STATUS_UNKNOWN: "unknown", |
|
92 |
STATUS_EXISTING: "existing", |
|
93 |
STATUS_STANDBY: "ready for use", |
|
94 |
STATUS_ONLINE: "online", |
|
95 |
} |
|
96 |
|
|
97 | 81 |
def __init__(self, unique_id, children): |
98 | 82 |
self._children = children |
99 | 83 |
self.dev_path = None |
... | ... | |
179 | 163 |
""" |
180 | 164 |
raise NotImplementedError |
181 | 165 |
|
182 |
def GetStatus(self): |
|
183 |
"""Return the status of the device. |
|
184 |
|
|
185 |
""" |
|
186 |
raise NotImplementedError |
|
187 |
|
|
188 | 166 |
def Open(self, force=False): |
189 | 167 |
"""Make the device ready for use. |
190 | 168 |
|
... | ... | |
439 | 417 |
""" |
440 | 418 |
return True |
441 | 419 |
|
442 |
def GetStatus(self): |
|
443 |
"""Return the status of the device. |
|
444 |
|
|
445 |
Logical volumes will can be in all four states, although we don't |
|
446 |
deactivate (lvchange -an) them when shutdown, so STATUS_EXISTING |
|
447 |
should not be seen for our devices. |
|
448 |
|
|
449 |
""" |
|
450 |
result = utils.RunCmd(["lvs", "--noheadings", "-olv_attr", self.dev_path]) |
|
451 |
if result.failed: |
|
452 |
logger.Error("Can't display lv: %s" % result.fail_reason) |
|
453 |
return self.STATUS_UNKNOWN |
|
454 |
out = result.stdout.strip() |
|
455 |
# format: type/permissions/alloc/fixed_minor/state/open |
|
456 |
if len(out) != 6: |
|
457 |
return self.STATUS_UNKNOWN |
|
458 |
#writable = (out[1] == "w") |
|
459 |
active = (out[4] == "a") |
|
460 |
online = (out[5] == "o") |
|
461 |
if online: |
|
462 |
retval = self.STATUS_ONLINE |
|
463 |
elif active: |
|
464 |
retval = self.STATUS_STANDBY |
|
465 |
else: |
|
466 |
retval = self.STATUS_EXISTING |
|
467 |
|
|
468 |
return retval |
|
469 |
|
|
470 | 420 |
def GetSyncStatus(self): |
471 | 421 |
"""Returns the sync status of the device. |
472 | 422 |
|
... | ... | |
823 | 773 |
for dev in orig_devs: |
824 | 774 |
self._children.remove(dev) |
825 | 775 |
|
826 |
def GetStatus(self): |
|
827 |
"""Return the status of the device. |
|
828 |
|
|
829 |
""" |
|
830 |
self.Attach() |
|
831 |
if self.minor is None: |
|
832 |
retval = self.STATUS_UNKNOWN |
|
833 |
else: |
|
834 |
retval = self.STATUS_ONLINE |
|
835 |
return retval |
|
836 |
|
|
837 | 776 |
def _SetFromMinor(self, minor): |
838 | 777 |
"""Set our parameters based on the given minor. |
839 | 778 |
|
... | ... | |
1553 | 1492 |
is_degraded = client_state != "Connected" |
1554 | 1493 |
return sync_percent, est_time, is_degraded, False |
1555 | 1494 |
|
1556 |
def GetStatus(self): |
|
1557 |
"""Compute the status of the DRBD device |
|
1558 |
|
|
1559 |
Note that DRBD devices don't have the STATUS_EXISTING state. |
|
1560 |
|
|
1561 |
""" |
|
1562 |
if self.minor is None and not self.Attach(): |
|
1563 |
return self.STATUS_UNKNOWN |
|
1564 |
|
|
1565 |
data = self._GetProcData() |
|
1566 |
match = re.compile("^ *%d: cs:[^ ]+ st:(Primary|Secondary)/.*$" % |
|
1567 |
self.minor) |
|
1568 |
for line in data: |
|
1569 |
mresult = match.match(line) |
|
1570 |
if mresult: |
|
1571 |
break |
|
1572 |
else: |
|
1573 |
logger.Error("Can't find myself!") |
|
1574 |
return self.STATUS_UNKNOWN |
|
1575 |
|
|
1576 |
state = mresult.group(2) |
|
1577 |
if state == "Primary": |
|
1578 |
result = self.STATUS_ONLINE |
|
1579 |
else: |
|
1580 |
result = self.STATUS_STANDBY |
|
1581 |
|
|
1582 |
return result |
|
1583 |
|
|
1584 | 1495 |
@staticmethod |
1585 | 1496 |
def _ZeroDevice(device): |
1586 | 1497 |
"""Zero a device. |
... | ... | |
2049 | 1960 |
is_degraded = client_state != "Connected" |
2050 | 1961 |
return sync_percent, est_time, is_degraded or ldisk, ldisk |
2051 | 1962 |
|
2052 |
def GetStatus(self): |
|
2053 |
"""Compute the status of the DRBD device |
|
2054 |
|
|
2055 |
Note that DRBD devices don't have the STATUS_EXISTING state. |
|
2056 |
|
|
2057 |
""" |
|
2058 |
if self.minor is None and not self.Attach(): |
|
2059 |
return self.STATUS_UNKNOWN |
|
2060 |
|
|
2061 |
data = self._GetProcData() |
|
2062 |
match = re.compile("^ *%d: cs:[^ ]+ st:(Primary|Secondary)/.*$" % |
|
2063 |
self.minor) |
|
2064 |
for line in data: |
|
2065 |
mresult = match.match(line) |
|
2066 |
if mresult: |
|
2067 |
break |
|
2068 |
else: |
|
2069 |
logger.Error("Can't find myself!") |
|
2070 |
return self.STATUS_UNKNOWN |
|
2071 |
|
|
2072 |
state = mresult.group(2) |
|
2073 |
if state == "Primary": |
|
2074 |
result = self.STATUS_ONLINE |
|
2075 |
else: |
|
2076 |
result = self.STATUS_STANDBY |
|
2077 |
|
|
2078 |
return result |
|
2079 |
|
|
2080 | 1963 |
def Open(self, force=False): |
2081 | 1964 |
"""Make the local state primary. |
2082 | 1965 |
|
Also available in: Unified diff