lib: new tst_test field to save and restore proc|sys
RFC PATCH v2 1/1 lib: new tst_test field to save and restore proc|sys
To avoid adding specially crafted functions for every feature where we need to save/restore some proc/sys config, this patch introduces a new field to tst_test struct where user specifies NULL terminated array of strings whose values should be saved before test and restored after.
--- doc/test-writing-guidelines.txt | 37 +++++++++++++ include/tst_sys_conf.h | 27 ++++++++++ include/tst_test.h | 7 +++ lib/newlib_tests/.gitignore | 1 + lib/newlib_tests/test19.c | 48 +++++++++++++++++ lib/tst_sys_conf.c | 112 ++++++++++++++++++++++++++++++++++++++++ lib/tst_test.c | 14 +++++ 7 files changed, 246 insertions(+) create mode 100644 include/tst_sys_conf.h create mode 100644 lib/newlib_tests/test19.c create mode 100644 lib/tst_sys_conf.c
doc/test-writing-guidelines.txt +37 -0
@@ -1468,6 +1468,43 @@ first missing driver. Since it relies on modprobe command, the check will be skipped if the command itself is not available on the system. +2.2.27 Saving & restoring /proc|sys values +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +LTP library can be instructed to save and restore value of specified +(/proc|sys) files. This is achieved by initialized tst_test struct +field 'save_restore'. It is a NULL terminated array of strings where +each string represents a file, whose value is saved at the beginning +and restored at the end of the test. Only first line of a specified +file is saved and restored. + +Pathnames can be optionally prefixed to specify how strictly (during +'store') are handled files that don't exist: + (no prefix) - test ends with TCONF + '?' - test prints info message and continues + '!' - test ends with TBROK + +'restore' is always strict and will TWARN if it encounters any error. + +Example: + +static const char *save_restore[] = { + "/proc/sys/kernel/core_pattern", + NULL, +}; + +static void setup(void) +{ + FILE_PRINTF("/proc/sys/kernel/core_pattern", "/mypath"); +} + +static struct tst_test test = { + ... + .setup = setup, + .save_restore = save_restore, +}; + + 2.3 Writing a testcase in shell ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
include/tst_sys_conf.h new file +27 -0
@@ -0,0 +1,27 @@ +/* +* SPDX-License-Identifier: GPL-2.0-or-later +* +* Copyright (c) 2018 Jan Stancek <[email protected]> +*/ + +#ifndef TST_SYS_CONF_H__ +#define TST_SYS_CONF_H__ + +struct tst_sys_conf { +char path[PATH_MAX ]; +char value[PATH_MAX ]; +struct tst_sys_conf *prev; +struct tst_sys_conf *next; +}; + +#define SYS_CONF_HEAD_INIT (name) { .prev = &(name), .next = &(name) } +#define TST_SYS_CONF_INIT (name) \ + struct tst_sys_conf name = SYS_CONF_HEAD_INIT(name) + +int tst_sys_conf_save_str (struct tst_sys_conf *c,const char *path, +const char *value); +int tst_sys_conf_save (struct tst_sys_conf *c,const char *path); +void tst_sys_conf_restore (struct tst_sys_conf *c,int verbose); +void tst_sys_conf_dump (struct tst_sys_conf *c); + +#endif
include/tst_test.h +7 -0
@@ -42,6 +42,7 @@#include "tst_minmax.h" #include "tst_get_bad_addr.h" #include "tst_path_has_mnt_flags.h" +#include "tst_sys_conf.h" /* * Reports testcase result.
@@ -175,6 +176,12 @@ struct tst_test {/* NULL terminated array of needed kernel drivers */ const char *const *needs_drivers; + +/* +* NULL terminated array of (/proc, /sys) files to save +* before setup and restore after cleanup +*/ +const char *const *save_restore; };/*
lib/newlib_tests/.gitignore +1 -0
@@ -20,6 +20,7 @@ tst_res_hexd tst_strstatus test17 test18 +test19 tst_expiration_timer test_exec test_exec_child
lib/newlib_tests/test19.c new file +48 -0
48 lines not on this page · raw message
lib/tst_sys_conf.c new file +112 -0
112 lines not on this page · raw message
lib/tst_test.c +14 -0
@@ -35,6 +35,7 @@#include "tst_timer_test.h" #include "tst_clocks.h" #include "tst_timer.h" +#include "tst_sys_conf.h" #include "old_resource.h" #include "old_device.h"
@@ -48,6 +49,7 @@ static float duration = -1;static pid_t main_pid, lib_pid;static int mntpoint_mounted;static struct timespec tst_start_time;/* valid only for test pid */ +static TST_SYS_CONF_INIT (save_restore_data);struct results {int passed;
@@ -809,6 +811,15 @@ static void do_setup(int argc, char *argv[])if (needs_tmpdir () && !tst_tmpdir_created ())tst_tmpdir (); +if (tst_test->save_restore) { +const char *const *name = tst_test->save_restore; + +while (*name) { +tst_sys_conf_save (&save_restore_data, *name); + name++; + } + } +if (tst_test->mntpoint)SAFE_MKDIR (tst_test->mntpoint,0777 );
@@ -885,6 +896,9 @@ static void do_cleanup(void)tst_rmdir (); } +if (tst_test->save_restore) +tst_sys_conf_restore (&save_restore_data,0 ); +cleanup_ipc (); }
Signature · 1 line
1.8.3.1
RFC PATCH v2 1/1 lib: new tst_test field to save and restore proc|sys
Hi!
Quoted 15 lines
include/tst_sys_conf.h new file +9
-0@@ -0,0 +1,27 @@ +/* +* SPDX-License-Identifier: GPL-2.0-or-later +* +* Copyright (c) 2018 Jan Stancek <[email protected]> +*/ + +#ifndef TST_SYS_CONF_H__ +#define TST_SYS_CONF_H__ +
include/tst_sys_conf.h line 19
Quoted 10 lines
include/tst_sys_conf.h new file +10
-0+struct tst_sys_conf { +char path[PATH_MAX ]; +char value[PATH_MAX ]; +struct tst_sys_conf *prev; +struct tst_sys_conf *next; +}; + +#define SYS_CONF_HEAD_INIT (name) { .prev = &(name), .next = &(name) } +#define TST_SYS_CONF_INIT (name) \ + struct tst_sys_conf name = SYS_CONF_HEAD_INIT(name)
Well we can use ordinary (single link) linked list unless we want to delete from it I guess. Or is there a reason to have double linked one?
Also I suppose that we do not need explicit declaration for the root pointer, there would be only one list in existence. I would just put one static pointer into the tst_sys_conf.c.
Other than these minor things it looks very good.
Signature · 2 lines
Cyril Hrubis [email protected]