parent
5d061bfc1b
commit
e134166d5b
|
@ -0,0 +1,41 @@
|
|||
diff -up iotop-0.6/iotop/data.py.delayacctmsg iotop-0.6/iotop/data.py
|
||||
--- iotop-0.6/iotop/data.py.delayacctmsg 2022-02-15 21:52:27.206378348 +0100
|
||||
+++ iotop-0.6/iotop/data.py 2022-02-15 21:52:27.208378321 +0100
|
||||
@@ -32,7 +32,6 @@ import time
|
||||
# Check for requirements:
|
||||
# o Linux >= 2.6.20 with I/O accounting and VM event counters
|
||||
#
|
||||
-
|
||||
ioaccounting = os.path.exists('/proc/self/io')
|
||||
|
||||
try:
|
||||
@@ -77,7 +76,7 @@ class Stats(DumpableObject):
|
||||
('cancelled_write_bytes', 264)
|
||||
]
|
||||
|
||||
- has_blkio_delay_total = False
|
||||
+ has_blkio_delay_total = None
|
||||
|
||||
def __init__(self, task_stats_buffer):
|
||||
sd = self.__dict__
|
||||
@@ -88,7 +87,7 @@ class Stats(DumpableObject):
|
||||
# This is a heuristic to detect if CONFIG_TASK_DELAY_ACCT is enabled in
|
||||
# the kernel.
|
||||
if not Stats.has_blkio_delay_total:
|
||||
- Stats.has_blkio_delay_total = self.blkio_delay_total != 0
|
||||
+ Stats.has_blkio_delay_total = sysctl_task_delayacct()
|
||||
|
||||
def accumulate(self, other_stats, destination, coeff=1):
|
||||
"""Update destination from operator(self, other_stats)"""
|
||||
diff -up iotop-0.6/iotop/ui.py.delayacctmsg iotop-0.6/iotop/ui.py
|
||||
--- iotop-0.6/iotop/ui.py.delayacctmsg 2022-02-15 21:52:27.208378321 +0100
|
||||
+++ iotop-0.6/iotop/ui.py 2022-02-15 21:52:54.607013860 +0100
|
||||
@@ -489,7 +489,7 @@ class IOTopUI(object):
|
||||
title = title[:remaining_cols]
|
||||
remaining_cols -= len(title)
|
||||
self.win.addstr(title, attr)
|
||||
- if self.has_swapin_io:
|
||||
+ if self.has_swapin_io is not False:
|
||||
status_msg = None
|
||||
else:
|
||||
status_msg = ('CONFIG_TASK_DELAY_ACCT '
|
|
@ -0,0 +1,63 @@
|
|||
diff -up iotop-0.6/iotop/ui.py.git9c49d59 iotop-0.6/iotop/ui.py
|
||||
--- iotop-0.6/iotop/ui.py.git9c49d59 2022-02-15 21:35:33.983889767 +0100
|
||||
+++ iotop-0.6/iotop/ui.py 2022-02-15 21:39:22.508839448 +0100
|
||||
@@ -184,6 +184,12 @@ class IOTopUI(object):
|
||||
self.sorting_key += delta
|
||||
self.sorting_key = max(0, self.sorting_key)
|
||||
self.sorting_key = min(len(IOTopUI.sorting_keys) - 1, self.sorting_key)
|
||||
+ if not self.has_swapin_io:
|
||||
+ if self.sorting_key in (5, 6):
|
||||
+ if delta <= 0:
|
||||
+ self.sorting_key = 4
|
||||
+ elif delta > 0:
|
||||
+ self.sorting_key = 7
|
||||
if orig_sorting_key != self.sorting_key:
|
||||
self.sorting_reverse = IOTopUI.sorting_keys[self.sorting_key][1]
|
||||
|
||||
@@ -377,14 +383,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)
|
||||
@@ -439,6 +453,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
|
||||
@@ -462,6 +477,8 @@ class IOTopUI(object):
|
||||
self.width)
|
||||
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:
|
|
@ -0,0 +1,60 @@
|
|||
diff -up iotop-0.6/iotop/data.py.gitab35334d iotop-0.6/iotop/data.py
|
||||
--- iotop-0.6/iotop/data.py.gitab35334d 2022-02-15 21:51:20.828263067 +0100
|
||||
+++ iotop-0.6/iotop/data.py 2022-02-15 21:51:20.830263041 +0100
|
||||
@@ -453,3 +453,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 -up iotop-0.6/iotop/ui.py.gitab35334d iotop-0.6/iotop/ui.py
|
||||
--- iotop-0.6/iotop/ui.py.gitab35334d 2022-02-15 21:51:20.828263067 +0100
|
||||
+++ iotop-0.6/iotop/ui.py 2022-02-15 21:51:56.415788740 +0100
|
||||
@@ -30,7 +30,7 @@ import signal
|
||||
import sys
|
||||
import time
|
||||
|
||||
-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
|
||||
@@ -377,7 +377,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? '
|
||||
@@ -431,6 +431,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
|
||||
@@ -464,7 +472,7 @@ class IOTopUI(object):
|
||||
title = title[:remaining_cols]
|
||||
remaining_cols -= len(title)
|
||||
self.win.addstr(title, attr)
|
||||
- if Stats.has_blkio_delay_total:
|
||||
+ if self.has_swapin_io:
|
||||
status_msg = None
|
||||
else:
|
||||
status_msg = ('CONFIG_TASK_DELAY_ACCT '
|
|
@ -0,0 +1,52 @@
|
|||
diff -up iotop-0.6/iotop.8.gitdd4fcc71 iotop-0.6/iotop.8
|
||||
--- iotop-0.6/iotop.8.gitdd4fcc71 2013-05-27 00:44:18.000000000 +0200
|
||||
+++ iotop-0.6/iotop.8 2022-02-15 21:48:24.738610077 +0100
|
||||
@@ -10,7 +10,8 @@ iotop watches I/O usage information outp
|
||||
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 -up iotop-0.6/iotop/data.py.gitdd4fcc71 iotop-0.6/iotop/data.py
|
||||
--- iotop-0.6/iotop/data.py.gitdd4fcc71 2013-05-27 00:44:18.000000000 +0200
|
||||
+++ iotop-0.6/iotop/data.py 2022-02-15 21:48:24.738610077 +0100
|
||||
@@ -49,7 +49,7 @@ if not ioaccounting or not vm_event_coun
|
||||
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 -up iotop-0.6/iotop/ui.py.gitdd4fcc71 iotop-0.6/iotop/ui.py
|
||||
--- iotop-0.6/iotop/ui.py.gitdd4fcc71 2022-02-15 21:48:24.738610077 +0100
|
||||
+++ iotop-0.6/iotop/ui.py 2022-02-15 21:50:55.382602220 +0100
|
||||
@@ -467,7 +467,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 %')
|
||||
num_lines = min(len(lines), self.height - 2 - int(bool(status_msg)))
|
||||
for i in range(num_lines):
|
||||
diff -up iotop-0.6/README.gitdd4fcc71 iotop-0.6/README
|
||||
--- iotop-0.6/README.gitdd4fcc71 2013-05-27 00:44:18.000000000 +0200
|
||||
+++ iotop-0.6/README 2022-02-15 21:48:24.738610077 +0100
|
||||
@@ -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:
|
Loading…
Reference in New Issue