aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorPaolo Abeni <pabeni@redhat.com>2025-03-21 18:59:27 +0100
committerPaolo Abeni <pabeni@redhat.com>2025-03-21 18:59:28 +0100
commitddf9c6d982ae7472a4da982e0497be2a140a194b (patch)
treeab0cdbb075f3f47717817129c159bdbbe8fc5667
parentnet: airoha: fix CONFIG_DEBUG_FS check (diff)
parentdocs: netconsole: document release feature (diff)
downloadwireguard-linux-ddf9c6d982ae7472a4da982e0497be2a140a194b.tar.xz
wireguard-linux-ddf9c6d982ae7472a4da982e0497be2a140a194b.zip
Merge branch 'netconsole-add-support-for-userdata-release'
Breno Leitao says: ==================== netconsole: Add support for userdata release I am submitting a series of patches that introduce a new feature for the netconsole subsystem, specifically the addition of the 'release' field to the sysdata structure. This feature allows the kernel release/version to be appended to the userdata dictionary in every message sent, enhancing the information available for debugging and monitoring purposes. This complements the already supported release prepend feature, which was added some time ago. The release prepend appends the release information at the message header, which is not ideal for two reasons: 1) It is difficult to determine if a message includes this information, making it hard and resource-intensive to parse. 2) When a message is fragmented, the release information is appended to every message fragment, consuming valuable space in the packet. The "release prepend" feature was created before the concept of userdata and sysdata. Now that this format has proven successful, we are implementing the release feature as part of this enhanced structure. This patch series aims to improve the netconsole subsystem by providing a more efficient and user-friendly way to include kernel release information in messages. I believe these changes will significantly aid in system analysis and troubleshooting. Suggested-by: Manu Bretelle <chantr4@gmail.com> Signed-off-by: Breno Leitao <leitao@debian.org> ==================== Link: https://patch.msgid.link/20250314-netcons_release-v1-0-07979c4b86af@debian.org Signed-off-by: Paolo Abeni <pabeni@redhat.com>
-rw-r--r--Documentation/networking/netconsole.rst25
-rw-r--r--drivers/net/netconsole.c71
-rwxr-xr-xtools/testing/selftests/drivers/net/netcons_sysdata.sh44
3 files changed, 133 insertions, 7 deletions
diff --git a/Documentation/networking/netconsole.rst b/Documentation/networking/netconsole.rst
index ec740ba12797..a0076b542e9c 100644
--- a/Documentation/networking/netconsole.rst
+++ b/Documentation/networking/netconsole.rst
@@ -272,6 +272,31 @@ Example::
In this example, the message was generated while "echo" was the current
scheduled process.
+Kernel release auto population in userdata
+------------------------------------------
+
+Within the netconsole configfs hierarchy, there is a file named `release_enabled`
+located in the `userdata` directory. This file controls the kernel release
+(version) auto-population feature, which appends the kernel release information
+to userdata dictionary in every message sent.
+
+To enable the release auto-population::
+
+ echo 1 > /sys/kernel/config/netconsole/target1/userdata/release_enabled
+
+Example::
+
+ echo "This is a message" > /dev/kmsg
+ 12,607,22085407756,-;This is a message
+ release=6.14.0-rc6-01219-g3c027fbd941d
+
+.. note::
+
+ This feature provides the same data as the "release prepend" feature.
+ However, in this case, the release information is appended to the userdata
+ dictionary rather than being included in the message header.
+
+
CPU number auto population in userdata
--------------------------------------
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 43757b5c0216..4289ccd3e41b 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -106,6 +106,8 @@ enum sysdata_feature {
SYSDATA_CPU_NR = BIT(0),
/* Populate the task name (as in current->comm) in sysdata */
SYSDATA_TASKNAME = BIT(1),
+ /* Kernel release/version as part of sysdata */
+ SYSDATA_RELEASE = BIT(2),
};
/**
@@ -440,6 +442,19 @@ static ssize_t sysdata_taskname_enabled_show(struct config_item *item,
return sysfs_emit(buf, "%d\n", taskname_enabled);
}
+static ssize_t sysdata_release_enabled_show(struct config_item *item,
+ char *buf)
+{
+ struct netconsole_target *nt = to_target(item->ci_parent);
+ bool release_enabled;
+
+ mutex_lock(&dynamic_netconsole_mutex);
+ release_enabled = !!(nt->sysdata_fields & SYSDATA_TASKNAME);
+ mutex_unlock(&dynamic_netconsole_mutex);
+
+ return sysfs_emit(buf, "%d\n", release_enabled);
+}
+
/*
* This one is special -- targets created through the configfs interface
* are not enabled (and the corresponding netpoll activated) by default.
@@ -719,6 +734,8 @@ static size_t count_extradata_entries(struct netconsole_target *nt)
entries += 1;
if (nt->sysdata_fields & SYSDATA_TASKNAME)
entries += 1;
+ if (nt->sysdata_fields & SYSDATA_RELEASE)
+ entries += 1;
return entries;
}
@@ -855,6 +872,40 @@ static void disable_sysdata_feature(struct netconsole_target *nt,
nt->extradata_complete[nt->userdata_length] = 0;
}
+static ssize_t sysdata_release_enabled_store(struct config_item *item,
+ const char *buf, size_t count)
+{
+ struct netconsole_target *nt = to_target(item->ci_parent);
+ bool release_enabled, curr;
+ ssize_t ret;
+
+ ret = kstrtobool(buf, &release_enabled);
+ if (ret)
+ return ret;
+
+ mutex_lock(&dynamic_netconsole_mutex);
+ curr = !!(nt->sysdata_fields & SYSDATA_RELEASE);
+ if (release_enabled == curr)
+ goto unlock_ok;
+
+ if (release_enabled &&
+ count_extradata_entries(nt) >= MAX_EXTRADATA_ITEMS) {
+ ret = -ENOSPC;
+ goto unlock;
+ }
+
+ if (release_enabled)
+ nt->sysdata_fields |= SYSDATA_RELEASE;
+ else
+ disable_sysdata_feature(nt, SYSDATA_RELEASE);
+
+unlock_ok:
+ ret = strnlen(buf, count);
+unlock:
+ mutex_unlock(&dynamic_netconsole_mutex);
+ return ret;
+}
+
static ssize_t sysdata_taskname_enabled_store(struct config_item *item,
const char *buf, size_t count)
{
@@ -935,6 +986,7 @@ unlock:
CONFIGFS_ATTR(userdatum_, value);
CONFIGFS_ATTR(sysdata_, cpu_nr_enabled);
CONFIGFS_ATTR(sysdata_, taskname_enabled);
+CONFIGFS_ATTR(sysdata_, release_enabled);
static struct configfs_attribute *userdatum_attrs[] = {
&userdatum_attr_value,
@@ -996,6 +1048,7 @@ static void userdatum_drop(struct config_group *group, struct config_item *item)
static struct configfs_attribute *userdata_attrs[] = {
&sysdata_attr_cpu_nr_enabled,
&sysdata_attr_taskname_enabled,
+ &sysdata_attr_release_enabled,
NULL,
};
@@ -1171,7 +1224,7 @@ static void populate_configfs_item(struct netconsole_target *nt,
init_target_config_group(nt, target_name);
}
-static int append_cpu_nr(struct netconsole_target *nt, int offset)
+static int sysdata_append_cpu_nr(struct netconsole_target *nt, int offset)
{
/* Append cpu=%d at extradata_complete after userdata str */
return scnprintf(&nt->extradata_complete[offset],
@@ -1179,12 +1232,20 @@ static int append_cpu_nr(struct netconsole_target *nt, int offset)
raw_smp_processor_id());
}
-static int append_taskname(struct netconsole_target *nt, int offset)
+static int sysdata_append_taskname(struct netconsole_target *nt, int offset)
{
return scnprintf(&nt->extradata_complete[offset],
MAX_EXTRADATA_ENTRY_LEN, " taskname=%s\n",
current->comm);
}
+
+static int sysdata_append_release(struct netconsole_target *nt, int offset)
+{
+ return scnprintf(&nt->extradata_complete[offset],
+ MAX_EXTRADATA_ENTRY_LEN, " release=%s\n",
+ init_utsname()->release);
+}
+
/*
* prepare_extradata - append sysdata at extradata_complete in runtime
* @nt: target to send message to
@@ -1203,9 +1264,11 @@ static int prepare_extradata(struct netconsole_target *nt)
goto out;
if (nt->sysdata_fields & SYSDATA_CPU_NR)
- extradata_len += append_cpu_nr(nt, extradata_len);
+ extradata_len += sysdata_append_cpu_nr(nt, extradata_len);
if (nt->sysdata_fields & SYSDATA_TASKNAME)
- extradata_len += append_taskname(nt, extradata_len);
+ extradata_len += sysdata_append_taskname(nt, extradata_len);
+ if (nt->sysdata_fields & SYSDATA_RELEASE)
+ extradata_len += sysdata_append_release(nt, extradata_len);
WARN_ON_ONCE(extradata_len >
MAX_EXTRADATA_ENTRY_LEN * MAX_EXTRADATA_ITEMS);
diff --git a/tools/testing/selftests/drivers/net/netcons_sysdata.sh b/tools/testing/selftests/drivers/net/netcons_sysdata.sh
index f351206ed1bd..a737e377bf08 100755
--- a/tools/testing/selftests/drivers/net/netcons_sysdata.sh
+++ b/tools/testing/selftests/drivers/net/netcons_sysdata.sh
@@ -42,6 +42,17 @@ function set_taskname() {
echo 1 > "${NETCONS_PATH}/userdata/taskname_enabled"
}
+# Enable the release to be appended to sysdata
+function set_release() {
+ if [[ ! -f "${NETCONS_PATH}/userdata/release_enabled" ]]
+ then
+ echo "Not able to enable release sysdata append. Configfs not available in ${NETCONS_PATH}/userdata/release_enabled" >&2
+ exit "${ksft_skip}"
+ fi
+
+ echo 1 > "${NETCONS_PATH}/userdata/release_enabled"
+}
+
# Disable the sysdata cpu_nr feature
function unset_cpu_nr() {
echo 0 > "${NETCONS_PATH}/userdata/cpu_nr_enabled"
@@ -52,6 +63,10 @@ function unset_taskname() {
echo 0 > "${NETCONS_PATH}/userdata/taskname_enabled"
}
+function unset_release() {
+ echo 0 > "${NETCONS_PATH}/userdata/release_enabled"
+}
+
# Test if MSG contains sysdata
function validate_sysdata() {
# OUTPUT_FILE will contain something like:
@@ -93,6 +108,21 @@ function validate_sysdata() {
pkill_socat
}
+function validate_release() {
+ RELEASE=$(uname -r)
+
+ if [ ! -f "$OUTPUT_FILE" ]; then
+ echo "FAIL: File was not generated." >&2
+ exit "${ksft_fail}"
+ fi
+
+ if ! grep -q "release=${RELEASE}" "${OUTPUT_FILE}"; then
+ echo "FAIL: 'release=${RELEASE}' not found in ${OUTPUT_FILE}" >&2
+ cat "${OUTPUT_FILE}" >&2
+ exit "${ksft_fail}"
+ fi
+}
+
# Test if MSG content exists in OUTPUT_FILE but no `cpu=` and `taskname=`
# strings
function validate_no_sysdata() {
@@ -119,6 +149,12 @@ function validate_no_sysdata() {
exit "${ksft_fail}"
fi
+ if grep -q "release=" "${OUTPUT_FILE}"; then
+ echo "FAIL: 'release= found in ${OUTPUT_FILE}" >&2
+ cat "${OUTPUT_FILE}" >&2
+ exit "${ksft_fail}"
+ fi
+
rm "${OUTPUT_FILE}"
}
@@ -169,9 +205,11 @@ MSG="Test #1 from CPU${CPU}"
set_cpu_nr
# Enable taskname to be appended to sysdata
set_taskname
+set_release
runtest
# Make sure the message was received in the dst part
# and exit
+validate_release
validate_sysdata
#====================================================
@@ -184,19 +222,19 @@ OUTPUT_FILE="/tmp/${TARGET}_2"
MSG="Test #2 from CPU${CPU}"
set_user_data
runtest
+validate_release
validate_sysdata
# ===================================================
# TEST #3
-# Unset cpu_nr, so, no CPU should be appended.
-# userdata is still set
+# Unset all sysdata, fail if any userdata is set
# ===================================================
CPU=$((RANDOM % $(nproc)))
OUTPUT_FILE="/tmp/${TARGET}_3"
MSG="Test #3 from CPU${CPU}"
-# Enable the auto population of cpu_nr
unset_cpu_nr
unset_taskname
+unset_release
runtest
# At this time, cpu= shouldn't be present in the msg
validate_no_sysdata