diff options
author | Matthew Wood <thepacketgeek@gmail.com> | 2024-02-04 15:27:39 -0800 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2024-02-09 10:23:46 +0000 |
commit | 1ec9daf950936c2a1c591596e83c09ce2eb12ade (patch) | |
tree | ee5ca807dadabf62ccddf32e8076e8bf20a504d2 /drivers/net | |
parent | b4ab4f2c0ff5f6b5aeccd71c5caeef2cbcfea47d (diff) |
net: netconsole: append userdata to fragmented netconsole messages
Regardless of whether the original message body or formatted userdata
exceeds the MAX_PRINT_CHUNK, append userdata to the netconsole message
starting with the first chunk that has available space after writing the
body.
Co-developed-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Matthew Wood <thepacketgeek@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/netconsole.c | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index d53bb1172336..0de108a1c0c8 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -1085,24 +1085,48 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg, memcpy(buf + release_len, header, header_len); header_len += release_len; - while (offset < body_len) { + while (offset < body_len + userdata_len) { int this_header = header_len; - int this_chunk; + int this_offset = 0; + int this_chunk = 0; this_header += scnprintf(buf + this_header, sizeof(buf) - this_header, - ",ncfrag=%d/%d;", offset, body_len); - - this_chunk = min(body_len - offset, - MAX_PRINT_CHUNK - this_header); - if (WARN_ON_ONCE(this_chunk <= 0)) - return; - - memcpy(buf + this_header, body + offset, this_chunk); - - netpoll_send_udp(&nt->np, buf, this_header + this_chunk); + ",ncfrag=%d/%d;", offset, + body_len + userdata_len); + + /* Not all body data has been written yet */ + if (offset < body_len) { + this_chunk = min(body_len - offset, + MAX_PRINT_CHUNK - this_header); + if (WARN_ON_ONCE(this_chunk <= 0)) + return; + memcpy(buf + this_header, body + offset, this_chunk); + this_offset += this_chunk; + } + /* Body is fully written and there is pending userdata to write, + * append userdata in this chunk + */ + if (offset + this_offset >= body_len && + offset + this_offset < userdata_len + body_len) { + int sent_userdata = (offset + this_offset) - body_len; + int preceding_bytes = this_chunk + this_header; + + if (WARN_ON_ONCE(sent_userdata < 0)) + return; + + this_chunk = min(userdata_len - sent_userdata, + MAX_PRINT_CHUNK - preceding_bytes); + if (WARN_ON_ONCE(this_chunk <= 0)) + return; + memcpy(buf + this_header + this_offset, + userdata + sent_userdata, + this_chunk); + this_offset += this_chunk; + } - offset += this_chunk; + netpoll_send_udp(&nt->np, buf, this_header + this_offset); + offset += this_offset; } } |