From: Jeff Mahoney <jeffm@suse.com>
Subject: kernel: add product-identifying information to kernel build
References: FATE#325281
Patch-mainline: Never, SUSE-specific
Our kernels may be offered using the same base kernel version across
several product streams. We have tags in our git repository to map
specific versions to a release, but that requires having easy access
to the repository and taking the multiple steps to resolve the release
information.
This patch makes the product release easier to discover by both SUSE
support staff and third-party developers.
This adds a new <linux/suse_version.h> header that defines several
values that can be used to programatically discover what kernel
version is being used:
* SUSE_PRODUCT_FAMILY The "family" of product, e.g. SLE or Leap
* SUSE_PRODUCT_NAME The full product name, which may consist of
several whitespace-separated words
* SUSE_PRODUCT_SHORTNAME The abbreviated product name where it makes
sense, e.g. SLE15-SP1.
* SUSE_VERSION Numeric major number of release
* SUSE_PATCHLEVEL The minor numer or service pack level of the
release
* SUSE_AUXRELEASE Currently unused
* SUSE_PRODUCT_CODE An encoded product code that is the result of
combining the family, version, patchlevel, and
aux release
* SUSE_PRODUCT Macro to use to generate the code
It also adds a new "suserelease" module tag that contains the
shortname and also prints the shortname after the kernel version during
system faults.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
---
Makefile | 11 +++++
init/Kconfig.suse | 72 ++++++++++++++++++++++++++++++++++++-
kernel/printk/printk.c | 5 +-
scripts/gen-suse_version_h.sh | 81 ++++++++++++++++++++++++++++++++++++++++++
scripts/mod/modpost.c | 10 +++++
5 files changed, 175 insertions(+), 4 deletions(-)
--- a/Makefile
+++ b/Makefile
@@ -1035,6 +1035,15 @@ endef
include/config/kernel.release: include/config/auto.conf FORCE
$(call filechk,kernel.release)
+suse_version_h := include/generated/uapi/linux/suse_version.h
+
+define filechk_suse_version
+ $(CONFIG_SHELL) $(srctree)/scripts/gen-suse_version_h.sh
+endef
+
+$(suse_version_h): include/config/auto.conf FORCE
+ $(call filechk,suse_version)
+
# Things we need to do before we recursively start building the kernel
# or the modules are listed in "prepare".
@@ -1064,7 +1073,7 @@ endif
prepare2: prepare3 prepare-compiler-check outputmakefile asm-generic
prepare1: prepare2 $(version_h) include/generated/utsrelease.h \
- include/config/auto.conf
+ include/config/auto.conf $(suse_version_h)
$(cmd_crmodverdir)
archprepare: archheaders archscripts prepare1 scripts_basic
--- a/init/Kconfig.suse
+++ b/init/Kconfig.suse
@@ -1,9 +1,78 @@
config SUSE_KERNEL
def_bool y
+menu "SUSE Release Details"
+ depends on SUSE_KERNEL
+
+choice
+ prompt "SUSE Product Family"
+ default SUSE_PRODUCT_SLE
+ help
+ This option defines the SUSE product family that owns this
+ kernel release.
+
+config SUSE_PRODUCT_SLE
+ bool "SUSE Linux Enteprise"
+
+config SUSE_PRODUCT_OPENSUSE_LEAP
+ bool "openSUSE Leap"
+
+config SUSE_PRODUCT_OPENSUSE_TUMBLEWEED
+ bool "openSUSE Tumbleweed"
+endchoice
+
+config SUSE_PRODUCT_CODE
+ int
+ range 1 3
+ default 1 if SUSE_PRODUCT_SLE
+ default 2 if SUSE_PRODUCT_OPENSUSE_LEAP
+ default 3 if SUSE_PRODUCT_OPENSUSE_TUMBLEWEED
+
+if SUSE_PRODUCT_SLE
+config SUSE_VERSION
+ int "Release Version"
+ range 0 255
+ default 255
+
+config SUSE_PATCHLEVEL
+ int "Service Pack Version"
+ range 0 255
+ default 255
+endif
+
+if SUSE_PRODUCT_OPENSUSE_LEAP
+config SUSE_VERSION
+ int "Release Major Version"
+ range 0 255
+ default 255
+
+config SUSE_PATCHLEVEL
+ int "Release Minor Version"
+ range 0 255
+ default 255
+endif
+
+# Tumbleweed doesn't currently use version information, but we should
+# still have the values defined even if zeroed out.
+if SUSE_PRODUCT_OPENSUSE_TUMBLEWEED
+config SUSE_VERSION
+ int
+ range 0 255
+ default 0
+
+config SUSE_PATCHLEVEL
+ int
+ range 0 255
+ default 0
+endif
+
+config SUSE_AUXRELEASE
+ int
+ range 0 255
+ default 0
+
config SUSE_KERNEL_SUPPORTED
bool "Enable enterprise support facility"
- depends on SUSE_KERNEL
help
This feature enables the handling of the "supported" module flag.
This flag can be used to report unsupported module loads or even
@@ -18,3 +87,4 @@ config SUSE_KERNEL_SUPPORTED
If you aren't building a kernel for an enterprise distribution,
say n.
+endmenu
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -48,6 +48,7 @@
#include <linux/sched/clock.h>
#include <linux/sched/debug.h>
#include <linux/sched/task_stack.h>
+#include <linux/suse_version.h>
#include <linux/uaccess.h>
#include <asm/sections.h>
@@ -3272,11 +3273,11 @@ void __init dump_stack_set_arch_desc(con
*/
void dump_stack_print_info(const char *log_lvl)
{
- printk("%sCPU: %d PID: %d Comm: %.20s %s %s %.*s\n",
+ printk("%sCPU: %d PID: %d Comm: %.20s %s %s %.*s %s\n",
log_lvl, raw_smp_processor_id(), current->pid, current->comm,
print_tainted(), init_utsname()->release,
(int)strcspn(init_utsname()->version, " "),
- init_utsname()->version);
+ init_utsname()->version, SUSE_PRODUCT_SHORTNAME);
if (dump_stack_arch_desc_str[0] != '\0')
printk("%sHardware name: %s\n",
--- /dev/null
+++ b/scripts/gen-suse_version_h.sh
@@ -0,0 +1,81 @@
+#!/bin/bash
+
+if test -e include/config/auto.conf; then
+ . include/config/auto.conf
+else
+ echo "Error: auto.conf not generated - run 'make prepare' to create it" >&2
+ exit 1
+fi
+
+VERSION="${CONFIG_SUSE_VERSION}"
+PATCHLEVEL="${CONFIG_SUSE_PATCHLEVEL}"
+AUXRELEASE="${CONFIG_SUSE_AUXRELEASE}"
+
+if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$AUXRELEASE" ]; then
+ # This would be a bug in the Kconfig
+ cat <<- END >&2
+ ERROR: Missing VERSION, PATCHLEVEL, or AUXRELEASE."
+ Please check init/Kconfig.suse for correctness.
+ END
+ exit 1
+fi
+
+if [ "$VERSION" = 255 -o "$PATCHLEVEL" = 255 ]; then
+ cat <<- END >&2
+
+ ERROR: This release needs to be properly configured.
+ Please add real values for SUSE_VERSION and SUSE_PATCHLEVEL.
+
+ END
+ exit 1
+fi
+
+
+case "$CONFIG_SUSE_PRODUCT_CODE" in
+ 1)
+ if [ "${PATCHLEVEL}" = "0" ]; then
+ SP=""
+ else
+ SP="${PATCHLEVEL}"
+ fi
+ SUSE_PRODUCT_NAME="SUSE Linux Enterprise ${VERSION}${SP:+ SP}${SP}"
+ SUSE_PRODUCT_SHORTNAME="SLE${VERSION}${SP:+-SP}${SP}"
+ SUSE_PRODUCT_FAMILY="SLE"
+ ;;
+ 2)
+ SUSE_PRODUCT_NAME="openSUSE Leap ${VERSION}.${PATCHLEVEL}"
+ SUSE_PRODUCT_SHORTNAME="$SUSE_PRODUCT_NAME"
+ SUSE_PRODUCT_FAMILY="Leap"
+ ;;
+ 3)
+ SUSE_PRODUCT_NAME="openSUSE Tumbleweed"
+ SUSE_PRODUCT_SHORTNAME="$SUSE_PRODUCT_NAME"
+ SUSE_PRODUCT_FAMILY="Tumbleweed"
+ ;;
+ *)
+ echo "Unknown SUSE_PRODUCT_CODE=${CONFIG_SUSE_PRODUCT_CODE}" >&2
+ exit 1
+ ;;
+esac
+
+SUSE_PRODUCT_CODE=$(( (${CONFIG_SUSE_PRODUCT_CODE} << 24) + \
+ (${VERSION} << 16) + (${PATCHLEVEL} << 8) + \
+ ${AUXRELEASE} ))
+
+cat <<END
+#ifndef _SUSE_VERSION_H
+#define _SUSE_VERSION_H
+
+#define SUSE_PRODUCT_FAMILY "${SUSE_PRODUCT_FAMILY}"
+#define SUSE_PRODUCT_NAME "${SUSE_PRODUCT_NAME}"
+#define SUSE_PRODUCT_SHORTNAME "${SUSE_PRODUCT_SHORTNAME}"
+#define SUSE_VERSION ${VERSION}
+#define SUSE_PATCHLEVEL ${PATCHLEVEL}
+#define SUSE_AUXRELEASE ${AUXRELEASE}
+#define SUSE_PRODUCT_CODE ${SUSE_PRODUCT_CODE}
+#define SUSE_PRODUCT(product, version, patchlevel, auxrelease) \\
+ (((product) << 24) + ((version) << 16) + \\
+ ((patchlevel) << 8) + (auxrelease))
+
+#endif /* _SUSE_VERSION_H */
+END
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -23,6 +23,7 @@
#include "../../include/generated/autoconf.h"
#include "../../include/linux/license.h"
#include "../../include/linux/export.h"
+#include "../../include/generated/uapi/linux/suse_version.h"
/* Are we using CONFIG_MODVERSIONS? */
static int modversions = 0;
@@ -2373,6 +2374,14 @@ static void add_srcversion(struct buffer
}
}
+static void add_suserelease(struct buffer *b, struct module *mod)
+{
+#ifdef SUSE_PRODUCT_SHORTNAME
+ buf_printf(b, "\n");
+ buf_printf(b, "MODULE_INFO(suserelease, \"%s\");\n",
+ SUSE_PRODUCT_SHORTNAME);
+#endif
+}
static void write_if_changed(struct buffer *b, const char *fname)
{
char *tmp;
@@ -2632,6 +2641,7 @@ int main(int argc, char **argv)
add_depends(&buf, mod, modules);
add_moddevtable(&buf, mod);
add_srcversion(&buf, mod);
+ add_suserelease(&buf, mod);
sprintf(fname, "%s.mod.c", mod->name);
write_if_changed(&buf, fname);