[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