1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55#include <linux/types.h>
56#include <linux/errno.h>
57#include <linux/time.h>
58#include <linux/kernel.h>
59#include <linux/kernel_stat.h>
60#include <linux/tty.h>
61#include <linux/string.h>
62#include <linux/mman.h>
63#include <linux/proc_fs.h>
64#include <linux/ioport.h>
65#include <linux/uaccess.h>
66#include <linux/io.h>
67#include <linux/mm.h>
68#include <linux/hugetlb.h>
69#include <linux/pagemap.h>
70#include <linux/swap.h>
71#include <linux/smp.h>
72#include <linux/signal.h>
73#include <linux/highmem.h>
74#include <linux/file.h>
75#include <linux/fdtable.h>
76#include <linux/times.h>
77#include <linux/cpuset.h>
78#include <linux/rcupdate.h>
79#include <linux/delayacct.h>
80#include <linux/seq_file.h>
81#include <linux/pid_namespace.h>
82#include <linux/ptrace.h>
83#include <linux/tracehook.h>
84
85#include <asm/pgtable.h>
86#include <asm/processor.h>
87#include "internal.h"
88
89static inline void task_name(struct seq_file *m, struct task_struct *p)
90{
91 int i;
92 char *buf, *end;
93 char *name;
94 char tcomm[sizeof(p->comm)];
95
96 get_task_comm(tcomm, p);
97
98 seq_puts(m, "Name:\t");
99 end = m->buf + m->size;
100 buf = m->buf + m->count;
101 name = tcomm;
102 i = sizeof(tcomm);
103 while (i && (buf < end)) {
104 unsigned char c = *name;
105 name++;
106 i--;
107 *buf = c;
108 if (!c)
109 break;
110 if (c == '\\') {
111 buf++;
112 if (buf < end)
113 *buf++ = c;
114 continue;
115 }
116 if (c == '\n') {
117 *buf++ = '\\';
118 if (buf < end)
119 *buf++ = 'n';
120 continue;
121 }
122 buf++;
123 }
124 m->count = buf - m->buf;
125 seq_putc(m, '\n');
126}
127
128
129
130
131
132
133
134static const char *task_state_array[] = {
135 "R (running)",
136 "S (sleeping)",
137 "D (disk sleep)",
138 "T (stopped)",
139 "t (tracing stop)",
140 "Z (zombie)",
141 "X (dead)",
142 "x (dead)",
143 "K (wakekill)",
144 "W (waking)",
145};
146
147static inline const char *get_task_state(struct task_struct *tsk)
148{
149 unsigned int state = (tsk->state & TASK_REPORT) | tsk->exit_state;
150 const char **p = &task_state_array[0];
151
152 BUILD_BUG_ON(1 + ilog2(TASK_STATE_MAX) != ARRAY_SIZE(task_state_array));
153
154 while (state) {
155 p++;
156 state >>= 1;
157 }
158 return *p;
159}
160
161static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
162 struct pid *pid, struct task_struct *p)
163{
164 struct group_info *group_info;
165 int g;
166 struct fdtable *fdt = NULL;
167 const struct cred *cred;
168 pid_t ppid, tpid;
169
170 rcu_read_lock();
171 ppid = pid_alive(p) ?
172 task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
173 tpid = 0;
174 if (pid_alive(p)) {
175 struct task_struct *tracer = tracehook_tracer_task(p);
176 if (tracer)
177 tpid = task_pid_nr_ns(tracer, ns);
178 }
179 cred = get_task_cred(p);
180 seq_printf(m,
181 "State:\t%s\n"
182 "Tgid:\t%d\n"
183 "Pid:\t%d\n"
184 "PPid:\t%d\n"
185 "TracerPid:\t%d\n"
186 "Uid:\t%d\t%d\t%d\t%d\n"
187 "Gid:\t%d\t%d\t%d\t%d\n",
188 get_task_state(p),
189 task_tgid_nr_ns(p, ns),
190 pid_nr_ns(pid, ns),
191 ppid, tpid,
192 cred->uid, cred->euid, cred->suid, cred->fsuid,
193 cred->gid, cred->egid, cred->sgid, cred->fsgid);
194
195 task_lock(p);
196 if (p->files)
197 fdt = files_fdtable(p->files);
198 seq_printf(m,
199 "FDSize:\t%d\n"
200 "Groups:\t",
201 fdt ? fdt->max_fds : 0);
202 rcu_read_unlock();
203
204 group_info = cred->group_info;
205 task_unlock(p);
206
207 for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++)
208 seq_printf(m, "%d ", GROUP_AT(group_info, g));
209 put_cred(cred);
210
211 seq_putc(m, '\n');
212}
213
214static void render_sigset_t(struct seq_file *m, const char *header,
215 sigset_t *set)
216{
217 int i;
218
219 seq_puts(m, header);
220
221 i = _NSIG;
222 do {
223 int x = 0;
224
225 i -= 4;
226 if (sigismember(set, i+1)) x |= 1;
227 if (sigismember(set, i+2)) x |= 2;
228 if (sigismember(set, i+3)) x |= 4;
229 if (sigismember(set, i+4)) x |= 8;
230 seq_printf(m, "%x", x);
231 } while (i >= 4);
232
233 seq_putc(m, '\n');
234}
235
236static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
237 sigset_t *catch)
238{
239 struct k_sigaction *k;
240 int i;
241
242 k = p->sighand->action;
243 for (i = 1; i <= _NSIG; ++i, ++k) {
244 if (k->sa.sa_handler == SIG_IGN)
245 sigaddset(ign, i);
246 else if (k->sa.sa_handler != SIG_DFL)
247 sigaddset(catch, i);
248 }
249}
250
251static inline void task_sig(struct seq_file *m, struct task_struct *p)
252{
253 unsigned long flags;
254 sigset_t pending, shpending, blocked, ignored, caught;
255 int num_threads = 0;
256 unsigned long qsize = 0;
257 unsigned long qlim = 0;
258
259 sigemptyset(&pending);
260 sigemptyset(&shpending);
261 sigemptyset(&blocked);
262 sigemptyset(&ignored);
263 sigemptyset(&caught);
264
265 if (lock_task_sighand(p, &flags)) {
266 pending = p->pending.signal;
267 shpending = p->signal->shared_pending.signal;
268 blocked = p->blocked;
269 collect_sigign_sigcatch(p, &ignored, &caught);
270 num_threads = get_nr_threads(p);
271 rcu_read_lock();
272 qsize = atomic_read(&__task_cred(p)->user->sigpending);
273 rcu_read_unlock();
274 qlim = task_rlimit(p, RLIMIT_SIGPENDING);
275 unlock_task_sighand(p, &flags);
276 }
277
278 seq_printf(m, "Threads:\t%d\n", num_threads);
279 seq_printf(m, "SigQ:\t%lu/%lu\n", qsize, qlim);
280
281
282 render_sigset_t(m, "SigPnd:\t", &pending);
283 render_sigset_t(m, "ShdPnd:\t", &shpending);
284 render_sigset_t(m, "SigBlk:\t", &blocked);
285 render_sigset_t(m, "SigIgn:\t", &ignored);
286 render_sigset_t(m, "SigCgt:\t", &caught);
287}
288
289static void render_cap_t(struct seq_file *m, const char *header,
290 kernel_cap_t *a)
291{
292 unsigned __capi;
293
294 seq_puts(m, header);
295 CAP_FOR_EACH_U32(__capi) {
296 seq_printf(m, "%08x",
297 a->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]);
298 }
299 seq_putc(m, '\n');
300}
301
302static inline void task_cap(struct seq_file *m, struct task_struct *p)
303{
304 const struct cred *cred;
305 kernel_cap_t cap_inheritable, cap_permitted, cap_effective, cap_bset;
306
307 rcu_read_lock();
308 cred = __task_cred(p);
309 cap_inheritable = cred->cap_inheritable;
310 cap_permitted = cred->cap_permitted;
311 cap_effective = cred->cap_effective;
312 cap_bset = cred->cap_bset;
313 rcu_read_unlock();
314
315 render_cap_t(m, "CapInh:\t", &cap_inheritable);
316 render_cap_t(m, "CapPrm:\t", &cap_permitted);
317 render_cap_t(m, "CapEff:\t", &cap_effective);
318 render_cap_t(m, "CapBnd:\t", &cap_bset);
319}
320
321static inline void task_context_switch_counts(struct seq_file *m,
322 struct task_struct *p)
323{
324 seq_printf(m, "voluntary_ctxt_switches:\t%lu\n"
325 "nonvoluntary_ctxt_switches:\t%lu\n",
326 p->nvcsw,
327 p->nivcsw);
328}
329
330static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
331{
332 seq_puts(m, "Cpus_allowed:\t");
333 seq_cpumask(m, &task->cpus_allowed);
334 seq_putc(m, '\n');
335 seq_puts(m, "Cpus_allowed_list:\t");
336 seq_cpumask_list(m, &task->cpus_allowed);
337 seq_putc(m, '\n');
338}
339
340int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
341 struct pid *pid, struct task_struct *task)
342{
343 struct mm_struct *mm = get_task_mm(task);
344
345 task_name(m, task);
346 task_state(m, ns, pid, task);
347
348 if (mm) {
349 task_mem(m, mm);
350 mmput(mm);
351 }
352 task_sig(m, task);
353 task_cap(m, task);
354 task_cpus_allowed(m, task);
355 cpuset_task_status_allowed(m, task);
356 task_context_switch_counts(m, task);
357 return 0;
358}
359
360static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
361 struct pid *pid, struct task_struct *task, int whole)
362{
363 unsigned long vsize, eip, esp, wchan = ~0UL;
364 long priority, nice;
365 int tty_pgrp = -1, tty_nr = 0;
366 sigset_t sigign, sigcatch;
367 char state;
368 pid_t ppid = 0, pgid = -1, sid = -1;
369 int num_threads = 0;
370 int permitted;
371 struct mm_struct *mm;
372 unsigned long long start_time;
373 unsigned long cmin_flt = 0, cmaj_flt = 0;
374 unsigned long min_flt = 0, maj_flt = 0;
375 cputime_t cutime, cstime, utime, stime;
376 cputime_t cgtime, gtime;
377 unsigned long rsslim = 0;
378 char tcomm[sizeof(task->comm)];
379 unsigned long flags;
380
381 state = *get_task_state(task);
382 vsize = eip = esp = 0;
383 permitted = ptrace_may_access(task, PTRACE_MODE_READ);
384 mm = get_task_mm(task);
385 if (mm) {
386 vsize = task_vsize(mm);
387 if (permitted) {
388 eip = KSTK_EIP(task);
389 esp = KSTK_ESP(task);
390 }
391 }
392
393 get_task_comm(tcomm, task);
394
395 sigemptyset(&sigign);
396 sigemptyset(&sigcatch);
397 cutime = cstime = utime = stime = cputime_zero;
398 cgtime = gtime = cputime_zero;
399
400 if (lock_task_sighand(task, &flags)) {
401 struct signal_struct *sig = task->signal;
402
403 if (sig->tty) {
404 struct pid *pgrp = tty_get_pgrp(sig->tty);
405 tty_pgrp = pid_nr_ns(pgrp, ns);
406 put_pid(pgrp);
407 tty_nr = new_encode_dev(tty_devnum(sig->tty));
408 }
409
410 num_threads = get_nr_threads(task);
411 collect_sigign_sigcatch(task, &sigign, &sigcatch);
412
413 cmin_flt = sig->cmin_flt;
414 cmaj_flt = sig->cmaj_flt;
415 cutime = sig->cutime;
416 cstime = sig->cstime;
417 cgtime = sig->cgtime;
418 rsslim = ACCESS_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
419
420
421 if (whole) {
422 struct task_struct *t = task;
423 do {
424 min_flt += t->min_flt;
425 maj_flt += t->maj_flt;
426 gtime = cputime_add(gtime, t->gtime);
427 t = next_thread(t);
428 } while (t != task);
429
430 min_flt += sig->min_flt;
431 maj_flt += sig->maj_flt;
432 thread_group_times(task, &utime, &stime);
433 gtime = cputime_add(gtime, sig->gtime);
434 }
435
436 sid = task_session_nr_ns(task, ns);
437 ppid = task_tgid_nr_ns(task->real_parent, ns);
438 pgid = task_pgrp_nr_ns(task, ns);
439
440 unlock_task_sighand(task, &flags);
441 }
442
443 if (permitted && (!whole || num_threads < 2))
444 wchan = get_wchan(task);
445 if (!whole) {
446 min_flt = task->min_flt;
447 maj_flt = task->maj_flt;
448 task_times(task, &utime, &stime);
449 gtime = task->gtime;
450 }
451
452
453
454 priority = task_prio(task);
455 nice = task_nice(task);
456
457
458
459 start_time =
460 (unsigned long long)task->real_start_time.tv_sec * NSEC_PER_SEC
461 + task->real_start_time.tv_nsec;
462
463 start_time = nsec_to_clock_t(start_time);
464
465 seq_printf(m, "%d (%s) %c %d %d %d %d %d %u %lu \
466%lu %lu %lu %lu %lu %ld %ld %ld %ld %d 0 %llu %lu %ld %lu %lu %lu %lu %lu \
467%lu %lu %lu %lu %lu %lu %lu %lu %d %d %u %u %llu %lu %ld\n",
468 pid_nr_ns(pid, ns),
469 tcomm,
470 state,
471 ppid,
472 pgid,
473 sid,
474 tty_nr,
475 tty_pgrp,
476 task->flags,
477 min_flt,
478 cmin_flt,
479 maj_flt,
480 cmaj_flt,
481 cputime_to_clock_t(utime),
482 cputime_to_clock_t(stime),
483 cputime_to_clock_t(cutime),
484 cputime_to_clock_t(cstime),
485 priority,
486 nice,
487 num_threads,
488 start_time,
489 vsize,
490 mm ? get_mm_rss(mm) : 0,
491 rsslim,
492 mm ? (permitted ? mm->start_code : 1) : 0,
493 mm ? (permitted ? mm->end_code : 1) : 0,
494 (permitted && mm) ? mm->start_stack : 0,
495 esp,
496 eip,
497
498
499
500
501 task->pending.signal.sig[0] & 0x7fffffffUL,
502 task->blocked.sig[0] & 0x7fffffffUL,
503 sigign .sig[0] & 0x7fffffffUL,
504 sigcatch .sig[0] & 0x7fffffffUL,
505 wchan,
506 0UL,
507 0UL,
508 task->exit_signal,
509 task_cpu(task),
510 task->rt_priority,
511 task->policy,
512 (unsigned long long)delayacct_blkio_ticks(task),
513 cputime_to_clock_t(gtime),
514 cputime_to_clock_t(cgtime));
515 if (mm)
516 mmput(mm);
517 return 0;
518}
519
520int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
521 struct pid *pid, struct task_struct *task)
522{
523 return do_task_stat(m, ns, pid, task, 0);
524}
525
526int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
527 struct pid *pid, struct task_struct *task)
528{
529 return do_task_stat(m, ns, pid, task, 1);
530}
531
532int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
533 struct pid *pid, struct task_struct *task)
534{
535 unsigned long size = 0, resident = 0, shared = 0, text = 0, data = 0;
536 struct mm_struct *mm = get_task_mm(task);
537
538 if (mm) {
539 size = task_statm(mm, &shared, &text, &data, &resident);
540 mmput(mm);
541 }
542 seq_printf(m, "%lu %lu %lu %lu 0 %lu 0\n",
543 size, resident, shared, text, data);
544
545 return 0;
546}
547