This patch series introduces a new configfs attribute that enables sending messages directly through netconsole without going through the kernel's logging infrastructure.
This feature allows users to send custom messages, alerts, or status updates directly to netconsole receivers by writing to /sys/kernel/config/netconsole/<target>/send_msg, without poluting kernel buffers, and sending msgs to the serial, which could be slow.
At Meta this is currently used in two cases right now (through printk by now):
a) When a new workload enters or leave the machine. b) From time to time, as a "ping" to make sure the netconsole/machine is alive.
The implementation reuses the existing message transmission functions (send_msg_udp() and send_ext_msg_udp()) to handle both basic and extended message formats.
Regarding code organization, this version uses forward declarations for send_msg_udp() and send_ext_msg_udp() functions rather than relocating them within the file. While forward declarations do add a small amount of redundancy, they avoid the larger churn that would result from moving entire function definitions.
--- Breno Leitao (4): netconsole: extract message fragmentation into send_msg_udp() netconsole: Add configfs attribute for direct message sending selftests/netconsole: Switch to configfs send_msg interface Documentation: netconsole: Document send_msg configfs attribute
Documentation/networking/netconsole.rst | 40 +++++++++++++++ drivers/net/netconsole.c | 59 ++++++++++++++++++---- .../selftests/drivers/net/netcons_sysdata.sh | 2 +- 3 files changed, 91 insertions(+), 10 deletions(-) --- base-commit: ab084f0b8d6d2ee4b1c6a28f39a2a7430bdfa7f0 change-id: 20251127-netconsole_send_msg-89813956dc23
Best regards, -- Breno Leitao leitao@debian.org
Add documentation for the new send_msg configfs attribute that allows sending custom messages directly through netconsole targets.
The documentation covers: - How to use the send_msg attribute - Key features and requirements - Use cases for direct message sending - Example of periodic health check implementation
This feature enables userspace applications to inject custom messages into the netconsole stream without going through the kernel's printk infrastructure, which is useful for application monitoring, testing, and debugging purposes.
Signed-off-by: Breno Leitao leitao@debian.org --- Documentation/networking/netconsole.rst | 40 +++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+)
diff --git a/Documentation/networking/netconsole.rst b/Documentation/networking/netconsole.rst index 4ab5d7b05cf1..229d5fe9a3b3 100644 --- a/Documentation/networking/netconsole.rst +++ b/Documentation/networking/netconsole.rst @@ -139,6 +139,7 @@ The interface exposes these parameters of a netconsole target to userspace: local_mac Local interface's MAC address (read-only) remote_mac Remote agent's MAC address (read-write) transmit_errors Number of packet send errors (read-only) + send_msg Send custom messages directly (write-only) =============== ================================= ============
The "enabled" attribute is also used to control whether the parameters of @@ -158,6 +159,45 @@ You can also update the local interface dynamically. This is especially useful if you want to use interfaces that have newly come up (and may not have existed when netconsole was loaded / initialized).
+Direct Message Sending +---------------------- + +The `send_msg` attribute allows sending custom messages directly through a +netconsole target without going through the kernel's printk infrastructure. +This is a write-only attribute that can be used to send arbitrary text to +the configured remote logging agent. + +To send a message directly:: + + echo "Custom status message" > /sys/kernel/config/netconsole/target1/send_msg + +Key features: + +* Messages can be sent only when the target is enabled +* The network interface must be up and running +* For extended targets, messages are sent with the extended header format +* For non-extended targets, messages are fragmented if they exceed the + maximum chunk size +* Messages bypass the kernel log buffer entirely + +This is useful for: + +* Sending application-level alerts or status updates +* Injecting custom markers or delimiters into the log stream +* Sending diagnostic information from userspace scripts +* Testing netconsole connectivity without generating kernel messages + +Example use case - sending periodic health checks:: + + while true; do + echo "[$(date)] System health: OK" > /sys/kernel/config/netconsole/target1/send_msg + sleep 60 + done + +.. note:: + The `send_msg` attribute requires the target to be enabled. Unlike other + parameters, you do not need to disable the target to use this attribute. + Netconsole targets defined at boot time (or module load time) with the `netconsole=` param are assigned the name `cmdline<index>`. For example, the first target in the parameter is named `cmdline0`. You can control and modify
Extract the message fragmentation logic from write_msg() into a dedicated send_msg_udp() function. This improves code readability and prepares for future enhancements.
The new send_msg_udp() function handles splitting messages that exceed MAX_PRINT_CHUNK into smaller fragments and sending them sequentially. This function is placed before send_ext_msg_udp() to maintain a logical ordering of related functions.
No functional changes - this is purely a refactoring commit.
Signed-off-by: Breno Leitao leitao@debian.org Reviewed-by: Petr Mladek pmladek@suse.com --- drivers/net/netconsole.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index 9cb4dfc242f5..dc3bd7c9b049 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -1725,12 +1725,24 @@ static void write_ext_msg(struct console *con, const char *msg, spin_unlock_irqrestore(&target_list_lock, flags); }
+static void send_msg_udp(struct netconsole_target *nt, const char *msg, + unsigned int len) +{ + const char *tmp = msg; + int frag, left = len; + + while (left > 0) { + frag = min(left, MAX_PRINT_CHUNK); + send_udp(nt, tmp, frag); + tmp += frag; + left -= frag; + } +} + static void write_msg(struct console *con, const char *msg, unsigned int len) { - int frag, left; unsigned long flags; struct netconsole_target *nt; - const char *tmp;
if (oops_only && !oops_in_progress) return; @@ -1747,13 +1759,7 @@ static void write_msg(struct console *con, const char *msg, unsigned int len) * at least one target if we die inside here, instead * of unnecessarily keeping all targets in lock-step. */ - tmp = msg; - for (left = len; left;) { - frag = min(left, MAX_PRINT_CHUNK); - send_udp(nt, tmp, frag); - tmp += frag; - left -= frag; - } + send_msg_udp(nt, msg, len); } } spin_unlock_irqrestore(&target_list_lock, flags);
Add a new write-only configfs attribute "send_msg" to netconsole targets that allows sending arbitrary messages directly through netconsole.
This feature enables users to send custom messages through netconsole without having to go through the kernel logging infrastructure. Messages can be sent by simply writing to: /sys/kernel/config/netconsole/<target>/send_msg
The implementation: - Checks if the target is enabled before sending - Verifies the network interface is running - Handles both basic and extended message formats - Fragments large messages when needed for basic targets - Reuses existing send_msg_udp() and send_ext_msg_udp() functions
Unfortunately this patch has two forward declaration, which is not ideal, but, moving send_msg_udp() functions earlier would cause too many changes, and this could be done in an idependent patch.
Signed-off-by: Breno Leitao leitao@debian.org --- drivers/net/netconsole.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index dc3bd7c9b049..245ed2584bbb 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c @@ -1194,6 +1194,39 @@ static const struct config_item_type userdata_type = { .ct_owner = THIS_MODULE, };
+/* Forward declarations */ +static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg, + int msg_len); +static void send_msg_udp(struct netconsole_target *nt, const char *msg, + unsigned int len); + +static ssize_t send_msg_store(struct config_item *item, const char *buf, + size_t count) +{ + struct netconsole_target *nt = to_target(item); + ssize_t ret = -EINVAL; + unsigned long flags; + + mutex_lock(&dynamic_netconsole_mutex); + if (!nt->enabled) + goto out; + + if (!netif_running(nt->np.dev)) + goto out; + + spin_lock_irqsave(&target_list_lock, flags); + if (nt->extended) + send_ext_msg_udp(nt, buf, count); + else + send_msg_udp(nt, buf, count); + spin_unlock_irqrestore(&target_list_lock, flags); + + ret = count; +out: + mutex_unlock(&dynamic_netconsole_mutex); + + return ret; +} CONFIGFS_ATTR(, enabled); CONFIGFS_ATTR(, extended); CONFIGFS_ATTR(, dev_name); @@ -1205,6 +1238,7 @@ CONFIGFS_ATTR_RO(, local_mac); CONFIGFS_ATTR(, remote_mac); CONFIGFS_ATTR(, release); CONFIGFS_ATTR_RO(, transmit_errors); +CONFIGFS_ATTR_WO(, send_msg);
static struct configfs_attribute *netconsole_target_attrs[] = { &attr_enabled, @@ -1218,6 +1252,7 @@ static struct configfs_attribute *netconsole_target_attrs[] = { &attr_local_mac, &attr_remote_mac, &attr_transmit_errors, + &attr_send_msg, NULL, };
Update the netcons_sysdata test to use the configfs send_msg attribute for message injection instead of /dev/kmsg. This validates the new direct message sending functionality that bypasses the kernel's printk infrastructure.
Only move this test to the new mechanism, given the traditional printk() flow continues to be default path, and the one that should be mostly tested.
Signed-off-by: Breno Leitao leitao@debian.org --- tools/testing/selftests/drivers/net/netcons_sysdata.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/drivers/net/netcons_sysdata.sh b/tools/testing/selftests/drivers/net/netcons_sysdata.sh index baf69031089e..27df730dc8f3 100755 --- a/tools/testing/selftests/drivers/net/netcons_sysdata.sh +++ b/tools/testing/selftests/drivers/net/netcons_sysdata.sh @@ -195,7 +195,7 @@ function runtest { # Wait for socat to start and listen to the port. wait_local_port_listen "${NAMESPACE}" "${PORT}" udp # Send the message - taskset -c "${CPU}" echo "${MSG}: ${TARGET}" > /dev/kmsg + taskset -c "${CPU}" echo "${MSG}: ${TARGET}" > "$NETCONS_PATH"/send_msg # Wait until socat saves the file to disk busywait "${BUSYWAIT_TIMEOUT}" test -s "${OUTPUT_FILE}" }
linux-kselftest-mirror@lists.linaro.org