diff options
author | Paul Wise <pabs3@bonedaddy.net> | 2021-10-02 12:13:16 +0800 |
---|---|---|
committer | Paul Wise <pabs3@bonedaddy.net> | 2021-10-02 12:15:13 +0800 |
commit | ab35334d374e588bec12d201fb8869c536f0545d (patch) | |
tree | e354b878abdbdfddd0adb8713be63710aeb1eb02 | |
parent | dd4fcc71b1184264bed25fbc0ce7e2d758d8c396 (diff) | |
download | iotop-ab35334d374e588bec12d201fb8869c536f0545d.tar.gz |
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>
-rw-r--r-- | iotop/data.py | 8 | ||||
-rw-r--r-- | iotop/ui.py | 14 |
2 files changed, 19 insertions, 3 deletions
diff --git a/iotop/data.py b/iotop/data.py index e9c06be..5d70e29 100644 --- a/iotop/data.py +++ b/iotop/data.py @@ -477,3 +477,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 fa7e35b..7ae8bad 100644 --- a/iotop/ui.py +++ b/iotop/ui.py @@ -43,7 +43,7 @@ except (ImportError, RuntimeError): 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 @@ -421,7 +421,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? ' @@ -473,6 +473,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 @@ -491,7 +499,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 ' |