All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] bcache-status
@ 2013-08-15 23:35 Darrick J. Wong
       [not found] ` <20130815233508.GB6949-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Darrick J. Wong @ 2013-08-15 23:35 UTC (permalink / raw)
  To: Kent Overstreet; +Cc: bcache

Hi all,

I wrote a script to dump out various stats about a bcache.  It would be nice
eventually to put it into bcache-tools so that users don't have to go digging
through sysfs, but for now I'm really just wondering, does this program
interpret the sysfs files correctly?

I'm particularly anxious about 'cache used' since it's just reading out of
/sys/fs/bcache/*/cache*/priority_stats and multiplying by cache size...

...also I wonder what the negative dirty data count means?

$ bcache-status -s
--- bcache ---
Device                      /dev/bcache0 (253:0)
UUID                        c4157b48-5cdc-4554-8ce6-520dafdbac55
Block Size                  4.00KiB
Bucket Size                 512.00KiB
Congested?                  False
Read Congestion             2.0ms
Write Congestion            20.0ms
Total Cache Size            205.66GiB
Total Cache Used            26.74GiB	(12%)
Total Cache Unused          178.92GiB	(87%)
Dirty Data                  0B	(0%)
Evictable Cache             205.66GiB	(100%)
Replacement Policy          [lru] fifo random
Cache Mode                  writethrough [writeback] writearound none
Total Hits                  263809	(56%)
Total Misses                199136
Total Bypass Hits           9079	(100%)
Total Bypass Misses         0
Total Bypassed              2.70GiB
--- Backing Device ---
  Device                    /dev/sdb1 (8:17)
  Size                      698.64GiB
  Cache Mode                writethrough [writeback] writearound none
  Readahead                 0
  Sequential Cutoff         4.00MiB
  Merge sequential?         True
  State                     dirty
  Writeback?                True
  Dirty Data                -2.10MiB
  Total Hits                263809	(56%)
  Total Misses              199136
  Total Bypass Hits         9079	(100%)
  Total Bypass Misses       0
  Total Bypassed            2.60GiB
--- Cache Device ---
  Device                    /dev/sda4 (8:4)
  Size                      205.66GiB
  Block Size                4.00KiB
  Bucket Size               512.00KiB
  Replacement Policy        [lru] fifo random
  Discard?                  False
  I/O Errors                0
  Metadata Written          1.10GiB
  Data Written              25.30GiB
  Buckets                   421190
  Cache Used                26.74GiB	(12%)
  Cache Unused              178.92GiB	(87%)

--D

#!/usr/bin/env python3
# Dumb script to dump (some) of bcache status
# Copyright 2013 Darrick J. Wong. All rights reserved.
# This program is licensed under GPLv2.

import os
import sys

MAX_KEY_LENGTH = 28

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 len(ret) > 0:
		return ret[0].strip()
	return ''

def str_to_bool(x):
	if x == '1':
		return True
	return False

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

	if asectors == 0:
		return '0B'
	elif asectors < 2048:
		return '%.2fKiB' % (sectors / 2)
	elif asectors < 2097152:
		return '%.2fMiB' % (sectors / 2048)
	elif asectors < 2147483648:
		return '%.2fGiB' % (sectors / 2097152)
	else:
		return '%.2fTiB' % (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 dump_bdev(bdev_path):
	'''Dump a backing device stats.'''
	global MAX_KEY_LENGTH, devnum_map
	attrs = [
		('../dev',		'Device',		lambda x: '%s (%s)' % (devnum_map.get(x, '?'), x)),
		('../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),
	]

	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(%d%%)' % (format_sectors(val), float(val) / cache_size * 100)

	global MAX_KEY_LENGTH, devnum_map
	attrs = [
		('../dev',			'Device',		lambda x: '%s (%s)' % (devnum_map.get(x, '?'), x)),
		('../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'''
	global devnum_map
	def fmt_cachesize(val):
		return '%s\t(%d%%)' % (format_sectors(val), 100.0 * val / cache_sectors)

	attrs = [
		(None,					'Device',		lambda x: '%s (%s)' % (devnum_map.get(device, '?'), device)),
		(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))),
		('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 '(Unknown)'),
		(None,					'Cache Mode',		lambda x: cache_modes.pop() if len(cache_modes) == 1 else '(Unknown)'),
	]

	# 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 = {}

	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 map_devnum_to_device():
	'''Map device numbers to device files.'''
	global DEV_BLOCK_PATH
	ret = {}

	for bdev in os.listdir(DEV_BLOCK_PATH):
		ret[bdev] = os.path.realpath('%s%s' % (DEV_BLOCK_PATH, bdev))

	return ret

def print_help():
	print('Usage: %s [OPTIONS]' % sys.argv[0])
	print('Options:')
	print(' -f	Print the last five minutes of stats.')
	print(' -d	Print the last hour of stats.')
	print(' -h	Print the last day of stats.')
	print(' -t	Print total stats.')
	print(' -a	Print all stats.')
	print(' -r	Reset stats after printing them.')
	print(' -s	Print subdevice status.')
	print(' -g	Invoke GC before printing status.')
	print('By default, print only the total stats.')

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

	for arg in sys.argv[1:]:
		if arg == '--help':
			print_help()
			return 0
		elif arg == '-f':
			stats.add('five_minute')
		elif arg == '-h':
			stats.add('hour')
		elif arg == '-d':
			stats.add('day')
		elif arg == '-t':
			stats.add('total')
		elif arg == '-a':
			stats.add('five_minute')
			stats.add('hour')
			stats.add('day')
			stats.add('total')
		elif arg == '-r':
			reset_stats = True
		elif arg == '-s':
			print_subdevices = True
		elif arg == '-g':
			run_gc = True
		else:
			print_help()
			return 0
	if len(stats) == 0:
		stats.add('total')

	uuid_map = map_uuid_to_device()
	devnum_map = map_devnum_to_device()
	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')

SYSFS_BCACHE_PATH = '/sys/fs/bcache/'
SYSFS_BLOCK_PATH = '/sys/block/'
DEV_BLOCK_PATH = '/dev/block/'
if __name__ == '__main__':
	main()

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found] ` <20130815233508.GB6949-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
@ 2013-08-16  5:09   ` Andrew Thrift
       [not found]     ` <520DB3EC.70001-3e6jenk95VYpDvLZ8AWkcaVXKuFTiq87@public.gmane.org>
  2013-08-19 11:48   ` Damien Churchill
  1 sibling, 1 reply; 14+ messages in thread
From: Andrew Thrift @ 2013-08-16  5:09 UTC (permalink / raw)
  To: Darrick J. Wong, linux-bcache-u79uwXL29TY76Z2rM5mHXA

On 8/16/2013 11:35 AM, Darrick J. Wong wrote:
> Hi all,
>
> I wrote a script to dump out various stats about a bcache.  It would be nice
> eventually to put it into bcache-tools so that users don't have to go digging
> through sysfs, but for now I'm really just wondering, does this program
> interpret the sysfs files correctly?
>
> I'm particularly anxious about 'cache used' since it's just reading out of
> /sys/fs/bcache/*/cache*/priority_stats and multiplying by cache size...
>
> ...also I wonder what the negative dirty data count means?
>
> $ bcache-status -s
> --- bcache ---
> Device                      /dev/bcache0 (253:0)
> UUID                        c4157b48-5cdc-4554-8ce6-520dafdbac55
> Block Size                  4.00KiB
> Bucket Size                 512.00KiB
> Congested?                  False
> Read Congestion             2.0ms
> Write Congestion            20.0ms
> Total Cache Size            205.66GiB
> Total Cache Used            26.74GiB	(12%)
> Total Cache Unused          178.92GiB	(87%)
> Dirty Data                  0B	(0%)
> Evictable Cache             205.66GiB	(100%)
> Replacement Policy          [lru] fifo random
> Cache Mode                  writethrough [writeback] writearound none
> Total Hits                  263809	(56%)
> Total Misses                199136
> Total Bypass Hits           9079	(100%)
> Total Bypass Misses         0
> Total Bypassed              2.70GiB
> --- Backing Device ---
>    Device                    /dev/sdb1 (8:17)
>    Size                      698.64GiB
>    Cache Mode                writethrough [writeback] writearound none
>    Readahead                 0
>    Sequential Cutoff         4.00MiB
>    Merge sequential?         True
>    State                     dirty
>    Writeback?                True
>    Dirty Data                -2.10MiB
>    Total Hits                263809	(56%)
>    Total Misses              199136
>    Total Bypass Hits         9079	(100%)
>    Total Bypass Misses       0
>    Total Bypassed            2.60GiB
> --- Cache Device ---
>    Device                    /dev/sda4 (8:4)
>    Size                      205.66GiB
>    Block Size                4.00KiB
>    Bucket Size               512.00KiB
>    Replacement Policy        [lru] fifo random
>    Discard?                  False
>    I/O Errors                0
>    Metadata Written          1.10GiB
>    Data Written              25.30GiB
>    Buckets                   421190
>    Cache Used                26.74GiB	(12%)
>    Cache Unused              178.92GiB	(87%)
>
> --D
>
> #!/usr/bin/env python3
> # Dumb script to dump (some) of bcache status
> # Copyright 2013 Darrick J. Wong. All rights reserved.
> # This program is licensed under GPLv2.
>
> import os
> import sys
>
> MAX_KEY_LENGTH = 28
>
> 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 len(ret) > 0:
> 		return ret[0].strip()
> 	return ''
>
> def str_to_bool(x):
> 	if x == '1':
> 		return True
> 	return False
>
> def format_sectors(x):
> 	'''Pretty print a sector count.'''
> 	sectors = int(x)
> 	asectors = abs(sectors)
>
> 	if asectors == 0:
> 		return '0B'
> 	elif asectors < 2048:
> 		return '%.2fKiB' % (sectors / 2)
> 	elif asectors < 2097152:
> 		return '%.2fMiB' % (sectors / 2048)
> 	elif asectors < 2147483648:
> 		return '%.2fGiB' % (sectors / 2097152)
> 	else:
> 		return '%.2fTiB' % (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 dump_bdev(bdev_path):
> 	'''Dump a backing device stats.'''
> 	global MAX_KEY_LENGTH, devnum_map
> 	attrs = [
> 		('../dev',		'Device',		lambda x: '%s (%s)' % (devnum_map.get(x, '?'), x)),
> 		('../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),
> 	]
>
> 	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(%d%%)' % (format_sectors(val), float(val) / cache_size * 100)
>
> 	global MAX_KEY_LENGTH, devnum_map
> 	attrs = [
> 		('../dev',			'Device',		lambda x: '%s (%s)' % (devnum_map.get(x, '?'), x)),
> 		('../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'''
> 	global devnum_map
> 	def fmt_cachesize(val):
> 		return '%s\t(%d%%)' % (format_sectors(val), 100.0 * val / cache_sectors)
>
> 	attrs = [
> 		(None,					'Device',		lambda x: '%s (%s)' % (devnum_map.get(device, '?'), device)),
> 		(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))),
> 		('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 '(Unknown)'),
> 		(None,					'Cache Mode',		lambda x: cache_modes.pop() if len(cache_modes) == 1 else '(Unknown)'),
> 	]
>
> 	# 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 = {}
>
> 	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 map_devnum_to_device():
> 	'''Map device numbers to device files.'''
> 	global DEV_BLOCK_PATH
> 	ret = {}
>
> 	for bdev in os.listdir(DEV_BLOCK_PATH):
> 		ret[bdev] = os.path.realpath('%s%s' % (DEV_BLOCK_PATH, bdev))
>
> 	return ret
>
> def print_help():
> 	print('Usage: %s [OPTIONS]' % sys.argv[0])
> 	print('Options:')
> 	print(' -f	Print the last five minutes of stats.')
> 	print(' -d	Print the last hour of stats.')
> 	print(' -h	Print the last day of stats.')
> 	print(' -t	Print total stats.')
> 	print(' -a	Print all stats.')
> 	print(' -r	Reset stats after printing them.')
> 	print(' -s	Print subdevice status.')
> 	print(' -g	Invoke GC before printing status.')
> 	print('By default, print only the total stats.')
>
> def main():
> 	'''Main function'''
> 	global SYSFS_BCACHE_PATH
> 	global uuid_map, devnum_map
> 	stats = set()
> 	reset_stats = False
> 	print_subdevices = False
> 	run_gc = False
>
> 	for arg in sys.argv[1:]:
> 		if arg == '--help':
> 			print_help()
> 			return 0
> 		elif arg == '-f':
> 			stats.add('five_minute')
> 		elif arg == '-h':
> 			stats.add('hour')
> 		elif arg == '-d':
> 			stats.add('day')
> 		elif arg == '-t':
> 			stats.add('total')
> 		elif arg == '-a':
> 			stats.add('five_minute')
> 			stats.add('hour')
> 			stats.add('day')
> 			stats.add('total')
> 		elif arg == '-r':
> 			reset_stats = True
> 		elif arg == '-s':
> 			print_subdevices = True
> 		elif arg == '-g':
> 			run_gc = True
> 		else:
> 			print_help()
> 			return 0
> 	if len(stats) == 0:
> 		stats.add('total')
>
> 	uuid_map = map_uuid_to_device()
> 	devnum_map = map_devnum_to_device()
> 	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')
>
> SYSFS_BCACHE_PATH = '/sys/fs/bcache/'
> SYSFS_BLOCK_PATH = '/sys/block/'
> DEV_BLOCK_PATH = '/dev/block/'
> if __name__ == '__main__':
> 	main()
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bcache" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Hi Darrick,


A very useful script indeed.

We made the following changes:

-    Removed "Device" from under cache-set header
-    Added "bcache Device" to Backing Device section
-    Changed "Device" to "Physical Device" in Backing Device section
-    Removed "Cache Mode" from cache-set header as it set per backing device

We will make some more changes in the coming weeks to implement a brief 
display mode as well as a verbose display mode.

Patch inline:

--- /usr/local/bin/bcache-status        2013-08-16 11:51:55.281095640 +1200
+++ bcache-status       2013-08-16 17:00:28.884020997 +1200
@@ -64,11 +64,16 @@
  def pretty_size(x):
          return format_sectors(interpret_sectors(x))

+def device_path(x):
+       x="/dev/block/%s" % x
+       return os.path.abspath(os.path.join(os.path.dirname(x), 
os.readlink(x)))
+
  def dump_bdev(bdev_path):
          '''Dump a backing device stats.'''
          global MAX_KEY_LENGTH, devnum_map
          attrs = [
-                ('../dev',              'Device', lambda x: '%s (%s)' % 
(devnum_map.get(x, '?'), x)),
+                ('dev/dev',             'bcache Device', device_path),
+               ('../dev',              'Physical Device', lambda x: '%s 
(%s)' % (devnum_map.get(x, '?'), x)),
                  ('../size',             'Size', format_sectors),
                  ('cache_mode',          'Cache Mode', None),
                  ('readahead',           'Readahead', None),
@@ -180,7 +185,7 @@
                  return '%s\t(%d%%)' % (format_sectors(val), 100.0 * 
val / cache_sectors)

          attrs = [
-                (None, 'Device',               lambda x: '%s (%s)' % 
(devnum_map.get(device, '?'), device)),
+                #(None, 'Device',               lambda x: '%s (%s)' % 
(devnum_map.get(device, '?'), device)),
                  (None, 'UUID',                 lambda x: 
os.path.basename(bcache_sysfs_path)),
                  ('block_size',                          'Block 
Size',           pretty_size),
                  ('bucket_size',                         'Bucket 
Size',          pretty_size),
@@ -268,8 +273,8 @@
          print('Usage: %s [OPTIONS]' % sys.argv[0])
          print('Options:')
          print(' -f      Print the last five minutes of stats.')
-        print(' -d      Print the last hour of stats.')
-        print(' -h      Print the last day of stats.')
+        print(' -h      Print the last hour of stats.')
+        print(' -d      Print the last day of stats.')
          print(' -t      Print total stats.')
          print(' -a      Print all stats.')
          print(' -r      Reset stats after printing them.')


Regards,







Andrew

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found]     ` <520DB3EC.70001-3e6jenk95VYpDvLZ8AWkcaVXKuFTiq87@public.gmane.org>
@ 2013-08-16 21:35       ` Darrick J. Wong
  0 siblings, 0 replies; 14+ messages in thread
From: Darrick J. Wong @ 2013-08-16 21:35 UTC (permalink / raw)
  To: Andrew Thrift; +Cc: linux-bcache-u79uwXL29TY76Z2rM5mHXA

On Fri, Aug 16, 2013 at 05:09:00PM +1200, Andrew Thrift wrote:
> On 8/16/2013 11:35 AM, Darrick J. Wong wrote:
> >Hi all,
> >
> >I wrote a script to dump out various stats about a bcache.  It would be nice
> >eventually to put it into bcache-tools so that users don't have to go digging
> >through sysfs, but for now I'm really just wondering, does this program
> >interpret the sysfs files correctly?
> >
> >I'm particularly anxious about 'cache used' since it's just reading out of
> >/sys/fs/bcache/*/cache*/priority_stats and multiplying by cache size...
> >
> >...also I wonder what the negative dirty data count means?
> >
> >$ bcache-status -s
> >--- bcache ---
> >Device                      /dev/bcache0 (253:0)
> >UUID                        c4157b48-5cdc-4554-8ce6-520dafdbac55
> >Block Size                  4.00KiB
> >Bucket Size                 512.00KiB
> >Congested?                  False
> >Read Congestion             2.0ms
> >Write Congestion            20.0ms
> >Total Cache Size            205.66GiB
> >Total Cache Used            26.74GiB	(12%)
> >Total Cache Unused          178.92GiB	(87%)
> >Dirty Data                  0B	(0%)
> >Evictable Cache             205.66GiB	(100%)
> >Replacement Policy          [lru] fifo random
> >Cache Mode                  writethrough [writeback] writearound none
> >Total Hits                  263809	(56%)
> >Total Misses                199136
> >Total Bypass Hits           9079	(100%)
> >Total Bypass Misses         0
> >Total Bypassed              2.70GiB
> >--- Backing Device ---
> >   Device                    /dev/sdb1 (8:17)
> >   Size                      698.64GiB
> >   Cache Mode                writethrough [writeback] writearound none
> >   Readahead                 0
> >   Sequential Cutoff         4.00MiB
> >   Merge sequential?         True
> >   State                     dirty
> >   Writeback?                True
> >   Dirty Data                -2.10MiB
> >   Total Hits                263809	(56%)
> >   Total Misses              199136
> >   Total Bypass Hits         9079	(100%)
> >   Total Bypass Misses       0
> >   Total Bypassed            2.60GiB
> >--- Cache Device ---
> >   Device                    /dev/sda4 (8:4)
> >   Size                      205.66GiB
> >   Block Size                4.00KiB
> >   Bucket Size               512.00KiB
> >   Replacement Policy        [lru] fifo random
> >   Discard?                  False
> >   I/O Errors                0
> >   Metadata Written          1.10GiB
> >   Data Written              25.30GiB
> >   Buckets                   421190
> >   Cache Used                26.74GiB	(12%)
> >   Cache Unused              178.92GiB	(87%)
> >
> >--D
> >
> >#!/usr/bin/env python3
> ># Dumb script to dump (some) of bcache status
> ># Copyright 2013 Darrick J. Wong. All rights reserved.
> ># This program is licensed under GPLv2.
> >
> >import os
> >import sys
> >
> >MAX_KEY_LENGTH = 28
> >
> >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 len(ret) > 0:
> >		return ret[0].strip()
> >	return ''
> >
> >def str_to_bool(x):
> >	if x == '1':
> >		return True
> >	return False
> >
> >def format_sectors(x):
> >	'''Pretty print a sector count.'''
> >	sectors = int(x)
> >	asectors = abs(sectors)
> >
> >	if asectors == 0:
> >		return '0B'
> >	elif asectors < 2048:
> >		return '%.2fKiB' % (sectors / 2)
> >	elif asectors < 2097152:
> >		return '%.2fMiB' % (sectors / 2048)
> >	elif asectors < 2147483648:
> >		return '%.2fGiB' % (sectors / 2097152)
> >	else:
> >		return '%.2fTiB' % (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 dump_bdev(bdev_path):
> >	'''Dump a backing device stats.'''
> >	global MAX_KEY_LENGTH, devnum_map
> >	attrs = [
> >		('../dev',		'Device',		lambda x: '%s (%s)' % (devnum_map.get(x, '?'), x)),
> >		('../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),
> >	]
> >
> >	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(%d%%)' % (format_sectors(val), float(val) / cache_size * 100)
> >
> >	global MAX_KEY_LENGTH, devnum_map
> >	attrs = [
> >		('../dev',			'Device',		lambda x: '%s (%s)' % (devnum_map.get(x, '?'), x)),
> >		('../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'''
> >	global devnum_map
> >	def fmt_cachesize(val):
> >		return '%s\t(%d%%)' % (format_sectors(val), 100.0 * val / cache_sectors)
> >
> >	attrs = [
> >		(None,					'Device',		lambda x: '%s (%s)' % (devnum_map.get(device, '?'), device)),
> >		(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))),
> >		('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 '(Unknown)'),
> >		(None,					'Cache Mode',		lambda x: cache_modes.pop() if len(cache_modes) == 1 else '(Unknown)'),
> >	]
> >
> >	# 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 = {}
> >
> >	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 map_devnum_to_device():
> >	'''Map device numbers to device files.'''
> >	global DEV_BLOCK_PATH
> >	ret = {}
> >
> >	for bdev in os.listdir(DEV_BLOCK_PATH):
> >		ret[bdev] = os.path.realpath('%s%s' % (DEV_BLOCK_PATH, bdev))
> >
> >	return ret
> >
> >def print_help():
> >	print('Usage: %s [OPTIONS]' % sys.argv[0])
> >	print('Options:')
> >	print(' -f	Print the last five minutes of stats.')
> >	print(' -d	Print the last hour of stats.')
> >	print(' -h	Print the last day of stats.')
> >	print(' -t	Print total stats.')
> >	print(' -a	Print all stats.')
> >	print(' -r	Reset stats after printing them.')
> >	print(' -s	Print subdevice status.')
> >	print(' -g	Invoke GC before printing status.')
> >	print('By default, print only the total stats.')
> >
> >def main():
> >	'''Main function'''
> >	global SYSFS_BCACHE_PATH
> >	global uuid_map, devnum_map
> >	stats = set()
> >	reset_stats = False
> >	print_subdevices = False
> >	run_gc = False
> >
> >	for arg in sys.argv[1:]:
> >		if arg == '--help':
> >			print_help()
> >			return 0
> >		elif arg == '-f':
> >			stats.add('five_minute')
> >		elif arg == '-h':
> >			stats.add('hour')
> >		elif arg == '-d':
> >			stats.add('day')
> >		elif arg == '-t':
> >			stats.add('total')
> >		elif arg == '-a':
> >			stats.add('five_minute')
> >			stats.add('hour')
> >			stats.add('day')
> >			stats.add('total')
> >		elif arg == '-r':
> >			reset_stats = True
> >		elif arg == '-s':
> >			print_subdevices = True
> >		elif arg == '-g':
> >			run_gc = True
> >		else:
> >			print_help()
> >			return 0
> >	if len(stats) == 0:
> >		stats.add('total')
> >
> >	uuid_map = map_uuid_to_device()
> >	devnum_map = map_devnum_to_device()
> >	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')
> >
> >SYSFS_BCACHE_PATH = '/sys/fs/bcache/'
> >SYSFS_BLOCK_PATH = '/sys/block/'
> >DEV_BLOCK_PATH = '/dev/block/'
> >if __name__ == '__main__':
> >	main()
> >
> >--
> >To unsubscribe from this list: send the line "unsubscribe linux-bcache" in
> >the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> >More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Hi Darrick,
> 
> 
> A very useful script indeed.
> 
> We made the following changes:
> 
> -    Removed "Device" from under cache-set header
> -    Added "bcache Device" to Backing Device section
> -    Changed "Device" to "Physical Device" in Backing Device section

"Device File"?  There's nothing requiring the inputs to a cache set be
*physical* devices at all.

> -    Removed "Cache Mode" from cache-set header as it set per backing device

I realize that; if all the backing devices have the same cache mode then it'll
print that, otherwise it prints "unknown".  Come to think of it, that really
ought to be "various" or something.


> We will make some more changes in the coming weeks to implement a
> brief display mode as well as a verbose display mode.

Cool, thanks.  I'm glad you can get some use out of it.

--D
> 
> Patch inline:
> 
> --- /usr/local/bin/bcache-status        2013-08-16 11:51:55.281095640 +1200
> +++ bcache-status       2013-08-16 17:00:28.884020997 +1200
> @@ -64,11 +64,16 @@
>  def pretty_size(x):
>          return format_sectors(interpret_sectors(x))
> 
> +def device_path(x):
> +       x="/dev/block/%s" % x
> +       return os.path.abspath(os.path.join(os.path.dirname(x),
> os.readlink(x)))
> +
>  def dump_bdev(bdev_path):
>          '''Dump a backing device stats.'''
>          global MAX_KEY_LENGTH, devnum_map
>          attrs = [
> -                ('../dev',              'Device', lambda x: '%s
> (%s)' % (devnum_map.get(x, '?'), x)),
> +                ('dev/dev',             'bcache Device', device_path),
> +               ('../dev',              'Physical Device', lambda x:
> '%s (%s)' % (devnum_map.get(x, '?'), x)),
>                  ('../size',             'Size', format_sectors),
>                  ('cache_mode',          'Cache Mode', None),
>                  ('readahead',           'Readahead', None),
> @@ -180,7 +185,7 @@
>                  return '%s\t(%d%%)' % (format_sectors(val), 100.0 *
> val / cache_sectors)
> 
>          attrs = [
> -                (None, 'Device',               lambda x: '%s (%s)'
> % (devnum_map.get(device, '?'), device)),
> +                #(None, 'Device',               lambda x: '%s (%s)'
> % (devnum_map.get(device, '?'), device)),
>                  (None, 'UUID',                 lambda x:
> os.path.basename(bcache_sysfs_path)),
>                  ('block_size',                          'Block
> Size',           pretty_size),
>                  ('bucket_size',                         'Bucket
> Size',          pretty_size),
> @@ -268,8 +273,8 @@
>          print('Usage: %s [OPTIONS]' % sys.argv[0])
>          print('Options:')
>          print(' -f      Print the last five minutes of stats.')
> -        print(' -d      Print the last hour of stats.')
> -        print(' -h      Print the last day of stats.')
> +        print(' -h      Print the last hour of stats.')
> +        print(' -d      Print the last day of stats.')
>          print(' -t      Print total stats.')
>          print(' -a      Print all stats.')
>          print(' -r      Reset stats after printing them.')
> 
> 
> Regards,
> 
> 
> 
> 
> 
> 
> 
> Andrew

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found] ` <20130815233508.GB6949-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
  2013-08-16  5:09   ` Andrew Thrift
@ 2013-08-19 11:48   ` Damien Churchill
  1 sibling, 0 replies; 14+ messages in thread
