#!/usr/bin/env python
#
# Dumb script to dump (some) of bcache status
# Copyright 2014 Darrick J. Wong. All rights reserved.
#
# This file is part of Bcache.  Bcache is free software: you can
# redistribute it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, version 2.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#

import os
import sys
import argparse

MAX_KEY_LENGTH		= 28
DEV_BLOCK_PATH		= '/dev/block/'
SYSFS_BCACHE_PATH	= '/sys/fs/bcache/'
SYSFS_BLOCK_PATH	= '/sys/block/'

def file_to_lines(fname):
	try:
		with open(fname, "r") as fd:
			return fd.readlines()
	except:
		return []

def file_to_line(fname):
	ret = file_to_lines(fname)
	if ret:
		return ret[0].strip()
	return ''

def str_to_bool(x):
	return x == '1'

def format_sectors(x):
	'''Pretty print a sector count.'''
	sectors = float(x)
	asectors = abs(sectors)

	if asectors < 2:
		return '%d B' % (sectors * 512)
	elif asectors < 2048:
		return '%.2f KiB' % (sectors / 2)
	elif asectors < 2097152:
		return '%.1f MiB' % (sectors / 2048)
	elif asectors < 2147483648:
		return '%.0f GiB' % (sectors / 2097152)
	else:
		return '%.0f TiB' % (sectors / 2147483648)

def interpret_sectors(x):
	'''Interpret a pretty-printed disk size.'''
	factors = {
		'k': 1 << 10,
		'M': 1 << 20,
		'G': 1 << 30,
		'T': 1 << 40,
		'P': 1 << 50,
		'E': 1 << 60,
		'Z': 1 << 70,
		'Y': 1 << 80,
	}

	factor = 1
	if x[-1] in factors:
		factor = factors[x[-1]]
		x = x[:-1]
	return int(float(x) * factor / 512)

def pretty_size(x):
	return format_sectors(interpret_sectors(x))

def device_path(x):
	if not os.path.isdir(DEV_BLOCK_PATH):
		return '?'
	x = '%s/%s' % (DEV_BLOCK_PATH, x)
	return os.path.abspath(os.path.join(os.path.dirname(x), os.readlink(x)))

def str_device_path(x):
	return '%s (%s)' % (device_path(x), x)

def dump_bdev(bdev_path):
	'''Dump a backing device stats.'''
	global MAX_KEY_LENGTH
	attrs = [
		('../dev',		'Device File',		str_device_path),
		('dev/dev',		'bcache Device File',	str_device_path),
		('../size',		'Size',			format_sectors),
		('cache_mode',		'Cache Mode',		None),
		('readahead',		'Readahead',		None),
		('sequential_cutoff',	'Sequential Cutoff',	pretty_size),
		('sequential_merge',	'Merge sequential?',	str_to_bool),
		('state',		'State',		None),
		('writeback_running',	'Writeback?',		str_to_bool),
		('dirty_data',		'Dirty Data',		pretty_size),
		('writeback_rate',	'Writeback Rate',	lambda x: '%s/s' % x),
		('writeback_percent',	'Dirty Target',		lambda x: '%s%%' % x),
	]

	print('--- Backing Device ---')
	for (sysfs_name, display_name, conversion_func) in attrs:
		val = file_to_line('%s/%s' % (bdev_path, sysfs_name))
		if conversion_func is not None:
			val = conversion_func(val)
		if display_name is None:
			display_name = sysfs_name
		print('  %-*s%s' % (MAX_KEY_LENGTH - 2, display_name, val))

def dump_cachedev(cachedev_path):
	'''Dump a cachding device stats.'''
	def fmt_cachesize(val):
		return '%s\t(%.0f%%)' % (format_sectors(val), float(val) / cache_size * 100)

	global MAX_KEY_LENGTH
	attrs = [
		('../dev',			'Device File',		str_device_path),
		('../size',			'Size',			format_sectors),
		('block_size',			'Block Size',		pretty_size),
		('bucket_size',			'Bucket Size',		pretty_size),
		('cache_replacement_policy',	'Replacement Policy',	None),
		('discard',			'Discard?',		str_to_bool),
		('io_errors',			'I/O Errors',		None),
		('metadata_written',		'Metadata Written',	pretty_size),
		('written',			'Data Written',		pretty_size),
		('nbuckets',			'Buckets',		None),
		(None,				'Cache Used',		lambda x: fmt_cachesize(used_sectors)),
		(None,				'Cache Unused',		lambda x: fmt_cachesize(unused_sectors)),
	]

	stats = get_cache_priority_stats(cachedev_path)
	cache_size = int(file_to_line('%s/../size' % cachedev_path))
	unused_sectors = float(stats['Unused'][:-1]) * cache_size / 100
	used_sectors = cache_size - unused_sectors

	print('--- Cache Device ---')
	for (sysfs_name, display_name, conversion_func) in attrs:
		if sysfs_name is not None:
			val = file_to_line('%s/%s' % (cachedev_path, sysfs_name))
		if conversion_func is not None:
			val = conversion_func(val)
		if display_name is None:
			display_name = sysfs_name
		print('  %-*s%s' % (MAX_KEY_LENGTH - 2, display_name, val))

