Commit 6f67bb8f authored by Pavel Emelyanov's avatar Pavel Emelyanov

xids: Save pgid and sid on pstree_Item and pstree_entry

I store them on _entry since sids can only be inherited or
set to current's pid. Thus the best we can do it restore sids
at fork time, thus save them in the image we use to fork.

Maybe when we submit patches that will give us ability to set
arbitrary pgid and sid we'll change this, but this is in the
future.
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 6ed9f872
...@@ -1105,7 +1105,7 @@ static int seize_threads(const struct pstree_item *item) ...@@ -1105,7 +1105,7 @@ static int seize_threads(const struct pstree_item *item)
continue; continue;
pr_info("\tSeizing %d's %d thread\n", item->pid, item->threads[i]); pr_info("\tSeizing %d's %d thread\n", item->pid, item->threads[i]);
ret = seize_task(item->threads[i], item_ppid(item)); ret = seize_task(item->threads[i], item_ppid(item), NULL, NULL);
if (ret < 0) if (ret < 0)
goto err; goto err;
...@@ -1159,7 +1159,7 @@ static struct pstree_item *collect_task(pid_t pid, struct pstree_item *parent, ...@@ -1159,7 +1159,7 @@ static struct pstree_item *collect_task(pid_t pid, struct pstree_item *parent,
item->pid = pid; item->pid = pid;
item->parent = parent; item->parent = parent;
ret = seize_task(pid, item_ppid(item)); ret = seize_task(pid, item_ppid(item), &item->pgid, &item->sid);
if (ret < 0) if (ret < 0)
goto err_free; goto err_free;
...@@ -1327,6 +1327,8 @@ static int dump_pstree(pid_t pid, const struct list_head *pstree_list) ...@@ -1327,6 +1327,8 @@ static int dump_pstree(pid_t pid, const struct list_head *pstree_list)
item->pid, item->nr_children); item->pid, item->nr_children);
e.pid = item->pid; e.pid = item->pid;
e.pgid = item->pgid;
e.sid = item->sid;
e.nr_children = item->nr_children; e.nr_children = item->nr_children;
e.nr_threads = item->nr_threads; e.nr_threads = item->nr_threads;
......
...@@ -230,6 +230,8 @@ static int prepare_pstree(void) ...@@ -230,6 +230,8 @@ static int prepare_pstree(void)
break; break;
pi->pid = e.pid; pi->pid = e.pid;
pi->pgid = e.pgid;
pi->sid = e.sid;
ret = -1; ret = -1;
pi->nr_children = e.nr_children; pi->nr_children = e.nr_children;
......
...@@ -358,8 +358,8 @@ static int show_collect_pstree(int fd_pstree, struct list_head *collect) ...@@ -358,8 +358,8 @@ static int show_collect_pstree(int fd_pstree, struct list_head *collect)
ret = read_img_eof(fd_pstree, &e); ret = read_img_eof(fd_pstree, &e);
if (ret <= 0) if (ret <= 0)
goto out; goto out;
pr_msg("pid: %8d nr_children: %8d nr_threads: %8d\n", pr_msg("pid: %8d pgid: %8d sid %8d nr_children: %8d nr_threads: %8d\n",
e.pid, e.nr_children, e.nr_threads); e.pid, e.pgid, e.sid, e.nr_children, e.nr_threads);
if (collect) { if (collect) {
item = xzalloc(sizeof(struct pstree_item)); item = xzalloc(sizeof(struct pstree_item));
......
...@@ -177,6 +177,8 @@ struct pstree_item { ...@@ -177,6 +177,8 @@ struct pstree_item {
struct list_head list; struct list_head list;
pid_t pid; /* leader pid */ pid_t pid; /* leader pid */
struct pstree_item *parent; struct pstree_item *parent;
pid_t pgid;
pid_t sid;
int state; /* TASK_XXX constants */ int state; /* TASK_XXX constants */
int nr_children; /* number of children */ int nr_children; /* number of children */
int nr_threads; /* number of threads */ int nr_threads; /* number of threads */
......
...@@ -69,6 +69,8 @@ struct fs_entry { ...@@ -69,6 +69,8 @@ struct fs_entry {
struct pstree_entry { struct pstree_entry {
u32 pid; u32 pid;
u32 pgid;
u32 sid;
u32 nr_children; u32 nr_children;
u32 nr_threads; u32 nr_threads;
} __packed; } __packed;
......
...@@ -32,7 +32,7 @@ ...@@ -32,7 +32,7 @@
#define PTRACE_O_TRACEVFORKDONE 0x00000020 #define PTRACE_O_TRACEVFORKDONE 0x00000020
#define PTRACE_O_TRACEEXIT 0x00000040 #define PTRACE_O_TRACEEXIT 0x00000040
extern int seize_task(pid_t pid, pid_t ppid); extern int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid);
extern int unseize_task(pid_t pid, int state); extern int unseize_task(pid_t pid, int state);
extern int ptrace_peek_area(pid_t pid, void *dst, void *addr, long bytes); extern int ptrace_peek_area(pid_t pid, void *dst, void *addr, long bytes);
extern int ptrace_poke_area(pid_t pid, void *src, void *addr, long bytes); extern int ptrace_poke_area(pid_t pid, void *src, void *addr, long bytes);
......
...@@ -44,7 +44,7 @@ int unseize_task(pid_t pid, int st) ...@@ -44,7 +44,7 @@ int unseize_task(pid_t pid, int st)
* up with someone else. * up with someone else.
*/ */
int seize_task(pid_t pid, pid_t ppid) int seize_task(pid_t pid, pid_t ppid, pid_t *pgid, pid_t *sid)
{ {
siginfo_t si; siginfo_t si;
int status; int status;
...@@ -53,10 +53,23 @@ int seize_task(pid_t pid, pid_t ppid) ...@@ -53,10 +53,23 @@ int seize_task(pid_t pid, pid_t ppid)
ret = ptrace(PTRACE_SEIZE, pid, NULL, ret = ptrace(PTRACE_SEIZE, pid, NULL,
(void *)(unsigned long)PTRACE_SEIZE_DEVEL); (void *)(unsigned long)PTRACE_SEIZE_DEVEL);
/*
* It's ugly, but the ptrace API doesn't allow to distinguish
* attaching to zombie from other errors. Thus we have to parse
* the target's /proc/pid/stat. Sad, but parse whatever else
* we might nead at that early point.
*/
ret2 = parse_pid_stat_small(pid, &ps); ret2 = parse_pid_stat_small(pid, &ps);
if (ret2 < 0) if (ret2 < 0)
return -1; return -1;
if (pgid)
*pgid = ps.pgid;
if (sid)
*sid = ps.sid;
if (ret < 0) { if (ret < 0) {
if (ps.state != 'Z') { if (ps.state != 'Z') {
pr_err("Unseizeable non-zombie %d found, state %c\n", pr_err("Unseizeable non-zombie %d found, state %c\n",
......
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