From: Damien Churchill @ 2013-08-19 11:48 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: Kent Overstreet, bcache

Hi,

On 16 August 2013 00:35, Darrick J. Wong <darrick.wong-QHcLZuEGTsvQT0dZR+AlfA@public.gmane.org> wrote:
> Hi all,
>
> I wrote a script to dump out various stats about a bcache.

I've put your script in a gist[0] and modified a few things, all
cosmetic. Switched to use argparse and changed a few conditionals to
be slightly more pythonic.

[0] https://gist.github.com/damoxc/6267899

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found]                             ` <52279DA5.7050505-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
  2013-09-05  6:14                               ` Stefan Priebe - Profihost AG
@ 2013-09-09 22:45                               ` Darrick J. Wong
  1 sibling, 0 replies; 14+ messages in thread
From: Darrick J. Wong @ 2013-09-09 22:45 UTC (permalink / raw)
  To: Rolf Fokkens; +Cc: linux-bcache-u79uwXL29TY76Z2rM5mHXA

On Wed, Sep 04, 2013 at 10:52:53PM +0200, Rolf Fokkens wrote:
> I'm not sure if I understand.
> 
> On 09/04/2013 10:26 PM, Darrick J. Wong wrote:
> >Yeah... I calculate total cache size, then cache-used = cache-size * whatever
> >percentage bcache reports.  It won't add up exactly due to rounding errors.
> >0.999 -> 1.00.  That's rather a lot, really.
> Is the following (snippet of the output I sent) the result of
> rounding errors?
> 
> Total Cache Size            1.00GiB
> Total Cache Used            204.00MiB    (10%)
> Total Cache Unused          1.00GiB    (90%)
> 
> I mean: the percentages are 10% and 90%..

Oops, this was a Py3 v. Py2 issue -- Python3 saw the '%.2f' in the function
that pretty-printed cache sizes and would fp-divide the two integers, whereas
Pyhon2 saw that we were trying to divide two integers and used integer
division. Fixed in the Gist.

Kent: Any chance you'd like to pick up bcache-status into bcache-tools.git?

(Or really, anyone who has commit access to that repo.)

--D
> 
> >>- "Dirty Data" is -6 MB?
> >I think this was fixed in 3.11.
> OK, so that is a kernel issue.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found]                             ` <52279DA5.7050505-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
@ 2013-09-05  6:14                               ` Stefan Priebe - Profihost AG
  2013-09-09 22:45                               ` Darrick J. Wong
  1 sibling, 0 replies; 14+ messages in thread
