Commit 08ca20e2 authored by Kirill Tkhai's avatar Kirill Tkhai Committed by Andrei Vagin

compel: Add more arguments to compel_wait_task()

Some get_status() methods may allocate data, because
not all of the fields in /proc/[pid]/status file
have the fixed size. For example, NSpid, which
size may vary.

Introduce new method free_status() in counterweight
for such type get_status() methods. it will be called
in case of we go to try_again and need to free allocated
data.

Also, introduce data parameter for a use in the future.
Signed-off-by: 's avatarKirill Tkhai <ktkhai@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 0469a46a
...@@ -24,8 +24,9 @@ struct seize_task_status { ...@@ -24,8 +24,9 @@ struct seize_task_status {
}; };
extern int compel_wait_task(int pid, int ppid, extern int compel_wait_task(int pid, int ppid,
int (*get_status)(int pid, struct seize_task_status *), int (*get_status)(int pid, struct seize_task_status *, void *data),
struct seize_task_status *st); void (*free_status)(int pid, struct seize_task_status *, void *data),
struct seize_task_status *st, void *data);
extern int compel_stop_task(int pid); extern int compel_stop_task(int pid);
extern int compel_resume_task(pid_t pid, int orig_state, int state); extern int compel_resume_task(pid_t pid, int orig_state, int state);
......
...@@ -52,7 +52,7 @@ static inline void close_safe(int *pfd) ...@@ -52,7 +52,7 @@ static inline void close_safe(int *pfd)
} }
} }
static int parse_pid_status(int pid, struct seize_task_status *ss) static int parse_pid_status(int pid, struct seize_task_status *ss, void *data)
{ {
char aux[128]; char aux[128];
FILE *f; FILE *f;
...@@ -107,7 +107,7 @@ int compel_stop_task(int pid) ...@@ -107,7 +107,7 @@ int compel_stop_task(int pid)
ret = compel_interrupt_task(pid); ret = compel_interrupt_task(pid);
if (ret == 0) if (ret == 0)
ret = compel_wait_task(pid, -1, parse_pid_status, &ss); ret = compel_wait_task(pid, -1, parse_pid_status, NULL, &ss, NULL);
return ret; return ret;
} }
...@@ -192,8 +192,9 @@ static int skip_sigstop(int pid, int nr_signals) ...@@ -192,8 +192,9 @@ static int skip_sigstop(int pid, int nr_signals)
* up with someone else. * up with someone else.
*/ */
int compel_wait_task(int pid, int ppid, int compel_wait_task(int pid, int ppid,
int (*get_status)(int pid, struct seize_task_status *), int (*get_status)(int pid, struct seize_task_status *, void *),
struct seize_task_status *ss) void (*free_status)(int pid, struct seize_task_status *, void *),
struct seize_task_status *ss, void *data)
{ {
siginfo_t si; siginfo_t si;
int status, nr_sigstop; int status, nr_sigstop;
...@@ -220,7 +221,7 @@ try_again: ...@@ -220,7 +221,7 @@ try_again:
wait_errno = errno; wait_errno = errno;
} }
ret2 = get_status(pid, ss); ret2 = get_status(pid, ss, data);
if (ret2) if (ret2)
goto err; goto err;
...@@ -271,6 +272,8 @@ try_again: ...@@ -271,6 +272,8 @@ try_again:
} }
ret = 0; ret = 0;
if (free_status)
free_status(pid, ss, data);
goto try_again; goto try_again;
} }
......
...@@ -96,7 +96,7 @@ extern int parse_pid_stat(pid_t pid, struct proc_pid_stat *s); ...@@ -96,7 +96,7 @@ extern int parse_pid_stat(pid_t pid, struct proc_pid_stat *s);
extern unsigned int parse_pid_loginuid(pid_t pid, int *err, bool ignore_noent); extern unsigned int parse_pid_loginuid(pid_t pid, int *err, bool ignore_noent);
extern int parse_pid_oom_score_adj(pid_t pid, int *err); extern int parse_pid_oom_score_adj(pid_t pid, int *err);
extern int prepare_loginuid(unsigned int value, unsigned int loglevel); extern int prepare_loginuid(unsigned int value, unsigned int loglevel);
extern int parse_pid_status(pid_t pid, struct seize_task_status *); extern int parse_pid_status(pid_t pid, struct seize_task_status *, void *data);
extern int parse_file_locks(void); extern int parse_file_locks(void);
extern int get_fd_mntid(int fd, int *mnt_id); extern int get_fd_mntid(int fd, int *mnt_id);
......
...@@ -993,7 +993,7 @@ static int cap_parse(char *str, unsigned int *res) ...@@ -993,7 +993,7 @@ static int cap_parse(char *str, unsigned int *res)
return 0; return 0;
} }
int parse_pid_status(pid_t pid, struct seize_task_status *ss) int parse_pid_status(pid_t pid, struct seize_task_status *ss, void *data)
{ {
struct proc_status_creds *cr = container_of(ss, struct proc_status_creds, s); struct proc_status_creds *cr = container_of(ss, struct proc_status_creds, s);
struct bfd f; struct bfd f;
......
...@@ -490,7 +490,7 @@ static int collect_children(struct pstree_item *item) ...@@ -490,7 +490,7 @@ static int collect_children(struct pstree_item *item)
goto free; goto free;
} }
ret = compel_wait_task(pid, item->pid->real, parse_pid_status, &creds->s); ret = compel_wait_task(pid, item->pid->real, parse_pid_status, NULL, &creds->s, NULL);
if (ret < 0) { if (ret < 0) {
/* /*
* Here is a race window between parse_children() and seize(), * Here is a race window between parse_children() and seize(),
...@@ -716,7 +716,7 @@ static int collect_threads(struct pstree_item *item) ...@@ -716,7 +716,7 @@ static int collect_threads(struct pstree_item *item)
if (!opts.freeze_cgroup && compel_interrupt_task(pid)) if (!opts.freeze_cgroup && compel_interrupt_task(pid))
continue; continue;
ret = compel_wait_task(pid, item_ppid(item), parse_pid_status, &t_creds.s); ret = compel_wait_task(pid, item_ppid(item), parse_pid_status, NULL, &t_creds.s, NULL);
if (ret < 0) { if (ret < 0) {
/* /*
* Here is a race window between parse_threads() and seize(), * Here is a race window between parse_threads() and seize(),
...@@ -855,7 +855,7 @@ int collect_pstree(void) ...@@ -855,7 +855,7 @@ int collect_pstree(void)
if (!creds) if (!creds)
goto err; goto err;
ret = compel_wait_task(pid, -1, parse_pid_status, &creds->s); ret = compel_wait_task(pid, -1, parse_pid_status, NULL, &creds->s, NULL);
if (ret < 0) if (ret < 0)
goto err; goto err;
......
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