net: netconsole: separate fragmented message handling in send_ext_msg

Following the previous change, where the non-fragmented case was moved
to its own function, this update introduces a new function called
send_msg_fragmented to specifically manage scenarios where message
fragmentation is required.

Signed-off-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Breno Leitao 2024-10-17 02:50:18 -07:00 committed by Paolo Abeni
parent e7650d8d47
commit e1e1ea2e78

View File

@ -1084,42 +1084,23 @@ static void send_msg_no_fragmentation(struct netconsole_target *nt,
netpoll_send_udp(&nt->np, buf, msg_len);
}
/**
* send_ext_msg_udp - send extended log message to target
* @nt: target to send message to
* @msg: extended log message to send
* @msg_len: length of message
*
* Transfer extended log @msg to @nt. If @msg is longer than
* MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with
* ncfrag header field added to identify them.
*/
static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
int msg_len)
static void send_msg_fragmented(struct netconsole_target *nt,
const char *msg,
const char *userdata,
int msg_len,
int release_len)
{
static char buf[MAX_PRINT_CHUNK]; /* protected by target_list_lock */
int offset = 0, userdata_len = 0;
const char *header, *body;
int offset = 0;
int header_len, body_len;
const char *release;
int release_len = 0;
int userdata_len = 0;
char *userdata = NULL;
#ifdef CONFIG_NETCONSOLE_DYNAMIC
userdata = nt->userdata_complete;
userdata_len = nt->userdata_length;
if (userdata)
userdata_len = nt->userdata_length;
#endif
if (nt->release) {
release = init_utsname()->release;
release_len = strlen(release) + 1;
}
if (msg_len + release_len + userdata_len <= MAX_PRINT_CHUNK)
return send_msg_no_fragmentation(nt, msg, userdata, msg_len,
release_len);
/* need to insert extra header fields, detect header and body */
header = msg;
body = memchr(msg, ';', msg_len);
@ -1134,11 +1115,18 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
* Transfer multiple chunks with the following extra header.
* "ncfrag=<byte-offset>/<total-bytes>"
*/
if (nt->release)
if (release_len) {
release = init_utsname()->release;
scnprintf(buf, MAX_PRINT_CHUNK, "%s,", release);
}
/* Copy the header into the buffer */
memcpy(buf + release_len, header, header_len);
header_len += release_len;
/* for now on, the header will be persisted, and the body
* will be replaced
*/
while (offset < body_len + userdata_len) {
int this_header = header_len;
int this_offset = 0;
@ -1190,6 +1178,38 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
}
}
/**
* send_ext_msg_udp - send extended log message to target
* @nt: target to send message to
* @msg: extended log message to send
* @msg_len: length of message
*
* Transfer extended log @msg to @nt. If @msg is longer than
* MAX_PRINT_CHUNK, it'll be split and transmitted in multiple chunks with
* ncfrag header field added to identify them.
*/
static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
int msg_len)
{
char *userdata = NULL;
int userdata_len = 0;
int release_len = 0;
#ifdef CONFIG_NETCONSOLE_DYNAMIC
userdata = nt->userdata_complete;
userdata_len = nt->userdata_length;
#endif
if (nt->release)
release_len = strlen(init_utsname()->release) + 1;
if (msg_len + release_len + userdata_len <= MAX_PRINT_CHUNK)
return send_msg_no_fragmentation(nt, msg, userdata, msg_len,
release_len);
return send_msg_fragmented(nt, msg, userdata, msg_len, release_len);
}
static void write_ext_msg(struct console *con, const char *msg,
unsigned int len)
{