From: Stefan Priebe - Profihost AG @ 2013-09-05  6:14 UTC (permalink / raw)
  To: Rolf Fokkens
  Cc: Darrick J. Wong, linux-bcache-u79uwXL29TY76Z2rM5mHXA, Kent Overstreet

Am 04.09.2013 22:52, schrieb Rolf Fokkens:
> I'm not sure if I understand.
> 
> On 09/04/2013 10:26 PM, Darrick J. Wong wrote:
>> Yeah... I calculate total cache size, then cache-used = cache-size *
>> whatever
>> percentage bcache reports.  It won't add up exactly due to rounding
>> errors.
>> 0.999 -> 1.00.  That's rather a lot, really.
> Is the following (snippet of the output I sent) the result of rounding
> errors?
> 
> Total Cache Size            1.00GiB
> Total Cache Used            204.00MiB    (10%)
> Total Cache Unused          1.00GiB    (90%)
> 
> I mean: the percentages are 10% and 90%..
> 
>>> - "Dirty Data" is -6 MB?
>> I think this was fixed in 3.11.
> OK, so that is a kernel issue.

Any chance to get this fixed in 3.10 stable kernel too?

Stefan

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found]                         ` <20130904202600.GA4554-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
@ 2013-09-04 20:52                           ` Rolf Fokkens
       [not found]                             ` <52279DA5.7050505-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Rolf Fokkens @ 2013-09-04 20:52 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-bcache-u79uwXL29TY76Z2rM5mHXA

I'm not sure if I understand.

On 09/04/2013 10:26 PM, Darrick J. Wong wrote:
> Yeah... I calculate total cache size, then cache-used = cache-size * whatever
> percentage bcache reports.  It won't add up exactly due to rounding errors.
> 0.999 -> 1.00.  That's rather a lot, really.
Is the following (snippet of the output I sent) the result of rounding 
errors?

Total Cache Size            1.00GiB
Total Cache Used            204.00MiB    (10%)
Total Cache Unused          1.00GiB    (90%)

I mean: the percentages are 10% and 90%..

>> - "Dirty Data" is -6 MB?
> I think this was fixed in 3.11.
OK, so that is a kernel issue.

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found]                     ` <52264AAD.3050401-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
@ 2013-09-04 20:26                       ` Darrick J. Wong
       [not found]                         ` <20130904202600.GA4554-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Darrick J. Wong @ 2013-09-04 20:26 UTC (permalink / raw)
  To: Rolf Fokkens; +Cc: linux-bcache-u79uwXL29TY76Z2rM5mHXA

