Last active
March 28, 2016 16:22
-
-
Save likema/1f113ad5b0c17918d980 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# \Author: Like Ma <likemartinma@gmail.com> | |
# \brief: It shows btrfs subvolume info and supports Python 2/3 | |
import sys | |
from re import compile as rcomp | |
from subprocess import Popen, PIPE, STDOUT | |
SUBVOL_CHECKER = rcomp( | |
r'^ID\s+(?P<id>\d+)\s+gen\s+(?P<gen>\d+)\s+' | |
r'top\s+level\s+(?P<ogen>\d+)\s+path\s+(?P<path>.+)') | |
QGROUP_HDR_CHECKER = rcomp(r'^qgroupid\s+rfer\s+excl\s*') | |
QGROUP_CHECKER = rcomp(r'\d+/(?P<id>\d+)\s+(?P<rfer>\d+)\s+(?P<excl>\d+)') | |
CTIME_CHECKER = rcomp(r'^\s*Creation time:\s*(\S+)\s*(\S+)\s*') | |
def each_stdout_stderr(*args): | |
proc = Popen(args, stdout=PIPE, stderr=STDOUT) | |
try: | |
for i in proc.stdout: | |
yield i.decode("utf-8") # Decoding is for python3 | |
finally: | |
proc.wait() | |
def btrfs_subvolume_list(mp): | |
for i in each_stdout_stderr('btrfs', 'subvolume', 'list', mp): | |
m = SUBVOL_CHECKER.match(i.strip()) | |
if m: | |
yield m.groupdict() | |
def btrfs_subvolume_creation_time(path): | |
result = None | |
for i in each_stdout_stderr('btrfs', 'subvolume', 'show', path): | |
m = CTIME_CHECKER.match(i) | |
if m: | |
result = '%s %s' % (m.group(1), m.group(2)) | |
break | |
return result | |
def parse_btrfs_qgroup_show(fp): | |
result = {} | |
for i in fp: | |
if 'unrecognized option' in i: | |
return None | |
if QGROUP_HDR_CHECKER.match(i) or i.startswith('^---'): | |
continue | |
m = QGROUP_CHECKER.match(i.strip()) | |
if m: | |
d = m.groupdict() | |
result[d['id']] = d | |
return result | |
def btrfs_qgroup_show(mp): | |
result = parse_btrfs_qgroup_show( | |
each_stdout_stderr('btrfs', 'qgroup', 'show', mp, '--raw')) | |
if result: | |
return result | |
return parse_btrfs_qgroup_show( | |
each_stdout_stderr('btrfs', 'qgroup', 'show', mp)) | |
def format_byte(size): | |
units = ('T', 'G', 'M', 'K') | |
q = 1 << 40 | |
for i in units: | |
if size >= q: | |
return '%d %s' % (int(size / q), i) | |
q >>= 10 | |
if len(sys.argv) < 2: | |
sys.stderr.write('%s <mount point>\n' % sys.argv[0]) | |
sys.exit(1) | |
mp = sys.argv[1] | |
qgroup = btrfs_qgroup_show(mp) | |
subvolumes = [] | |
for i in btrfs_subvolume_list(mp): | |
rec = qgroup.get(i['id']) | |
if rec: | |
i.update(rec) | |
subvolumes.append(i) | |
print('%6s %-32s %-20s %16s %16s' % | |
('ID', 'Subvolume', 'Creation Time', 'Total', 'Exclusive Data')) | |
for i in subvolumes: | |
ctime = btrfs_subvolume_creation_time('%s/%s' % (mp, i['path'])) | |
print('%6s %-32s %-20s %16s %16s' % (i['id'], | |
i['path'], | |
ctime, | |
format_byte(int(i['rfer'])), | |
format_byte(int(i['excl'])))) | |
# vim: ts=4 sw=4 sts=4 et: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment