代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/criu 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From 8c7cfce7c9f90af9314b96c6ec34c97fb6f9be8a Mon Sep 17 00:00:00 2001
From: "fu.lin" <fulin10@huawei.com>
Date: Mon, 14 Feb 2022 19:11:15 +0800
Subject: [PATCH 64/72] zdtm: init notifier testcase
Signed-off-by: fu.lin <fulin10@huawei.com>
---
test/zdtm.py | 70 ++++++++--
test/zdtm/customization/Makefile | 3 +-
test/zdtm/customization/notifier00.c | 68 ++++++++++
test/zdtm/customization/notifier00.desc | 1 +
test/zdtm/mod/.gitignore | 163 ++++++++++++++++++++++++
test/zdtm/mod/Makefile | 28 ++++
test/zdtm/mod/notifier.c | 145 +++++++++++++++++++++
7 files changed, 466 insertions(+), 12 deletions(-)
create mode 100644 test/zdtm/customization/notifier00.c
create mode 100644 test/zdtm/customization/notifier00.desc
create mode 100644 test/zdtm/mod/.gitignore
create mode 100644 test/zdtm/mod/Makefile
create mode 100644 test/zdtm/mod/notifier.c
diff --git a/test/zdtm.py b/test/zdtm.py
index d3b146f..d64a683 100755
--- a/test/zdtm.py
+++ b/test/zdtm.py
@@ -25,6 +25,7 @@ import tempfile
import time
import socket
import pathlib
+import platform
from builtins import (input, int, open, range, str, zip)
import pycriu as crpc
@@ -1466,6 +1467,13 @@ class criu:
return True
return False
+ @staticmethod
+ def check_sysfs(pathes):
+ for path in pathes.split():
+ if not pathlib.Path(path).exists():
+ return True
+ return False
+
@staticmethod
def available():
if not os.access(opts['criu_bin'], os.X_OK):
@@ -1991,21 +1999,49 @@ class Launcher:
testline = u"ok %d - %s # SKIP %s" % (self.__runtest, name, reason)
print(testline, file=self.__file_report)
+ def check_module(self, mod):
+ found = False
+ with open("/proc/modules") as f:
+ for line in f.readlines():
+ if "pin_memory" == line.split()[0]:
+ found = True
+ return found
+
def modprobe_pin_memory(self, load):
+ mod = "pin_memory"
if not load:
return
- else:
- found = False
- with open("/proc/modules") as f:
- for line in f.readlines():
- if "pin_memory" == line.split()[0]:
- found = True
- if not found:
- subprocess.check_call(["modprobe", "pin_memory"])
+ elif not self.check_module(mod):
+ subprocess.check_call(["modprobe", mod])
cmd = [opts["criu_bin"], "init-pagemap-read"]
subprocess.check_call(cmd, shell=False)
+ def build_and_load_mod(self, target, kdir):
+ if platform.machine() != "aarch64" or not target:
+ return
+
+ if not os.access("zdtm/mod", os.R_OK):
+ print("should be executed in the test subdir")
+ sys.exit(0)
+
+ dirpath = f"MOD={os.getcwd()}/zdtm/mod"
+ build_mod = ["make", "-C", "zdtm/mod", dirpath, target]
+ if kdir:
+ build_mod.append(f"KDIR={kdir}")
+ subprocess.check_call(build_mod)
+
+ # ensure the module has been unloaded
+ if self.check_module(target.rstrip(".ko")):
+ subprocess.run(["rmmod", target], check=False)
+
+ modpath = f"zdtm/mod/{target}"
+ subprocess.check_call(["insmod", modpath])
+
+ def unload_mod(self, mod):
+ if mod:
+ subprocess.check_call(["rmmod", mod])
+
def run_test(self, name, desc, flavor):
if len(self.__subs) >= self.__max:
@@ -2014,9 +2050,9 @@ class Launcher:
with open("/proc/sys/kernel/tainted") as taintfd:
taint = taintfd.read()
# 0x1000 means the out of tree module has been loaded
- if self.__taint != taint and (int(self.__taint) | 0x1000) != int(taint):
+ if self.__taint != taint and (int(self.__taint) | 0x3000) != int(taint):
raise Exception("The kernel is tainted: %r (%r)" %
- (taint, self.__taint))
+ (taint, str(int(self.__taint) | 0x3000)))
if test_flag(desc, 'excl'):
self.wait_all()
@@ -2045,6 +2081,8 @@ class Launcher:
# `--use-fork-pid`, so don't care `--pin-memory` option
self.modprobe_pin_memory(no_pid_ns)
+ self.build_and_load_mod(desc.get("mod", ""), opts["kdir"])
+
sub = subprocess.Popen(["./zdtm_ct", "zdtm.py"],
env=dict(os.environ, CR_CT_TEST_INFO=arg,
ZDTM_NO_PID_NS=zdtm_no_pid_ns),
@@ -2059,9 +2097,11 @@ class Launcher:
}
# pin memory function don't support concurrency
- if test_flag(desc, 'excl') or test_value(desc, "opts", "--pin-memory"):
+ if test_flag(desc, 'excl') or test_value(desc, "opts", "--pin-memory") or desc.get("mod", ""):
self.wait()
+ self.unload_mod(desc.get("mod", ""))
+
def __wait_one(self, flags):
pid = -1
status = -1
@@ -2412,6 +2452,11 @@ def run_tests(opts):
t, f"cmdline '{cmdline}' isn't support, or don't set")
continue
+ sysfs = tdesc.get('sysfs', '')
+ if sysfs and criu.check_sysfs(sysfs):
+ launcher.skip(t, f"sysfs file {sysfs} don't exist")
+ continue
+
test_flavs = tdesc.get('flavor', 'h ns uns').split()
opts_flavs = (opts['flavor'] or 'h,ns,uns').split(',')
if opts_flavs != ['best']:
@@ -2434,6 +2479,7 @@ def run_tests(opts):
launcher.run_test(t, tdesc, run_flavs)
else:
launcher.skip(t, "no flavors")
+
finally:
fail = launcher.finish()
if opts['join_ns']:
@@ -2723,6 +2769,8 @@ rp.add_argument("--pre-dump-mode",
rp.add_argument("--kdat",
help="Path to criu.kdat, default '/run/criu.kdat'",
default="/run/criu.kdat")
+rp.add_argument(
+ "--kdir", help="specific kernel devel path, the default value is `/lib/modules/$(uname -r)/build`")
lp = sp.add_parser("list", help="List tests")
lp.set_defaults(action=list_tests)
diff --git a/test/zdtm/customization/Makefile b/test/zdtm/customization/Makefile
index 82348f2..93922c7 100644
--- a/test/zdtm/customization/Makefile
+++ b/test/zdtm/customization/Makefile
@@ -10,7 +10,8 @@ TST_NOFILE = \
maps04 \
maps05 \
maps007 \
- maps008
+ maps008 \
+ notifier00
TST_FILE = \
maps00 \
diff --git a/test/zdtm/customization/notifier00.c b/test/zdtm/customization/notifier00.c
new file mode 100644
index 0000000..5fc3d54
--- /dev/null
+++ b/test/zdtm/customization/notifier00.c
@@ -0,0 +1,68 @@
+#include <stdio.h>
+/* Historical reasons: in order to compatible with R10 */
+#define CONFIG_EULEROS_MODRESTORE_NOTIFY
+#include <linux/modrestore.h>
+
+#include "zdtmtst.h"
+
+const char *test_doc = "Tests the basic function of the notifiers";
+static char *nvwa_notifiers[] = {
+ "PRE_FREEZE",
+ "FREEZE_TO_KILL",
+ "PRE_UPDATE_KERNEL",
+ "POST_UPDATE_KERNEL",
+ "UNFREEZE_TO_RUN",
+ "POST_RUN"
+};
+
+_Static_assert(sizeof(nvwa_notifiers)/sizeof(nvwa_notifiers[0]) == KUP_HOOK_MAX, "nvwa_notifiers number is wrong!");
+
+int main(int argc, char *argv[])
+{
+ int orig_values[KUP_HOOK_MAX] = {0};
+ bool failure = false;
+ FILE *fp;
+
+ test_init(argc, argv);
+
+ fp = fopen("/sys/kernel/criu_notifier", "r");
+ if (fp == NULL) {
+ pr_perror("fopen");
+ return 1;
+ }
+
+ for (int i = 0; i < KUP_HOOK_MAX; i++)
+ fscanf(fp, "%d ", orig_values+i);
+
+ test_daemon();
+ test_waitsig();
+
+ if (fseek(fp, 0, SEEK_SET) != 0) {
+ pr_perror("fseek");
+ return 2;
+ }
+
+ for (int i = 0; i < KUP_HOOK_MAX; i++) {
+ int val = 0;
+ int should = orig_values[i]+1;
+
+ fscanf(fp, "%d ", &val);
+
+ /* those are not called in criu */
+ if (i == PRE_UPDATE_KERNEL || i == POST_UPDATE_KERNEL)
+ continue;
+
+ if (val != should) {
+ pr_err("%s notifier is abnormal, it should be %d, but %d.\n",
+ nvwa_notifiers[i], should, val);
+ failure = true;
+ }
+ }
+
+ if (failure)
+ fail("notifier is abnormal.");
+ else
+ pass();
+
+ return 0;
+}
diff --git a/test/zdtm/customization/notifier00.desc b/test/zdtm/customization/notifier00.desc
new file mode 100644
index 0000000..1c6b512
--- /dev/null
+++ b/test/zdtm/customization/notifier00.desc
@@ -0,0 +1 @@
+{'arch': 'aarch64', 'opts': '--with-notifier', 'flavor': 'h', 'flags': 'suid', 'sysfs': '/sys/kernel/modrestore/nvwa_notifier', 'mod': 'notifier.ko'}
diff --git a/test/zdtm/mod/.gitignore b/test/zdtm/mod/.gitignore
new file mode 100644
index 0000000..7afd412
--- /dev/null
+++ b/test/zdtm/mod/.gitignore
@@ -0,0 +1,163 @@
+# SPDX-License-Identifier: GPL-2.0-only
+#
+# NOTE! Don't add files that are generated in specific
+# subdirectories here. Add them in the ".gitignore" file
+# in that subdirectory instead.
+#
+# NOTE! Please use 'git ls-files -i --exclude-standard'
+# command after changing this file, to see if there are
+# any tracked files which get ignored after the change.
+#
+# Normal rules (sorted alphabetically)
+#
+.*
+*.a
+*.asn1.[ch]
+*.bin
+*.bz2
+*.c.[012]*.*
+*.dt.yaml
+*.dtb
+*.dtbo
+*.dtb.S
+*.dwo
+*.elf
+*.gcno
+*.gz
+*.i
+*.ko
+*.lex.c
+*.ll
+*.lst
+*.lz4
+*.lzma
+*.lzo
+*.mod
+*.mod.c
+*.o
+*.o.*
+*.patch
+*.s
+*.so
+*.so.dbg
+*.su
+*.symtypes
+*.symversions
+*.tab.[ch]
+*.tar
+*.xz
+*.zst
+Module.symvers
+modules.order
+
+#
+# Top-level generic files
+#
+/linux
+/modules-only.symvers
+/vmlinux
+/vmlinux.32
+/vmlinux.map
+/vmlinux.symvers
+/vmlinux-gdb.py
+/vmlinuz
+/System.map
+/Module.markers
+/modules.builtin
+/modules.builtin.modinfo
+/modules.nsdeps
+
+#
+# RPM spec file (make rpm-pkg)
+#
+/*.spec
+
+#
+# Debian directory (make deb-pkg)
+#
+/debian/
+
+#
+# Snap directory (make snap-pkg)
+#
+/snap/
+
+#
+# tar directory (make tar*-pkg)
+#
+/tar-install/
+
+#
+# We don't want to ignore the following even if they are dot-files
+#
+!.clang-format
+!.cocciconfig
+!.get_maintainer.ignore
+!.gitattributes
+!.gitignore
+!.mailmap
+
+#
+# Generated include files
+#
+/include/config/
+/include/generated/
+/include/ksym/
+/arch/*/include/generated/
+
+# stgit generated dirs
+patches-*
+
+# quilt's files
+patches
+series
+
+# ctags files
+tags
+TAGS
+
+# cscope files
+cscope.*
+ncscope.*
+
+# gnu global files
+GPATH
+GRTAGS
+GSYMS
+GTAGS
+
+# id-utils files
+ID
+
+*.orig
+*~
+\#*#
+
+#
+# Leavings from module signing
+#
+extra_certificates
+signing_key.pem
+signing_key.priv
+signing_key.x509
+x509.genkey
+
+# Kconfig presets
+/all.config
+/alldef.config
+/allmod.config
+/allno.config
+/allrandom.config
+/allyes.config
+
+# Kconfig savedefconfig output
+/defconfig
+
+# Kdevelop4
+*.kdev4
+
+# Clang's compilation database file
+/compile_commands.json
+
+# Documentation toolchain
+sphinx_*/
diff --git a/test/zdtm/mod/Makefile b/test/zdtm/mod/Makefile
new file mode 100644
index 0000000..10c9c9a
--- /dev/null
+++ b/test/zdtm/mod/Makefile
@@ -0,0 +1,28 @@
+# notice:
+# `ARCH` var is used in both criu and kernel, but they have the different value
+# for the same architecture(e.g. arm64). Therefore, this Makefile can't be
+# included in the criu Makefile.
+obj-m += notifier.o
+
+# specific the kernel devel path
+# example (use `/home/me/kernel` as `KDIR`):
+# $ export KDIR="/home/me/kernel"
+ifeq ($(KDIR),)
+ KDIR := /lib/modules/$(shell uname -r)/build
+endif
+
+# specific the mod src path
+ifeq ($(MOD),)
+ MOD := $(PWD)
+endif
+
+all:
+ $(MAKE) -C $(KDIR) M=$(MOD) modules
+
+clean:
+ $(MAKE) -C $(KDIR) M=$(MOD) clean
+
+.PHONY: all clean
+
+notifier.ko:
+ $(MAKE) -C $(KDIR) M=$(MOD) notifier.ko
diff --git a/test/zdtm/mod/notifier.c b/test/zdtm/mod/notifier.c
new file mode 100644
index 0000000..70a5b33
--- /dev/null
+++ b/test/zdtm/mod/notifier.c
@@ -0,0 +1,145 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/modrestore.h>
+
+static int values[KUP_HOOK_MAX];
+static char *nvwa_actions[] = {
+ "PREPARE",
+ "ROLLBACK",
+};
+static char *nvwa_notifiers[] = {
+ "PRE_FREEZE",
+ "FREEZE_TO_KILL",
+ "PRE_UPDATE_KERNEL",
+ "POST_UPDATE_KERNEL",
+ "UNFREEZE_TO_RUN",
+ "POST_RUN"
+};
+
+static int nvwa_notifier_func(struct notifier_block *nb, unsigned long val, void *data)
+{
+ struct nvwa_action *action = data;
+
+ switch (action->cmd) {
+ case PREPARE:
+ values[val] += 1;
+ break;
+ case ROLLBACK:
+ values[val] -= 1;
+ break;
+ default:
+ pr_err("invalid cmd: %d", action->cmd);
+ return NOTIFY_BAD;
+ }
+
+ pr_info("nvwa notifier action %s", nvwa_actions[action->cmd]);
+
+ return NOTIFY_DONE;
+}
+
+#define DEFINE_NVWA_NB(name) \
+ static struct notifier_block nvwa_##name##_nb = { \
+ .notifier_call = nvwa_notifier_func, \
+ }
+
+DEFINE_NVWA_NB(pre_freeze);
+DEFINE_NVWA_NB(freeze_to_kill);
+DEFINE_NVWA_NB(pre_update_kernel);
+DEFINE_NVWA_NB(post_update_kernel);
+DEFINE_NVWA_NB(unfreeze_to_run);
+DEFINE_NVWA_NB(post_run);
+
+static struct notifier_block *nvwa_nbs[] = {
+ &nvwa_pre_freeze_nb,
+ &nvwa_freeze_to_kill_nb,
+ &nvwa_pre_update_kernel_nb,
+ &nvwa_post_update_kernel_nb,
+ &nvwa_unfreeze_to_run_nb,
+ &nvwa_post_run_nb,
+};
+
+static int register_nvwa_notifiers(void)
+{
+ int i;
+
+ BUILD_BUG_ON_MSG(ARRAY_SIZE(nvwa_nbs) != KUP_HOOK_MAX,
+ "wrong nvwa notifier block size!");
+
+ for (i = 0; i < ARRAY_SIZE(nvwa_nbs); i++) {
+ if (register_nvwa_notifier(i, nvwa_nbs[i]) != 0) {
+ pr_err("register nvwa %s notifier failed!", nvwa_notifiers[i]);
+ goto error;
+ }
+ }
+
+ return 0;
+
+error:
+
+ for (i -= 1; i >= 0; i -= 1)
+ unregister_nvwa_notifier(i, nvwa_nbs[i]);
+
+ return -1;
+}
+
+static void unregister_nvwa_notifiers(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(nvwa_nbs); i++)
+ unregister_nvwa_notifier(i, nvwa_nbs[i]);
+}
+
+static ssize_t criu_notifier_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *buf, size_t count)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(values); i++)
+ values[i] = 0;
+
+ return count;
+}
+
+static ssize_t criu_notifier_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ int i;
+ ssize_t count = 0;
+
+ for (i = 0; i < ARRAY_SIZE(values); i++)
+ count += sprintf(buf+count, "%d ", values[i]);
+
+ buf[count-1] = '\n';
+
+ return count;
+}
+
+static struct kobj_attribute notifier_file = __ATTR_RW(criu_notifier);
+
+static int __init notifier_init(void)
+{
+ if (register_nvwa_notifiers() != 0)
+ return -1;
+
+ if (sysfs_create_file(kernel_kobj, ¬ifier_file.attr) != 0) {
+ unregister_nvwa_notifiers();
+ return -1;
+ }
+
+ return 0;
+}
+
+static void __exit notifier_exit(void)
+{
+ sysfs_remove_file(kernel_kobj, ¬ifier_file.attr);
+ unregister_nvwa_notifiers();
+}
+
+module_init(notifier_init);
+module_exit(notifier_exit);
+MODULE_LICENSE("GPL");
--
2.34.1
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。