public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH iproute2-next] utils: add fflush_monitor() helper
@ 2026-04-24 17:11 Eric Dumazet
  2026-04-24 19:30 ` David Ahern
  0 siblings, 1 reply; 3+ messages in thread
From: Eric Dumazet @ 2026-04-24 17:11 UTC (permalink / raw)
  To: David Ahern, Stephen Hemminger
  Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Kuniyuki Iwashima,
	netdev, eric.dumazet, Eric Dumazet

Some fflush() calls only make sense for monitor programs.

For other cases, forcing a flush is expensive.

After this patch, ip, tc and ss are correctly buffering their
output when redirected to a file.

Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 include/utils.h |  7 +++++++
 ip/ipaddress.c  | 12 +++++++-----
 ip/iplink.c     |  4 ++--
 ip/ipmonitor.c  |  1 +
 ip/iproute.c    |  4 ++--
 lib/utils.c     |  1 +
 misc/ss.c       |  3 ++-
 tc/tc_class.c   |  2 +-
 tc/tc_filter.c  |  2 +-
 tc/tc_monitor.c |  1 +
 tc/tc_qdisc.c   |  2 +-
 11 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/include/utils.h b/include/utils.h
index b68d6bc4edcf9ca335148f731cd240871b6c809b..9099a78b1593738c5ba181274d784d0a1913407a 100644
--- a/include/utils.h
+++ b/include/utils.h
@@ -38,6 +38,7 @@ extern int numeric;
 extern bool do_all;
 extern int echo_request;
 extern int use_iec;
+extern int monitor_mode;
 
 #define SPRINT_BSIZE 64
 #define SPRINT_BUF(x)	char x[SPRINT_BSIZE]
@@ -399,4 +400,10 @@ FILE *generic_proc_open(const char *env, const char *name);
 int open_fds_add(int fd);
 void open_fds_close(void);
 
+static inline void fflush_monitor(FILE *fp)
+{
+	if (monitor_mode)
+		fflush_monitor(fp);
+}
+
 #endif /* __UTILS_H__ */
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 4d93a04a8555e141ae30a4aaeb42ac607a181c9b..14aa98e77452c9681c9d3660f6a882df56b44f1c 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -894,7 +894,7 @@ static int print_linkinfo_brief(FILE *fp, const char *name,
 		print_string(PRINT_FP, NULL, "%s", "\n");
 	}
 
-	fflush(fp);
+	fflush_monitor(fp);
 	return 0;
 }
 
@@ -1346,10 +1346,12 @@ int print_linkinfo(struct nlmsghdr *n, void *arg)
 	}
 
 	print_string(PRINT_FP, NULL, "%s", "\n");
-	fflush(fp);
+	fflush_monitor(fp);
 	/* prettier here if stderr and stdout go to the same place */
-	if (truncated_vfs)
+	if (truncated_vfs) {
+		fflush(fp);
 		fprintf(stderr, "Truncated VF list: %s\n", name);
+	}
 	return 1;
 }
 
@@ -1732,7 +1734,7 @@ int print_addrinfo(struct nlmsghdr *n, void *arg)
 	}
 	print_string(PRINT_FP, NULL, "%s", "\n");
 brief_exit:
-	fflush(fp);
+	fflush_monitor(fp);
 	return 0;
 }
 
@@ -1768,7 +1770,7 @@ static int print_selected_addrinfo(struct ifinfomsg *ifi,
 
 	if (brief) {
 		print_string(PRINT_FP, NULL, "%s", "\n");
-		fflush(fp);
+		fflush_monitor(fp);
 	}
 	return 0;
 }
diff --git a/ip/iplink.c b/ip/iplink.c
index fce6631d2d821a8739d28805e13d98f6804bda30..806f86987ed7c8af5ddd40f04a44fb8ce8debfaf 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -1296,7 +1296,7 @@ static void print_mpls_stats(FILE *fp, struct rtattr *attr)
 	print_nl();
 	print_mpls_link_stats(fp, stats, "        ");
 	print_string(PRINT_FP, NULL, "%s", "\n");
-	fflush(fp);
+	fflush_monitor(fp);
 }
 
 static void print_af_stats_attr(FILE *fp, int ifindex, struct rtattr *attr)
@@ -1359,7 +1359,7 @@ static int print_af_stats(struct nlmsghdr *n, void *arg)
 	if (tb[IFLA_STATS_AF_SPEC])
 		print_af_stats_attr(fp, ifsm->ifindex, tb[IFLA_STATS_AF_SPEC]);
 
-	fflush(fp);
+	fflush_monitor(fp);
 	return 0;
 }
 
diff --git a/ip/ipmonitor.c b/ip/ipmonitor.c
index 1f4e860f8d6726edffcf9bf81636c6555757dd09..23bd667a2f7a27e620d0f6dd13a16476c1ac0d08 100644
--- a/ip/ipmonitor.c
+++ b/ip/ipmonitor.c
@@ -324,6 +324,7 @@ int do_ipmonitor(int argc, char **argv)
 		return err;
 	}
 
+	monitor_mode = 1;
 	if (rtnl_open(&rth, groups) < 0)
 		exit(1);
 
diff --git a/ip/iproute.c b/ip/iproute.c
index c2538894da633b56f5b926ecafda4960a48e9fbd..c6a6ba9dd37076acfceb9b259874a50e7cd3c3d0 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -1012,7 +1012,7 @@ int print_route(struct nlmsghdr *n, void *arg)
 
 	print_string(PRINT_FP, NULL, "\n", NULL);
 	close_json_object();
-	fflush(fp);
+	fflush_monitor(fp);
 	return 0;
 }
 
@@ -2035,7 +2035,7 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action)
 	}
 
 	delete_json_obj();
-	fflush(stdout);
+	fflush_monitor(stdout);
 	return 0;
 }
 
diff --git a/lib/utils.c b/lib/utils.c
index 1215fe31cb3f63c0fa768fef60da77a641c51581..7017b0e6afacd8e770fb9f8b26aa5a319c1279e7 100644
--- a/lib/utils.c
+++ b/lib/utils.c
@@ -41,6 +41,7 @@ int timestamp_short;
 int pretty;
 int use_iec;
 int human_readable;
+int monitor_mode;
 const char *_SL_ = "\n";
 
 static int open_fds[5];
diff --git a/misc/ss.c b/misc/ss.c
index 14e9f27a75321556240a5f290b8bcf51c605a4c2..0f9b37177d375ddf70cb34674992723b5c4883be 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -5544,7 +5544,7 @@ static int generic_show_sock(struct nlmsghdr *nlh, void *arg)
 
 	render();
 
-	fflush(stdout);
+	fflush_monitor(stdout);
 	return ret;
 }
 
@@ -5580,6 +5580,7 @@ static int handle_follow_request(struct filter *f)
 		f->rth_for_killing = &rth2;
 	}
 
+	monitor_mode = 1;
 	if (rtnl_dump_filter(&rth, generic_show_sock, f))
 		ret = -1;
 
diff --git a/tc/tc_class.c b/tc/tc_class.c
index 6d707d8c924f4b5e90201d4de8e9779f82ce17f3..8197566281fad47d4efcf4768ed406ab809dd08a 100644
--- a/tc/tc_class.c
+++ b/tc/tc_class.c
@@ -380,7 +380,7 @@ int print_class(struct nlmsghdr *n, void *arg)
 		close_json_object();
 	}
 	close_json_object();
-	fflush(fp);
+	fflush_monitor(fp);
 	return 0;
 }
 
diff --git a/tc/tc_filter.c b/tc/tc_filter.c
index 7db850bda11a3408ec66b457c9fc590f3a734f65..633f027d79865d98ba1ccba48af71d247dfc7a48 100644
--- a/tc/tc_filter.c
+++ b/tc/tc_filter.c
@@ -374,7 +374,7 @@ int print_filter(struct nlmsghdr *n, void *arg)
 
 	print_ext_msg(tb);
 	close_json_object();
-	fflush(fp);
+	fflush_monitor(fp);
 	return 0;
 }
 
diff --git a/tc/tc_monitor.c b/tc/tc_monitor.c
index 5b9bccbed4140241a4d7a5cffc50865106224867..49bd4b6a460fbfe41a35e06f92f07dbe56a6be2d 100644
--- a/tc/tc_monitor.c
+++ b/tc/tc_monitor.c
@@ -100,6 +100,7 @@ int do_tcmonitor(int argc, char **argv)
 		return ret;
 	}
 
+	monitor_mode = 1;
 	if (rtnl_open(&rth, groups) < 0)
 		exit(1);
 
diff --git a/tc/tc_qdisc.c b/tc/tc_qdisc.c
index 7eb9a31baa31fb91a8141c9eca1135e76a52fa8b..a8ef8fc9f70d91609d6ed61c2a46b29120512fd2 100644
--- a/tc/tc_qdisc.c
+++ b/tc/tc_qdisc.c
@@ -344,7 +344,7 @@ int print_qdisc(struct nlmsghdr *n, void *arg)
 
 	print_ext_msg(tb);
 	close_json_object();
-	fflush(fp);
+	fflush_monitor(fp);
 	return 0;
 }
 
-- 
2.54.0.545.g6539524ca2-goog


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH iproute2-next] utils: add fflush_monitor() helper
  2026-04-24 17:11 [PATCH iproute2-next] utils: add fflush_monitor() helper Eric Dumazet
@ 2026-04-24 19:30 ` David Ahern
  2026-04-27  7:39   ` Eric Dumazet
  0 siblings, 1 reply; 3+ messages in thread
From: David Ahern @ 2026-04-24 19:30 UTC (permalink / raw)
  To: Eric Dumazet, Stephen Hemminger
  Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, Kuniyuki Iwashima,
	netdev, eric.dumazet

On 4/24/26 11:11 AM, Eric Dumazet wrote:
> @@ -399,4 +400,10 @@ FILE *generic_proc_open(const char *env, const char *name);
>  int open_fds_add(int fd);
>  void open_fds_close(void);
>  
> +static inline void fflush_monitor(FILE *fp)
> +{
> +	if (monitor_mode)
> +		fflush_monitor(fp);

Circular call?


> +}
> +
>  #endif /* __UTILS_H__ */




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH iproute2-next] utils: add fflush_monitor() helper
  2026-04-24 19:30 ` David Ahern
@ 2026-04-27  7:39   ` Eric Dumazet
  0 siblings, 0 replies; 3+ messages in thread
From: Eric Dumazet @ 2026-04-27  7:39 UTC (permalink / raw)
  To: David Ahern
  Cc: Stephen Hemminger, David S . Miller, Jakub Kicinski, Paolo Abeni,
	Kuniyuki Iwashima, netdev, eric.dumazet

On Fri, Apr 24, 2026 at 12:30 PM David Ahern <dsahern@kernel.org> wrote:
>
> On 4/24/26 11:11 AM, Eric Dumazet wrote:
> > @@ -399,4 +400,10 @@ FILE *generic_proc_open(const char *env, const char *name);
> >  int open_fds_add(int fd);
> >  void open_fds_close(void);
> >
> > +static inline void fflush_monitor(FILE *fp)
> > +{
> > +     if (monitor_mode)
> > +             fflush_monitor(fp);
>
> Circular call?

Some last minute change I guess :/

Thanks.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-04-27  7:39 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-24 17:11 [PATCH iproute2-next] utils: add fflush_monitor() helper Eric Dumazet
2026-04-24 19:30 ` David Ahern
2026-04-27  7:39   ` Eric Dumazet

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox