Add library support for /proc/sys/kernel/tainted
RFC PATCH 1/1 Add library support for /proc/sys/kernel/tainted
Someteimes, it is important to detect if the kernel has issued a warning, or died. From 2.6.26 on, Linux has these inside /proc/sys/kernel/tainted. The bitmask there can be analyzed to detect the occurrance of these.
--- include/tst_taint.h | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++ lib/tst_taint.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 include/tst_taint.h create mode 100644 lib/tst_taint.c
include/tst_taint.h new file +67 -0
@@ -0,0 +1,67 @@ +/* +* Copyright (c) 2018 Michael Moese <[email protected]> +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#ifndef TST_TAINTED_H__ +#define TST_TAINTED_H__ + +/* +* This are all flags that are supported by kernel 4.4.15 +* see kernel/panic.c in kernel sources +*/ +#define TST_TAINT_G (1 << 0)/* a module with non-GPL license loaded */ +#define TST_TAINT_F (1 << 1)/* a module was force-loaded */ +#define TST_TAINT_S (1 << 2)/* SMP with Non-SMP kernel */ +#define TST_TAINT_R (1 << 3)/* module force unloaded */ +#define TST_TAINT_M (1 << 4)/* machine check error occurred */ +#define TST_TAINT_B (1 << 5)/* page-release function found bad page */ +#define TST_TAINT_U (1 << 6)/* user requested taint flag */ +#define TST_TAINT_D (1 << 7)/* kernel died recently - OOPS or BUG */ +#define TST_TAINT_A (1 << 8)/* ACPI table has been overwritten */ +#define TST_TAINT_W (1 << 9)/* a warning has been issued by kernel */ +#define TST_TAINT_C (1 << 10)/* driver from drivers/staging was loaded */ +#define TST_TAINT_I (1 << 11)/* working around BIOS/Firmware bug */ +#define TST_TAINT_O (1 << 12)/* out of tree module loaded */ +#define TST_TAINT_E (1 << 13)/* unsigned module was loaded */ +#define TST_TAINT_L (1 << 14)/* A soft lock-up has previously occurred */ +#define TST_TAINT_K (1 << 15)/* kernel has been live-patched */ +#define TST_TAINT_X (1 << 16)/* auxiliary taint, for distro's use */ + +/* +* check if kernel is recent enough to support the tainted-flags that +* allow us to check if the kernel issued a warning or died +* +* returns 1 if supported, 0 otherwise +*/ +int tst_taint_supported (void ); + +/* +* read /proc/sys/kernel/tainted and return the value +* this function allows to be called even when the relevant flags are +* unsupported. +* +* returns bitmask of taint flag, or (unsigned int) -1 on read error. +*/ +unsigned int tst_taint_read (void ); + +/* +* a small helper function to check if flags specified by mask are set +* +* returns 1 if@least one of the flags is set, 0 otherwise +*/ +int tst_taint_check_mask (unsigned int taint,unsigned int mask); + +#endif /* TST_TAINTED_H__ */
lib/tst_taint.c new file +69 -0
69 lines not on this page · raw message
Signature · 1 line
2.13.6
RFC PATCH 1/1 Add library support for /proc/sys/kernel/tainted
Hi!
Quoted 15 lines
include/tst_taint.h new file +15
-0+/* +* check if kernel is recent enough to support the tainted-flags that +* allow us to check if the kernel issued a warning or died +* +* returns 1 if supported, 0 otherwise +*/ +int tst_taint_supported (void ); + +/* +* read /proc/sys/kernel/tainted and return the value +* this function allows to be called even when the relevant flags are +* unsupported. +* +* returns bitmask of taint flag, or (unsigned int) -1 on read error. +*/
include/tst_taint.h line 67
Quoted 10 lines
include/tst_taint.h new file +10
-0+unsigned int tst_taint_read (void ); + +/* +* a small helper function to check if flags specified by mask are set +* +* returns 1 if at least one of the flags is set, 0 otherwise +*/ +int tst_taint_check_mask (unsigned int taint,unsigned int mask); + +#endif /* TST_TAINTED_H__ */
This patch lacks information on how this API is supposed to be used which is quite important for the review. What I mean is that, while important, the documentation for the function parameters and return values is not enough. What should be included is some sketch code of this is supposed to be used from an actual test source.
Quoted 27 lines
lib/tst_taint.c new file +21
-0@@ -0,0 +1,69 @@ +#include <stdio.h> +#include <stdlib.h> +#include <sys/utsname.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include <linux/version.h> + +#include "tst_test.h" +#include "tst_taint.h" +#include "tst_safe_stdio.h" + +#define TAINT_FILE "/proc/sys/kernel/tainted" + +static int taint_supported =-1 ; + +int tst_taint_supported (void ) +{ +struct utsname uname_data; +int maj, min, patch;
lib/tst_taint.c line 31
Quoted 10 lines
lib/tst_taint.c new file +10
-0+ +if (uname (&uname_data) ==-1 ) +return -1 ; + +if (sscanf (uname_data.release,"%d.%d.%d-" , &maj, &min, &patch) !=3 ) +fprintf (stderr,"error parsing uname information\n" ); + +if ((maj <2 ) || ((maj ==2 ) && (min <26 ))) { +fprintf (stderr,"Kernel version prior to 2.6.26 detected.\n" ); +fprintf (stderr,"please check kernel output manually\n" );
These messages should go out via tst_res().
lib/tst_taint.c line 34
Quoted 3 lines
lib/tst_taint.c new file +3
-0+ taint_supported =0 ; + }else + taint_supported =1 ;
We have tst_kvercmp() exactly for this purpose, see include/tst_kvercmp.h
lib/tst_taint.c line 47
Quoted 11 lines
lib/tst_taint.c new file +11
-0+return taint_supported; +} + +unsigned int tst_taint_read (void ) +{ +int fd; +unsigned int val; +char buffer[11 ]; + +if (taint_supported ==-1 ) +tst_taint_supported ();
So this will only cause warning to be printed into the stderr, then we go ahead and read the file? Shouldn't we just tst_brk(TCONF, "") at this point?
lib/tst_taint.c line 59
Quoted 11 lines
lib/tst_taint.c new file +11
-0+ buffer[10 ] =0 ; + + fd =SAFE_OPEN (TAINT_FILE ,O_RDONLY ); + + val =read (fd, buffer,10 ); +SAFE_CLOSE (fd); +if (val ==-1 ) { +fprintf (stderr,"unable to read %s\n" ,TAINT_FILE ); +return (unsigned int )-1 ; + } + val =safe_atoi (buffer);
What about using SAFE_FILE_SCANF() instead?
lib/tst_taint.c line 69
Quoted 9 lines
lib/tst_taint.c new file +9
-0+return val; +} + +int tst_taint_check_mask (unsigned int taint,unsigned int mask) +{ +if ((taint & mask) !=0 ) +return 1 ; +return 0 ; +}
Hmm, should this be combined with the read function?
Signature · 2 lines
Cyril Hrubis [email protected]
RFC PATCH 1/1 Add library support for /proc/sys/kernel/tainted
Hi,
Quoted 5 lines · Cyril Hrubis
This patch lacks information on how this API is supposed to be used which is quite important for the review. What I mean is that, while important, the documentation for the function parameters and return values is not enough. What should be included is some sketch code of this is supposed to be used from an actual test source.
Agree. I will spend more effort on the documentation before submitting again.
Quoted 1 line
These messages should go out via
tst_res().
Agreed.
Quoted 1 line
We have
tst_kvercmp()exactly for this purpose, seeinclude/tst_kvercmp.h
Well, I tried to find this. But somehow I failed :) Thanks for pointing this out.
Quoted 16 lines
lib/tst_taint.c line 47
Quoted 11 lines
lib/tst_taint.c new file +11
-0+return taint_supported; +} + +unsigned int tst_taint_read (void ) +{ +int fd; +unsigned int val; +char buffer[11 ]; + +if (taint_supported ==-1 ) +tst_taint_supported ();So this will only cause warning to be printed into the stderr, then we go ahead and read the file? Shouldn't we just
tst_brk(TCONF, "")at this point?
Quoted 11 lines
lib/tst_taint.c line 69
Quoted 9 lines
lib/tst_taint.c new file +9
-0+return val; +} + +int tst_taint_check_mask (unsigned int taint,unsigned int mask) +{ +if ((taint & mask) !=0 ) +return 1 ; +return 0 ; +}Hmm, should this be combined with the read function?
I had this consideration. But maybe someone needs to compare the flags for two points in time, and just check if the mask matched the delta. In this case, doing a implicit read would not be what the user wants. On the other hand, when this is not needed, we could save a line.
Thanks,
Michael
Signature · 1 line
SUSE Linux GmbH, GF: Felix Imendörffer, Jane Smithard, Graham Norton, HRB 21284 (AG Nürnberg)