diff options
-rw-r--r-- | Documentation/networking/netconsole.rst | 25 | ||||
-rw-r--r-- | drivers/net/netconsole.c | 71 | ||||
-rwxr-xr-x | tools/testing/selftests/drivers/net/netcons_sysdata.sh | 44 |
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 |