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.c231
1 files changed, 130 insertions, 101 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 10fd5223d600..0c9de19a1633 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -65,6 +65,7 @@
65#include <linux/mm.h> 65#include <linux/mm.h>
66#include <linux/rcupdate.h> 66#include <linux/rcupdate.h>
67#include <linux/kallsyms.h> 67#include <linux/kallsyms.h>
68#include <linux/stacktrace.h>
68#include <linux/resource.h> 69#include <linux/resource.h>
69#include <linux/module.h> 70#include <linux/module.h>
70#include <linux/mount.h> 71#include <linux/mount.h>
@@ -109,25 +110,22 @@ struct pid_entry {
109 .op = OP, \ 110 .op = OP, \
110} 111}
111 112
112#define DIR(NAME, MODE, OTYPE) \ 113#define DIR(NAME, MODE, iops, fops) \
113 NOD(NAME, (S_IFDIR|(MODE)), \ 114 NOD(NAME, (S_IFDIR|(MODE)), &iops, &fops, {} )
114 &proc_##OTYPE##_inode_operations, &proc_##OTYPE##_operations, \ 115#define LNK(NAME, get_link) \
115 {} )
116#define LNK(NAME, OTYPE) \
117 NOD(NAME, (S_IFLNK|S_IRWXUGO), \ 116 NOD(NAME, (S_IFLNK|S_IRWXUGO), \
118 &proc_pid_link_inode_operations, NULL, \ 117 &proc_pid_link_inode_operations, NULL, \
119 { .proc_get_link = &proc_##OTYPE##_link } ) 118 { .proc_get_link = get_link } )
120#define REG(NAME, MODE, OTYPE) \ 119#define REG(NAME, MODE, fops) \
121 NOD(NAME, (S_IFREG|(MODE)), NULL, \ 120 NOD(NAME, (S_IFREG|(MODE)), NULL, &fops, {})
122 &proc_##OTYPE##_operations, {}) 121#define INF(NAME, MODE, read) \
123#define INF(NAME, MODE, OTYPE) \
124 NOD(NAME, (S_IFREG|(MODE)), \ 122 NOD(NAME, (S_IFREG|(MODE)), \
125 NULL, &proc_info_file_operations, \ 123 NULL, &proc_info_file_operations, \
126 { .proc_read = &proc_##OTYPE } ) 124 { .proc_read = read } )
127#define ONE(NAME, MODE, OTYPE) \ 125#define ONE(NAME, MODE, show) \
128 NOD(NAME, (S_IFREG|(MODE)), \ 126 NOD(NAME, (S_IFREG|(MODE)), \
129 NULL, &proc_single_file_operations, \ 127 NULL, &proc_single_file_operations, \
130 { .proc_show = &proc_##OTYPE } ) 128 { .proc_show = show } )
131 129
132/* 130/*
133 * Count the number of hardlinks for the pid_entry table, excluding the . 131 * Count the number of hardlinks for the pid_entry table, excluding the .
@@ -308,9 +306,9 @@ static int proc_pid_auxv(struct task_struct *task, char *buffer)
308 struct mm_struct *mm = get_task_mm(task); 306 struct mm_struct *mm = get_task_mm(task);
309 if (mm) { 307 if (mm) {
310 unsigned int nwords = 0; 308 unsigned int nwords = 0;
311 do 309 do {
312 nwords += 2; 310 nwords += 2;
313 while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */ 311 } while (mm->saved_auxv[nwords - 2] != 0); /* AT_NULL */
314 res = nwords * sizeof(mm->saved_auxv[0]); 312 res = nwords * sizeof(mm->saved_auxv[0]);
315 if (res > PAGE_SIZE) 313 if (res > PAGE_SIZE)
316 res = PAGE_SIZE; 314 res = PAGE_SIZE;
@@ -340,6 +338,37 @@ static int proc_pid_wchan(struct task_struct *task, char *buffer)
340} 338}
341#endif /* CONFIG_KALLSYMS */ 339#endif /* CONFIG_KALLSYMS */
342 340
341#ifdef CONFIG_STACKTRACE
342
343#define MAX_STACK_TRACE_DEPTH 64
344
345static int proc_pid_stack(struct seq_file *m, struct pid_namespace *ns,
346 struct pid *pid, struct task_struct *task)
347{
348 struct stack_trace trace;
349 unsigned long *entries;
350 int i;
351
352 entries = kmalloc(MAX_STACK_TRACE_DEPTH * sizeof(*entries), GFP_KERNEL);
353 if (!entries)
354 return -ENOMEM;
355
356 trace.nr_entries = 0;
357 trace.max_entries = MAX_STACK_TRACE_DEPTH;
358 trace.entries = entries;
359 trace.skip = 0;
360 save_stack_trace_tsk(task, &trace);
361
362 for (i = 0; i < trace.nr_entries; i++) {
363 seq_printf(m, "[<%p>] %pS\n",
364 (void *)entries[i], (void *)entries[i]);
365 }
366 kfree(entries);
367
368 return 0;
369}
370#endif
371
343#ifdef CONFIG_SCHEDSTATS 372#ifdef CONFIG_SCHEDSTATS
344/* 373/*
345 * Provides /proc/PID/schedstat 374 * Provides /proc/PID/schedstat
@@ -1186,8 +1215,6 @@ static int sched_show(struct seq_file *m, void *v)
1186 struct inode *inode = m->private; 1215 struct inode *inode = m->private;
1187 struct task_struct *p; 1216 struct task_struct *p;
1188 1217
1189 WARN_ON(!inode);
1190
1191 p = get_proc_task(inode); 1218 p = get_proc_task(inode);
1192 if (!p) 1219 if (!p)
1193 return -ESRCH; 1220 return -ESRCH;
@@ -1205,8 +1232,6 @@ sched_write(struct file *file, const char __user *buf,
1205 struct inode *inode = file->f_path.dentry->d_inode; 1232 struct inode *inode = file->f_path.dentry->d_inode;
1206 struct task_struct *p; 1233 struct task_struct *p;
1207 1234
1208 WARN_ON(!inode);
1209
1210 p = get_proc_task(inode); 1235 p = get_proc_task(inode);
1211 if (!p) 1236 if (!p)
1212 return -ESRCH; 1237 return -ESRCH;
@@ -1974,13 +1999,11 @@ static struct dentry *proc_pident_lookup(struct inode *dir,
1974 const struct pid_entry *ents, 1999 const struct pid_entry *ents,
1975 unsigned int nents) 2000 unsigned int nents)
1976{ 2001{
1977 struct inode *inode;
1978 struct dentry *error; 2002 struct dentry *error;
1979 struct task_struct *task = get_proc_task(dir); 2003 struct task_struct *task = get_proc_task(dir);
1980 const struct pid_entry *p, *last; 2004 const struct pid_entry *p, *last;
1981 2005
1982 error = ERR_PTR(-ENOENT); 2006 error = ERR_PTR(-ENOENT);
1983 inode = NULL;
1984 2007
1985 if (!task) 2008 if (!task)
1986 goto out_no_task; 2009 goto out_no_task;
@@ -2136,12 +2159,12 @@ static const struct file_operations proc_pid_attr_operations = {
2136}; 2159};
2137 2160
2138static const struct pid_entry attr_dir_stuff[] = { 2161static const struct pid_entry attr_dir_stuff[] = {
2139 REG("current", S_IRUGO|S_IWUGO, pid_attr), 2162 REG("current", S_IRUGO|S_IWUGO, proc_pid_attr_operations),
2140 REG("prev", S_IRUGO, pid_attr), 2163 REG("prev", S_IRUGO, proc_pid_attr_operations),
2141 REG("exec", S_IRUGO|S_IWUGO, pid_attr), 2164 REG("exec", S_IRUGO|S_IWUGO, proc_pid_attr_operations),
2142 REG("fscreate", S_IRUGO|S_IWUGO, pid_attr), 2165 REG("fscreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations),
2143 REG("keycreate", S_IRUGO|S_IWUGO, pid_attr), 2166 REG("keycreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations),
2144 REG("sockcreate", S_IRUGO|S_IWUGO, pid_attr), 2167 REG("sockcreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations),
2145}; 2168};
2146 2169
2147static int proc_attr_dir_readdir(struct file * filp, 2170static int proc_attr_dir_readdir(struct file * filp,
@@ -2461,74 +2484,77 @@ static const struct file_operations proc_task_operations;
2461static const struct inode_operations proc_task_inode_operations; 2484static const struct inode_operations proc_task_inode_operations;
2462 2485
2463static const struct pid_entry tgid_base_stuff[] = { 2486static const struct pid_entry tgid_base_stuff[] = {
2464 DIR("task", S_IRUGO|S_IXUGO, task), 2487 DIR("task", S_IRUGO|S_IXUGO, proc_task_inode_operations, proc_task_operations),
2465 DIR("fd", S_IRUSR|S_IXUSR, fd), 2488 DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
2466 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), 2489 DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fdinfo_operations),
2467#ifdef CONFIG_NET 2490#ifdef CONFIG_NET
2468 DIR("net", S_IRUGO|S_IXUGO, net), 2491 DIR("net", S_IRUGO|S_IXUGO, proc_net_inode_operations, proc_net_operations),
2469#endif 2492#endif
2470 REG("environ", S_IRUSR, environ), 2493 REG("environ", S_IRUSR, proc_environ_operations),
2471 INF("auxv", S_IRUSR, pid_auxv), 2494 INF("auxv", S_IRUSR, proc_pid_auxv),
2472 ONE("status", S_IRUGO, pid_status), 2495 ONE("status", S_IRUGO, proc_pid_status),
2473 ONE("personality", S_IRUSR, pid_personality), 2496 ONE("personality", S_IRUSR, proc_pid_personality),
2474 INF("limits", S_IRUSR, pid_limits), 2497 INF("limits", S_IRUSR, proc_pid_limits),
2475#ifdef CONFIG_SCHED_DEBUG 2498#ifdef CONFIG_SCHED_DEBUG
2476 REG("sched", S_IRUGO|S_IWUSR, pid_sched), 2499 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
2477#endif 2500#endif
2478#ifdef CONFIG_HAVE_ARCH_TRACEHOOK 2501#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2479 INF("syscall", S_IRUSR, pid_syscall), 2502 INF("syscall", S_IRUSR, proc_pid_syscall),
2480#endif 2503#endif
2481 INF("cmdline", S_IRUGO, pid_cmdline), 2504 INF("cmdline", S_IRUGO, proc_pid_cmdline),
2482 ONE("stat", S_IRUGO, tgid_stat), 2505 ONE("stat", S_IRUGO, proc_tgid_stat),
2483 ONE("statm", S_IRUGO, pid_statm), 2506 ONE("statm", S_IRUGO, proc_pid_statm),
2484 REG("maps", S_IRUGO, maps), 2507 REG("maps", S_IRUGO, proc_maps_operations),
2485#ifdef CONFIG_NUMA 2508#ifdef CONFIG_NUMA
2486 REG("numa_maps", S_IRUGO, numa_maps), 2509 REG("numa_maps", S_IRUGO, proc_numa_maps_operations),
2487#endif 2510#endif
2488 REG("mem", S_IRUSR|S_IWUSR, mem), 2511 REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
2489 LNK("cwd", cwd), 2512 LNK("cwd", proc_cwd_link),
2490 LNK("root", root), 2513 LNK("root", proc_root_link),
2491 LNK("exe", exe), 2514 LNK("exe", proc_exe_link),
2492 REG("mounts", S_IRUGO, mounts), 2515 REG("mounts", S_IRUGO, proc_mounts_operations),
2493 REG("mountinfo", S_IRUGO, mountinfo), 2516 REG("mountinfo", S_IRUGO, proc_mountinfo_operations),
2494 REG("mountstats", S_IRUSR, mountstats), 2517 REG("mountstats", S_IRUSR, proc_mountstats_operations),
2495#ifdef CONFIG_PROC_PAGE_MONITOR 2518#ifdef CONFIG_PROC_PAGE_MONITOR
2496 REG("clear_refs", S_IWUSR, clear_refs), 2519 REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
2497 REG("smaps", S_IRUGO, smaps), 2520 REG("smaps", S_IRUGO, proc_smaps_operations),
2498 REG("pagemap", S_IRUSR, pagemap), 2521 REG("pagemap", S_IRUSR, proc_pagemap_operations),
2499#endif 2522#endif
2500#ifdef CONFIG_SECURITY 2523#ifdef CONFIG_SECURITY
2501 DIR("attr", S_IRUGO|S_IXUGO, attr_dir), 2524 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
2502#endif 2525#endif
2503#ifdef CONFIG_KALLSYMS 2526#ifdef CONFIG_KALLSYMS
2504 INF("wchan", S_IRUGO, pid_wchan), 2527 INF("wchan", S_IRUGO, proc_pid_wchan),
2528#endif
2529#ifdef CONFIG_STACKTRACE
2530 ONE("stack", S_IRUSR, proc_pid_stack),
2505#endif 2531#endif
2506#ifdef CONFIG_SCHEDSTATS 2532#ifdef CONFIG_SCHEDSTATS
2507 INF("schedstat", S_IRUGO, pid_schedstat), 2533 INF("schedstat", S_IRUGO, proc_pid_schedstat),
2508#endif 2534#endif
2509#ifdef CONFIG_LATENCYTOP 2535#ifdef CONFIG_LATENCYTOP
2510 REG("latency", S_IRUGO, lstats), 2536 REG("latency", S_IRUGO, proc_lstats_operations),
2511#endif 2537#endif
2512#ifdef CONFIG_PROC_PID_CPUSET 2538#ifdef CONFIG_PROC_PID_CPUSET
2513 REG("cpuset", S_IRUGO, cpuset), 2539 REG("cpuset", S_IRUGO, proc_cpuset_operations),
2514#endif 2540#endif
2515#ifdef CONFIG_CGROUPS 2541#ifdef CONFIG_CGROUPS
2516 REG("cgroup", S_IRUGO, cgroup), 2542 REG("cgroup", S_IRUGO, proc_cgroup_operations),
2517#endif 2543#endif
2518 INF("oom_score", S_IRUGO, oom_score), 2544 INF("oom_score", S_IRUGO, proc_oom_score),
2519 REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), 2545 REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations),
2520#ifdef CONFIG_AUDITSYSCALL 2546#ifdef CONFIG_AUDITSYSCALL
2521 REG("loginuid", S_IWUSR|S_IRUGO, loginuid), 2547 REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
2522 REG("sessionid", S_IRUGO, sessionid), 2548 REG("sessionid", S_IRUGO, proc_sessionid_operations),
2523#endif 2549#endif
2524#ifdef CONFIG_FAULT_INJECTION 2550#ifdef CONFIG_FAULT_INJECTION
2525 REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), 2551 REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
2526#endif 2552#endif
2527#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE) 2553#if defined(USE_ELF_CORE_DUMP) && defined(CONFIG_ELF_CORE)
2528 REG("coredump_filter", S_IRUGO|S_IWUSR, coredump_filter), 2554 REG("coredump_filter", S_IRUGO|S_IWUSR, proc_coredump_filter_operations),
2529#endif 2555#endif
2530#ifdef CONFIG_TASK_IO_ACCOUNTING 2556#ifdef CONFIG_TASK_IO_ACCOUNTING
2531 INF("io", S_IRUGO, tgid_io_accounting), 2557 INF("io", S_IRUGO, proc_tgid_io_accounting),
2532#endif 2558#endif
2533}; 2559};
2534 2560
@@ -2801,66 +2827,69 @@ out_no_task:
2801 * Tasks 2827 * Tasks
2802 */ 2828 */
2803static const struct pid_entry tid_base_stuff[] = { 2829static const struct pid_entry tid_base_stuff[] = {
2804 DIR("fd", S_IRUSR|S_IXUSR, fd), 2830 DIR("fd", S_IRUSR|S_IXUSR, proc_fd_inode_operations, proc_fd_operations),
2805 DIR("fdinfo", S_IRUSR|S_IXUSR, fdinfo), 2831 DIR("fdinfo", S_IRUSR|S_IXUSR, proc_fdinfo_inode_operations, proc_fd_operations),
2806 REG("environ", S_IRUSR, environ), 2832 REG("environ", S_IRUSR, proc_environ_operations),
2807 INF("auxv", S_IRUSR, pid_auxv), 2833 INF("auxv", S_IRUSR, proc_pid_auxv),
2808 ONE("status", S_IRUGO, pid_status), 2834 ONE("status", S_IRUGO, proc_pid_status),
2809 ONE("personality", S_IRUSR, pid_personality), 2835 ONE("personality", S_IRUSR, proc_pid_personality),
2810 INF("limits", S_IRUSR, pid_limits), 2836 INF("limits", S_IRUSR, proc_pid_limits),
2811#ifdef CONFIG_SCHED_DEBUG 2837#ifdef CONFIG_SCHED_DEBUG
2812 REG("sched", S_IRUGO|S_IWUSR, pid_sched), 2838 REG("sched", S_IRUGO|S_IWUSR, proc_pid_sched_operations),
2813#endif 2839#endif
2814#ifdef CONFIG_HAVE_ARCH_TRACEHOOK 2840#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
2815 INF("syscall", S_IRUSR, pid_syscall), 2841 INF("syscall", S_IRUSR, proc_pid_syscall),
2816#endif 2842#endif
2817 INF("cmdline", S_IRUGO, pid_cmdline), 2843 INF("cmdline", S_IRUGO, proc_pid_cmdline),
2818 ONE("stat", S_IRUGO, tid_stat), 2844 ONE("stat", S_IRUGO, proc_tid_stat),
2819 ONE("statm", S_IRUGO, pid_statm), 2845 ONE("statm", S_IRUGO, proc_pid_statm),
2820 REG("maps", S_IRUGO, maps), 2846 REG("maps", S_IRUGO, proc_maps_operations),
2821#ifdef CONFIG_NUMA 2847#ifdef CONFIG_NUMA
2822 REG("numa_maps", S_IRUGO, numa_maps), 2848 REG("numa_maps", S_IRUGO, proc_numa_maps_operations),
2823#endif 2849#endif
2824 REG("mem", S_IRUSR|S_IWUSR, mem), 2850 REG("mem", S_IRUSR|S_IWUSR, proc_mem_operations),
2825 LNK("cwd", cwd), 2851 LNK("cwd", proc_cwd_link),
2826 LNK("root", root), 2852 LNK("root", proc_root_link),
2827 LNK("exe", exe), 2853 LNK("exe", proc_exe_link),
2828 REG("mounts", S_IRUGO, mounts), 2854 REG("mounts", S_IRUGO, proc_mounts_operations),
2829 REG("mountinfo", S_IRUGO, mountinfo), 2855 REG("mountinfo", S_IRUGO, proc_mountinfo_operations),
2830#ifdef CONFIG_PROC_PAGE_MONITOR 2856#ifdef CONFIG_PROC_PAGE_MONITOR
2831 REG("clear_refs", S_IWUSR, clear_refs), 2857 REG("clear_refs", S_IWUSR, proc_clear_refs_operations),
2832 REG("smaps", S_IRUGO, smaps), 2858 REG("smaps", S_IRUGO, proc_smaps_operations),
2833 REG("pagemap", S_IRUSR, pagemap), 2859 REG("pagemap", S_IRUSR, proc_pagemap_operations),
2834#endif 2860#endif
2835#ifdef CONFIG_SECURITY 2861#ifdef CONFIG_SECURITY
2836 DIR("attr", S_IRUGO|S_IXUGO, attr_dir), 2862 DIR("attr", S_IRUGO|S_IXUGO, proc_attr_dir_inode_operations, proc_attr_dir_operations),
2837#endif 2863#endif
2838#ifdef CONFIG_KALLSYMS 2864#ifdef CONFIG_KALLSYMS
2839 INF("wchan", S_IRUGO, pid_wchan), 2865 INF("wchan", S_IRUGO, proc_pid_wchan),
2866#endif
2867#ifdef CONFIG_STACKTRACE
2868 ONE("stack", S_IRUSR, proc_pid_stack),
2840#endif 2869#endif
2841#ifdef CONFIG_SCHEDSTATS 2870#ifdef CONFIG_SCHEDSTATS
2842 INF("schedstat", S_IRUGO, pid_schedstat), 2871 INF("schedstat", S_IRUGO, proc_pid_schedstat),
2843#endif 2872#endif
2844#ifdef CONFIG_LATENCYTOP 2873#ifdef CONFIG_LATENCYTOP
2845 REG("latency", S_IRUGO, lstats), 2874 REG("latency", S_IRUGO, proc_lstats_operations),
2846#endif 2875#endif
2847#ifdef CONFIG_PROC_PID_CPUSET 2876#ifdef CONFIG_PROC_PID_CPUSET
2848 REG("cpuset", S_IRUGO, cpuset), 2877 REG("cpuset", S_IRUGO, proc_cpuset_operations),
2849#endif 2878#endif
2850#ifdef CONFIG_CGROUPS 2879#ifdef CONFIG_CGROUPS
2851 REG("cgroup", S_IRUGO, cgroup), 2880 REG("cgroup", S_IRUGO, proc_cgroup_operations),
2852#endif 2881#endif
2853 INF("oom_score", S_IRUGO, oom_score), 2882 INF("oom_score", S_IRUGO, proc_oom_score),
2854 REG("oom_adj", S_IRUGO|S_IWUSR, oom_adjust), 2883 REG("oom_adj", S_IRUGO|S_IWUSR, proc_oom_adjust_operations),
2855#ifdef CONFIG_AUDITSYSCALL 2884#ifdef CONFIG_AUDITSYSCALL
2856 REG("loginuid", S_IWUSR|S_IRUGO, loginuid), 2885 REG("loginuid", S_IWUSR|S_IRUGO, proc_loginuid_operations),
2857 REG("sessionid", S_IRUSR, sessionid), 2886 REG("sessionid", S_IRUSR, proc_sessionid_operations),
2858#endif 2887#endif
2859#ifdef CONFIG_FAULT_INJECTION 2888#ifdef CONFIG_FAULT_INJECTION
2860 REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), 2889 REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
2861#endif 2890#endif
2862#ifdef CONFIG_TASK_IO_ACCOUNTING 2891#ifdef CONFIG_TASK_IO_ACCOUNTING
2863 INF("io", S_IRUGO, tid_io_accounting), 2892 INF("io", S_IRUGO, proc_tid_io_accounting),
2864#endif 2893#endif
2865}; 2894};
2866 2895