From: Stefano Brivio <sbrivio@redhat.com>
To: Yumei Huang <yuhuang@redhat.com>
Cc: passt-dev@passt.top, david@gibson.dropbear.id.au
Subject: Re: [PATCH v8 2/6] util: Introduce read_file() and read_file_integer() function
Date: Tue, 18 Nov 2025 01:19:38 +0100 [thread overview]
Message-ID: <20251118011938.47d5c1e2@elisabeth> (raw)
In-Reply-To: <20251110093137.87705-3-yuhuang@redhat.com>
On Mon, 10 Nov 2025 17:31:33 +0800
Yumei Huang <yuhuang@redhat.com> wrote:
> Signed-off-by: Yumei Huang <yuhuang@redhat.com>
> Reviewed-by: David Gibson <david@gibson.dropbear.id.au>
> ---
> util.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> util.h | 2 ++
> 2 files changed, 88 insertions(+)
>
> diff --git a/util.c b/util.c
> index 44c21a3..c4c849c 100644
> --- a/util.c
> +++ b/util.c
> @@ -590,6 +590,92 @@ int write_file(const char *path, const char *buf)
> return len == 0 ? 0 : -1;
> }
>
> +/**
> + * read_file() - Read contents of file into a NULL-terminated buffer
> + * @path: Path to file to read
> + * @buf: Buffer to store file contents
> + * @buf_size: Size of buffer
> + *
> + * Return: number of bytes read on success, -1 on error, -ENOBUFS on truncation
> + */
> +ssize_t read_file(const char *path, char *buf, size_t buf_size)
> +{
> + int fd = open(path, O_RDONLY | O_CLOEXEC);
> + size_t total_read = 0;
> + ssize_t rc;
> +
> + if (fd < 0) {
> + warn_perror("Could not open %s", path);
While testing something unrelated I realised that this looks like a
serious failure, but it's perfectly normal on (even slightly) older
kernels:
---
$ git describe --contains ccce324dabfe # tcp: make the first N SYN RTO backoffs linear
v6.5-rc1~163^2~299
$ git describe --contains 1280c26228bd # tcp: add tcp_rto_max_ms sysctl
v6.15-rc1~160^2~352^2
---
On a 6.1 kernel, for example:
---
$ ./pasta -d --config-net
[...]
0.0258: Could not open /proc/sys/net/ipv4/tcp_syn_linear_timeouts: No such file or directory
0.0258: Could not open /proc/sys/net/ipv4/tcp_rto_max_ms: No such file or directory
0.0258: Read sysctl values syn_retries: 6, syn_linear_timeouts: 4, rto_max: 120
---
and actually the third message isn't accurate, because we didn't read
those values, we are just using them.
Worse, yet:
---
$ ./pasta
Could not open /proc/sys/net/ipv4/tcp_syn_linear_timeouts: No such file or directory
Could not open /proc/sys/net/ipv4/tcp_rto_max_ms: No such file or directory
---
so this would be logged *with default options* by Podman, rootlesskit /
Docker, via libvirt, and by other users too, meaning we would get
submerged by reports about this "error" if we release it like this (6.15
is fairly recent).
So maybe we could turn this (and the messages below) to debug() /
debug_perror(), and then:
> + return -1;
> + }
> +
> + while (total_read < buf_size) {
> + rc = read(fd, buf + total_read, buf_size - total_read);
> +
> + if (rc < 0) {
> + warn_perror("Couldn't read from %s", path);
> + close(fd);
> + return -1;
> + }
> +
> + if (rc == 0)
> + break;
> +
> + total_read += rc;
> + }
> +
> + close(fd);
> +
> + if (total_read == buf_size) {
> + warn("File %s contents exceed buffer size %zu", path,
> + buf_size);
> + buf[buf_size - 1] = '\0';
> + return -ENOBUFS;
> + }
> +
> + buf[total_read] = '\0';
> +
> + return total_read;
> +}
> +
> +/**
> + * read_file_integer() - Read an integer value from a file
> + * @path: Path to file to read
> + * @fallback: Default value if file can't be read
> + *
> + * Return: integer value, @fallback on failure
> + */
> +intmax_t read_file_integer(const char *path, intmax_t fallback)
> +{
> + ssize_t bytes_read;
> + char buf[BUFSIZ];
> + intmax_t value;
> + char *end;
> +
> + bytes_read = read_file(path, buf, sizeof(buf));
> +
> + if (bytes_read < 0)
> + return fallback;
...say something here, like "using %i as default value", so that it's
clear that the error doesn't have further consequences.
We should probably do that for all the failure cases here, so you might
want to 'goto error;' here, and also:
> +
> + if (bytes_read == 0) {
> + debug("Empty file %s", path);
here, and below, and then:
> + return fallback;
> + }
> +
> + errno = 0;
> + value = strtoimax(buf, &end, 10);
> + if (*end && *end != '\n') {
> + debug("Non-numeric content in %s", path);
> + return fallback;
> + }
> + if (errno) {
> + debug("Out of range value in %s: %s", path, buf);
> + return fallback;
> + }
> +
> + return value;
error:
debug("Using ...")
return fallback;
> +}
> +
> #ifdef __ia64__
> /* Needed by do_clone() below: glibc doesn't export the prototype of __clone2(),
> * use the description from clone(2).
> diff --git a/util.h b/util.h
> index a0b2ada..c1502cc 100644
> --- a/util.h
> +++ b/util.h
> @@ -229,6 +229,8 @@ void pidfile_write(int fd, pid_t pid);
> int __daemon(int pidfile_fd, int devnull_fd);
> int fls(unsigned long x);
> int write_file(const char *path, const char *buf);
> +ssize_t read_file(const char *path, char *buf, size_t buf_size);
> +intmax_t read_file_integer(const char *path, intmax_t fallback);
> int write_all_buf(int fd, const void *buf, size_t len);
> int write_remainder(int fd, const struct iovec *iov, size_t iovcnt, size_t skip);
> int read_all_buf(int fd, void *buf, size_t len);
--
Stefano
next prev parent reply other threads:[~2025-11-18 0:19 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-10 9:31 [PATCH v8 0/6] Retry SYNs for inbound connections Yumei Huang
2025-11-10 9:31 ` [PATCH v8 1/6] tcp: Rename "retrans" to "retries" Yumei Huang
2025-11-10 9:31 ` [PATCH v8 2/6] util: Introduce read_file() and read_file_integer() function Yumei Huang
2025-11-14 0:01 ` Stefano Brivio
2025-11-14 1:58 ` Yumei Huang
2025-11-14 4:32 ` David Gibson
2025-11-14 10:12 ` Stefano Brivio
2025-11-17 1:10 ` Yumei Huang
2025-11-18 0:19 ` Stefano Brivio
2025-11-18 0:19 ` Stefano Brivio [this message]
2025-11-18 3:22 ` David Gibson
2025-11-19 9:04 ` Yumei Huang
2025-11-19 9:38 ` David Gibson
2025-11-10 9:31 ` [PATCH v8 3/6] tcp: Add parameter struct ctx *c to tcp_timer_ctl() Yumei Huang
2025-11-10 10:35 ` David Gibson
2025-11-14 0:01 ` Stefano Brivio
2025-11-14 0:36 ` David Gibson
2025-11-10 9:31 ` [PATCH v8 4/6] tcp: Resend SYN for inbound connections Yumei Huang
2025-11-10 10:46 ` David Gibson
2025-11-14 0:00 ` Stefano Brivio
2025-11-14 0:31 ` David Gibson
2025-11-18 0:19 ` Stefano Brivio
2025-11-10 9:31 ` [PATCH v8 5/6] tcp: Update data retransmission timeout Yumei Huang
2025-11-10 9:31 ` [PATCH v8 6/6] tcp: Clamp the retry timeout Yumei Huang
2025-11-10 10:56 ` David Gibson
2025-11-14 0:01 ` Stefano Brivio
2025-11-14 0:35 ` David Gibson
2025-11-14 3:05 ` Yumei Huang
2025-11-14 3:35 ` David Gibson
2025-11-17 2:38 ` Yumei Huang
2025-11-17 4:50 ` David Gibson
2025-11-18 0:19 ` Stefano Brivio
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251118011938.47d5c1e2@elisabeth \
--to=sbrivio@redhat.com \
--cc=david@gibson.dropbear.id.au \
--cc=passt-dev@passt.top \
--cc=yuhuang@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://passt.top/passt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for IMAP folder(s).