On Tue, Sep 03, 2013 at 10:46:37PM +0200, Rolf Fokkens wrote:
> Hi,
> 
> bcache-status renders some weird output:
> 
> - "Total Cache Used" and "Total Cache Unused" don't always add up to
> "Total Cache Size"

Yeah... I calculate total cache size, then cache-used = cache-size * whatever
percentage bcache reports.  It won't add up exactly due to rounding errors.
0.999 -> 1.00.  That's rather a lot, really.

> - "Dirty Data" is -6 MB?

I think this was fixed in 3.11.

--D
> 
> Seems like bugs to me. Details below.
> 
> Rolf
> 
> [root@localhost bcache]# bcache-status -s
> --- bcache ---
> UUID c318c0b2-0b69-4f66-a729-23b82a9d0e91
> Block Size                  0.00KiB
> Bucket Size                 512.00KiB
> Congested?                  False
> Read Congestion             2.0ms
> Write Congestion            20.0ms
> Total Cache Size            1.00GiB
> Total Cache Used            20.00MiB    (1%)
> Total Cache Unused          1.00GiB    (99%)
> Dirty Data                  0B    (0%)
> Evictable Cache             1.00GiB    (100%)
> Replacement Policy          [lru] fifo random
> Cache Mode                  [writethrough] writeback writearound none
> Total Hits                  122    (100%)
> Total Misses                0
> Total Bypass Hits           0
> Total Bypass Misses         0
> Total Bypassed              0B
> --- Backing Device ---
>   Device File               /dev/sda3 (8:3)
>   bcache Device File        /dev/bcache1 (252:1)
>   Size                      7.00GiB
>   Cache Mode                [writethrough] writeback writearound none
>   Readahead                 0
>   Sequential Cutoff         4.00MiB
>   Merge sequential?         True
>   State                     clean
>   Writeback?                True
>   Dirty Data                0B
>   Total Hits                122    (100%)
>   Total Misses              0
>   Total Bypass Hits         0
>   Total Bypass Misses       0
>   Total Bypassed            0B
> --- Cache Device ---
>   Device File               /dev/sdb1 (8:17)
>   Size                      1.00GiB
>   Block Size                0.00KiB
>   Bucket Size               512.00KiB
>   Replacement Policy        [lru] fifo random
>   Discard?                  False
>   I/O Errors                0
>   Metadata Written          1.00KiB
>   Data Written              0B
>   Buckets                   4094
>   Cache Used                20.00MiB    (1%)
>   Cache Unused              1.00GiB    (99%)
> --- bcache ---
> UUID d07cd9a1-6211-4bba-bc37-a8ba8858ef4d
> Block Size                  0.00KiB
> Bucket Size                 512.00KiB
> Congested?                  False
> Read Congestion             2.0ms
> Write Congestion            20.0ms
> Total Cache Size            1.00GiB
> Total Cache Used            204.00MiB    (10%)
> Total Cache Unused          1.00GiB    (90%)
> Dirty Data                  0B    (0%)
> Evictable Cache             1.00GiB    (100%)
> Replacement Policy          [lru] fifo random
> Cache Mode                  writethrough [writeback] writearound none
> Total Hits                  1365    (81%)
> Total Misses                318
> Total Bypass Hits           3191    (100%)
> Total Bypass Misses         0
> Total Bypassed              46.00MiB
> --- Backing Device ---
>   Device File               /dev/sdc1 (8:33)
>   bcache Device File        /dev/bcache0 (252:0)
>   Size                      19.00GiB
>   Cache Mode                writethrough [writeback] writearound none
>   Readahead                 0
>   Sequential Cutoff         0B
>   Merge sequential?         True
>   State                     dirty
>   Writeback?                True
>   Dirty Data                -6.00MiB
>   Total Hits                1365    (81%)
>   Total Misses              318
>   Total Bypass Hits         3191    (100%)
>   Total Bypass Misses       0
>   Total Bypassed            46.00MiB
> --- Cache Device ---
>   Device File               /dev/sdd1 (8:49)
>   Size                      1.00GiB
>   Block Size                0.00KiB
>   Bucket Size               512.00KiB
>   Replacement Policy        [lru] fifo random
>   Discard?                  False
>   I/O Errors                0
>   Metadata Written          281.00KiB
>   Data Written              18.00MiB
>   Buckets                   4094
>   Cache Used                204.00MiB    (10%)
>   Cache Unused              1.00GiB    (90%)
> [root@localhost bcache]#
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found]                 ` <20130829004646.GA3099-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
@ 2013-09-03 20:46                   ` Rolf Fokkens
       [not found]                     ` <52264AAD.3050401-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Rolf Fokkens @ 2013-09-03 20:46 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-bcache-u79uwXL29TY76Z2rM5mHXA

Hi,

bcache-status renders some weird output:

- "Total Cache Used" and "Total Cache Unused" don't always add up to 
"Total Cache Size"
- "Dirty Data" is -6 MB?

Seems like bugs to me. Details below.

Rolf

[root@localhost bcache]# bcache-status -s
--- bcache ---
UUID c318c0b2-0b69-4f66-a729-23b82a9d0e91
Block Size                  0.00KiB
Bucket Size                 512.00KiB
Congested?                  False
Read Congestion             2.0ms
Write Congestion            20.0ms
Total Cache Size            1.00GiB
Total Cache Used            20.00MiB    (1%)
Total Cache Unused          1.00GiB    (99%)
Dirty Data                  0B    (0%)
Evictable Cache             1.00GiB    (100%)
Replacement Policy          [lru] fifo random
Cache Mode                  [writethrough] writeback writearound none
Total Hits                  122    (100%)
Total Misses                0
Total Bypass Hits           0
Total Bypass Misses         0
Total Bypassed              0B
--- Backing Device ---
   Device File               /dev/sda3 (8:3)
   bcache Device File        /dev/bcache1 (252:1)
   Size                      7.00GiB
   Cache Mode                [writethrough] writeback writearound none
   Readahead                 0
   Sequential Cutoff         4.00MiB
   Merge sequential?         True
   State                     clean
   Writeback?                True
   Dirty Data                0B
   Total Hits                122    (100%)
   Total Misses              0
   Total Bypass Hits         0
   Total Bypass Misses       0
   Total Bypassed            0B
--- Cache Device ---
   Device File               /dev/sdb1 (8:17)
   Size                      1.00GiB
   Block Size                0.00KiB
   Bucket Size               512.00KiB
   Replacement Policy        [lru] fifo random
   Discard?                  False
   I/O Errors                0
   Metadata Written          1.00KiB
   Data Written              0B
   Buckets                   4094
   Cache Used                20.00MiB    (1%)
   Cache Unused              1.00GiB    (99%)
--- bcache ---
UUID d07cd9a1-6211-4bba-bc37-a8ba8858ef4d
Block Size                  0.00KiB
Bucket Size                 512.00KiB
Congested?                  False
Read Congestion             2.0ms
Write Congestion            20.0ms
Total Cache Size            1.00GiB
Total Cache Used            204.00MiB    (10%)
Total Cache Unused          1.00GiB    (90%)
Dirty Data                  0B    (0%)
Evictable Cache             1.00GiB    (100%)
Replacement Policy          [lru] fifo random
Cache Mode                  writethrough [writeback] writearound none
Total Hits                  1365    (81%)
Total Misses                318
Total Bypass Hits           3191    (100%)
Total Bypass Misses         0
Total Bypassed              46.00MiB
--- Backing Device ---
   Device File               /dev/sdc1 (8:33)
   bcache Device File        /dev/bcache0 (252:0)
   Size                      19.00GiB
   Cache Mode                writethrough [writeback] writearound none
   Readahead                 0
   Sequential Cutoff         0B
   Merge sequential?         True
   State                     dirty
   Writeback?                True
   Dirty Data                -6.00MiB
   Total Hits                1365    (81%)
   Total Misses              318
   Total Bypass Hits         3191    (100%)
   Total Bypass Misses       0
   Total Bypassed            46.00MiB
--- Cache Device ---
   Device File               /dev/sdd1 (8:49)
   Size                      1.00GiB
   Block Size                0.00KiB
   Bucket Size               512.00KiB
   Replacement Policy        [lru] fifo random
   Discard?                  False
   I/O Errors                0
   Metadata Written          281.00KiB
   Data Written              18.00MiB
   Buckets                   4094
   Cache Used                204.00MiB    (10%)
   Cache Unused              1.00GiB    (90%)
[root@localhost bcache]#

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found]             ` <521BBC3B.9010003-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
@ 2013-08-29  0:46               ` Darrick J. Wong
       [not found]                 ` <20130829004646.GA3099-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Darrick J. Wong @ 2013-08-29  0:46 UTC (permalink / raw)
  To: Rolf Fokkens; +Cc: linux-bcache-u79uwXL29TY76Z2rM5mHXA

On Mon, Aug 26, 2013 at 10:36:11PM +0200, Rolf Fokkens wrote:
> On 08/26/2013 06:30 PM, Darrick J. Wong wrote:
> >https://bugzilla.redhat.com/show_bug.cgi?id=999690#c12
> >
> >I have a few questions/remarks:
> >- Is the python3 dependency really needed? I changed it to ordinary
> >python(2) and it runs fine I think.
> >Not required; I'm merely writing new scripts in python3.  (At least when I can
> >find py3 libraries...)  I didn't write anything py3-specific, as far as I know.
> Would you consider putting python in the header instead of python3?
> Having python3 in the heading adds the requirement to install
> python3, and I think python2 is (still) more standard. For Fedora 20
> I think it is anyway, which means I have to patch it everytime I
> want to package it.

Sure.  Go ahead and take the '3' out of hashbang.  (Gist updated.)

--D

> >For now, there's: https://gist.github.com/djwong/6343451 in which I've merged
> >all the changes made by the two people who (thank you both!) provided
> >modifications.
> >
> >Yeah, I fixed that before posting the gist. :) --D
> Thanks, I'll update the package!
> 

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found]         ` <20130826163055.GB4780-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
  2013-08-26 20:36           ` Rolf Fokkens
@ 2013-08-26 23:01           ` Rolf Fokkens
  1 sibling, 0 replies; 14+ messages in thread
From: Rolf Fokkens @ 2013-08-26 23:01 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-bcache-u79uwXL29TY76Z2rM5mHXA

On 08/26/2013 06:30 PM, Darrick J. Wong wrote:
>
> I was hoping someone will (eventually) commit the status tool to
> bcache-tools.git.

Because packaging for Fedora requires it, I created a man page for 
bcache-status:

http://bdsync.rolf-fokkens.nl/bcache-tools-0-0.7.20130820git/bcache-status.8

maybe this helps to get it in the bcache-tools git. Another argument: 
It's a very useful tool, users will like it!

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found]         ` <20130826163055.GB4780-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
@ 2013-08-26 20:36           ` Rolf Fokkens
       [not found]             ` <521BBC3B.9010003-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
  2013-08-26 23:01           ` Rolf Fokkens
  1 sibling, 1 reply; 14+ messages in thread
From: Rolf Fokkens @ 2013-08-26 20:36 UTC (permalink / raw)
  To: Darrick J. Wong; +Cc: linux-bcache-u79uwXL29TY76Z2rM5mHXA

On 08/26/2013 06:30 PM, Darrick J. Wong wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=999690#c12
>
> I have a few questions/remarks:
> - Is the python3 dependency really needed? I changed it to ordinary
> python(2) and it runs fine I think.
> Not required; I'm merely writing new scripts in python3.  (At least when I can
> find py3 libraries...)  I didn't write anything py3-specific, as far as I know.
Would you consider putting python in the header instead of python3? 
Having python3 in the heading adds the requirement to install python3, 
and I think python2 is (still) more standard. For Fedora 20 I think it 
is anyway, which means I have to patch it everytime I want to package it.
> For now, there's: https://gist.github.com/djwong/6343451 in which I've merged
> all the changes made by the two people who (thank you both!) provided
> modifications.
>
> Yeah, I fixed that before posting the gist. :) --D 
Thanks, I'll update the package!

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found]     ` <521A6B92.60001-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
@ 2013-08-26 16:30       ` Darrick J. Wong
       [not found]         ` <20130826163055.GB4780-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Darrick J. Wong @ 2013-08-26 16:30 UTC (permalink / raw)
  To: Rolf Fokkens; +Cc: linux-bcache-u79uwXL29TY76Z2rM5mHXA

