1 Star 0 Fork 35

bzg_repo/criu

forked from src-openEuler/criu 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
0044-proc-parse-fix-vma-offset-value-for-the-sysfs-file-o.patch 4.69 KB
一键复制 编辑 原始数据 按行查看 历史
river 提交于 2022-04-13 15:05 . criu: backport kinds of features/bugfix
From c7f9888e234a626a4d7bf31b89d66b91607f9785 Mon Sep 17 00:00:00 2001
From: "fu.lin" <fu.lin10@huawei.com>
Date: Tue, 27 Jul 2021 11:40:34 +0800
Subject: [PATCH 44/72] proc parse: fix vma offset value for the sysfs file of
pci devices
Some pci devices create bin sysfs file which permit to use `mmap()`
syscall, the 6th parameter `offset` is always 0 when those kinds of
files create file mapping. The value of `offset` will be assign to
`vma->vm_pgoff` in kernel. However, it will be changed to pci address
automically during mmap callback function `pci_mmap_resource_range()`,
and the offset in `/proc/<pid>/maps` will show non-zero. It will result
criu restore fails.
There are many of those files. Just retry the mmap action.
NOTICE: the stragy is try best, not whitelist.
Signed-off-by: He Jingxian <hejingxian@huawei.com>
Signed-off-by: fu.lin <fu.lin10@huawei.com>
Signed-off-by: fu.lin <fulin10@huawei.com>
---
criu/include/image.h | 1 +
criu/pie/restorer.c | 22 +++++++++++++++++++---
criu/proc_parse.c | 32 ++++++++++++++++++++++++++++++++
3 files changed, 52 insertions(+), 3 deletions(-)
diff --git a/criu/include/image.h b/criu/include/image.h
index 66492c0..0156314 100644
--- a/criu/include/image.h
+++ b/criu/include/image.h
@@ -86,6 +86,7 @@
#define VMA_AREA_MEMFD (1 << 14)
#define VMA_AREA_ANON_INODE (1 << 15)
#define VMA_AREA_CHR (1 << 16)
+#define VMA_AREA_DEV_SHARE (1 << 17)
#define VMA_CLOSE (1 << 28)
#define VMA_NO_PROT_WRITE (1 << 29)
diff --git a/criu/pie/restorer.c b/criu/pie/restorer.c
index fde6e30..67b0d4c 100644
--- a/criu/pie/restorer.c
+++ b/criu/pie/restorer.c
@@ -883,8 +883,9 @@ static unsigned long restore_mapping(VmaEntry *vma_entry)
* that mechanism as it causes the process to be charged for memory
* immediately upon mmap, not later upon preadv().
*/
- pr_debug("\tmmap(%" PRIx64 " -> %" PRIx64 ", %x %x %d)\n", vma_entry->start, vma_entry->end, prot, flags,
- (int)vma_entry->fd);
+ pr_debug("\tmmap(%" PRIx64 " -> %" PRIx64 ", %x %x %d %lx)\n",
+ vma_entry->start, vma_entry->end, prot, flags,
+ (int)vma_entry->fd, vma_entry->pgoff);
/*
* Should map memory here. Note we map them as
* writable since we're going to restore page
@@ -892,6 +893,20 @@ static unsigned long restore_mapping(VmaEntry *vma_entry)
*/
addr = sys_mmap(decode_pointer(vma_entry->start), vma_entry_len(vma_entry), prot, flags, vma_entry->fd,
vma_entry->pgoff);
+ /* Some drivers implements its own mmap callback, the `mmap()` argument
+ * `offset` has the differet semantic with POSIX standard. Therefore,
+ * try to re-mmap with offset 0.
+ *
+ * NOTICE: the stragy is try best, not whitelist.
+ */
+ if (addr == -EINVAL && vma_entry->pgoff != 0) {
+ pr_info("try mmap with offset 0\n");
+ addr = sys_mmap(decode_pointer(vma_entry->start),
+ vma_entry_len(vma_entry),
+ prot, flags,
+ vma_entry->fd,
+ 0);
+ }
if ((vma_entry->fd != -1) && (vma_entry->status & VMA_CLOSE))
sys_close(vma_entry->fd);
@@ -1979,7 +1994,8 @@ long __export_restore_task(struct task_restore_args *args)
if (!vma_entry->has_madv || !vma_entry->madv)
continue;
- if (vma_entry_is(vma_entry, VMA_AREA_ANON_INODE))
+ if (vma_entry_is(vma_entry, VMA_AREA_ANON_INODE) ||
+ vma_entry_is(vma_entry, VMA_AREA_DEV_SHARE))
continue;
for (m = 0; m < sizeof(vma_entry->madv) * 8; m++) {
diff --git a/criu/proc_parse.c b/criu/proc_parse.c
index d13589c..282a2e9 100644
--- a/criu/proc_parse.c
+++ b/criu/proc_parse.c
@@ -552,6 +552,35 @@ static inline int handle_vvar_vma(struct vma_area *vma)
return 0;
}
+static bool is_sysfs_resource(const char *path)
+{
+ char *sub = NULL;
+ const char *prefix = "resource";
+ const char *suffix = "_wc";
+
+ if (strstr(path, "devices/") == NULL)
+ return false;
+
+ sub = rindex(path, '/');
+ if (sub == NULL)
+ return false;
+
+ sub += 1;
+ if (strncmp(sub, prefix, strlen(prefix)) != 0)
+ return false;
+
+ sub += strlen(prefix);
+ while (*sub != '\0' && (*sub >= '0' && *sub <= '9'))
+ sub += 1;
+
+ if (*sub == '\0')
+ return true;
+ if (!strcmp(sub, suffix))
+ return true;
+ else
+ return false;
+}
+
static int handle_vma(pid_t pid, struct vma_area *vma_area, const char *file_path, DIR *map_files_dir,
struct vma_file_info *vfi, struct vma_file_info *prev_vfi, int *vm_file_fd)
{
@@ -571,6 +600,9 @@ static int handle_vma(pid_t pid, struct vma_area *vma_area, const char *file_pat
goto err;
} else if (!strcmp(file_path, "[heap]")) {
vma_area->e->status |= VMA_AREA_REGULAR | VMA_AREA_HEAP;
+ } else if (is_sysfs_resource(file_path)) {
+ pr_info("find sys device module share memory\n");
+ vma_area->e->status |= VMA_AREA_REGULAR | VMA_AREA_DEV_SHARE;
} else {
vma_area->e->status = VMA_AREA_REGULAR;
}
--
2.34.1
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/baizg1107/criu.git
git@gitee.com:baizg1107/criu.git
baizg1107
criu
criu
master

搜索帮助