diff --git a/fs/proc/array.c b/fs/proc/array.c index 4ac811e1a..c71541988 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c @@ -91,11 +91,15 @@ #include #include #include +#include +#include #include #include #include "internal.h" +unsigned int sysctl_watch_host_pid; + static inline void task_name(struct seq_file *m, struct task_struct *p) { char *buf; @@ -165,6 +169,9 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, const struct cred *cred; pid_t ppid, tpid = 0, tgid, ngid; unsigned int max_fds = 0; +#ifdef CONFIG_PID_NS + struct pid_namespace *current_pid_ns = task_active_pid_ns(current); +#endif rcu_read_lock(); ppid = pid_alive(p) ? @@ -188,6 +195,21 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns, task_unlock(p); rcu_read_unlock(); +#ifdef CONFIG_PID_NS + seq_puts(m, "NStgid:"); + for (g = current_pid_ns->level; g <= pid->level; g++) + seq_printf(m, "\t%d", + task_tgid_nr_ns(p, pid->numbers[g].ns)); + seq_puts(m, "\nNSpid:"); + for (g = current_pid_ns->level; g <= pid->level; g++) + seq_printf(m, "\t%d", + task_pid_nr_ns(p, pid->numbers[g].ns)); + seq_puts(m, "\nNSsid:"); + for (g = current_pid_ns->level; g <= pid->level; g++) + seq_printf(m, "\t%d", + task_session_nr_ns(p, pid->numbers[g].ns)); + seq_putc(m, '\n'); +#endif seq_printf(m, "State:\t%s", get_task_state(p)); seq_put_decimal_ull(m, "\nTgid:\t", tgid); @@ -391,6 +413,35 @@ static void task_cpus_allowed(struct seq_file *m, struct task_struct *task) cpumask_pr_args(&task->cpus_allowed)); } +int host_pid_info(struct seq_file *m, struct pid_namespace *ns, + struct pid *pid, struct task_struct *task) +{ + if (sysctl_watch_host_pid) { + struct task_struct *p = task; + int g; + struct pid_namespace *current_pid_ns = task_active_pid_ns(current); + + task_name(m, task); + rcu_read_lock(); + seq_puts(m, "NStgid:"); + for (g = current_pid_ns->level; g >= 0; g--) + seq_printf(m, "\t%d", + task_tgid_nr_ns(p, pid->numbers[g].ns)); + seq_puts(m, "\nNSpid:"); + for (g = current_pid_ns->level; g >= 0; g--) + seq_printf(m, "\t%d", + task_pid_nr_ns(p, pid->numbers[g].ns)); + seq_puts(m, "\nNSsid:"); + for (g = current_pid_ns->level; g >= 0; g--) + seq_printf(m, "\t%d", + task_session_nr_ns(p, pid->numbers[g].ns)); + rcu_read_unlock(); + seq_putc(m, '\n'); + return 0; + } + return 0; +} + int proc_pid_status(struct seq_file *m, struct pid_namespace *ns, struct pid *pid, struct task_struct *task) { diff --git a/fs/proc/base.c b/fs/proc/base.c index 64695dcf8..a628d0925 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -2946,6 +2946,7 @@ static const struct pid_entry tgid_base_stuff[] = { REG("environ", S_IRUSR, proc_environ_operations), REG("auxv", S_IRUSR, proc_auxv_operations), ONE("status", S_IRUGO, proc_pid_status), + ONE("hostinfo", S_IRUGO, host_pid_info), ONE("personality", S_IRUSR, proc_pid_personality), ONE("limits", S_IRUGO, proc_pid_limits), #ifdef CONFIG_SCHED_DEBUG @@ -3339,6 +3340,7 @@ static const struct pid_entry tid_base_stuff[] = { REG("environ", S_IRUSR, proc_environ_operations), REG("auxv", S_IRUSR, proc_auxv_operations), ONE("status", S_IRUGO, proc_pid_status), + ONE("hostinfo", S_IRUGO, host_pid_info), ONE("personality", S_IRUSR, proc_pid_personality), ONE("limits", S_IRUGO, proc_pid_limits), #ifdef CONFIG_SCHED_DEBUG diff --git a/fs/proc/internal.h b/fs/proc/internal.h index a34195e92..7d87245c1 100644 --- a/fs/proc/internal.h +++ b/fs/proc/internal.h @@ -144,6 +144,8 @@ extern int proc_tgid_stat(struct seq_file *, struct pid_namespace *, struct pid *, struct task_struct *); extern int proc_pid_status(struct seq_file *, struct pid_namespace *, struct pid *, struct task_struct *); +extern int host_pid_info(struct seq_file *, struct pid_namespace *, + struct pid *, struct task_struct *); extern int proc_pid_statm(struct seq_file *, struct pid_namespace *, struct pid *, struct task_struct *); diff --git a/include/linux/sched/sysctl.h b/include/linux/sched/sysctl.h index 1c1a1512e..bea5e3ad7 100644 --- a/include/linux/sched/sysctl.h +++ b/include/linux/sched/sysctl.h @@ -19,6 +19,7 @@ extern int proc_dohung_task_timeout_secs(struct ctl_table *table, int write, enum { sysctl_hung_task_timeout_secs = 0 }; #endif +extern unsigned int sysctl_watch_host_pid; extern unsigned int sysctl_sched_latency; extern unsigned int sysctl_sched_min_granularity; extern unsigned int sysctl_sched_wakeup_granularity; diff --git a/kernel/sysctl.c b/kernel/sysctl.c index e3cadcc54..891e587d3 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -335,6 +335,15 @@ static struct ctl_table kern_table[] = { .mode = 0644, .proc_handler = proc_dointvec, }, +#ifdef CONFIG_PID_NS + { + .procname = "watch_host_pid", + .data = &sysctl_watch_host_pid, + .maxlen = sizeof(unsigned int), + .mode = 0644, + .proc_handler = proc_dointvec, + }, +#endif #ifdef CONFIG_SCHED_DEBUG { .procname = "sched_min_granularity_ns",