[CRIU] [PATCH] [resend] criu restore: mismatched pid debug

Kir Kolyshkin kir at openvz.org
Thu Apr 27 21:23:07 PDT 2017


Sometimes we fail to restore because of PID mismatch. In this case,
we would like to know who the hell has taken our PID. Let's print
a process tree, which looks something like this (this example is
obviously from the host):

 1 /usr/lib/systemd/systemd --switched-root --system --deserialize 24
 \_482 /usr/lib/systemd/systemd-journald
 \_746 /sbin/auditd
   \_748 /sbin/audispd
     \_751 /usr/sbin/sedispatch
 \_769 /usr/lib/systemd/systemd-logind

This is debug for https://github.com/xemul/criu/issues/282.

[This is a resend of the same patch -- first time mail server broke it]

Signed-off-by: Kir Kolyshkin <kir at openvz.org>
---
 criu/cr-restore.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 45 insertions(+)

diff --git a/criu/cr-restore.c b/criu/cr-restore.c
index e78b72e..91874c0 100644
--- a/criu/cr-restore.c
+++ b/criu/cr-restore.c
@@ -1323,6 +1323,50 @@ static int create_children_and_session(void)
 	return 0;
 }
 
+static int show_pstree(pid_t p, int level)
+{
+	pid_t *ch;
+	int i, nr_ch, ret;
+	char cmd[80];
+	int fd, len, llen;
+
+	/* limit output to a single line on a terminal */
+	llen = 79 - printf("%*s%d ", level*2, level ? "\\_" : "", p);
+
+	fd = open_proc(p, "cmdline");
+	if (fd < 0)
+		return -1;
+	len = read(fd, cmd, sizeof(cmd) - 1);
+	close(fd);
+
+	if (len > 0) {
+		if (len > llen) {
+			len = llen;
+			// ellipsis
+			cmd[len - 1] = '.';
+			cmd[len - 2] = '.';
+		}
+		for (i = 0; i < len; i++)
+			if (cmd[i] == '\0')
+				cmd[i] = ' ';
+		cmd[len] = '\0';
+		puts(cmd);
+	} else {
+		puts("???");
+	}
+
+	ret = parse_children(p, &ch, &nr_ch);
+	if (ret < 0)
+		return ret;
+
+	for (i = 0; i < nr_ch; i++) {
+		show_pstree(ch[i], level+1);
+	}
+
+	xfree(ch);
+	return 0;
+}
+
 static int restore_task_with_children(void *_arg)
 {
 	struct cr_clone_arg *ca = _arg;
@@ -1351,6 +1395,7 @@ static int restore_task_with_children(void *_arg)
 	pid = getpid();
 	if (vpid(current) != pid) {
 		pr_err("Pid %d do not match expected %d\n", pid, vpid(current));
+		show_pstree(1, 0);
 		set_task_cr_err(EEXIST);
 		goto err;
 	}
-- 
2.9.3



More information about the CRIU mailing list