[CRIU] [PATCH] parasite/mem: unprotect VMAs if page dumping failed
Dmitry Safonov
dsafonov at virtuozzo.com
Mon Mar 28 12:38:51 PDT 2016
Before patch parasite_dump_pages_seized tried to unprotect pages
by parasite command. But it had two issues:
1. parasite doesn't wait any command, except PARASITE_CMD_FINI after
it failed;
2. return code for parasite_dump_pages_seized was not set according
to __parasite_dump_pages_seized failure.
During fixing compatible patches set troubles, I saw the following picture,
which the patch fixes:
(00.010992) Sent msg to daemon 8 0 0
pie: __fetched msg: 8 0 0
(00.010995) Wait for ack 8 on daemon socket
pie: Error (pie/parasite.c:82): Can't splice pages to pipe (0/16)
pie: __sent ack msg: 8 8 -1
pie: Error (pie/parasite.c:721): Close the control socket for writing
>
pie: Daemon waits for command
(00.011023) Fetched ack: 8 8 -1
(00.011025) Error (parasite-syscall.c:345): Command 8 for daemon failed with -1
(00.011131) page-pipe: Killing page pipe
(00.011150) ----------------------------------------
(00.011151) Error (mem.c:375): Can't dump page with parasite
(00.011155) Sent msg to daemon 7 0 0
(00.011156) Wait for ack 7 on daemon socket
pie: __fetched msg: 7 0 0
(00.011157) Error (parasite-syscall.c:318): Message reply from daemon is trimmed (12/0)
pie: Error (pie/parasite.c:665): Command rejected
(00.011159) Error (mem.c:379): Can't rollback unprotected vmas with parasite
pie: Daemon waits for command
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
---
criu/mem.c | 4 +++-
criu/pie/parasite.c | 21 ++++++++++++++++++++-
2 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/criu/mem.c b/criu/mem.c
index 5a7b5bb96ba9..a8e3953769d0 100644
--- a/criu/mem.c
+++ b/criu/mem.c
@@ -371,8 +371,10 @@ int parasite_dump_pages_seized(struct parasite_ctl *ctl,
}
ret = __parasite_dump_pages_seized(ctl, pargs, vma_area_list, pp);
- if (ret)
+ if (ret) {
pr_err("Can't dump page with parasite\n");
+ ret = -1;
+ }
pargs->add_prot = 0;
if (parasite_execute_daemon(PARASITE_CMD_MPROTECT_VMAS, ctl)) {
diff --git a/criu/pie/parasite.c b/criu/pie/parasite.c
index 9d822bb2a93a..b1808bc7ed5c 100644
--- a/criu/pie/parasite.c
+++ b/criu/pie/parasite.c
@@ -644,6 +644,25 @@ static int fini()
return -1;
}
+static inline bool after_fail_cmd_allowed(struct ctl_msg *m, void *args)
+{
+ if (m->cmd == PARASITE_CMD_FINI)
+ return true;
+
+ if (m->cmd == PARASITE_CMD_MPROTECT_VMAS) {
+ struct parasite_dump_pages_args *dp_args = args;
+
+ /*
+ * We should allow parasite to unprotect VMAs back
+ * from PROT_READ after failed pages dumping.
+ */
+ if (!dp_args->add_prot)
+ return true;
+ }
+
+ return false;
+}
+
static noinline __used int noinline parasite_daemon(void *args)
{
struct ctl_msg m = { };
@@ -661,7 +680,7 @@ static noinline __used int noinline parasite_daemon(void *args)
if (__parasite_daemon_wait_msg(&m))
break;
- if (ret && m.cmd != PARASITE_CMD_FINI) {
+ if (ret && !after_fail_cmd_allowed(&m, args)) {
pr_err("Command rejected\n");
continue;
}
--
2.7.4
More information about the CRIU
mailing list