Detect the kernel.task_delayacct sysctl value
This commit is contained in:
parent
0c65050be4
commit
cf8dbec64b
89
0014-Hide-UI-elements-on-smaller-terminals.patch
Normal file
89
0014-Hide-UI-elements-on-smaller-terminals.patch
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
From 16a30ece6ab4eaa9ca5d056ada94673265195e27 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Wise <pabs3@bonedaddy.net>
|
||||||
|
Date: Thu, 4 Aug 2016 18:00:29 +0800
|
||||||
|
Subject: [PATCH] Hide UI elements on smaller terminals
|
||||||
|
|
||||||
|
This helps usability on smaller terminals.
|
||||||
|
|
||||||
|
Hide the status bar first, then the summary and then the titles,
|
||||||
|
since that is the approximate order of usefulness.
|
||||||
|
|
||||||
|
Conflict: Adapt patch Context
|
||||||
|
Reference: https://repo.or.cz/iotop.git/commit/16a30ece6ab4eaa9ca5d056ada94673265195e27
|
||||||
|
---
|
||||||
|
iotop/ui.py | 39 +++++++++++++++++++++++++++------------
|
||||||
|
1 file changed, 27 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/iotop/ui.py b/iotop/ui.py
|
||||||
|
index abd6b79..b2ac8fb 100644
|
||||||
|
--- a/iotop/ui.py
|
||||||
|
+++ b/iotop/ui.py
|
||||||
|
@@ -410,8 +410,6 @@ class IOTopUI(object):
|
||||||
|
stats_lambda = lambda p: p.stats_delta
|
||||||
|
processes.sort(key=lambda p: key(p, stats_lambda(p)),
|
||||||
|
reverse=self.sorting_reverse)
|
||||||
|
- if not self.options.batch:
|
||||||
|
- del processes[self.height - 2:]
|
||||||
|
return list(map(format, processes))
|
||||||
|
|
||||||
|
def refresh_display(self, first_time, total, actual, duration):
|
||||||
|
@@ -448,10 +446,33 @@ class IOTopUI(object):
|
||||||
|
sys.stdout.flush()
|
||||||
|
else:
|
||||||
|
self.win.erase()
|
||||||
|
+
|
||||||
|
+ if Stats.has_blkio_delay_total:
|
||||||
|
+ status_msg = None
|
||||||
|
+ else:
|
||||||
|
+ status_msg = ('CONFIG_TASK_DELAY_ACCT not enabled in kernel, '
|
||||||
|
+ 'cannot determine SWAPIN and IO %')
|
||||||
|
+
|
||||||
|
+ len_summary = len(summary)
|
||||||
|
+ len_titles = int(bool(titles))
|
||||||
|
+ len_status_msg = int(bool(status_msg))
|
||||||
|
+ max_lines = self.height - len_summary - len_titles - len_status_msg
|
||||||
|
+ if max_lines < 5:
|
||||||
|
+ titles = []
|
||||||
|
+ len_titles = 0
|
||||||
|
+ if max_lines < 6:
|
||||||
|
+ summary = []
|
||||||
|
+ len_summary = 0
|
||||||
|
+ if max_lines < 7:
|
||||||
|
+ status_msg = None
|
||||||
|
+ len_status_msg = 0
|
||||||
|
+ max_lines = self.height - len_summary - len_titles - len_status_msg
|
||||||
|
+ num_lines = min(len(lines), max_lines)
|
||||||
|
+
|
||||||
|
for i, s in enumerate(summary):
|
||||||
|
self.win.addstr(i, 0, s[:self.width])
|
||||||
|
- self.win.hline(len(summary), 0, ord(' ') | curses.A_REVERSE,
|
||||||
|
- self.width)
|
||||||
|
+ if titles:
|
||||||
|
+ self.win.hline(len_summary, 0, ord(' ') | curses.A_REVERSE, self.width)
|
||||||
|
pos = 0
|
||||||
|
remaining_cols = self.width
|
||||||
|
for i in range(len(titles)):
|
||||||
|
@@ -464,18 +485,12 @@ class IOTopUI(object):
|
||||||
|
title += self.sorting_reverse and '>' or '<'
|
||||||
|
title = title[:remaining_cols]
|
||||||
|
remaining_cols -= len(title)
|
||||||
|
- self.win.addstr(len(summary), pos, title, attr)
|
||||||
|
+ self.win.addstr(len_summary, pos, title, attr)
|
||||||
|
pos += len(title)
|
||||||
|
- if Stats.has_blkio_delay_total:
|
||||||
|
- status_msg = None
|
||||||
|
- else:
|
||||||
|
- status_msg = ('CONFIG_TASK_DELAY_ACCT not enabled in kernel, '
|
||||||
|
- 'cannot determine SWAPIN and IO %')
|
||||||
|
- num_lines = min(len(lines), self.height - 2 - int(bool(status_msg)))
|
||||||
|
for i in range(num_lines):
|
||||||
|
try:
|
||||||
|
def print_line(line):
|
||||||
|
- self.win.addstr(i + len(summary) + 1, 0, line)
|
||||||
|
+ self.win.addstr(i + len_summary + len_titles, 0, line)
|
||||||
|
try:
|
||||||
|
print_line(lines[i])
|
||||||
|
except UnicodeEncodeError:
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
From 529a74a28be43c04840d937c87a5ee3b81133852 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Wise <pabs3@bonedaddy.net>
|
||||||
|
Date: Thu, 4 Aug 2016 18:24:46 +0800
|
||||||
|
Subject: [PATCH] Check the column title is not empty before using it
|
||||||
|
|
||||||
|
Fixes crash with terminals that don't fit all titles.
|
||||||
|
|
||||||
|
Traceback (most recent call last):
|
||||||
|
File "./iotop.py", line 12, in <module>
|
||||||
|
main()
|
||||||
|
File "./iotop/ui.py", line 669, in main
|
||||||
|
main_loop()
|
||||||
|
File "./iotop/ui.py", line 659, in <lambda>
|
||||||
|
main_loop = lambda: run_iotop(options)
|
||||||
|
File "./iotop/ui.py", line 554, in run_iotop
|
||||||
|
return curses.wrapper(run_iotop_window, options)
|
||||||
|
File "/usr/lib/python3.5/curses/__init__.py", line 94, in wrapper
|
||||||
|
return func(stdscr, *args, **kwds)
|
||||||
|
File "./iotop/ui.py", line 546, in run_iotop_window
|
||||||
|
ui.run()
|
||||||
|
File "./iotop/ui.py", line 176, in run
|
||||||
|
self.process_list.duration)
|
||||||
|
File "./iotop/ui.py", line 515, in refresh_display
|
||||||
|
self.win.addstr(len_summary, pos, title, attr)
|
||||||
|
_curses.error: addwstr() returned ERR
|
||||||
|
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://repo.or.cz/iotop.git/commit/529a74a28be43c04840d937c87a5ee3b81133852
|
||||||
|
---
|
||||||
|
iotop/ui.py | 3 ++-
|
||||||
|
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/iotop/ui.py b/iotop/ui.py
|
||||||
|
index 30efa73..a957bdd 100644
|
||||||
|
--- a/iotop/ui.py
|
||||||
|
+++ b/iotop/ui.py
|
||||||
|
@@ -511,7 +511,8 @@ class IOTopUI(object):
|
||||||
|
title += self.sorting_reverse and '>' or '<'
|
||||||
|
title = title[:remaining_cols]
|
||||||
|
remaining_cols -= len(title)
|
||||||
|
- self.win.addstr(len_summary, pos, title, attr)
|
||||||
|
+ if title:
|
||||||
|
+ self.win.addstr(len_summary, pos, title, attr)
|
||||||
|
pos += len(title)
|
||||||
|
for i in range(num_lines):
|
||||||
|
try:
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
151
0016-Add-a-footer-listing-keyboard-shortcuts.patch
Normal file
151
0016-Add-a-footer-listing-keyboard-shortcuts.patch
Normal file
@ -0,0 +1,151 @@
|
|||||||
|
From 877679bf74d1c84040f00eec2a42e2ace056e45e Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Wise <pabs3@bonedaddy.net>
|
||||||
|
Date: Thu, 4 Aug 2016 18:53:37 +0800
|
||||||
|
Subject: [PATCH] Add a footer listing keyboard shortcuts
|
||||||
|
|
||||||
|
This makes the program more friendly to new users.
|
||||||
|
|
||||||
|
Implements: https://bugs.launchpad.net/ubuntu/+source/iotop/+bug/1429645
|
||||||
|
|
||||||
|
Conflict: Adapt patch Context
|
||||||
|
Reference: https://repo.or.cz/iotop.git/commit/877679bf74d1c84040f00eec2a42e2ace056e45e
|
||||||
|
---
|
||||||
|
iotop.8 | 3 +++
|
||||||
|
iotop/ui.py | 66 +++++++++++++++++++++++++++++++++++++++++++++++++----
|
||||||
|
2 files changed, 64 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/iotop.8 b/iotop.8
|
||||||
|
index 68d9edd..e34fd6a 100644
|
||||||
|
--- a/iotop.8
|
||||||
|
+++ b/iotop.8
|
||||||
|
@@ -71,6 +71,9 @@ Add a timestamp on each line (implies \-\-batch). Each line will be prefixed by
|
||||||
|
.TP
|
||||||
|
\fB\-q\fR, \fB\-\-quiet\fR
|
||||||
|
suppress some lines of header (implies \-\-batch). This option can be specified up to three times to remove header lines.
|
||||||
|
+.TP
|
||||||
|
+\fB\-\-no\-help\fR
|
||||||
|
+Suppress the keyboard shortcuts help display.
|
||||||
|
.RS
|
||||||
|
.PD 0
|
||||||
|
.TP
|
||||||
|
diff --git a/iotop/ui.py b/iotop/ui.py
|
||||||
|
index 56383a2..6867ecb 100644
|
||||||
|
--- a/iotop/ui.py
|
||||||
|
+++ b/iotop/ui.py
|
||||||
|
@@ -29,6 +29,7 @@ import select
|
||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
+from collections import OrderedDict
|
||||||
|
|
||||||
|
from iotop.data import find_uids, TaskStatsNetlink, ProcessList, Stats
|
||||||
|
from iotop.data import ThreadInfo
|
||||||
|
@@ -181,12 +182,17 @@ class IOTopUI(object):
|
||||||
|
|
||||||
|
def adjust_sorting_key(self, delta):
|
||||||
|
orig_sorting_key = self.sorting_key
|
||||||
|
- self.sorting_key += delta
|
||||||
|
- self.sorting_key = max(0, self.sorting_key)
|
||||||
|
- self.sorting_key = min(len(IOTopUI.sorting_keys) - 1, self.sorting_key)
|
||||||
|
+ self.sorting_key = self.get_sorting_key(delta)
|
||||||
|
if orig_sorting_key != self.sorting_key:
|
||||||
|
self.sorting_reverse = IOTopUI.sorting_keys[self.sorting_key][1]
|
||||||
|
|
||||||
|
+ def get_sorting_key(self, delta):
|
||||||
|
+ new_sorting_key = self.sorting_key
|
||||||
|
+ new_sorting_key += delta
|
||||||
|
+ new_sorting_key = max(0, new_sorting_key)
|
||||||
|
+ new_sorting_key = min(len(IOTopUI.sorting_keys) - 1, new_sorting_key)
|
||||||
|
+ return new_sorting_key
|
||||||
|
+
|
||||||
|
# I wonder if switching to urwid for the display would be better here
|
||||||
|
|
||||||
|
def prompt_str(self, prompt, default=None, empty_is_cancel=True):
|
||||||
|
@@ -453,10 +459,47 @@ class IOTopUI(object):
|
||||||
|
status_msg = ('CONFIG_TASK_DELAY_ACCT not enabled in kernel, '
|
||||||
|
'cannot determine SWAPIN and IO %')
|
||||||
|
|
||||||
|
+ help_lines = []
|
||||||
|
+ help_attrs = []
|
||||||
|
+ if self.options.help:
|
||||||
|
+ prev = self.get_sorting_key(-1)
|
||||||
|
+ next = self.get_sorting_key(1)
|
||||||
|
+ help = OrderedDict([
|
||||||
|
+ ('keys', ''),
|
||||||
|
+ ('any', 'refresh'),
|
||||||
|
+ ('q', 'quit'),
|
||||||
|
+ ('i', 'ionice'),
|
||||||
|
+ ('o', 'all' if self.options.only else 'active'),
|
||||||
|
+ ('p', 'threads' if self.options.processes else 'procs'),
|
||||||
|
+ ('a', 'bandwidth' if self.options.accumulated else 'accum'),
|
||||||
|
+ ('sort', ''),
|
||||||
|
+ ('r', 'asc' if self.sorting_reverse else 'desc'),
|
||||||
|
+ ('left', titles[prev].strip()),
|
||||||
|
+ ('right', titles[next].strip()),
|
||||||
|
+ ('home', titles[0].strip()),
|
||||||
|
+ ('end', titles[-1].strip()),
|
||||||
|
+ ])
|
||||||
|
+ help_line = -1
|
||||||
|
+ for key, help in help.items():
|
||||||
|
+ if help:
|
||||||
|
+ help_item = [' ', key, ': ', help]
|
||||||
|
+ help_attr = [0, 0 if key == 'any' else curses.A_UNDERLINE, 0, 0]
|
||||||
|
+ else:
|
||||||
|
+ help_item = [' ', key, ':']
|
||||||
|
+ help_attr = [0, 0, 0]
|
||||||
|
+ if not help_lines or not help or len(''.join(help_lines[help_line]) + ''.join(help_item)) > self.width:
|
||||||
|
+ help_lines.append(help_item)
|
||||||
|
+ help_attrs.append(help_attr)
|
||||||
|
+ help_line += 1
|
||||||
|
+ else:
|
||||||
|
+ help_lines[help_line] += help_item
|
||||||
|
+ help_attrs[help_line] += help_attr
|
||||||
|
+
|
||||||
|
len_summary = len(summary)
|
||||||
|
len_titles = int(bool(titles))
|
||||||
|
len_status_msg = int(bool(status_msg))
|
||||||
|
- max_lines = self.height - len_summary - len_titles - len_status_msg
|
||||||
|
+ len_help = len(help_lines)
|
||||||
|
+ max_lines = self.height - len_summary - len_titles - len_status_msg - len_help
|
||||||
|
if max_lines < 5:
|
||||||
|
titles = []
|
||||||
|
len_titles = 0
|
||||||
|
@@ -466,7 +509,11 @@ class IOTopUI(object):
|
||||||
|
if max_lines < 7:
|
||||||
|
status_msg = None
|
||||||
|
len_status_msg = 0
|
||||||
|
- max_lines = self.height - len_summary - len_titles - len_status_msg
|
||||||
|
+ if max_lines < 8:
|
||||||
|
+ help_lines = []
|
||||||
|
+ help_attrs = []
|
||||||
|
+ len_help = 0
|
||||||
|
+ max_lines = self.height - len_summary - len_titles - len_status_msg - len_help
|
||||||
|
num_lines = min(len(lines), max_lines)
|
||||||
|
|
||||||
|
for i, s in enumerate(summary):
|
||||||
|
@@ -500,6 +547,13 @@ class IOTopUI(object):
|
||||||
|
print_line(lines[i].encode('utf-8'))
|
||||||
|
except curses.error:
|
||||||
|
pass
|
||||||
|
+ for ln in range(len_help):
|
||||||
|
+ line = self.height - len_status_msg - len_help + ln
|
||||||
|
+ self.win.hline(line, 0, ord(' ') | curses.A_REVERSE, self.width)
|
||||||
|
+ pos = 0
|
||||||
|
+ for i in range(len(help_lines[ln])):
|
||||||
|
+ self.win.insstr(line, pos, help_lines[ln][i], curses.A_REVERSE | help_attrs[ln][i])
|
||||||
|
+ pos += len(help_lines[ln][i])
|
||||||
|
if status_msg:
|
||||||
|
self.win.insstr(self.height - len(summary), 0, status_msg,
|
||||||
|
curses.A_BOLD)
|
||||||
|
@@ -626,6 +680,8 @@ def main():
|
||||||
|
help='suppress some lines of header (implies --batch)')
|
||||||
|
parser.add_option('--profile', action='store_true', dest='profile',
|
||||||
|
default=False, help=optparse.SUPPRESS_HELP)
|
||||||
|
+ parser.add_option('--no-help', action='store_false', dest='help', default=True,
|
||||||
|
+ help='suppress listing of shortcuts')
|
||||||
|
|
||||||
|
options, args = parser.parse_args()
|
||||||
|
if args:
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
From dd4fcc71b1184264bed25fbc0ce7e2d758d8c396 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Wise <pabs3@bonedaddy.net>
|
||||||
|
Date: Fri, 1 Oct 2021 07:32:49 +0800
|
||||||
|
Subject: [PATCH] Document the new kernel.task_delayacct sysctl requirement in
|
||||||
|
Linux 5.14
|
||||||
|
|
||||||
|
Fixes: https://github.com/Tomas-M/iotop/issues/21
|
||||||
|
Reported-by: @ManuLinares
|
||||||
|
Forwarded-by: Boian Bonev <bbonev@ipacct.com>
|
||||||
|
|
||||||
|
Conflict: Adapt patch context
|
||||||
|
Reference: https://repo.or.cz/iotop.git/commit/dd4fcc71b1184264bed25fbc0ce7e2d758d8c396
|
||||||
|
---
|
||||||
|
README | 3 ++-
|
||||||
|
iotop.8 | 3 ++-
|
||||||
|
iotop/data.py | 2 +-
|
||||||
|
iotop/ui.py | 4 +++-
|
||||||
|
4 files changed, 8 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/README b/README
|
||||||
|
index cf9e050..3f490ab 100644
|
||||||
|
--- a/README
|
||||||
|
+++ b/README
|
||||||
|
@@ -1,7 +1,8 @@
|
||||||
|
Iotop is a Python program with a top like UI used to show of behalf of which
|
||||||
|
process is the I/O going on. It requires Python >= 2.7 and a Linux kernel >=
|
||||||
|
2.6.20 with the CONFIG_TASK_DELAY_ACCT CONFIG_TASKSTATS,
|
||||||
|
-CONFIG_TASK_IO_ACCOUNTING and CONFIG_VM_EVENT_COUNTERS options on.
|
||||||
|
+CONFIG_TASK_IO_ACCOUNTING and CONFIG_VM_EVENT_COUNTERS build options on
|
||||||
|
+and for Linux kernels since 5.14, the kernel.task_delayacct sysctl enabled.
|
||||||
|
|
||||||
|
|
||||||
|
To run a local version of iotop:
|
||||||
|
diff --git a/iotop.8 b/iotop.8
|
||||||
|
index e34fd6a..867871f 100644
|
||||||
|
--- a/iotop.8
|
||||||
|
+++ b/iotop.8
|
||||||
|
@@ -10,7 +10,8 @@ iotop watches I/O usage information output by the Linux kernel (requires
|
||||||
|
2.6.20 or later) and displays a table of current I/O usage by processes
|
||||||
|
or threads on the system. At least the CONFIG_TASK_DELAY_ACCT,
|
||||||
|
CONFIG_TASK_IO_ACCOUNTING, CONFIG_TASKSTATS and CONFIG_VM_EVENT_COUNTERS
|
||||||
|
-options need to be enabled in your Linux kernel build configuration.
|
||||||
|
+options need to be enabled in your Linux kernel build configuration and
|
||||||
|
+since Linux kernel 5.14, the kernel.task_delayacct sysctl enabled.
|
||||||
|
.PP
|
||||||
|
iotop displays columns for the I/O bandwidth read and written by each
|
||||||
|
process/thread during the sampling period. It also displays the percentage
|
||||||
|
diff --git a/iotop/data.py b/iotop/data.py
|
||||||
|
index befa9c7..606376f 100644
|
||||||
|
--- a/iotop/data.py
|
||||||
|
+++ b/iotop/data.py
|
||||||
|
@@ -49,7 +49,7 @@ if not ioaccounting or not vm_event_counters:
|
||||||
|
if not ioaccounting:
|
||||||
|
print(' - I/O accounting support ' \
|
||||||
|
'(CONFIG_TASKSTATS, CONFIG_TASK_DELAY_ACCT, ' \
|
||||||
|
- 'CONFIG_TASK_IO_ACCOUNTING)')
|
||||||
|
+ 'CONFIG_TASK_IO_ACCOUNTING, kernel.task_delayacct sysctl)')
|
||||||
|
if not vm_event_counters:
|
||||||
|
print(' - VM event counters (CONFIG_VM_EVENT_COUNTERS)')
|
||||||
|
sys.exit(1)
|
||||||
|
diff --git a/iotop/ui.py b/iotop/ui.py
|
||||||
|
index 8d10721..5ab8fd4 100644
|
||||||
|
--- a/iotop/ui.py
|
||||||
|
+++ b/iotop/ui.py
|
||||||
|
@@ -456,7 +456,9 @@ class IOTopUI(object):
|
||||||
|
if Stats.has_blkio_delay_total:
|
||||||
|
status_msg = None
|
||||||
|
else:
|
||||||
|
- status_msg = ('CONFIG_TASK_DELAY_ACCT not enabled in kernel, '
|
||||||
|
+ status_msg = ('CONFIG_TASK_DELAY_ACCT '
|
||||||
|
+ 'and kernel.task_delayacct sysctl '
|
||||||
|
+ 'not enabled in kernel, '
|
||||||
|
'cannot determine SWAPIN and IO %')
|
||||||
|
|
||||||
|
help_lines = []
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
88
0018-Detect-the-kernel.task_delayacct-sysctl-value.patch
Normal file
88
0018-Detect-the-kernel.task_delayacct-sysctl-value.patch
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
From ab35334d374e588bec12d201fb8869c536f0545d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Wise <pabs3@bonedaddy.net>
|
||||||
|
Date: Sat, 2 Oct 2021 12:13:16 +0800
|
||||||
|
Subject: [PATCH] Detect the kernel.task_delayacct sysctl value
|
||||||
|
|
||||||
|
If you have ever turned on the kernel.task_delayacct sysctl for the
|
||||||
|
current
|
||||||
|
Linux boot, then the heuristic that iotop uses to find out if swapin/io
|
||||||
|
are
|
||||||
|
available, gives a false negative, so the sysctl has to be checked too
|
||||||
|
now.
|
||||||
|
|
||||||
|
Fixes: https://github.com/Tomas-M/iotop/issues/21
|
||||||
|
Reported-by: @ManuLinares
|
||||||
|
Forwarded-by: Boian Bonev <bbonev@ipacct.com>
|
||||||
|
|
||||||
|
Conflict: Adapt patch context
|
||||||
|
Reference: https://repo.or.cz/iotop.git/commit/ab35334d374e588bec12d201fb8869c536f0545d
|
||||||
|
---
|
||||||
|
iotop/data.py | 8 ++++++++
|
||||||
|
iotop/ui.py | 14 +++++++++++---
|
||||||
|
2 files changed, 19 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/iotop/data.py b/iotop/data.py
|
||||||
|
index 606376f..b784a19 100644
|
||||||
|
--- a/iotop/data.py
|
||||||
|
+++ b/iotop/data.py
|
||||||
|
@@ -459,3 +459,11 @@ class ProcessList(DumpableObject):
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
self.processes = {}
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+def sysctl_task_delayacct():
|
||||||
|
+ try:
|
||||||
|
+ with open('/proc/sys/kernel/task_delayacct') as f:
|
||||||
|
+ return bool(int(f.read().strip()))
|
||||||
|
+ except FileNotFoundError:
|
||||||
|
+ return None
|
||||||
|
diff --git a/iotop/ui.py b/iotop/ui.py
|
||||||
|
index 5ab8fd4..4ffbeea 100644
|
||||||
|
--- a/iotop/ui.py
|
||||||
|
+++ b/iotop/ui.py
|
||||||
|
@@ -31,7 +31,7 @@ import sys
|
||||||
|
import time
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
|
-from iotop.data import find_uids, TaskStatsNetlink, ProcessList, Stats
|
||||||
|
+from iotop.data import find_uids, TaskStatsNetlink, ProcessList, Stats, sysctl_task_delayacct
|
||||||
|
from iotop.data import ThreadInfo
|
||||||
|
from iotop.version import VERSION
|
||||||
|
from iotop import ioprio
|
||||||
|
@@ -383,7 +383,7 @@ class IOTopUI(object):
|
||||||
|
def format(p):
|
||||||
|
stats = format_stats(self.options, p, self.process_list.duration)
|
||||||
|
io_delay, swapin_delay, read_bytes, write_bytes = stats
|
||||||
|
- if Stats.has_blkio_delay_total:
|
||||||
|
+ if self.has_swapin_io:
|
||||||
|
delay_stats = '%7s %7s ' % (swapin_delay, io_delay)
|
||||||
|
else:
|
||||||
|
delay_stats = ' ?unavailable? '
|
||||||
|
@@ -435,6 +435,14 @@ class IOTopUI(object):
|
||||||
|
pid += 'TID'
|
||||||
|
titles = [pid, ' PRIO', ' USER', ' DISK READ', ' DISK WRITE',
|
||||||
|
' SWAPIN', ' IO', ' COMMAND']
|
||||||
|
+ self.has_swapin_io = Stats.has_blkio_delay_total
|
||||||
|
+ if self.has_swapin_io:
|
||||||
|
+ # Linux kernels without the sysctl return None and
|
||||||
|
+ # iotop just uses the heuristic for those versions.
|
||||||
|
+ # Linux kernels with the sysctl return True or False
|
||||||
|
+ # and iotop then uses the sysctl value instead.
|
||||||
|
+ if sysctl_task_delayacct() == False:
|
||||||
|
+ self.has_swapin_io = False
|
||||||
|
lines = self.get_data()
|
||||||
|
if self.options.time:
|
||||||
|
titles = [' TIME'] + titles
|
||||||
|
@@ -453,7 +461,7 @@ class IOTopUI(object):
|
||||||
|
else:
|
||||||
|
self.win.erase()
|
||||||
|
|
||||||
|
- if Stats.has_blkio_delay_total:
|
||||||
|
+ if self.has_swapin_io:
|
||||||
|
status_msg = None
|
||||||
|
else:
|
||||||
|
status_msg = ('CONFIG_TASK_DELAY_ACCT '
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -0,0 +1,95 @@
|
|||||||
|
From 9c49d594a5ddea14dcb30f0f2b7dc67018767295 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Paul Wise <pabs3@bonedaddy.net>
|
||||||
|
Date: Tue, 1 Feb 2022 11:31:15 +0800
|
||||||
|
Subject: [PATCH] Automatically hide the SWAPIN/IO columns when they are
|
||||||
|
unavailable
|
||||||
|
|
||||||
|
Now that the Linux kernel can enable or disable data collection for them at
|
||||||
|
runtime, showing the columns when collection is disabled is even less useful,
|
||||||
|
since the previous data could still be present in the Linux kernel buffers.
|
||||||
|
|
||||||
|
Preserve the behaviour of the batch mode though, so that programs parsing
|
||||||
|
its output aren't broken by the changes to the Linux kernel, but they may
|
||||||
|
still be broken when the output changes from ?unavailable? to real data.
|
||||||
|
|
||||||
|
Since the current sorting keys code makes it hard to dynamically choose which
|
||||||
|
columns are shown or hidden, when the two columns are hidden, just skip over
|
||||||
|
displaying them or using them as sorting keys.
|
||||||
|
|
||||||
|
Rewrite the data display code to be more flexible wrt column choice though.
|
||||||
|
|
||||||
|
Suggested-by: Boian Bonev <bbonev@ipacct.com>
|
||||||
|
|
||||||
|
Conflict: NA
|
||||||
|
Reference: https://repo.or.cz/iotop.git/commit/9c49d594a5ddea14dcb30f0f2b7dc67018767295
|
||||||
|
---
|
||||||
|
iotop/ui.py | 31 ++++++++++++++++++++++++-------
|
||||||
|
1 file changed, 24 insertions(+), 7 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/iotop/ui.py b/iotop/ui.py
|
||||||
|
index 7ae8bad..77f82c7 100644
|
||||||
|
--- a/iotop/ui.py
|
||||||
|
+++ b/iotop/ui.py
|
||||||
|
@@ -224,6 +224,12 @@ class IOTopUI(object):
|
||||||
|
new_sorting_key += delta
|
||||||
|
new_sorting_key = max(0, new_sorting_key)
|
||||||
|
new_sorting_key = min(len(IOTopUI.sorting_keys) - 1, new_sorting_key)
|
||||||
|
+ if not self.has_swapin_io:
|
||||||
|
+ if new_sorting_key in (5, 6):
|
||||||
|
+ if delta <= 0:
|
||||||
|
+ new_sorting_key = 4
|
||||||
|
+ elif delta > 0:
|
||||||
|
+ new_sorting_key = 7
|
||||||
|
return new_sorting_key
|
||||||
|
|
||||||
|
# I wonder if switching to urwid for the display would be better here
|
||||||
|
@@ -421,14 +427,22 @@ class IOTopUI(object):
|
||||||
|
def format(p):
|
||||||
|
stats = format_stats(self.options, p, self.process_list.duration)
|
||||||
|
io_delay, swapin_delay, read_bytes, write_bytes = stats
|
||||||
|
+ format = '%%%dd' % MAX_PID_WIDTH
|
||||||
|
+ params = p.pid,
|
||||||
|
+ format += ' %4s'
|
||||||
|
+ params += p.get_ioprio(),
|
||||||
|
+ format += ' %-8s'
|
||||||
|
+ params += p.get_user()[:8],
|
||||||
|
+ format += ' %11s %11s'
|
||||||
|
+ params += read_bytes, write_bytes
|
||||||
|
if self.has_swapin_io:
|
||||||
|
- delay_stats = '%7s %7s ' % (swapin_delay, io_delay)
|
||||||
|
- else:
|
||||||
|
- delay_stats = ' ?unavailable? '
|
||||||
|
- pid_format = '%%%dd' % MAX_PID_WIDTH
|
||||||
|
- line = (pid_format + ' %4s %-8s %11s %11s %s') % (
|
||||||
|
- p.pid, p.get_ioprio(), p.get_user()[:8], read_bytes,
|
||||||
|
- write_bytes, delay_stats)
|
||||||
|
+ format += ' %7s %7s'
|
||||||
|
+ params += swapin_delay, io_delay
|
||||||
|
+ elif self.options.batch:
|
||||||
|
+ format += ' %s '
|
||||||
|
+ params += '?unavailable?',
|
||||||
|
+ format += ' '
|
||||||
|
+ line = format % (params)
|
||||||
|
cmdline = p.get_cmdline()
|
||||||
|
if not self.options.batch:
|
||||||
|
remaining_length = self.width - len(line)
|
||||||
|
@@ -481,6 +495,7 @@ class IOTopUI(object):
|
||||||
|
# and iotop then uses the sysctl value instead.
|
||||||
|
if sysctl_task_delayacct() == False:
|
||||||
|
self.has_swapin_io = False
|
||||||
|
+ self.adjust_sorting_key(0)
|
||||||
|
lines = self.get_data()
|
||||||
|
if self.options.time:
|
||||||
|
titles = [' TIME'] + titles
|
||||||
|
@@ -571,6 +586,8 @@ class IOTopUI(object):
|
||||||
|
pos = 0
|
||||||
|
remaining_cols = self.width
|
||||||
|
for i in range(len(titles)):
|
||||||
|
+ if not self.has_swapin_io and i in (5, 6):
|
||||||
|
+ continue
|
||||||
|
attr = curses.A_REVERSE
|
||||||
|
title = titles[i]
|
||||||
|
if i == self.sorting_key:
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
12
iotop.spec
12
iotop.spec
@ -1,6 +1,6 @@
|
|||||||
Name: iotop
|
Name: iotop
|
||||||
Version: 0.6
|
Version: 0.6
|
||||||
Release: 27
|
Release: 28
|
||||||
Summary: Simple top-like I/O monitor
|
Summary: Simple top-like I/O monitor
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
URL: http://guichaz.free.fr/iotop/
|
URL: http://guichaz.free.fr/iotop/
|
||||||
@ -23,6 +23,12 @@ Patch10: 0010-Fix-crash-due-to-syntax-error.patch
|
|||||||
Patch11: 0011-Use-monotonic-time-to-calculate-durations.patch
|
Patch11: 0011-Use-monotonic-time-to-calculate-durations.patch
|
||||||
Patch12: 0012-riscv-Add-riscv64-support.patch
|
Patch12: 0012-riscv-Add-riscv64-support.patch
|
||||||
Patch13: 0013-loongarch64-add-loongarch64-support.patch
|
Patch13: 0013-loongarch64-add-loongarch64-support.patch
|
||||||
|
Patch14: 0014-Hide-UI-elements-on-smaller-terminals.patch
|
||||||
|
Patch15: 0015-Check-the-column-title-is-not-empty-before-using-it.patch
|
||||||
|
Patch16: 0016-Add-a-footer-listing-keyboard-shortcuts.patch
|
||||||
|
Patch17: 0017-Document-the-new-kernel.task_delayacct-sysctl-requir.patch
|
||||||
|
Patch18: 0018-Detect-the-kernel.task_delayacct-sysctl-value.patch
|
||||||
|
Patch19: 0019-Automatically-hide-the-SWAPIN-IO-columns-when-they-a.patch
|
||||||
|
|
||||||
%description
|
%description
|
||||||
iotop watches I/O usage information output by the Linux kernel (requires 2.6.20 or later) and
|
iotop watches I/O usage information output by the Linux kernel (requires 2.6.20 or later) and
|
||||||
@ -61,6 +67,10 @@ This contains man files for the using of iotop
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu Nov 14 2024 lvyy <lyunmail@163.com> - 0.6-28
|
||||||
|
- Fix SWAPIN I/O display issue
|
||||||
|
Add a footer listing keyboard shortcuts
|
||||||
|
|
||||||
* Tue Jul 2 2024 cenhuilin <cenhuilin@kylinos.cn> - 0.6-27
|
* Tue Jul 2 2024 cenhuilin <cenhuilin@kylinos.cn> - 0.6-27
|
||||||
- loongarch64: add loongarch64 support
|
- loongarch64: add loongarch64 support
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user