Bug#1106606: unblock: iotop-c/1.30-1
Package: release.debian.org
Severity: normal
X-Debbugs-Cc: iotop-c@packages.debian.org
Control: affects -1 + src:iotop-c
User: release.debian.org@packages.debian.org
Usertags: unblock
Please unblock package iotop-c
[ Reason ]
Kernel 6.14 introduced an incompatibility in struct taskstats [1][2]
iotop-c 1.29 wrongly assumes that the newer kernels will use the
broken struct from 6.14 but the change was fixed in mainline [3]
and there is a plan to backport it to 6.14 as well.
[ Impact ]
iotop-c 1.29 will be non-functional on all 6.14 kernels that include
the fix and all kernels newer that 6.14
[ Tests ]
iotop-c 1.30 was manually tested by compiling against both fixed and
unfixed kernel headers and then running the binary on older than 6.14,
broken 6.14 and fixed 6.14.
[ Risks ]
iotop-c is a leaf package, all the changes between 1.29 and 1.30 are
small and trivial. Hence the risk of unblocking the update is zero.
Both alternatives - iotop-py and htop are non-functional on 6.14
kernels before the fix gets applied. Also htop will not work on any
other kernel if it is compiled against the unfixed 6.14 headers.
[ Checklist ]
[x] all changes are documented in the d/changelog
[x] I reviewed all changes and I approve them
[x] attach debdiff against the package in testing
[ Other info ]
[1] https://github.com/Tomas-M/iotop/issues/82
[2] https://bugzilla.kernel.org/show_bug.cgi?id=220102
[3] https://lore.kernel.org/all/CAHk-=wiLRW8DN8-4jmeCZH0OpO8skXOC5e6FwMfsPwGMpQYmVQ@mail.gmail.com/
unblock iotop-c/1.30-1
diff -Nru iotop-c-1.29/debian/changelog iotop-c-1.30/debian/changelog
--- iotop-c-1.29/debian/changelog 2025-05-06 22:09:06.000000000 +0000
+++ iotop-c-1.30/debian/changelog 2025-05-26 20:24:48.000000000 +0000
@@ -1,3 +1,14 @@
+iotop-c (1.30-1) unstable; urgency=medium
+
+ * Update to new upstream release of 1.30
+ - kernel commit 0bf2d83 fixes the problem with struct taskstats
+ now iotop 1.30 handles only v15 of the struct in a different
+ way, retaining compatibility with both old and new kernels
+ - show zero current values for exited processes
+ - flush stdout after each batch run
+
+ -- Boian Bonev <bbonev@ipacct.com> Mon, 26 May 2025 20:24:48 +0000
+
iotop-c (1.29-1) unstable; urgency=medium
* Update to new upstream release of 1.29
diff -Nru iotop-c-1.29/fedora/iotop-c.spec iotop-c-1.30/fedora/iotop-c.spec
--- iotop-c-1.29/fedora/iotop-c.spec 2025-05-06 22:11:46.000000000 +0000
+++ iotop-c-1.30/fedora/iotop-c.spec 2025-05-26 20:36:11.000000000 +0000
@@ -1,5 +1,5 @@
Name: iotop-c
-Version: 1.29
+Version: 1.30
Release: 1%{?dist}
Summary: Simple top-like I/O monitor (implemented in C)
@@ -53,6 +53,9 @@
%{_mandir}/man8/iotop.8*
%changelog
+* Mon May 26 2025 Boian Bonev <bbonev@ipacct.com> - 1.30-1
+- Update to latest ver 1.30
+
* Tue May 6 2025 Boian Bonev <bbonev@ipacct.com> - 1.29-1
- Update to latest ver 1.29
diff -Nru iotop-c-1.29/src/iotop.h iotop-c-1.30/src/iotop.h
--- iotop-c-1.29/src/iotop.h 2025-05-06 22:08:49.000000000 +0000
+++ iotop-c-1.30/src/iotop.h 2025-05-26 20:36:11.000000000 +0000
@@ -30,7 +30,7 @@
#include "ucell.h"
-#define VERSION "1.29"
+#define VERSION "1.30"
typedef enum {
E_GR_IO,
@@ -96,6 +96,7 @@
extern int maxpidlen;
extern unsigned taskstats_ver;
+#define IOTOP_TASKSTATS_MINVER 4
#define IOTOP_TASKSTATS_VERSION 15
#define HISTORY_POS 60
diff -Nru iotop-c-1.29/src/view_batch.c iotop-c-1.30/src/view_batch.c
--- iotop-c-1.29/src/view_batch.c 2025-05-02 15:12:39.000000000 +0000
+++ iotop-c-1.30/src/view_batch.c 2025-05-26 20:36:05.000000000 +0000
@@ -136,6 +136,7 @@
if ((params.iter>-1)&&((--params.iter)==0))
break;
+ fflush(stdout);
sleep(params.delay);
}
arr_free(cs);
diff -Nru iotop-c-1.29/src/view_curses.c iotop-c-1.30/src/view_curses.c
--- iotop-c-1.29/src/view_curses.c 2025-05-06 22:08:49.000000000 +0000
+++ iotop-c-1.30/src/view_curses.c 2025-05-26 20:36:05.000000000 +0000
@@ -1190,8 +1190,13 @@
read_val=config.f.processes?s->read_val_acc_p:s->read_val_acc;
write_val=config.f.processes?s->write_val_acc_p:s->write_val_acc;
} else {
- read_val=config.f.processes?s->read_val_p:s->read_val;
- write_val=config.f.processes?s->write_val_p:s->write_val;
+ if (s->exited) {
+ read_val=0.0;
+ write_val=0.0;
+ } else {
+ read_val=config.f.processes?s->read_val_p:s->read_val;
+ write_val=config.f.processes?s->write_val_p:s->write_val;
+ }
}
humanize_val(&read_val,read_str,1);
@@ -1325,16 +1330,24 @@
attron(config.f.nocolor?A_ITALIC:COLOR_PAIR(RED_PAIR));
printw(" Error ");
attroff(config.f.nocolor?A_ITALIC:COLOR_PAIR(RED_PAIR));
- } else
- color_print_pc(config.f.processes?s->swapin_val_p:s->swapin_val);
+ } else {
+ if (s->exited)
+ color_print_pc(0);
+ else
+ color_print_pc(config.f.processes?s->swapin_val_p:s->swapin_val);
+ }
}
if (!config.f.hideio&&has_tda) {
if (s->error_x) {
attron(config.f.nocolor?A_ITALIC:COLOR_PAIR(RED_PAIR));
printw(" Error ");
attroff(config.f.nocolor?A_ITALIC:COLOR_PAIR(RED_PAIR));
- } else
- color_print_pc(config.f.processes?s->blkio_val_p:s->blkio_val);
+ } else {
+ if (s->exited)
+ color_print_pc(0);
+ else
+ color_print_pc(config.f.processes?s->blkio_val_p:s->blkio_val);
+ }
}
if (!config.f.hidegraph&&hrevpos>0) {
if (config.f.reverse_graph) {
@@ -2603,12 +2616,12 @@
"\tto restore it to its previous value and save some CPU cycles.\n"
);
}
- if (taskstats_ver)
+ if (taskstats_ver&&taskstats_ver<IOTOP_TASKSTATS_MINVER)
printf(
"WARNING:\n"
"\tThis kernel provides struct taskstats with version %u.\n"
- "\tThat may not be compatible with the currently supported version %u.\n",
- taskstats_ver,IOTOP_TASKSTATS_VERSION
+ "\tThat does not contain the required data and should be %u or greater.\n",
+ taskstats_ver,IOTOP_TASKSTATS_MINVER
);
}
diff -Nru iotop-c-1.29/src/xxxid_info.c iotop-c-1.30/src/xxxid_info.c
--- iotop-c-1.29/src/xxxid_info.c 2025-05-06 22:08:49.000000000 +0000
+++ iotop-c-1.30/src/xxxid_info.c 2025-05-26 20:36:05.000000000 +0000
@@ -191,29 +191,32 @@
na=(struct nlattr *)NLA_DATA(na);
while (len2<aggr_len) {
if (na->nla_type==TASKSTATS_TYPE_STATS) {
+ // NOTE: we use the build system kernel headers for the version field only
+ // all the data access is done by using copies of the respective versions
+ // of the kernel headers
+ // A patch that will fix the problem is proposed to be included in the kernel
+ // and the only broken struct taskstats will be the one with v15. But we can
+ // not rely on the build system kernel headers for universal access and have
+ // to keep the copies.
+ // In this way a build with any kernel headers will work everywhere
struct taskstats *ts=NLA_DATA(na);
struct taskstats_v14 *t14=NLA_DATA(na);
struct taskstats_v15 *t15=NLA_DATA(na);
- // add a compile time check to raise awareness
- #if TASKSTATS_VERSION > IOTOP_TASKSTATS_VERSION
- #warning Current kernel implements newer struct taskstats, maybe we need a fix for that too
- #endif
-
- if (ts->version<15) { // use v14 for 14 and below
+ if (ts->version<IOTOP_TASKSTATS_MINVER) // v3 and below does not have the data we require
+ taskstats_ver=ts->version;
+ else if (ts->version!=15) { // use v14 for v4..v14 & v16 onwards
stats->read_bytes=t14->read_bytes;
stats->write_bytes=t14->write_bytes;
stats->swapin_delay_total=t14->swapin_delay_total;
stats->blkio_delay_total=t14->blkio_delay_total;
stats->euid=t14->ac_uid;
- } else {
+ } else { // exception for v15 only
stats->read_bytes=t15->read_bytes;
stats->write_bytes=t15->write_bytes;
stats->swapin_delay_total=t15->swapin_delay_total;
stats->blkio_delay_total=t15->blkio_delay_total;
stats->euid=t15->ac_uid;
- if (ts->version>IOTOP_TASKSTATS_VERSION) // print a warning about running on a kernel with maybe incompatible struct taskstats
- taskstats_ver=ts->version;
}
}
len2+=NLA_ALIGN(na->nla_len);
Reply to: