[CRIU] [crtools-bot for Pavel Emelyanov ] dump: Check for process/threads tree not to change after seizeing

Cyrill Gorcunov gorcunov at openvz.org
Thu Mar 1 10:31:20 EST 2012


The commit is pushed to "master" and will appear on git://github.com/cyrillos/crtools.git
------>
commit 0afad031d54dd63fda302af354d24857ef7407ab
Author: Pavel Emelyanov <xemul at parallels.com>
Date:   Thu Mar 1 19:07:15 2012 +0400

    dump: Check for process/threads tree not to change after seizeing
    
    When we've seized all the tasks and threads found in /proc check for
    the /proc contents be the same. Do it one-by-one as we descend the tree.
    This is OK, since tasks cannot create kids for anyone but themselves or
    their parents (reparent will be handled later).
    
    Signed-off-by: Pavel Emelyanov <xemul at parallels.com>
    Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
 cr-dump.c         |   71 +++++++++++++++++++++++++++++++++++++++++++++++------
 include/crtools.h |    4 +-
 2 files changed, 65 insertions(+), 10 deletions(-)

diff --git a/cr-dump.c b/cr-dump.c
index 9717240..2e6fe53 100644
--- a/cr-dump.c
+++ b/cr-dump.c
@@ -738,7 +738,7 @@ err:
 	return ret;
 }
 
-static int parse_threads(struct pstree_item *item)
+static int parse_threads(struct pstree_item *item, u32 **_t, int *_n)
 {
 	struct dirent *de;
 	DIR *dir;
@@ -768,13 +768,38 @@ static int parse_threads(struct pstree_item *item)
 
 	closedir(dir);
 
-	item->threads = t;
-	item->nr_threads = nr - 1;
+	*_t = t;
+	*_n = nr - 1;
 
 	return 0;
 }
 
-static int parse_children(struct pstree_item *item)
+static int get_threads(struct pstree_item *item)
+{
+	return parse_threads(item, &item->threads, &item->nr_threads);
+}
+
+static int check_threads(struct pstree_item *item)
+{
+	u32 *t;
+	int nr, ret;
+
+	ret = parse_threads(item, &t, &nr);
+	if (ret)
+		return ret;
+
+	ret = ((nr == item->nr_threads) && !memcmp(t, item->threads, nr));
+	xfree(t);
+
+	if (!ret) {
+		pr_info("Threads set has changed while suspending\n");
+		return -1;
+	}
+
+	return 0;
+}
+
+static int parse_children(struct pstree_item *item, u32 **_c, int *_n)
 {
 	FILE *file;
 	char *tok;
@@ -805,8 +830,8 @@ static int parse_children(struct pstree_item *item)
 
 	}
 
-	item->children = ch;
-	item->nr_children = nr - 1;
+	*_c = ch;
+	*_n = nr - 1;
 
 	return 0;
 
@@ -815,6 +840,11 @@ err:
 	return -1;
 }
 
+static int get_children(struct pstree_item *item)
+{
+	return parse_children(item, &item->children, &item->nr_children);
+}
+
 static void unseize_task_and_threads(struct pstree_item *item, enum cr_task_state st)
 {
 	int i;
@@ -880,9 +910,11 @@ static int collect_threads(struct pstree_item *item)
 {
 	int ret;
 
-	ret = parse_threads(item);
+	ret = get_threads(item);
 	if (!ret)
 		ret = seize_threads(item);
+	if (!ret)
+		ret = check_threads(item);
 
 	return ret;
 }
@@ -909,7 +941,7 @@ static struct pstree_item *collect_task(pid_t pid, pid_t ppid, struct list_head
 	if (ret < 0)
 		goto err_close;
 
-	ret = parse_children(item);
+	ret = get_children(item);
 	if (ret < 0)
 		goto err_close;
 
@@ -933,6 +965,26 @@ err:
 	return NULL;
 }
 
+static int check_subtree(struct pstree_item *item)
+{
+	u32 *ch;
+	int nr, ret;
+
+	ret = parse_children(item, &ch, &nr);
+	if (ret < 0)
+		return ret;
+
+	ret = ((nr == item->nr_children) && !memcmp(ch, item->children, nr));
+	xfree(ch);
+
+	if (!ret) {
+		pr_info("Children set has changed while suspending\n");
+		return -1;
+	}
+
+	return 0;
+}
+
 static int collect_subtree(pid_t pid, pid_t ppid, struct list_head *pstree_list,
 		int leader_only)
 {
@@ -951,6 +1003,9 @@ static int collect_subtree(pid_t pid, pid_t ppid, struct list_head *pstree_list,
 		if (collect_subtree(item->children[i], item->pid, pstree_list, 0) < 0)
 			return -1;
 
+	if (check_subtree(item))
+		return -1;
+
 	return 0;
 }
 
diff --git a/include/crtools.h b/include/crtools.h
index ef3f0b3..47d51e0 100644
--- a/include/crtools.h
+++ b/include/crtools.h
@@ -152,8 +152,8 @@ struct pstree_item {
 	pid_t			pid;		/* leader pid */
 	pid_t			ppid;
 	int			state;		/* TASK_XXX constants */
-	u32			nr_children;	/* number of children */
-	u32			nr_threads;	/* number of threads */
+	int			nr_children;	/* number of children */
+	int			nr_threads;	/* number of threads */
 	u32			*threads;	/* array of threads */
 	u32			*children;	/* array of children */
 };


More information about the CRIU mailing list