Commit 0afad031 authored by Pavel Emelyanov's avatar Pavel Emelyanov Committed by Cyrill Gorcunov

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: 's avatarPavel Emelyanov <xemul@parallels.com>
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent 30a2b6f3
......@@ -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;
}
......
......@@ -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 */
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment