代码拉取完成,页面将自动刷新
同步操作将从 src-openEuler/criu 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
From c44c68028f22751ef12fac02567008a16e992fea Mon Sep 17 00:00:00 2001
From: "fu.lin" <fulin10@huawei.com>
Date: Thu, 17 Feb 2022 14:30:03 +0800
Subject: [PATCH 67/72] zdtm: add chardev testcase
- char dev `ioctl({IOCTL_CMD_NEEDREPAIR, IOCTL_CMD_REPAIR})`
checkpoint/restore test
- anonymous inode checkpoint/restore test
---
test/zdtm/customization/Makefile | 3 +-
test/zdtm/customization/chardev00.c | 65 +++++++++++
test/zdtm/customization/chardev00.desc | 1 +
test/zdtm/mod/Makefile | 5 +-
test/zdtm/mod/anon_inode.c | 148 +++++++++++++++++++++++++
5 files changed, 220 insertions(+), 2 deletions(-)
create mode 100644 test/zdtm/customization/chardev00.c
create mode 100644 test/zdtm/customization/chardev00.desc
create mode 100644 test/zdtm/mod/anon_inode.c
diff --git a/test/zdtm/customization/Makefile b/test/zdtm/customization/Makefile
index 93922c7..7d08db3 100644
--- a/test/zdtm/customization/Makefile
+++ b/test/zdtm/customization/Makefile
@@ -11,7 +11,8 @@ TST_NOFILE = \
maps05 \
maps007 \
maps008 \
- notifier00
+ notifier00 \
+ chardev00
TST_FILE = \
maps00 \
diff --git a/test/zdtm/customization/chardev00.c b/test/zdtm/customization/chardev00.c
new file mode 100644
index 0000000..c708699
--- /dev/null
+++ b/test/zdtm/customization/chardev00.c
@@ -0,0 +1,65 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "zdtmtst.h"
+
+#define CHARDEV_PATH "/dev/anon_test"
+
+const char *test_doc="Tests char dev and anonmous inode map checkpoint/restore";
+
+static int check_maps(unsigned long addr)
+{
+ FILE *fp = fopen("/proc/self/maps", "r");
+ char *line = NULL;
+ size_t n = 0;
+ unsigned long start = 0;
+
+ if (fp == NULL) {
+ pr_perror("open self maps failed");
+ return -1;
+ }
+
+ while (getline(&line, &n, fp) != -1) {
+ test_msg("%s", line);
+ sscanf(line, "%lx-", &start);
+ if (start == addr)
+ return 0;
+ }
+
+ return -1;
+}
+
+int main(int argc, char *argv[])
+{
+ int fd, retval = 0;
+ unsigned long addr;
+
+ test_init(argc, argv);
+
+ fd = open(CHARDEV_PATH, O_RDWR);
+ if (fd < 0) {
+ pr_perror("open '%s' failed", CHARDEV_PATH);
+ return -1;
+ }
+
+ retval = ioctl(fd, 0, &addr);
+ if (retval < 0) {
+ pr_perror("create anonymous map failed");
+ retval = -1;
+ goto out;
+ }
+ test_msg("create anonymous vma start 0x%lx\n", addr);
+
+ test_daemon();
+ test_waitsig();
+
+ retval = check_maps(addr);
+ if (retval == 0)
+ pass();
+ else
+ fail("anonymous inode map don't restore");
+out:
+ return retval;
+}
diff --git a/test/zdtm/customization/chardev00.desc b/test/zdtm/customization/chardev00.desc
new file mode 100644
index 0000000..9c51ba8
--- /dev/null
+++ b/test/zdtm/customization/chardev00.desc
@@ -0,0 +1 @@
+{'arch': 'aarch64', 'opts': '--dump-char-dev', 'flavor': 'h', 'flags': 'suid excl', 'sysfs': '/sys/kernel/modrestore/anon_state_restore /sys/kernel/repairing_device', 'mod': 'anon_inode.ko'}
diff --git a/test/zdtm/mod/Makefile b/test/zdtm/mod/Makefile
index 10c9c9a..0bc89f7 100644
--- a/test/zdtm/mod/Makefile
+++ b/test/zdtm/mod/Makefile
@@ -2,7 +2,7 @@
# `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
+obj-m += notifier.o anon_inode.o
# specific the kernel devel path
# example (use `/home/me/kernel` as `KDIR`):
@@ -26,3 +26,6 @@ clean:
notifier.ko:
$(MAKE) -C $(KDIR) M=$(MOD) notifier.ko
+
+anon_inode.ko:
+ $(MAKE) -C $(KDIR) M=$(MOD) anon_inode.ko
diff --git a/test/zdtm/mod/anon_inode.c b/test/zdtm/mod/anon_inode.c
new file mode 100644
index 0000000..d9c7d2a
--- /dev/null
+++ b/test/zdtm/mod/anon_inode.c
@@ -0,0 +1,148 @@
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/anon_inodes.h>
+#include <linux/file.h>
+#include <linux/modrestore.h>
+
+static int anon_mmap(struct file *file, struct vm_area_struct *vma)
+{
+ pr_info("call %s\n", __func__);
+ return 0;
+}
+
+static const struct file_operations none_fops = {
+ .owner = THIS_MODULE,
+ .mmap = anon_mmap,
+};
+
+static unsigned long create_mmap(void)
+{
+ struct file *filp;
+ unsigned long start;
+
+ pr_info("call %s\n", __func__);
+ filp = anon_inode_getfile("test", &none_fops, NULL, O_RDWR);
+ if (IS_ERR(filp)) {
+ pr_warn("anon_inode_getfile('test') failed: %d\n", (int)PTR_ERR(filp));
+ return PTR_ERR(filp);
+ }
+
+ start = vm_mmap(filp, 0, 1<<20, PROT_READ | PROT_WRITE, MAP_SHARED, 0);
+ if (IS_ERR_VALUE(start)) {
+ pr_warn("vm_mmap failed with: %d\n", (int)PTR_ERR((void *)start));
+ }
+
+ fput(filp);
+
+ return start;
+}
+
+static int anon_inode_notifier(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ struct vma_anon_entry *vma_entry = data;
+ struct file *filp;
+ unsigned long start;
+
+ filp = anon_inode_getfile("test", &none_fops, NULL, O_RDWR);
+ if (IS_ERR(filp)) {
+ pr_warn("anon_inode_getfile('test') failed: %d\n", (int)PTR_ERR(filp));
+ return 0;
+ }
+
+ start = vm_mmap(filp, vma_entry->start, vma_entry -> end-vma_entry->start,
+ PROT_READ | PROT_WRITE, MAP_SHARED, 0);
+ if (start != vma_entry->start)
+ pr_warn("vm_mmap() failed: %#lx\n", start);
+
+ fput(filp);
+ return 0;
+}
+
+static long anon_ioctl(struct file *file, unsigned int cmd, unsigned long argp)
+{
+ unsigned long start;
+
+ switch (cmd) {
+ case 0:
+ start = create_mmap();
+ if (IS_ERR_VALUE(start))
+ return -EINVAL;
+ if (put_user(start, (unsigned long __user *)argp))
+ return -EFAULT;
+ break;
+ case IOCTL_CMD_NEEDREPAIR:
+ pr_info("call IOCTL_CMD_NEEDREPAIR");
+ /* do nothing, just a request slot */
+ return 17173;
+ case IOCTL_CMD_REPAIR:
+ pr_info("call IOCTL_CMD_REPAIR");
+ /* do nothing, just a request slot */
+ break;
+ default:
+ pr_warn("wrong cmd\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct file_operations anon_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = anon_ioctl,
+ .compat_ioctl = anon_ioctl,
+};
+
+static struct miscdevice anon_dev = {
+ .minor = MISC_DYNAMIC_MINOR,
+ .name = "anon_test",
+ .fops = &anon_fops,
+};
+
+static struct notifier_block anon_inode_nb = {
+ .notifier_call = anon_inode_notifier,
+};
+
+static int __init anon_init(void)
+{
+ int retval;
+
+ retval = mures_add_devname(anon_dev.name);
+ if (retval != 0)
+ goto out;
+
+ retval = register_anon_notifier(&anon_inode_nb);
+ if (retval != 0)
+ goto del_devname;
+
+ retval = misc_register(&anon_dev);
+ if (retval != 0)
+ goto del_notifier;
+
+ return 0;
+
+del_notifier:
+ unregister_anon_notifier(&anon_inode_nb);
+del_devname:
+ mures_del_devname(anon_dev.name);
+out:
+ return retval;
+}
+
+static void __exit anon_exit(void)
+{
+ mures_del_devname(anon_dev.name);
+ unregister_anon_notifier(&anon_inode_nb);
+ misc_deregister(&anon_dev);
+ return;
+}
+
+module_init(anon_init);
+module_exit(anon_exit);
+MODULE_LICENSE("GPL");
--
2.34.1
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。