[CRIU] [PATCH v2 2/7] proc_parse: make smaps parsing helpers globally available
Mike Rapoport
rppt at linux.vnet.ibm.com
Wed Jun 21 14:35:26 MSK 2017
The is_vma_range_fmt and parse_vmflags will be required for detection of
availability of PR_SET_THP_DISABLE prctl
Signed-off-by: Mike Rapoport <rppt at linux.vnet.ibm.com>
---
criu/include/proc_parse.h | 3 ++
criu/proc_parse.c | 75 ++++++++++++++++++++++++++++-------------------
2 files changed, 48 insertions(+), 30 deletions(-)
diff --git a/criu/include/proc_parse.h b/criu/include/proc_parse.h
index 98ec88f..0f5e910 100644
--- a/criu/include/proc_parse.h
+++ b/criu/include/proc_parse.h
@@ -106,4 +106,7 @@ extern int parse_threads(int pid, struct pid ***_t, int *_n);
int parse_children(pid_t pid, pid_t **_c, int *_n);
+extern bool is_vma_range_fmt(char *line);
+extern void parse_vmflags(char *buf, u32 *flags, u64 *madv, int *io_pf);
+
#endif /* __CR_PROC_PARSE_H__ */
diff --git a/criu/proc_parse.c b/criu/proc_parse.c
index 041d451..be8b7de 100644
--- a/criu/proc_parse.c
+++ b/criu/proc_parse.c
@@ -76,7 +76,7 @@ static char *buf = __buf.buf;
#define AIO_FNAME "/[aio]"
/* check the @line starts with "%lx-%lx" format */
-static bool is_vma_range_fmt(char *line)
+static bool __is_vma_range_fmt(char *line)
{
#define ____is_vma_addr_char(__c) \
(((__c) <= '9' && (__c) >= '0') || \
@@ -98,55 +98,54 @@ static bool is_vma_range_fmt(char *line)
#undef ____is_vma_addr_char
}
-static int parse_vmflags(char *buf, struct vma_area *vma_area)
+bool is_vma_range_fmt(char *line)
+{
+ return __is_vma_range_fmt(line);
+}
+
+static void __parse_vmflags(char *buf, u32 *flags, u64 *madv, int *io_pf)
{
char *tok;
if (!buf[0])
- return 0;
+ return;
tok = strtok(buf, " \n");
if (!tok)
- return 0;
+ return;
#define _vmflag_match(_t, _s) (_t[0] == _s[0] && _t[1] == _s[1])
do {
/* mmap() block */
if (_vmflag_match(tok, "gd"))
- vma_area->e->flags |= MAP_GROWSDOWN;
+ *flags |= MAP_GROWSDOWN;
else if (_vmflag_match(tok, "lo"))
- vma_area->e->flags |= MAP_LOCKED;
+ *flags |= MAP_LOCKED;
else if (_vmflag_match(tok, "nr"))
- vma_area->e->flags |= MAP_NORESERVE;
+ *flags |= MAP_NORESERVE;
else if (_vmflag_match(tok, "ht"))
- vma_area->e->flags |= MAP_HUGETLB;
+ *flags |= MAP_HUGETLB;
/* madvise() block */
if (_vmflag_match(tok, "sr"))
- vma_area->e->madv |= (1ul << MADV_SEQUENTIAL);
+ *madv |= (1ul << MADV_SEQUENTIAL);
else if (_vmflag_match(tok, "rr"))
- vma_area->e->madv |= (1ul << MADV_RANDOM);
+ *madv |= (1ul << MADV_RANDOM);
else if (_vmflag_match(tok, "dc"))
- vma_area->e->madv |= (1ul << MADV_DONTFORK);
+ *madv |= (1ul << MADV_DONTFORK);
else if (_vmflag_match(tok, "dd"))
- vma_area->e->madv |= (1ul << MADV_DONTDUMP);
+ *madv |= (1ul << MADV_DONTDUMP);
else if (_vmflag_match(tok, "mg"))
- vma_area->e->madv |= (1ul << MADV_MERGEABLE);
+ *madv |= (1ul << MADV_MERGEABLE);
else if (_vmflag_match(tok, "hg"))
- vma_area->e->madv |= (1ul << MADV_HUGEPAGE);
+ *madv |= (1ul << MADV_HUGEPAGE);
else if (_vmflag_match(tok, "nh"))
- vma_area->e->madv |= (1ul << MADV_NOHUGEPAGE);
+ *madv |= (1ul << MADV_NOHUGEPAGE);
/* vmsplice doesn't work for VM_IO and VM_PFNMAP mappings. */
- if (_vmflag_match(tok, "io") || _vmflag_match(tok, "pf")) {
- /*
- * VVAR area mapped by the kernel as
- * VM_IO | VM_PFNMAP| VM_DONTEXPAND | VM_DONTDUMP
- */
- if (!vma_area_is(vma_area, VMA_AREA_VVAR))
- vma_area->e->status |= VMA_UNSUPP;
- }
+ if (_vmflag_match(tok, "io") || _vmflag_match(tok, "pf"))
+ *io_pf = 1;
/*
* Anything else is just ignored.
@@ -154,11 +153,29 @@ static int parse_vmflags(char *buf, struct vma_area *vma_area)
} while ((tok = strtok(NULL, " \n")));
#undef _vmflag_match
+}
+
+void parse_vmflags(char *buf, u32 *flags, u64 *madv, int *io_pf)
+{
+ __parse_vmflags(buf, flags, madv, io_pf);
+}
+
+static void parse_vma_vmflags(char *buf, struct vma_area *vma_area)
+{
+ int io_pf = 0;
+
+ __parse_vmflags(buf, &vma_area->e->flags, &vma_area->e->madv, &io_pf);
+
+ /*
+ * vmsplice doesn't work for VM_IO and VM_PFNMAP mappings, the
+ * only exception is VVAR area that mapped by the kernel as
+ * VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP
+ */
+ if (io_pf && !vma_area_is(vma_area, VMA_AREA_VVAR))
+ vma_area->e->status |= VMA_UNSUPP;
if (vma_area->e->madv)
vma_area->e->has_madv = true;
-
- return 0;
}
static inline int is_anon_shmem_map(dev_t dev)
@@ -705,7 +722,7 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list,
goto err;
eof = (str == NULL);
- if (!eof && !is_vma_range_fmt(str)) {
+ if (!eof && !__is_vma_range_fmt(str)) {
if (!strncmp(str, "Nonlinear", 9)) {
BUG_ON(!vma_area);
pr_err("Nonlinear mapping found %016"PRIx64"-%016"PRIx64"\n",
@@ -718,8 +735,7 @@ int parse_smaps(pid_t pid, struct vm_area_list *vma_area_list,
goto err;
} else if (!strncmp(str, "VmFlags: ", 9)) {
BUG_ON(!vma_area);
- if (parse_vmflags(&str[9], vma_area))
- goto err;
+ parse_vma_vmflags(&str[9], vma_area);
continue;
} else
continue;
@@ -2557,7 +2573,7 @@ int collect_controllers(struct list_head *cgroups, unsigned int *n_cgroups)
nc->controllers[nc->n_controllers-1] = n;
}
-
+
skip:
if (!off)
break;
@@ -2664,4 +2680,3 @@ err:
xfree(ch);
return -1;
}
-
--
2.7.4
More information about the CRIU
mailing list