def hits_to_str(hits_str, misses_str):
	'''Render a hits/misses ratio as a string.'''
	hits = int(hits_str)
	misses = int(misses_str)

	ret = '%d' % hits
	if hits + misses != 0:
		ret = '%s\t(%.d%%)' % (ret, 100 * hits / (hits + misses))
	return ret

def dump_stats(sysfs_path, indent_str, stats):
	'''Dump stats on a bcache device.'''
	stat_types = [
		('five_minute',	'Last 5min'),
		('hour',	'Last Hour'),
		('day',		'Last Day'),
		('total',	'Total'),
	]
	attrs = ['bypassed', 'cache_bypass_hits', 'cache_bypass_misses', 'cache_hits', 'cache_misses']
	display = [
		('Hits',		lambda: hits_to_str(stat_data['cache_hits'], stat_data['cache_misses'])),
		('Misses',		lambda: stat_data['cache_misses']),
		('Bypass Hits',		lambda: hits_to_str(stat_data['cache_bypass_hits'], stat_data['cache_bypass_misses'])),
		('Bypass Misses',	lambda: stat_data['cache_bypass_misses']),
		('Bypassed',		lambda: pretty_size(stat_data['bypassed'])),
	]

	for (sysfs_name, stat_display_name) in stat_types:
		if len(stats) > 0 and sysfs_name not in stats:
			continue
		stat_data = {}
		for attr in attrs:
			val = file_to_line('%s/stats_%s/%s' % (sysfs_path, sysfs_name, attr))
			stat_data[attr] = val
		for (display_name, str_func) in display:
			d = '%s%s %s' % (indent_str, stat_display_name, display_name)
			print('%-*s%s' % (MAX_KEY_LENGTH, d, str_func()))

def get_cache_priority_stats(cache):
	'''Retrieve priority stats from a cache.'''
	attrs = {}

	for line in file_to_lines('%s/priority_stats' % cache):
		x = line.split()
		key = x[0]
		value = x[1]
		attrs[key[:-1]] = value
	return attrs

def dump_bcache(bcache_sysfs_path, stats, print_subdevices, device):
	'''Dump bcache stats'''
	def fmt_cachesize(val):
		return '%s\t(%.0f%%)' % (format_sectors(val), 100.0 * val / cache_sectors)

	attrs = [
		(None,					'UUID',			lambda x: os.path.basename(bcache_sysfs_path)),
		('block_size',				'Block Size',		pretty_size),
		('bucket_size',				'Bucket Size',		pretty_size),
		('congested', 				'Congested?',		str_to_bool),
		('congested_read_threshold_us',		'Read Congestion',	lambda x: '%.1fms' % (int(x) / 1000)),
		('congested_write_threshold_us',	'Write Congestion',	lambda x: '%.1fms' % (int(x) / 1000)),
		(None,					'Total Cache Size',	lambda x: format_sectors(cache_sectors)),
		(None,					'Total Cache Used',	lambda x: fmt_cachesize(cache_used_sectors)),
		(None,					'Total Cache Unused',	lambda x: fmt_cachesize(cache_unused_sectors)),
		#('dirty_data',				'Dirty Data',		lambda x: fmt_cachesize(interpret_sectors(x))),		# disappeared in 3.13?
		('cache_available_percent',		'Evictable Cache',	lambda x: '%s\t(%s%%)' % (format_sectors(float(x) * cache_sectors / 100), x)),
		(None,					'Replacement Policy',	lambda x: replacement_policies.pop() if len(replacement_policies) == 1 else '(Various)'),
		(None,					'Cache Mode',		lambda x: cache_modes.pop() if len(cache_modes) == 1 else '(Various)'),
	]

	# Calculate aggregate data
	cache_sectors = 0
	cache_unused_sectors = 0
	cache_modes = set()
	replacement_policies = set()
	for obj in os.listdir(bcache_sysfs_path):
		if not os.path.isdir('%s/%s' % (bcache_sysfs_path, obj)):
			continue
		if obj.startswith('cache'):
			cache_size = int(file_to_line('%s/%s/../size' % (bcache_sysfs_path, obj)))
			cache_sectors += cache_size
			cstats = get_cache_priority_stats('%s/%s' % (bcache_sysfs_path, obj))
			unused_size = float(cstats['Unused'][:-1]) * cache_size / 100
			cache_unused_sectors += unused_size
			replacement_policies.add(file_to_line('%s/%s/cache_replacement_policy' % (bcache_sysfs_path, obj)))
		elif obj.startswith('bdev'):
			cache_modes.add(file_to_line('%s/%s/cache_mode' % (bcache_sysfs_path, obj)))
	cache_used_sectors = cache_sectors - cache_unused_sectors

	# Dump basic stats
	print("--- bcache ---")
	for (sysfs_name, display_name, conversion_func) in attrs:
		if sysfs_name is not None:
			val = file_to_line('%s/%s' % (bcache_sysfs_path, sysfs_name))
		else:
			val = None
		if conversion_func is not None:
			val = conversion_func(val)
		if display_name is None:
			display_name = sysfs_name
		print('%-*s%s' % (MAX_KEY_LENGTH, display_name, val))
	dump_stats(bcache_sysfs_path, '', stats)

	# Dump sub-device stats
	if not print_subdevices:
		return
	for obj in os.listdir(bcache_sysfs_path):
		if not os.path.isdir('%s/%s' % (bcache_sysfs_path, obj)):
			continue
		if obj.startswith('bdev'):
			dump_bdev('%s/%s' % (bcache_sysfs_path, obj))
			dump_stats('%s/%s' % (bcache_sysfs_path, obj), '  ', stats)
		elif obj.startswith('cache'):
			dump_cachedev('%s/%s' % (bcache_sysfs_path, obj))

def map_uuid_to_device():
	'''Map bcache UUIDs to device files.'''
	global SYSFS_BLOCK_PATH
	ret = {}

	if not os.path.isdir(SYSFS_BLOCK_PATH):
		return ret
	for bdev in os.listdir(SYSFS_BLOCK_PATH):
		link = '%s%s/bcache/cache' % (SYSFS_BLOCK_PATH, bdev)
		if not os.path.islink(link):
			continue
		basename = os.path.basename(os.readlink(link))
		ret[basename] = file_to_line('%s%s/dev' % (SYSFS_BLOCK_PATH, bdev))
	return ret

def main():
	'''Main function'''
	global SYSFS_BCACHE_PATH
	global uuid_map
	stats = set()
	reset_stats = False
	print_subdevices = False
	run_gc = False

	parser = argparse.ArgumentParser(add_help=False)
	parser.add_argument('--help',			help='Show this help message and exit',		action='store_true')
	parser.add_argument('-f', '--five-minute',	help='Print the last five minutes of stats.',	action='store_true')
	parser.add_argument('-h', '--hour',		help='Print the last hour of stats.',		action='store_true')
	parser.add_argument('-d', '--day',		help='Print the last day of stats.',		action='store_true')
	parser.add_argument('-t', '--total',		help='Print total stats.',			action='store_true')
	parser.add_argument('-a', '--all',		help='Print all stats.',			action='store_true')
	parser.add_argument('-r', '--reset-stats',	help='Reset stats after printing them.',	action='store_true')
	parser.add_argument('-s', '--sub-status',	help='Print subdevice status.',			action='store_true')
	parser.add_argument('-g', '--gc',		help='Invoke GC before printing status.',	action='store_true')
	args = parser.parse_args()

	if args.help:
		parser.print_help()
		return 0

	if args.five_minute:
		stats.add('five_minute')
	if args.hour:
		stats.add('hour')
	if args.day:
		stats.add('day')
	if args.total:
		stats.add('total')
	if args.all:
		stats.add('five_minute')
		stats.add('hour')
		stats.add('day')
		stats.add('total')
	if args.reset_stats:
		reset_stats = True
	if args.sub_status:
		print_subdevices = True
	if args.gc:
		run_gc = True

	if not stats:
		stats.add('total')

	uuid_map = map_uuid_to_device()
	if not os.path.isdir(SYSFS_BCACHE_PATH):
		print('bcache is not loaded.')
		return
	for cache in os.listdir(SYSFS_BCACHE_PATH):
		if not os.path.isdir('%s%s' % (SYSFS_BCACHE_PATH, cache)):
			continue

		if run_gc:
			with open('%s%s/internal/trigger_gc' % (SYSFS_BCACHE_PATH, cache), 'w') as fd:
				fd.write('1\n')

		dump_bcache('%s%s' % (SYSFS_BCACHE_PATH, cache), stats, print_subdevices, uuid_map.get(cache, '?'))

		if reset_stats:
			with open('%s%s/clear_stats' % (SYSFS_BCACHE_PATH, cache), 'w') as fd:
				fd.write('1\n')

if __name__ == '__main__':
	main()
