Gentoo Archives: gentoo-commits

From: Sergei Trofimovich <slyfox@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: sys-fs/bcache-tools/files/1.1/, sys-fs/bcache-tools/
Date: Fri, 25 Sep 2020 22:28:33
Message-Id: 1601072903.c1d32d59c7cb7d8ef7351e1c64575ac780e8d1b7.slyfox@gentoo
1 commit: c1d32d59c7cb7d8ef7351e1c64575ac780e8d1b7
2 Author: Alec Moskvin <alecm <AT> gmx <DOT> com>
3 AuthorDate: Sat Sep 12 16:26:11 2020 +0000
4 Commit: Sergei Trofimovich <slyfox <AT> gentoo <DOT> org>
5 CommitDate: Fri Sep 25 22:28:23 2020 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=c1d32d59
7
8 sys-fs/bcache-tools: version bump to 1.1
9
10 Closes: https://bugs.gentoo.org/722002
11 Closes: https://bugs.gentoo.org/656884
12 Signed-off-by: Alec Moskvin <alecm <AT> gmx.com>
13 Closes: https://github.com/gentoo/gentoo/pull/17510
14 Signed-off-by: Sergei Trofimovich <slyfox <AT> gentoo.org>
15
16 sys-fs/bcache-tools/Manifest | 1 +
17 sys-fs/bcache-tools/bcache-tools-1.1.ebuild | 70 ++++
18 .../files/1.1/bcache-tools-add-bcache-status.patch | 381 +++++++++++++++++++++
19 ...bcache-tools-add-man-page-bcache-status.8.patch | 69 ++++
20 4 files changed, 521 insertions(+)
21
22 diff --git a/sys-fs/bcache-tools/Manifest b/sys-fs/bcache-tools/Manifest
23 index 7e092b1fd8f..030990051d5 100644
24 --- a/sys-fs/bcache-tools/Manifest
25 +++ b/sys-fs/bcache-tools/Manifest
26 @@ -1,2 +1,3 @@
27 DIST bcache-status-20140220.tar.gz 3779 BLAKE2B a3fa5e9d87b2c51f1f5178693db6d9f8b4bde31c77783d1ebd9de6e81995d89a4b07df43178cba384757b212087c474a0508640d1d3ddcd97d3d928643971e4a SHA512 0c8db02dc865b469f3a5964f679a3bfdf5cdbf5a2f6ccd5d81544f3bb3c06df2f5d06b9f09aaec527ec90229740dcd31fbb33e2628721b6da139cfcee6b48d7c
28 DIST bcache-tools-1.0.8_p20140220.tgz 22153 BLAKE2B d40a64b02e0d66ef8868151870715f6e6ab54633e4875c32d0e03dfe1871e5aa98d7e133b9eed583ac4898b1598f38b71e47109210009ca51c4dfe9dbd31768c SHA512 21eaed457e5de623089c0d4e1c11394a3950f29c749c502bfd5dd94d3dcdc7379c4a910825e33bf9fc8080df656949b94a1a28d19048a8eb6422976cb391b7dc
29 +DIST bcache-tools-1.1.tar.gz 34548 BLAKE2B e6ebc0f609debe0cc123deba0e21076441c37cdbc6edd02bf2c16c0e36fe806f1fc160b9e9baed577f86f6358884182a4e3903f34bccee81943191c0ba6a2d11 SHA512 4ccbef47255bf3644a50242a79951b1f3720e71a55eb1e07dc6b8486df0245da99a77bba751b50197d489b4c5d738e5284aabc014c2f7f44816ddf6a1bb807ca
30
31 diff --git a/sys-fs/bcache-tools/bcache-tools-1.1.ebuild b/sys-fs/bcache-tools/bcache-tools-1.1.ebuild
32 new file mode 100644
33 index 00000000000..38d4ef379bf
34 --- /dev/null
35 +++ b/sys-fs/bcache-tools/bcache-tools-1.1.ebuild
36 @@ -0,0 +1,70 @@
37 +# Copyright 1999-2020 Gentoo Authors
38 +# Distributed under the terms of the GNU General Public License v2
39 +
40 +EAPI=7
41 +
42 +PYTHON_COMPAT=( python3_{6,7,8,9} )
43 +
44 +inherit flag-o-matic python-r1 toolchain-funcs udev
45 +
46 +DESCRIPTION="Tools for bcache"
47 +HOMEPAGE="https://bcache.evilpiepirate.org/"
48 +SRC_URI="https://git.kernel.org/pub/scm/linux/kernel/git/colyli/${PN}.git/snapshot/${P}.tar.gz"
49 +
50 +SLOT="0"
51 +LICENSE="GPL-2"
52 +KEYWORDS="~amd64 ~x86 ~amd64-linux ~x86-linux"
53 +IUSE=""
54 +
55 +REQUIRED_USE="${PYTHON_REQUIRED_USE}"
56 +
57 +RDEPEND="${PYTHON_DEPS}
58 + sys-apps/util-linux"
59 +DEPEND="${RDEPEND}"
60 +
61 +PATCHES=(
62 + "${FILESDIR}"/1.0.8_p20140220/bcache-tools-1.0.8-noprobe.patch
63 + "${FILESDIR}"/${PV}/bcache-tools-add-bcache-status.patch
64 + "${FILESDIR}"/${PV}/bcache-tools-add-man-page-bcache-status.8.patch
65 +)
66 +
67 +src_prepare() {
68 + eapply_user
69 +
70 + tc-export CC
71 + sed \
72 + -e '/^CFLAGS/s:-O2::' \
73 + -e '/^CFLAGS/s:-g::' \
74 + -i Makefile || die
75 +
76 + append-lfs-flags
77 +
78 + eapply "${PATCHES[@]}"
79 +}
80 +
81 +src_install() {
82 + into /
83 + dosbin bcache make-bcache bcache-super-show
84 +
85 + exeinto $(get_udevdir)
86 + doexe bcache-register probe-bcache
87 +
88 + python_foreach_impl python_doscript bcache-status
89 +
90 + udev_dorules 69-bcache.rules
91 +
92 + insinto /etc/initramfs-tools/hooks/bcache
93 + doins initramfs/hook
94 +
95 + # that is what dracut does
96 + insinto /usr/lib/dracut/modules.d/90bcache
97 + doins dracut/module-setup.sh
98 +
99 + doman *.8
100 +
101 + dodoc README
102 +}
103 +
104 +pkg_postinst() {
105 + udev_reload
106 +}
107
108 diff --git a/sys-fs/bcache-tools/files/1.1/bcache-tools-add-bcache-status.patch b/sys-fs/bcache-tools/files/1.1/bcache-tools-add-bcache-status.patch
109 new file mode 100644
110 index 00000000000..bd58d0a309d
111 --- /dev/null
112 +++ b/sys-fs/bcache-tools/files/1.1/bcache-tools-add-bcache-status.patch
113 @@ -0,0 +1,381 @@
114 +From 10824170800268e91508e2edc6ed745f40370f0a Mon Sep 17 00:00:00 2001
115 +From: Coly Li <colyli@××××.de>
116 +Date: Wed, 2 Sep 2020 19:27:08 +0800
117 +Subject: [PATCH 1/2] bcache-tools: add bcache-status
118 +
119 +People request to include bcache-status into bcache-tools package. This
120 +patch picks bcache-status script from github page of the orginal author
121 +Darrick J. Wong,
122 + https://github.com/djwong/bcache-tools/blob/master/bcache-status
123 +
124 +Thanks to Darrick for writing the great bcache-status, and I will keep
125 +this script being updated from Darrick's repo time to time.
126 +
127 +Signed-off-by: Coly Li <colyli@××××.de>
128 +Cc: Darrick J. Wong <darrick.wong@××××××.com>
129 +---
130 + bcache-status | 352 ++++++++++++++++++++++++++++++++++++++++++++++++++
131 + 1 file changed, 352 insertions(+)
132 + create mode 100755 bcache-status
133 +
134 +diff --git a/bcache-status b/bcache-status
135 +new file mode 100755
136 +index 0000000..ac5a22f
137 +--- /dev/null
138 ++++ b/bcache-status
139 +@@ -0,0 +1,352 @@
140 ++#!/usr/bin/env python
141 ++#
142 ++# Dumb script to dump (some) of bcache status
143 ++# Copyright 2014 Darrick J. Wong. All rights reserved.
144 ++#
145 ++# This file is part of Bcache. Bcache is free software: you can
146 ++# redistribute it and/or modify it under the terms of the GNU General Public
147 ++# License as published by the Free Software Foundation, version 2.
148 ++#
149 ++# This program is distributed in the hope that it will be useful, but WITHOUT
150 ++# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
151 ++# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
152 ++# details.
153 ++#
154 ++# You should have received a copy of the GNU General Public License along with
155 ++# this program; if not, write to the Free Software Foundation, Inc., 51
156 ++# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
157 ++#
158 ++
159 ++import os
160 ++import sys
161 ++import argparse
162 ++
163 ++MAX_KEY_LENGTH = 28
164 ++DEV_BLOCK_PATH = '/dev/block/'
165 ++SYSFS_BCACHE_PATH = '/sys/fs/bcache/'
166 ++SYSFS_BLOCK_PATH = '/sys/block/'
167 ++
168 ++def file_to_lines(fname):
169 ++ try:
170 ++ with open(fname, "r") as fd:
171 ++ return fd.readlines()
172 ++ except:
173 ++ return []
174 ++
175 ++def file_to_line(fname):
176 ++ ret = file_to_lines(fname)
177 ++ if ret:
178 ++ return ret[0].strip()
179 ++ return ''
180 ++
181 ++def str_to_bool(x):
182 ++ return x == '1'
183 ++
184 ++def format_sectors(x):
185 ++ '''Pretty print a sector count.'''
186 ++ sectors = float(x)
187 ++ asectors = abs(sectors)
188 ++
189 ++ if asectors < 2:
190 ++ return '%d B' % (sectors * 512)
191 ++ elif asectors < 2048:
192 ++ return '%.2f KiB' % (sectors / 2)
193 ++ elif asectors < 2097152:
194 ++ return '%.1f MiB' % (sectors / 2048)
195 ++ elif asectors < 2147483648:
196 ++ return '%.0f GiB' % (sectors / 2097152)
197 ++ else:
198 ++ return '%.0f TiB' % (sectors / 2147483648)
199 ++
200 ++def interpret_sectors(x):
201 ++ '''Interpret a pretty-printed disk size.'''
202 ++ factors = {
203 ++ 'k': 1 << 10,
204 ++ 'M': 1 << 20,
205 ++ 'G': 1 << 30,
206 ++ 'T': 1 << 40,
207 ++ 'P': 1 << 50,
208 ++ 'E': 1 << 60,
209 ++ 'Z': 1 << 70,
210 ++ 'Y': 1 << 80,
211 ++ }
212 ++
213 ++ factor = 1
214 ++ if x[-1] in factors:
215 ++ factor = factors[x[-1]]
216 ++ x = x[:-1]
217 ++ return int(float(x) * factor / 512)
218 ++
219 ++def pretty_size(x):
220 ++ return format_sectors(interpret_sectors(x))
221 ++
222 ++def device_path(x):
223 ++ if not os.path.isdir(DEV_BLOCK_PATH):
224 ++ return '?'
225 ++ x = '%s/%s' % (DEV_BLOCK_PATH, x)
226 ++ return os.path.abspath(os.path.join(os.path.dirname(x), os.readlink(x)))
227 ++
228 ++def str_device_path(x):
229 ++ return '%s (%s)' % (device_path(x), x)
230 ++
231 ++def dump_bdev(bdev_path):
232 ++ '''Dump a backing device stats.'''
233 ++ global MAX_KEY_LENGTH
234 ++ attrs = [
235 ++ ('../dev', 'Device File', str_device_path),
236 ++ ('dev/dev', 'bcache Device File', str_device_path),
237 ++ ('../size', 'Size', format_sectors),
238 ++ ('cache_mode', 'Cache Mode', None),
239 ++ ('readahead', 'Readahead', None),
240 ++ ('sequential_cutoff', 'Sequential Cutoff', pretty_size),
241 ++ ('sequential_merge', 'Merge sequential?', str_to_bool),
242 ++ ('state', 'State', None),
243 ++ ('writeback_running', 'Writeback?', str_to_bool),
244 ++ ('dirty_data', 'Dirty Data', pretty_size),
245 ++ ('writeback_rate', 'Writeback Rate', lambda x: '%s/s' % x),
246 ++ ('writeback_percent', 'Dirty Target', lambda x: '%s%%' % x),
247 ++ ]
248 ++
249 ++ print('--- Backing Device ---')
250 ++ for (sysfs_name, display_name, conversion_func) in attrs:
251 ++ val = file_to_line('%s/%s' % (bdev_path, sysfs_name))
252 ++ if conversion_func is not None:
253 ++ val = conversion_func(val)
254 ++ if display_name is None:
255 ++ display_name = sysfs_name
256 ++ print(' %-*s%s' % (MAX_KEY_LENGTH - 2, display_name, val))
257 ++
258 ++def dump_cachedev(cachedev_path):
259 ++ '''Dump a cachding device stats.'''
260 ++ def fmt_cachesize(val):
261 ++ return '%s\t(%.0f%%)' % (format_sectors(val), float(val) / cache_size * 100)
262 ++
263 ++ global MAX_KEY_LENGTH
264 ++ attrs = [
265 ++ ('../dev', 'Device File', str_device_path),
266 ++ ('../size', 'Size', format_sectors),
267 ++ ('block_size', 'Block Size', pretty_size),
268 ++ ('bucket_size', 'Bucket Size', pretty_size),
269 ++ ('cache_replacement_policy', 'Replacement Policy', None),
270 ++ ('discard', 'Discard?', str_to_bool),
271 ++ ('io_errors', 'I/O Errors', None),
272 ++ ('metadata_written', 'Metadata Written', pretty_size),
273 ++ ('written', 'Data Written', pretty_size),
274 ++ ('nbuckets', 'Buckets', None),
275 ++ (None, 'Cache Used', lambda x: fmt_cachesize(used_sectors)),
276 ++ (None, 'Cache Unused', lambda x: fmt_cachesize(unused_sectors)),
277 ++ ]
278 ++
279 ++ stats = get_cache_priority_stats(cachedev_path)
280 ++ cache_size = int(file_to_line('%s/../size' % cachedev_path))
281 ++ unused_sectors = float(stats['Unused'][:-1]) * cache_size / 100
282 ++ used_sectors = cache_size - unused_sectors
283 ++
284 ++ print('--- Cache Device ---')
285 ++ for (sysfs_name, display_name, conversion_func) in attrs:
286 ++ if sysfs_name is not None:
287 ++ val = file_to_line('%s/%s' % (cachedev_path, sysfs_name))
288 ++ if conversion_func is not None:
289 ++ val = conversion_func(val)
290 ++ if display_name is None:
291 ++ display_name = sysfs_name
292 ++ print(' %-*s%s' % (MAX_KEY_LENGTH - 2, display_name, val))
293 ++
294 ++def hits_to_str(hits_str, misses_str):
295 ++ '''Render a hits/misses ratio as a string.'''
296 ++ hits = int(hits_str)
297 ++ misses = int(misses_str)
298 ++
299 ++ ret = '%d' % hits
300 ++ if hits + misses != 0:
301 ++ ret = '%s\t(%.d%%)' % (ret, 100 * hits / (hits + misses))
302 ++ return ret
303 ++
304 ++def dump_stats(sysfs_path, indent_str, stats):
305 ++ '''Dump stats on a bcache device.'''
306 ++ stat_types = [
307 ++ ('five_minute', 'Last 5min'),
308 ++ ('hour', 'Last Hour'),
309 ++ ('day', 'Last Day'),
310 ++ ('total', 'Total'),
311 ++ ]
312 ++ attrs = ['bypassed', 'cache_bypass_hits', 'cache_bypass_misses', 'cache_hits', 'cache_misses']
313 ++ display = [
314 ++ ('Hits', lambda: hits_to_str(stat_data['cache_hits'], stat_data['cache_misses'])),
315 ++ ('Misses', lambda: stat_data['cache_misses']),
316 ++ ('Bypass Hits', lambda: hits_to_str(stat_data['cache_bypass_hits'], stat_data['cache_bypass_misses'])),
317 ++ ('Bypass Misses', lambda: stat_data['cache_bypass_misses']),
318 ++ ('Bypassed', lambda: pretty_size(stat_data['bypassed'])),
319 ++ ]
320 ++
321 ++ for (sysfs_name, stat_display_name) in stat_types:
322 ++ if len(stats) > 0 and sysfs_name not in stats:
323 ++ continue
324 ++ stat_data = {}
325 ++ for attr in attrs:
326 ++ val = file_to_line('%s/stats_%s/%s' % (sysfs_path, sysfs_name, attr))
327 ++ stat_data[attr] = val
328 ++ for (display_name, str_func) in display:
329 ++ d = '%s%s %s' % (indent_str, stat_display_name, display_name)
330 ++ print('%-*s%s' % (MAX_KEY_LENGTH, d, str_func()))
331 ++
332 ++def get_cache_priority_stats(cache):
333 ++ '''Retrieve priority stats from a cache.'''
334 ++ attrs = {}
335 ++
336 ++ for line in file_to_lines('%s/priority_stats' % cache):
337 ++ x = line.split()
338 ++ key = x[0]
339 ++ value = x[1]
340 ++ attrs[key[:-1]] = value
341 ++ return attrs
342 ++
343 ++def dump_bcache(bcache_sysfs_path, stats, print_subdevices, device):
344 ++ '''Dump bcache stats'''
345 ++ def fmt_cachesize(val):
346 ++ return '%s\t(%.0f%%)' % (format_sectors(val), 100.0 * val / cache_sectors)
347 ++
348 ++ attrs = [
349 ++ (None, 'UUID', lambda x: os.path.basename(bcache_sysfs_path)),
350 ++ ('block_size', 'Block Size', pretty_size),
351 ++ ('bucket_size', 'Bucket Size', pretty_size),
352 ++ ('congested', 'Congested?', str_to_bool),
353 ++ ('congested_read_threshold_us', 'Read Congestion', lambda x: '%.1fms' % (int(x) / 1000)),
354 ++ ('congested_write_threshold_us', 'Write Congestion', lambda x: '%.1fms' % (int(x) / 1000)),
355 ++ (None, 'Total Cache Size', lambda x: format_sectors(cache_sectors)),
356 ++ (None, 'Total Cache Used', lambda x: fmt_cachesize(cache_used_sectors)),
357 ++ (None, 'Total Cache Unused', lambda x: fmt_cachesize(cache_unused_sectors)),
358 ++ #('dirty_data', 'Dirty Data', lambda x: fmt_cachesize(interpret_sectors(x))), # disappeared in 3.13?
359 ++ ('cache_available_percent', 'Evictable Cache', lambda x: '%s\t(%s%%)' % (format_sectors(float(x) * cache_sectors / 100), x)),
360 ++ (None, 'Replacement Policy', lambda x: replacement_policies.pop() if len(replacement_policies) == 1 else '(Various)'),
361 ++ (None, 'Cache Mode', lambda x: cache_modes.pop() if len(cache_modes) == 1 else '(Various)'),
362 ++ ]
363 ++
364 ++ # Calculate aggregate data
365 ++ cache_sectors = 0
366 ++ cache_unused_sectors = 0
367 ++ cache_modes = set()
368 ++ replacement_policies = set()
369 ++ for obj in os.listdir(bcache_sysfs_path):
370 ++ if not os.path.isdir('%s/%s' % (bcache_sysfs_path, obj)):
371 ++ continue
372 ++ if obj.startswith('cache'):
373 ++ cache_size = int(file_to_line('%s/%s/../size' % (bcache_sysfs_path, obj)))
374 ++ cache_sectors += cache_size
375 ++ cstats = get_cache_priority_stats('%s/%s' % (bcache_sysfs_path, obj))
376 ++ unused_size = float(cstats['Unused'][:-1]) * cache_size / 100
377 ++ cache_unused_sectors += unused_size
378 ++ replacement_policies.add(file_to_line('%s/%s/cache_replacement_policy' % (bcache_sysfs_path, obj)))
379 ++ elif obj.startswith('bdev'):
380 ++ cache_modes.add(file_to_line('%s/%s/cache_mode' % (bcache_sysfs_path, obj)))
381 ++ cache_used_sectors = cache_sectors - cache_unused_sectors
382 ++
383 ++ # Dump basic stats
384 ++ print("--- bcache ---")
385 ++ for (sysfs_name, display_name, conversion_func) in attrs:
386 ++ if sysfs_name is not None:
387 ++ val = file_to_line('%s/%s' % (bcache_sysfs_path, sysfs_name))
388 ++ else:
389 ++ val = None
390 ++ if conversion_func is not None:
391 ++ val = conversion_func(val)
392 ++ if display_name is None:
393 ++ display_name = sysfs_name
394 ++ print('%-*s%s' % (MAX_KEY_LENGTH, display_name, val))
395 ++ dump_stats(bcache_sysfs_path, '', stats)
396 ++
397 ++ # Dump sub-device stats
398 ++ if not print_subdevices:
399 ++ return
400 ++ for obj in os.listdir(bcache_sysfs_path):
401 ++ if not os.path.isdir('%s/%s' % (bcache_sysfs_path, obj)):
402 ++ continue
403 ++ if obj.startswith('bdev'):
404 ++ dump_bdev('%s/%s' % (bcache_sysfs_path, obj))
405 ++ dump_stats('%s/%s' % (bcache_sysfs_path, obj), ' ', stats)
406 ++ elif obj.startswith('cache'):
407 ++ dump_cachedev('%s/%s' % (bcache_sysfs_path, obj))
408 ++
409 ++def map_uuid_to_device():
410 ++ '''Map bcache UUIDs to device files.'''
411 ++ global SYSFS_BLOCK_PATH
412 ++ ret = {}
413 ++
414 ++ if not os.path.isdir(SYSFS_BLOCK_PATH):
415 ++ return ret
416 ++ for bdev in os.listdir(SYSFS_BLOCK_PATH):
417 ++ link = '%s%s/bcache/cache' % (SYSFS_BLOCK_PATH, bdev)
418 ++ if not os.path.islink(link):
419 ++ continue
420 ++ basename = os.path.basename(os.readlink(link))
421 ++ ret[basename] = file_to_line('%s%s/dev' % (SYSFS_BLOCK_PATH, bdev))
422 ++ return ret
423 ++
424 ++def main():
425 ++ '''Main function'''
426 ++ global SYSFS_BCACHE_PATH
427 ++ global uuid_map
428 ++ stats = set()
429 ++ reset_stats = False
430 ++ print_subdevices = False
431 ++ run_gc = False
432 ++
433 ++ parser = argparse.ArgumentParser(add_help=False)
434 ++ parser.add_argument('--help', help='Show this help message and exit', action='store_true')
435 ++ parser.add_argument('-f', '--five-minute', help='Print the last five minutes of stats.', action='store_true')
436 ++ parser.add_argument('-h', '--hour', help='Print the last hour of stats.', action='store_true')
437 ++ parser.add_argument('-d', '--day', help='Print the last day of stats.', action='store_true')
438 ++ parser.add_argument('-t', '--total', help='Print total stats.', action='store_true')
439 ++ parser.add_argument('-a', '--all', help='Print all stats.', action='store_true')
440 ++ parser.add_argument('-r', '--reset-stats', help='Reset stats after printing them.', action='store_true')
441 ++ parser.add_argument('-s', '--sub-status', help='Print subdevice status.', action='store_true')
442 ++ parser.add_argument('-g', '--gc', help='Invoke GC before printing status.', action='store_true')
443 ++ args = parser.parse_args()
444 ++
445 ++ if args.help:
446 ++ parser.print_help()
447 ++ return 0
448 ++
449 ++ if args.five_minute:
450 ++ stats.add('five_minute')
451 ++ if args.hour:
452 ++ stats.add('hour')
453 ++ if args.day:
454 ++ stats.add('day')
455 ++ if args.total:
456 ++ stats.add('total')
457 ++ if args.all:
458 ++ stats.add('five_minute')
459 ++ stats.add('hour')
460 ++ stats.add('day')
461 ++ stats.add('total')
462 ++ if args.reset_stats:
463 ++ reset_stats = True
464 ++ if args.sub_status:
465 ++ print_subdevices = True
466 ++ if args.gc:
467 ++ run_gc = True
468 ++
469 ++ if not stats:
470 ++ stats.add('total')
471 ++
472 ++ uuid_map = map_uuid_to_device()
473 ++ if not os.path.isdir(SYSFS_BCACHE_PATH):
474 ++ print('bcache is not loaded.')
475 ++ return
476 ++ for cache in os.listdir(SYSFS_BCACHE_PATH):
477 ++ if not os.path.isdir('%s%s' % (SYSFS_BCACHE_PATH, cache)):
478 ++ continue
479 ++
480 ++ if run_gc:
481 ++ with open('%s%s/internal/trigger_gc' % (SYSFS_BCACHE_PATH, cache), 'w') as fd:
482 ++ fd.write('1\n')
483 ++
484 ++ dump_bcache('%s%s' % (SYSFS_BCACHE_PATH, cache), stats, print_subdevices, uuid_map.get(cache, '?'))
485 ++
486 ++ if reset_stats:
487 ++ with open('%s%s/clear_stats' % (SYSFS_BCACHE_PATH, cache), 'w') as fd:
488 ++ fd.write('1\n')
489 ++
490 ++if __name__ == '__main__':
491 ++ main()
492 +--
493 +2.28.0
494 +
495
496 diff --git a/sys-fs/bcache-tools/files/1.1/bcache-tools-add-man-page-bcache-status.8.patch b/sys-fs/bcache-tools/files/1.1/bcache-tools-add-man-page-bcache-status.8.patch
497 new file mode 100644
498 index 00000000000..cd999a994a1
499 --- /dev/null
500 +++ b/sys-fs/bcache-tools/files/1.1/bcache-tools-add-man-page-bcache-status.8.patch
501 @@ -0,0 +1,69 @@
502 +From 91fd5fb518ae535e36cff1ae188d1bcef874cf40 Mon Sep 17 00:00:00 2001
503 +From: Coly Li <colyli@××××.de>
504 +Date: Wed, 2 Sep 2020 20:09:06 +0800
505 +Subject: [PATCH 2/2] bcache-tools: add man page bcache-status.8
506 +
507 +Add the initial man page for bcache-status.
508 +
509 +Signed-off-by: Coly Li <colyli@××××.de>
510 +---
511 + bcache-status.8 | 47 +++++++++++++++++++++++++++++++++++++++++++++++
512 + 1 file changed, 47 insertions(+)
513 + create mode 100644 bcache-status.8
514 +
515 +diff --git a/bcache-status.8 b/bcache-status.8
516 +new file mode 100644
517 +index 0000000..f56cfb6
518 +--- /dev/null
519 ++++ b/bcache-status.8
520 +@@ -0,0 +1,47 @@
521 ++.TH bcache-status 8
522 ++.SH NAME
523 ++bcache-status \- Display useful bcache statistics
524 ++
525 ++.SH SYNOPSIS
526 ++.B bcache-status [ --help ] [ -f ] [ -h ] [ -d ] [ -t ] [ -a ] [ -r ] [ -s ] [ -g ]
527 ++
528 ++.SH DESCRIPTION
529 ++This command displays useful bcache statistics in a convenient way.
530 ++
531 ++.SH OPTIONS
532 ++
533 ++.TP
534 ++.BR \-\-help
535 ++Print help message and exit.
536 ++
537 ++.TP
538 ++.BR \-f ", " \-\-five\-minute
539 ++Print the last five minutes of stats.
540 ++
541 ++.TP
542 ++.BR \-h ", " \-\-hour
543 ++Print the last hour of stats.
544 ++
545 ++.TP
546 ++.BR \-d ", " \-\-day
547 ++Print the last day of stats.
548 ++
549 ++.TP
550 ++.BR \-t ", " \-\-total
551 ++Print total stats.
552 ++
553 ++.TP
554 ++.BR \-a ", " \-\-all
555 ++Print all stats.
556 ++
557 ++.TP
558 ++.BR \-r ", " \-\-reset\-stats
559 ++Reset stats after printing them.
560 ++
561 ++.TP
562 ++.BR \-s ", " \-\-sub\-status
563 ++Print subdevice status.
564 ++
565 ++.TP
566 ++.BR \-g ", " \-\-gc
567 ++Invoke GC before printing status (root only).
568 +--
569 +2.28.0
570 +