On Sun, Aug 25, 2013 at 10:39:46PM +0200, Rolf Fokkens wrote:
> Hi,
> 
> I took the liberty of adding bcache-status to the bcache-tools
> package I'm building:

Yay! :)

> https://bugzilla.redhat.com/show_bug.cgi?id=999690#c12
> 
> I have a few questions/remarks:
> - Is the python3 dependency really needed? I changed it to ordinary
> python(2) and it runs fine I think.

Not required; I'm merely writing new scripts in python3.  (At least when I can
find py3 libraries...)  I didn't write anything py3-specific, as far as I know.

> - Is https://gist.github.com/damoxc/6267899 the proper source?

I was hoping someone will (eventually) commit the status tool to
bcache-tools.git.

For now, there's: https://gist.github.com/djwong/6343451 in which I've merged
all the changes made by the two people who (thank you both!) provided
modifications.

> - When the bcache kernel module is not loaded, the feedback looks buggy:
> [root@home07 ~]# bcache-status
> Traceback (most recent call last):
>   File "/sbin/bcache-status", line 348, in <module>
>     main()
>   File "/sbin/bcache-status", line 333, in main
>     for cache in os.listdir(SYSFS_BCACHE_PATH):
> OSError: [Errno 2] No such file or directory: '/sys/fs/bcache/'
> [root@home07 ~]#

Yeah, I fixed that before posting the gist. :)

--D
> 
> Rolf
> 
> On 08/25/2013 09:07 PM, Rolf Fokkens wrote:
> >To allow Fedora users to benefit from bcache I'm currently
> >packaging bcache-tools for Fedora.
> >
> >See also: https://bugzilla.redhat.com/show_bug.cgi?id=999690
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bcache" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC] bcache-status
       [not found] ` <521A55D4.20908-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
@ 2013-08-25 20:39   ` Rolf Fokkens
       [not found]     ` <521A6B92.60001-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
  0 siblings, 1 reply; 14+ messages in thread
From: Rolf Fokkens @ 2013-08-25 20:39 UTC (permalink / raw)
  To: linux-bcache-u79uwXL29TY76Z2rM5mHXA

Hi,

I took the liberty of adding bcache-status to the bcache-tools package 
I'm building:

https://bugzilla.redhat.com/show_bug.cgi?id=999690#c12

I have a few questions/remarks:
- Is the python3 dependency really needed? I changed it to ordinary 
python(2) and it runs fine I think.
- Is https://gist.github.com/damoxc/6267899 the proper source?
- When the bcache kernel module is not loaded, the feedback looks buggy:
[root@home07 ~]# bcache-status
Traceback (most recent call last):
   File "/sbin/bcache-status", line 348, in <module>
     main()
   File "/sbin/bcache-status", line 333, in main
     for cache in os.listdir(SYSFS_BCACHE_PATH):
OSError: [Errno 2] No such file or directory: '/sys/fs/bcache/'
[root@home07 ~]#

Rolf

On 08/25/2013 09:07 PM, Rolf Fokkens wrote:
> To allow Fedora users to benefit from bcache I'm currently packaging 
> bcache-tools for Fedora.
>
> See also: https://bugzilla.redhat.com/show_bug.cgi?id=999690

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2013-09-09 22:45 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-15 23:35 [RFC] bcache-status Darrick J. Wong
     [not found] ` <20130815233508.GB6949-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
