Skip to content

Instantly share code, notes, and snippets.

@Xaroth
Created April 25, 2014 00:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Xaroth/11273909 to your computer and use it in GitHub Desktop.
Save Xaroth/11273909 to your computer and use it in GitHub Desktop.
libzfs-python zpool status
from ..zpool import ZPool, c_libzfs, ffi_libzfs, enums
zpool_status_t = enums.zpool_status
import sys
from datetime import datetime
import time
def nicenum(value):
pass
def _state_to_name(state, aux):
return ffi_libzfs.string(c_libzfs.zpool_state_to_name(state, aux))
def print_scan_status(stats):
if stats is None or stats[0] == int(enums.pool_scan_func.NONE) or stats[0] == int(enums.pool_scan_func.FUNCS):
value = "none requested"
else:
(func, state, start_time, end_time, to_examine, examined, to_process,
processed, errors, pass_examined, pass_start) = stats
func = enums.pool_scan_func(func)
state = enums.dsl_scan_state(state)
minutes_taken = (end_time - start_time) / 60
end_time = datetime.fromtimestamp(end_time)
ftype = "scrub" if func == enums.pool_scan_func.SCRUB else "resilver"
if state == enums.dsl_scan_state.FINISHED:
if func == enums.pool_scan_func.SCRUB:
value = "scrub repaired %s in %dh%dm with %d errors on %s"
elif func == enums.pool_scan_func.RESILVER:
value = "resilvered %s in %dh%dm with %d errors on %s"
value = value % (processed, int(minutes_taken / 60), int(minutes_taken % 60), errors, end_time)
elif state == enums.dsl_scan_state.CANCELED:
value = "%s canceled on %s" % (ftype, end_time)
else:
value = "%s in progress since %s" % (ftype, start_time)
examined = examined or 1
fraction_done = float(examined) / float(to_examine)
elapsed = (time.time() - pass_start) or 1
pass_examined = pass_examined or 1
rate = (pass_examined / elapsed) or 1
mins_left = ((to_examine - examined) / rate) / 60
hours_left = int(mins_left / 60)
value += "\n %s scanned out of %s at %s/s" % (examined, to_examine, rate)
if hours_left < (30 * 24):
value += ", %dh%dm to go\n" % (hours_left, mins_left)
ftype = "repaired" if func == enums.pool_scan_func.SCRUB else "resilvered"
value += "\n %s %s, %.2f%% done" % (processed, ftype, fraction_done * 100)
print(" scan: %s" % value)
status_messages = {
zpool_status_t.MISSING_DEV_R: [
"status: One or more devices could not be opened. Sufficient replicas exist for",
" the pool to continue functioning in a degraded state",
"action: Attach the missing device and online it using 'zpool online'."
],
zpool_status_t.MISSING_DEV_NR: [
"status: One or more devices could not be opened. There are insufficient",
" replicas for the pool to continue functioning.",
"action: Attach the missing device and online it using 'zpool online'."
],
zpool_status_t.CORRUPT_LABEL_R: [
"status: One or more devices could not be used because the label is missing or",
" invalid. Sufficient replicas exist for the pool to continue",
" functioning in a degraded state."
"action: Replace the device using 'zpool replace'."
],
zpool_status_t.CORRUPT_LABEL_NR: [
"status: One or more devices could not be used because the label is missing or",
" invalid. There are insufficient replicas for the pool to continue",
" functioning."
],
zpool_status_t.FAILING_DEV: [
"status: One or more devices has experienced an unrecoverable error. An",
" attempt was made to correct the error. Applications are unaffected.",
"action: Determine if the device needs to be replaced, and clear the errors",
" using 'zpool clear' or replace the device with 'zpool replace'",
],
zpool_status_t.OFFLINE_DEV: [
"status: One or more devices has been taken offline by the administrator.",
" Sufficient replicas exist for the pool to continue functioning in a",
" degraded state.",
"action: Online the device using 'zpool online' or replace the device with",
" 'zpool replace'.",
],
zpool_status_t.REMOVED_DEV: [
"status: One or more devices has been removed by the administrator.",
" Sufficient replicas exist for the pool to continue functioning in a",
" degraded state.",
"action: Online the device using 'zpool online' or replace the device with",
" 'zpool replace'.",
],
zpool_status_t.RESILVERING: [
"status: One or more devices is currently being resilvered. The pool will",
" continue to function, possibly in a degraded state.",
"action: Wait for the resilver to complete",
],
# TODO: more status messages
}
def zpool_status():
for pool in ZPool.list():
config = pool.config
vdev_stats = config['vdev_tree']['vdev_stats']
vs_state, vs_aux = vdev_stats[1:3]
state = _state_to_name(vs_state, vs_aux)
print(" pool: %s" % pool.name)
print(" state: %s" % state)
status = pool.status
if status in status_messages:
print('\n'.join(status_messages[status]))
if pool.status_extra:
print(" see: http://zfsonlinux.org/msg/%s" % pool.status_extra)
print_scan_status(config['vdev_tree'].get('scan_stats'))
print("")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment