tools/testing/selftests/net/mptcp/mptcp_connect.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+)
In case of poll timeout, it might be too late to print the stats after
the socket closure.
Now, in case of poll timeout, 'ss' and 'nstat' are invoked from
mptcp_connect to print the stats before exiting. This should help
debugging poll timeout issues.
Note: for this "workaround", system() is used for debugging purposes
only. The returned result can then be safely ignored.
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
---
tools/testing/selftests/net/mptcp/mptcp_connect.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
index ea4cb6c1bd5e..842c0eb99aa9 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
@@ -210,6 +210,19 @@ static void xgetaddrinfo(const char *node, const char *service,
}
}
+static void print_err_stats(void)
+{
+ char cmd[128];
+
+ snprintf(cmd, sizeof(cmd), "ss -Menitam -o '%cport = :%s' >&2",
+ listen_mode ? 's' : 'd', cfg_port);
+
+ fprintf(stderr, "socket stats before socket closure:\n");
+ (void)!system(cmd);
+ (void)!system("NSTAT_HISTORY='/tmp/$(ip netns id).nstat' nstat -s | "
+ "grep Tcp >&2");
+}
+
static void set_rcvbuf(int fd, unsigned int size)
{
int err;
@@ -656,6 +669,7 @@ static int copyfd_io_poll(int infd, int peerfd, int outfd,
fprintf(stderr, "%s: poll timed out (events: "
"POLLIN %u, POLLOUT %u)\n", __func__,
fds.events & POLLIN, fds.events & POLLOUT);
+ print_err_stats();
return 2;
}
@@ -1194,6 +1208,7 @@ int main_loop_s(int listensock)
return 1;
case 0:
fprintf(stderr, "%s: timed out\n", __func__);
+ print_err_stats();
close(listensock);
return 2;
}
---
base-commit: d536472a82d18356d323227213acb5603bb9050c
change-id: 20260814-sft-mptcp-stats-b4-close-20964ff6a6ba
Best regards,
--
Matthieu Baerts (NGI0) <matttbe@kernel.org>
On 8/14/26 4:07 PM, Matthieu Baerts (NGI0) wrote:
> In case of poll timeout, it might be too late to print the stats after
> the socket closure.
>
> Now, in case of poll timeout, 'ss' and 'nstat' are invoked from
> mptcp_connect to print the stats before exiting. This should help
> debugging poll timeout issues.
>
> Note: for this "workaround", system() is used for debugging purposes
> only. The returned result can then be safely ignored.
>
> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
> ---
> tools/testing/selftests/net/mptcp/mptcp_connect.c | 15 +++++++++++++++
> 1 file changed, 15 insertions(+)
>
> diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
> index ea4cb6c1bd5e..842c0eb99aa9 100644
> --- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
> +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
> @@ -210,6 +210,19 @@ static void xgetaddrinfo(const char *node, const char *service,
> }
> }
>
> +static void print_err_stats(void)
> +{
> + char cmd[128];
> +
> + snprintf(cmd, sizeof(cmd), "ss -Menitam -o '%cport = :%s' >&2",
> + listen_mode ? 's' : 'd', cfg_port);
> +
> + fprintf(stderr, "socket stats before socket closure:\n");
> + (void)!system(cmd);
> + (void)!system("NSTAT_HISTORY='/tmp/$(ip netns id).nstat' nstat -s | "
> + "grep Tcp >&2");
Overall LGTM. I tried something similar in the past, but the correct
redirection always fouled me. A couple of questions:
- Is the '!' operator needed?
- Can we avoid the pipe? with something alike the following:
(void)system("NSTAT_HISTORY='/tmp/$(ip netns id).nstat' nstat -s *Tcp*
>&2");
/P
Hi Paolo,
On 14/08/2026 18:44, Paolo Abeni wrote:
> On 8/14/26 4:07 PM, Matthieu Baerts (NGI0) wrote:
>> In case of poll timeout, it might be too late to print the stats after
>> the socket closure.
>>
>> Now, in case of poll timeout, 'ss' and 'nstat' are invoked from
>> mptcp_connect to print the stats before exiting. This should help
>> debugging poll timeout issues.
>>
>> Note: for this "workaround", system() is used for debugging purposes
>> only. The returned result can then be safely ignored.
>>
>> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
>> ---
>> tools/testing/selftests/net/mptcp/mptcp_connect.c | 15 +++++++++++++++
>> 1 file changed, 15 insertions(+)
>>
>> diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
>> index ea4cb6c1bd5e..842c0eb99aa9 100644
>> --- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
>> +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
>> @@ -210,6 +210,19 @@ static void xgetaddrinfo(const char *node, const char *service,
>> }
>> }
>>
>> +static void print_err_stats(void)
>> +{
>> + char cmd[128];
>> +
>> + snprintf(cmd, sizeof(cmd), "ss -Menitam -o '%cport = :%s' >&2",
>> + listen_mode ? 's' : 'd', cfg_port);
>> +
>> + fprintf(stderr, "socket stats before socket closure:\n");
>> + (void)!system(cmd);
>> + (void)!system("NSTAT_HISTORY='/tmp/$(ip netns id).nstat' nstat -s | "
>> + "grep Tcp >&2");
>
> Overall LGTM. I tried something similar in the past, but the correct
> redirection always fouled me. A couple of questions:
Thank you for having checked!
> - Is the '!' operator needed?
Yes, to avoid a warning because the results are unused. Only using
(void) is not enough from what I saw.
> - Can we avoid the pipe? with something alike the following:
> (void)system("NSTAT_HISTORY='/tmp/$(ip netns id).nstat' nstat -s *Tcp*
Oh nice, I didn't think about that. Yes it works except it keeps the
header (#kernel). Maybe fine here, but we don't change that in the .sh
scripts?
I can send a v2 with that and an extra explanation.
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
Hi Matthieu,
Thank you for your modifications, that's great!
Our CI did some validations and here is its report:
- KVM Validation: normal (except selftest_mptcp_join): Success! ✅
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Success! ✅
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/31809426881
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/47284683c1d2
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1146126
If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:
$ cd [kernel source code]
$ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
--pull always mptcp/mptcp-upstream-virtme-docker:latest \
auto-normal
For more details:
https://github.com/multipath-tcp/mptcp-upstream-virtme-docker
Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)
Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Invalid iproute2 command `ip netns id` causes an error message and incorrect NSTAT_HISTORY file path.
--
--- Patch [1]: [PATCH mptcp-next] selftests: mptcp: print stats before socket closure ---
commit 0e02bc2b403cc7ef4929da44802ea29557081b60
Author: Matthieu Baerts (NGI0) <matttbe@kernel.org>
selftests: mptcp: print stats before socket closure
This commit adds a mechanism to dump socket statistics via ss and nstat
just before socket closure when a poll timeout occurs. This helps debug
timeout issues in the mptcp_connect test.
> diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
> --- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
> +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
[ ... ]
> @@ -210,6 +210,19 @@ static void xgetaddrinfo(const char *node, const char *service,
> }
> }
>
> +static void print_err_stats(void)
> +{
> + char cmd[128];
> +
> + snprintf(cmd, sizeof(cmd), "ss -Menitam -o '%cport = :%s' >&2",
> + listen_mode ? 's' : 'd', cfg_port);
> +
> + fprintf(stderr, "socket stats before socket closure:\n");
> + (void)!system(cmd);
> + (void)!system("NSTAT_HISTORY='/tmp/$(ip netns id).nstat' nstat -s | "
[Severity: Medium]
Will this ip netns id command fail and cause an iproute2 error during the
test?
It appears ip netns id is an invalid command, and should likely be
ip netns identify.
If it fails, ip netns id will log an error message instead of outputting
the namespace name, which causes the NSTAT_HISTORY environment variable to
fall back to /tmp/.nstat.
Because this fallback file path isn't isolated per namespace, concurrent
test runs might share it, potentially resulting in garbled network
statistics in the debug logs when a timeout occurs.
> + "grep Tcp >&2");
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260814-sft-mptcp-stats-b4-close-v1-1-2945a591be7e@kernel.org?part=1
On 14/08/2026 16:15, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] Invalid iproute2 command `ip netns id` causes an error message and incorrect NSTAT_HISTORY file path.
> --
>
> --- Patch [1]: [PATCH mptcp-next] selftests: mptcp: print stats before socket closure ---
> commit 0e02bc2b403cc7ef4929da44802ea29557081b60
> Author: Matthieu Baerts (NGI0) <matttbe@kernel.org>
>
> selftests: mptcp: print stats before socket closure
>
> This commit adds a mechanism to dump socket statistics via ss and nstat
> just before socket closure when a poll timeout occurs. This helps debug
> timeout issues in the mptcp_connect test.
>
>> diff --git a/tools/testing/selftests/net/mptcp/mptcp_connect.c b/tools/testing/selftests/net/mptcp/mptcp_connect.c
>> --- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
>> +++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
> [ ... ]
>> @@ -210,6 +210,19 @@ static void xgetaddrinfo(const char *node, const char *service,
>> }
>> }
>>
>> +static void print_err_stats(void)
>> +{
>> + char cmd[128];
>> +
>> + snprintf(cmd, sizeof(cmd), "ss -Menitam -o '%cport = :%s' >&2",
>> + listen_mode ? 's' : 'd', cfg_port);
>> +
>> + fprintf(stderr, "socket stats before socket closure:\n");
>> + (void)!system(cmd);
>> + (void)!system("NSTAT_HISTORY='/tmp/$(ip netns id).nstat' nstat -s | "
> [Severity: Medium]
> Will this ip netns id command fail and cause an iproute2 error during the
> test?
>
> It appears ip netns id is an invalid command, and should likely be
> ip netns identify.
No, 'ip netns id' is valid and is the same as 'ip netns identify'.
I used the short version initially to fit on 80 chars, but I guess I
should still use 'identify' to avoid this warning when sending the patch
upstream...
Cheers,
Matt
--
Sponsored by the NGI0 Core fund.
© 2016 - 2026 Red Hat, Inc.