2013-08-16  5:09   ` Andrew Thrift
     [not found]     ` <520DB3EC.70001-3e6jenk95VYpDvLZ8AWkcaVXKuFTiq87@public.gmane.org>
2013-08-16 21:35       ` Darrick J. Wong
2013-08-19 11:48   ` Damien Churchill
2013-08-25 19:07 bcache-tools package for Fedora Rolf Fokkens
     [not found] ` <521A55D4.20908-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
2013-08-25 20:39   ` [RFC] bcache-status Rolf Fokkens
     [not found]     ` <521A6B92.60001-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
2013-08-26 16:30       ` Darrick J. Wong
     [not found]         ` <20130826163055.GB4780-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
2013-08-26 20:36           ` Rolf Fokkens
     [not found]             ` <521BBC3B.9010003-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
2013-08-29  0:46               ` Darrick J. Wong
     [not found]                 ` <20130829004646.GA3099-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
2013-09-03 20:46                   ` Rolf Fokkens
     [not found]                     ` <52264AAD.3050401-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
2013-09-04 20:26                       ` Darrick J. Wong
     [not found]                         ` <20130904202600.GA4554-yuuUpGxbzT9UbpRmUfBrXUB+6BGkLq7r@public.gmane.org>
2013-09-04 20:52                           ` Rolf Fokkens
     [not found]                             ` <52279DA5.7050505-6w2rdlBuEQTpMFipWq+H6g@public.gmane.org>
2013-09-05  6:14                               ` Stefan Priebe - Profihost AG
2013-09-09 22:45                               ` Darrick J. Wong
2013-08-26 23:01           ` Rolf Fokkens

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.