[CRIU] [RFC 5/5] dump: Check for restorer blob on dump and skip it
Cyrill Gorcunov
gorcunov at openvz.org
Sun May 26 17:12:42 EDT 2013
We already skip auto-generated vdso area on subsequent
dumps, lets do the same for restorer blob.
Need to use more unified (unioned) way to represent
marks instead of opencoded solution.
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
cr-dump.c | 4 ++--
include/parasite-syscall.h | 4 ++--
include/parasite.h | 12 +++++++++---
parasite-syscall.c | 46 ++++++++++++++++++++++++++++------------------
pie/parasite.c | 15 +++++++++------
5 files changed, 50 insertions(+), 31 deletions(-)
diff --git a/cr-dump.c b/cr-dump.c
index 6ea17a7..dd5ac7b 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -1418,9 +1418,9 @@ static int dump_one_task(struct pstree_item *item)
}
}
- ret = parasite_fixup_vdso(parasite_ctl, pid, &vmas);
+ ret = parasite_fixup_marked(parasite_ctl, pid, &vmas);
if (ret) {
- pr_err("Can't fixup vdso VMAs (pid: %d)\n", pid);
+ pr_err("Can't fixup marked VMAs (pid: %d)\n", pid);
goto err_cure_fdset;
}
diff --git a/include/parasite-syscall.h b/include/parasite-syscall.h
index 3babeb8..fccfe38 100644
--- a/include/parasite-syscall.h
+++ b/include/parasite-syscall.h
@@ -109,7 +109,7 @@ extern int __parasite_execute_trap(struct parasite_ctl *ctl, pid_t pid,
bool signals_blocked);
extern bool arch_can_dump_task(pid_t pid);
-extern int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
- struct vm_area_list *vma_area_list);
+extern int parasite_fixup_marked(struct parasite_ctl *ctl, pid_t pid,
+ struct vm_area_list *vma_area_list);
#endif /* __CR_PARASITE_SYSCALL_H__ */
diff --git a/include/parasite.h b/include/parasite.h
index d26b130..12dd5fe 100644
--- a/include/parasite.h
+++ b/include/parasite.h
@@ -45,7 +45,7 @@ enum {
PARASITE_CMD_DRAIN_FDS,
PARASITE_CMD_GET_PROC_FD,
PARASITE_CMD_DUMP_TTY,
- PARASITE_CMD_CHECK_VDSO_MARK,
+ PARASITE_CMD_CHECK_MARK,
PARASITE_CMD_MAX,
};
@@ -90,11 +90,17 @@ struct parasite_vma_entry
int prot;
};
-struct parasite_vdso_vma_entry {
+enum {
+ MTYPE_INVALID,
+ MTYPE_RESTORER,
+ MTYPE_VDSO,
+};
+
+struct parasite_marked_vma_entry {
unsigned long start;
unsigned long len;
+ int mtype;
unsigned long proxy_addr;
- int is_marked;
};
struct parasite_dump_pages_args {
diff --git a/parasite-syscall.c b/parasite-syscall.c
index 37a9c4f..bfda314 100644
--- a/parasite-syscall.c
+++ b/parasite-syscall.c
@@ -652,22 +652,20 @@ err:
return ret;
}
-/*
- * Find out proxy vdso vma and drop it from the list. Also
- * fix vdso status on vmas if wrong status found.
- */
-int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
- struct vm_area_list *vma_area_list)
+/* Find out marked vmas and drop them from the list */
+int parasite_fixup_marked(struct parasite_ctl *ctl, pid_t pid,
+ struct vm_area_list *vma_area_list)
{
unsigned long proxy_addr = VDSO_BAD_ADDR;
- struct parasite_vdso_vma_entry *args;
- struct vma_area *marked = NULL;
+ struct parasite_marked_vma_entry *args;
+ struct vma_area *restorer = NULL;
+ struct vma_area *vdso = NULL;
struct vma_area *vma;
int fd, ret = -1;
off_t off;
u64 pfn;
- args = parasite_args(ctl, struct parasite_vdso_vma_entry);
+ args = parasite_args(ctl, struct parasite_marked_vma_entry);
fd = open_proc(pid, "pagemap");
if (fd < 0)
return -1;
@@ -687,19 +685,24 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
args->start = vma->vma.start;
args->len = vma_area_len(vma);
- if (parasite_execute_daemon(PARASITE_CMD_CHECK_VDSO_MARK, ctl)) {
+ if (parasite_execute_daemon(PARASITE_CMD_CHECK_MARK, ctl)) {
pr_err("vdso: Parasite failed to poke for mark\n");
ret = -1;
goto err;
}
/*
- * Defer handling marked vdso.
+ * Defer handling marked areas.
*/
- if (unlikely(args->is_marked)) {
+ switch (args->mtype) {
+ case MTYPE_RESTORER:
+ BUG_ON(restorer);
+ restorer = vma;
+ continue;
+ case MTYPE_VDSO:
BUG_ON(args->proxy_addr == VDSO_BAD_ADDR);
- BUG_ON(marked);
- marked = vma;
+ BUG_ON(vdso);
+ vdso = vma;
proxy_addr = args->proxy_addr;
continue;
}
@@ -743,9 +746,9 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
* There is marked vdso, it means such vdso is autogenerated
* and must be dropped from vma list.
*/
- if (marked) {
+ if (vdso) {
pr_debug("vdso: Found marked at %lx (proxy at %lx)\n",
- (long)marked->vma.start, (long)proxy_addr);
+ (long)vdso->vma.start, (long)proxy_addr);
/*
* Don't forget to restore the proxy vdso status, since
@@ -762,8 +765,15 @@ int parasite_fixup_vdso(struct parasite_ctl *ctl, pid_t pid,
pr_debug("vdso: Droppping marked vdso at %lx\n",
(long)vma->vma.start);
- list_del(&marked->list);
- xfree(marked);
+ list_del(&vdso->list);
+ xfree(vdso);
+ }
+
+ if (restorer) {
+ pr_debug("rstr: Found marked at %lx, dropping it\n",
+ (long)restorer->vma.start);
+ list_del(&restorer->list);
+ xfree(restorer);
}
ret = 0;
err:
diff --git a/pie/parasite.c b/pie/parasite.c
index 3e01cc7..e384450 100644
--- a/pie/parasite.c
+++ b/pie/parasite.c
@@ -6,6 +6,7 @@
#include <stdarg.h>
#include <sys/ioctl.h>
+#include "signatures.h"
#include "syscall.h"
#include "parasite.h"
#include "lock.h"
@@ -410,16 +411,18 @@ static int parasite_cfg_log(struct parasite_log_args *args)
return ret;
}
-static int parasite_check_vdso_mark(struct parasite_vdso_vma_entry *args)
+static int parasite_check_mark(struct parasite_marked_vma_entry *args)
{
struct vdso_mark *m = (void *)args->start;
+ args->mtype = MTYPE_INVALID;
+
if (is_vdso_mark(m)) {
- args->is_marked = 1;
+ args->mtype = MTYPE_VDSO;
args->proxy_addr = m->proxy_addr;
} else {
- args->is_marked = 0;
- args->proxy_addr = VDSO_BAD_ADDR;
+ if (*(u64 *)(void *)args->start == CRIU_SIG_RESTORER)
+ args->mtype = MTYPE_VDSO;
}
return 0;
@@ -605,8 +608,8 @@ __parasite_daemon_thread_leader(void *args, struct tid_state_s *s)
case PARASITE_CMD_DUMP_TTY:
ret = parasite_dump_tty(args);
break;
- case PARASITE_CMD_CHECK_VDSO_MARK:
- ret = parasite_check_vdso_mark(args);
+ case PARASITE_CMD_CHECK_MARK:
+ ret = parasite_check_mark(args);
break;
default:
pr_err("Unknown command in parasite daemon thread leader: %d\n", m.cmd);
--
1.8.1.4
More information about the CRIU
mailing list