aboutsummaryrefslogtreecommitdiffstats
path: root/fs/proc/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r--fs/proc/base.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 69078c7cef1f..a19308604145 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -86,6 +86,7 @@
86#include <linux/fs_struct.h> 86#include <linux/fs_struct.h>
87#include <linux/slab.h> 87#include <linux/slab.h>
88#include <linux/flex_array.h> 88#include <linux/flex_array.h>
89#include <linux/posix-timers.h>
89#ifdef CONFIG_HARDWALL 90#ifdef CONFIG_HARDWALL
90#include <asm/hardwall.h> 91#include <asm/hardwall.h>
91#endif 92#endif
@@ -2013,6 +2014,102 @@ static const struct file_operations proc_map_files_operations = {
2013 .llseek = default_llseek, 2014 .llseek = default_llseek,
2014}; 2015};
2015 2016
2017struct timers_private {
2018 struct pid *pid;
2019 struct task_struct *task;
2020 struct sighand_struct *sighand;
2021 struct pid_namespace *ns;
2022 unsigned long flags;
2023};
2024
2025static void *timers_start(struct seq_file *m, loff_t *pos)
2026{
2027 struct timers_private *tp = m->private;
2028
2029 tp->task = get_pid_task(tp->pid, PIDTYPE_PID);
2030 if (!tp->task)
2031 return ERR_PTR(-ESRCH);
2032
2033 tp->sighand = lock_task_sighand(tp->task, &tp->flags);
2034 if (!tp->sighand)
2035 return ERR_PTR(-ESRCH);
2036
2037 return seq_list_start(&tp->task->signal->posix_timers, *pos);
2038}
2039
2040static void *timers_next(struct seq_file *m, void *v, loff_t *pos)
2041{
2042 struct timers_private *tp = m->private;
2043 return seq_list_next(v, &tp->task->signal->posix_timers, pos);
2044}
2045
2046static void timers_stop(struct seq_file *m, void *v)
2047{
2048 struct timers_private *tp = m->private;
2049
2050 if (tp->sighand) {
2051 unlock_task_sighand(tp->task, &tp->flags);
2052 tp->sighand = NULL;
2053 }
2054
2055 if (tp->task) {
2056 put_task_struct(tp->task);
2057 tp->task = NULL;
2058 }
2059}
2060
2061static int show_timer(struct seq_file *m, void *v)
2062{
2063 struct k_itimer *timer;
2064 struct timers_private *tp = m->private;
2065 int notify;
2066 static char *nstr[] = {
2067 [SIGEV_SIGNAL] = "signal",
2068 [SIGEV_NONE] = "none",
2069 [SIGEV_THREAD] = "thread",
2070 };
2071
2072 timer = list_entry((struct list_head *)v, struct k_itimer, list);
2073 notify = timer->it_sigev_notify;
2074
2075 seq_printf(m, "ID: %d\n", timer->it_id);
2076 seq_printf(m, "signal: %d/%p\n", timer->sigq->info.si_signo,
2077 timer->sigq->info.si_value.sival_ptr);
2078 seq_printf(m, "notify: %s/%s.%d\n",
2079 nstr[notify & ~SIGEV_THREAD_ID],
2080 (notify & SIGEV_THREAD_ID) ? "tid" : "pid",
2081 pid_nr_ns(timer->it_pid, tp->ns));
2082
2083 return 0;
2084}
2085
2086static const struct seq_operations proc_timers_seq_ops = {
2087 .start = timers_start,
2088 .next = timers_next,
2089 .stop = timers_stop,
2090 .show = show_timer,
2091};
2092
2093static int proc_timers_open(struct inode *inode, struct file *file)
2094{
2095 struct timers_private *tp;
2096
2097 tp = __seq_open_private(file, &proc_timers_seq_ops,
2098 sizeof(struct timers_private));
2099 if (!tp)
2100 return -ENOMEM;
2101
2102 tp->pid = proc_pid(inode);
2103 tp->ns = inode->i_sb->s_fs_info;
2104 return 0;
2105}
2106
2107static const struct file_operations proc_timers_operations = {
2108 .open = proc_timers_open,
2109 .read = seq_read,
2110 .llseek = seq_lseek,
2111 .release = seq_release_private,
2112};
2016#endif /* CONFIG_CHECKPOINT_RESTORE */ 2113#endif /* CONFIG_CHECKPOINT_RESTORE */
2017 2114
2018static struct dentry *proc_pident_instantiate(struct inode *dir, 2115static struct dentry *proc_pident_instantiate(struct inode *dir,
@@ -2583,6 +2680,9 @@ static const struct pid_entry tgid_base_stuff[] = {
2583 REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations), 2680 REG("gid_map", S_IRUGO|S_IWUSR, proc_gid_map_operations),
2584 REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations), 2681 REG("projid_map", S_IRUGO|S_IWUSR, proc_projid_map_operations),
2585#endif 2682#endif
2683#ifdef CONFIG_CHECKPOINT_RESTORE
2684 REG("timers", S_IRUGO, proc_timers_operations),
2685#endif
2586}; 2686};
2587 2687
2588static int proc_tgid_base_readdir(struct file * filp, 2688static int proc_tgid_base_readdir(struct file * filp,