Skip to content

Commit ec15bc4

Browse files
leitaodavem330
authored andcommitted
netconsole: add support for sysdata and CPU population
Add infrastructure to automatically append kernel-generated data (sysdata) to netconsole messages. As the first use case, implement CPU number population, which adds the CPU that sent the message. This change introduces three distinct data types: - extradata: The complete set of appended data (sysdata + userdata) - userdata: User-provided key-value pairs from userspace - sysdata: Kernel-populated data (e.g. cpu=XX) The implementation adds a new configfs attribute 'cpu_nr' to control CPU number population per target. When enabled, each message is tagged with its originating CPU. The sysdata is dynamically updated at message time and appended after any existing userdata. The CPU number is formatted as "cpu=XX" and is added to the extradata buffer, respecting the existing size limits. Signed-off-by: Breno Leitao <leitao@debian.org> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 2bae25b commit ec15bc4

File tree

1 file changed

+43
-10
lines changed

1 file changed

+43
-10
lines changed

drivers/net/netconsole.c

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,40 @@ static void populate_configfs_item(struct netconsole_target *nt,
11171117
init_target_config_group(nt, target_name);
11181118
}
11191119

1120+
/*
1121+
* prepare_extradata - append sysdata at extradata_complete in runtime
1122+
* @nt: target to send message to
1123+
*/
1124+
static int prepare_extradata(struct netconsole_target *nt)
1125+
{
1126+
int sysdata_len, extradata_len;
1127+
1128+
/* userdata was appended when configfs write helper was called
1129+
* by update_userdata().
1130+
*/
1131+
extradata_len = nt->userdata_length;
1132+
1133+
if (!(nt->sysdata_fields & CPU_NR))
1134+
goto out;
1135+
1136+
/* Append cpu=%d at extradata_complete after userdata str */
1137+
sysdata_len = scnprintf(&nt->extradata_complete[nt->userdata_length],
1138+
MAX_EXTRADATA_ENTRY_LEN, " cpu=%u\n",
1139+
raw_smp_processor_id());
1140+
1141+
extradata_len += sysdata_len;
1142+
1143+
WARN_ON_ONCE(extradata_len >
1144+
MAX_EXTRADATA_ENTRY_LEN * MAX_EXTRADATA_ITEMS);
1145+
1146+
out:
1147+
return extradata_len;
1148+
}
1149+
#else /* CONFIG_NETCONSOLE_DYNAMIC not set */
1150+
static int prepare_extradata(struct netconsole_target *nt)
1151+
{
1152+
return 0;
1153+
}
11201154
#endif /* CONFIG_NETCONSOLE_DYNAMIC */
11211155

11221156
/* Handle network interface device notifications */
@@ -1251,16 +1285,14 @@ static void append_release(char *buf)
12511285

12521286
static void send_fragmented_body(struct netconsole_target *nt,
12531287
const char *msgbody, int header_len,
1254-
int msgbody_len)
1288+
int msgbody_len, int extradata_len)
12551289
{
12561290
int sent_extradata, preceding_bytes;
12571291
const char *extradata = NULL;
12581292
int body_len, offset = 0;
1259-
int extradata_len = 0;
12601293

12611294
#ifdef CONFIG_NETCONSOLE_DYNAMIC
12621295
extradata = nt->extradata_complete;
1263-
extradata_len = nt->userdata_length;
12641296
#endif
12651297

12661298
/* body_len represents the number of bytes that will be sent. This is
@@ -1341,7 +1373,8 @@ static void send_fragmented_body(struct netconsole_target *nt,
13411373
static void send_msg_fragmented(struct netconsole_target *nt,
13421374
const char *msg,
13431375
int msg_len,
1344-
int release_len)
1376+
int release_len,
1377+
int extradata_len)
13451378
{
13461379
int header_len, msgbody_len;
13471380
const char *msgbody;
@@ -1369,7 +1402,8 @@ static void send_msg_fragmented(struct netconsole_target *nt,
13691402
/* for now on, the header will be persisted, and the msgbody
13701403
* will be replaced
13711404
*/
1372-
send_fragmented_body(nt, msgbody, header_len, msgbody_len);
1405+
send_fragmented_body(nt, msgbody, header_len, msgbody_len,
1406+
extradata_len);
13731407
}
13741408

13751409
/**
@@ -1385,20 +1419,19 @@ static void send_msg_fragmented(struct netconsole_target *nt,
13851419
static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg,
13861420
int msg_len)
13871421
{
1388-
int extradata_len = 0;
13891422
int release_len = 0;
1423+
int extradata_len;
13901424

1391-
#ifdef CONFIG_NETCONSOLE_DYNAMIC
1392-
extradata_len = nt->userdata_length;
1393-
#endif
1425+
extradata_len = prepare_extradata(nt);
13941426

13951427
if (nt->release)
13961428
release_len = strlen(init_utsname()->release) + 1;
13971429

13981430
if (msg_len + release_len + extradata_len <= MAX_PRINT_CHUNK)
13991431
return send_msg_no_fragmentation(nt, msg, msg_len, release_len);
14001432

1401-
return send_msg_fragmented(nt, msg, msg_len, release_len);
1433+
return send_msg_fragmented(nt, msg, msg_len, release_len,
1434+
extradata_len);
14021435
}
14031436

14041437
static void write_ext_msg(struct console *con, const char *msg,

0 commit comments

Comments
 (0)