Skip to contentSkip to conversation

lib: new tst_test field to save and restore proc|sys

RFC PATCH Superseded Jan Stancek 2 participants 2 messages Oct 19, 2018 – Nov 1, 2018 Library code

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore
#0 lore raw

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
index f590896472d1..d0b91c36294c 100644
@@ -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
new file mode 100644
index 000000000000..ed558f3cc8fd
@@ -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
index 080b0171d5f2..2ebf746eb720 100644
@@ -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
index 76e89e438f55..c702644f0d1c 100644
@@ -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
index 117e61462d30..8ca1aa8e9ffc 100644
@@ -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
#1 lore raw

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
new file mode 100644
index 000000000000..ed558f3cc8fd
@@ -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]