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
56#include <linux/types.h>
57#include <linux/errno.h>
58#include <linux/time.h>
59#include <linux/time_namespace.h>
60#include <linux/kernel.h>
61#include <linux/kernel_stat.h>
62#include <linux/tty.h>
63#include <linux/string.h>
64#include <linux/mman.h>
65#include <linux/sched/mm.h>
66#include <linux/sched/numa_balancing.h>
67#include <linux/sched/task_stack.h>
68#include <linux/sched/task.h>
69#include <linux/sched/cputime.h>
70#include <linux/proc_fs.h>
71#include <linux/ioport.h>
72#include <linux/io.h>
73#include <linux/mm.h>
74#include <linux/hugetlb.h>
75#include <linux/pagemap.h>
76#include <linux/swap.h>
77#include <linux/smp.h>
78#include <linux/signal.h>
79#include <linux/highmem.h>
80#include <linux/file.h>
81#include <linux/fdtable.h>
82#include <linux/times.h>
83#include <linux/cpuset.h>
84#include <linux/rcupdate.h>
85#include <linux/delayacct.h>
86#include <linux/seq_file.h>
87#include <linux/pid_namespace.h>
88#include <linux/prctl.h>
89#include <linux/ptrace.h>
90#include <linux/string_helpers.h>
91#include <linux/user_namespace.h>
92#include <linux/fs_struct.h>
93#include <linux/kthread.h>
94
95#include <asm/processor.h>
96#include "internal.h"
97
98void proc_task_name(struct seq_file *m, struct task_struct *p, bool escape)
99{
100 char tcomm[64];
101
102
103
104
105
106 if (p->flags & PF_WQ_WORKER)
107 wq_worker_comm(tcomm, sizeof(tcomm), p);
108 else if (p->flags & PF_KTHREAD)
109 get_kthread_comm(tcomm, sizeof(tcomm), p);
110 else
111 __get_task_comm(tcomm, sizeof(tcomm), p);
112
113 if (escape)
114 seq_escape_str(m, tcomm, ESCAPE_SPACE | ESCAPE_SPECIAL, "\n\\");
115 else
116 seq_printf(m, "%.64s", tcomm);
117}
118
119
120
121
122
123
124
125static const char * const task_state_array[] = {
126
127
128 "R (running)",
129 "S (sleeping)",
130 "D (disk sleep)",
131 "T (stopped)",
132 "t (tracing stop)",
133 "X (dead)",
134 "Z (zombie)",
135 "P (parked)",
136
137
138 "I (idle)",
139};
140
141static inline const char *get_task_state(struct task_struct *tsk)
142{
143 BUILD_BUG_ON(1 + ilog2(TASK_REPORT_MAX) != ARRAY_SIZE(task_state_array));
144 return task_state_array[task_state_index(tsk)];
145}
146
147static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
148 struct pid *pid, struct task_struct *p)
149{
150 struct user_namespace *user_ns = seq_user_ns(m);
151 struct group_info *group_info;
152 int g, umask = -1;
153 struct task_struct *tracer;
154 const struct cred *cred;
155 pid_t ppid, tpid = 0, tgid, ngid;
156 unsigned int max_fds = 0;
157
158 rcu_read_lock();
159 ppid = pid_alive(p) ?
160 task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
161
162 tracer = ptrace_parent(p);
163 if (tracer)
164 tpid = task_pid_nr_ns(tracer, ns);
165
166 tgid = task_tgid_nr_ns(p, ns);
167 ngid = task_numa_group_id(p);
168 cred = get_task_cred(p);
169
170 task_lock(p);
171 if (p->fs)
172 umask = p->fs->umask;
173 if (p->files)
174 max_fds = files_fdtable(p->files)->max_fds;
175 task_unlock(p);
176 rcu_read_unlock();
177
178 if (umask >= 0)
179 seq_printf(m, "Umask:\t%#04o\n", umask);
180 seq_puts(m, "State:\t");
181 seq_puts(m, get_task_state(p));
182
183 seq_put_decimal_ull(m, "\nTgid:\t", tgid);
184 seq_put_decimal_ull(m, "\nNgid:\t", ngid);
185 seq_put_decimal_ull(m, "\nPid:\t", pid_nr_ns(pid, ns));
186 seq_put_decimal_ull(m, "\nPPid:\t", ppid);
187 seq_put_decimal_ull(m, "\nTracerPid:\t", tpid);
188 seq_put_decimal_ull(m, "\nUid:\t", from_kuid_munged(user_ns, cred->uid));
189 seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->euid));
190 seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->suid));
191 seq_put_decimal_ull(m, "\t", from_kuid_munged(user_ns, cred->fsuid));
192 seq_put_decimal_ull(m, "\nGid:\t", from_kgid_munged(user_ns, cred->gid));
193 seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->egid));
194 seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->sgid));
195 seq_put_decimal_ull(m, "\t", from_kgid_munged(user_ns, cred->fsgid));
196 seq_put_decimal_ull(m, "\nFDSize:\t", max_fds);
197
198 seq_puts(m, "\nGroups:\t");
199 group_info = cred->group_info;
200 for (g = 0; g < group_info->ngroups; g++)
201 seq_put_decimal_ull(m, g ? " " : "",
202 from_kgid_munged(user_ns, group_info->gid[g]));
203 put_cred(cred);
204
205 seq_putc(m, ' ');
206
207#ifdef CONFIG_PID_NS
208 seq_puts(m, "\nNStgid:");
209 for (g = ns->level; g <= pid->level; g++)
210 seq_put_decimal_ull(m, "\t", task_tgid_nr_ns(p, pid->numbers[g].ns));
211 seq_puts(m, "\nNSpid:");
212 for (g = ns->level; g <= pid->level; g++)
213 seq_put_decimal_ull(m, "\t", task_pid_nr_ns(p, pid->numbers[g].ns));
214 seq_puts(m, "\nNSpgid:");
215 for (g = ns->level; g <= pid->level; g++)
216 seq_put_decimal_ull(m, "\t", task_pgrp_nr_ns(p, pid->numbers[g].ns));
217 seq_puts(m, "\nNSsid:");
218 for (g = ns->level; g <= pid->level; g++)
219 seq_put_decimal_ull(m, "\t", task_session_nr_ns(p, pid->numbers[g].ns));
220#endif
221 seq_putc(m, '\n');
222}
223
224void render_sigset_t(struct seq_file *m, const char *header,
225 sigset_t *set)
226{
227 int i;
228
229 seq_puts(m, header);
230
231 i = _NSIG;
232 do {
233 int x = 0;
234
235 i -= 4;
236 if (sigismember(set, i+1)) x |= 1;
237 if (sigismember(set, i+2)) x |= 2;
238 if (sigismember(set, i+3)) x |= 4;
239 if (sigismember(set, i+4)) x |= 8;
240 seq_putc(m, hex_asc[x]);
241 } while (i >= 4);
242
243 seq_putc(m, '\n');
244}
245
246static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *sigign,
247 sigset_t *sigcatch)
248{
249 struct k_sigaction *k;
250 int i;
251
252 k = p->sighand->action;
253 for (i = 1; i <= _NSIG; ++i, ++k) {
254 if (k->sa.sa_handler == SIG_IGN)
255 sigaddset(sigign, i);
256 else if (k->sa.sa_handler != SIG_DFL)
257 sigaddset(sigcatch, i);
258 }
259}
260
261static inline void task_sig(struct seq_file *m, struct task_struct *p)
262{
263 unsigned long flags;
264 sigset_t pending, shpending, blocked, ignored, caught;
265 int num_threads = 0;
266 unsigned int qsize = 0;
267 unsigned long qlim = 0;
268
269 sigemptyset(&pending);
270 sigemptyset(&shpending);
271 sigemptyset(&blocked);
272 sigemptyset(&ignored);
273 sigemptyset(&caught);
274
275 if (lock_task_sighand(p, &flags)) {
276 pending = p->pending.signal;
277 shpending = p->signal->shared_pending.signal;
278 blocked = p->blocked;
279 collect_sigign_sigcatch(p, &ignored, &caught);
280 num_threads = get_nr_threads(p);
281 rcu_read_lock();
282 qsize = get_ucounts_value(task_ucounts(p), UCOUNT_RLIMIT_SIGPENDING);
283 rcu_read_unlock();
284 qlim = task_rlimit(p, RLIMIT_SIGPENDING);
285 unlock_task_sighand(p, &flags);
286 }
287
288 seq_put_decimal_ull(m, "Threads:\t", num_threads);
289 seq_put_decimal_ull(m, "\nSigQ:\t", qsize);
290 seq_put_decimal_ull(m, "/", qlim);
291
292
293 render_sigset_t(m, "\nSigPnd:\t", &pending);
294 render_sigset_t(m, "ShdPnd:\t", &shpending);
295 render_sigset_t(m, "SigBlk:\t", &blocked);
296 render_sigset_t(m, "SigIgn:\t", &ignored);
297 render_sigset_t(m, "SigCgt:\t", &caught);
298}
299
300static void render_cap_t(struct seq_file *m, const char *header,
301 kernel_cap_t *a)
302{
303 unsigned __capi;
304
305 seq_puts(m, header);
306 CAP_FOR_EACH_U32(__capi) {
307 seq_put_hex_ll(m, NULL,
308 a->cap[CAP_LAST_U32 - __capi], 8);
309 }
310 seq_putc(m, '\n');
311}
312
313static inline void task_cap(struct seq_file *m, struct task_struct *p)
314{
315 const struct cred *cred;
316 kernel_cap_t cap_inheritable, cap_permitted, cap_effective,
317 cap_bset, cap_ambient;
318
319 rcu_read_lock();
320 cred = __task_cred(p);
321 cap_inheritable = cred->cap_inheritable;
322 cap_permitted = cred->cap_permitted;
323 cap_effective = cred->cap_effective;
324 cap_bset = cred->cap_bset;
325 cap_ambient = cred->cap_ambient;
326 rcu_read_unlock();
327
328 render_cap_t(m, "CapInh:\t", &cap_inheritable);
329 render_cap_t(m, "CapPrm:\t", &cap_permitted);
330 render_cap_t(m, "CapEff:\t", &cap_effective);
331 render_cap_t(m, "CapBnd:\t", &cap_bset);
332 render_cap_t(m, "CapAmb:\t", &cap_ambient);
333}
334
335static inline void task_seccomp(struct seq_file *m, struct task_struct *p)
336{
337 seq_put_decimal_ull(m, "NoNewPrivs:\t", task_no_new_privs(p));
338#ifdef CONFIG_SECCOMP
339 seq_put_decimal_ull(m, "\nSeccomp:\t", p->seccomp.mode);
340#ifdef CONFIG_SECCOMP_FILTER
341 seq_put_decimal_ull(m, "\nSeccomp_filters:\t",
342 atomic_read(&p->seccomp.filter_count));
343#endif
344#endif
345 seq_puts(m, "\nSpeculation_Store_Bypass:\t");
346 switch (arch_prctl_spec_ctrl_get(p, PR_SPEC_STORE_BYPASS)) {
347 case -EINVAL:
348 seq_puts(m, "unknown");
349 break;
350 case PR_SPEC_NOT_AFFECTED:
351 seq_puts(m, "not vulnerable");
352 break;
353 case PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE:
354 seq_puts(m, "thread force mitigated");
355 break;
356 case PR_SPEC_PRCTL | PR_SPEC_DISABLE:
357 seq_puts(m, "thread mitigated");
358 break;
359 case PR_SPEC_PRCTL | PR_SPEC_ENABLE:
360 seq_puts(m, "thread vulnerable");
361 break;
362 case PR_SPEC_DISABLE:
363 seq_puts(m, "globally mitigated");
364 break;
365 default:
366 seq_puts(m, "vulnerable");
367 break;
368 }
369
370 seq_puts(m, "\nSpeculationIndirectBranch:\t");
371 switch (arch_prctl_spec_ctrl_get(p, PR_SPEC_INDIRECT_BRANCH)) {
372 case -EINVAL:
373 seq_puts(m, "unsupported");
374 break;
375 case PR_SPEC_NOT_AFFECTED:
376 seq_puts(m, "not affected");
377 break;
378 case PR_SPEC_PRCTL | PR_SPEC_FORCE_DISABLE:
379 seq_puts(m, "conditional force disabled");
380 break;
381 case PR_SPEC_PRCTL | PR_SPEC_DISABLE:
382 seq_puts(m, "conditional disabled");
383 break;
384 case PR_SPEC_PRCTL | PR_SPEC_ENABLE:
385 seq_puts(m, "conditional enabled");
386 break;
387 case PR_SPEC_ENABLE:
388 seq_puts(m, "always enabled");
389 break;
390 case PR_SPEC_DISABLE:
391 seq_puts(m, "always disabled");
392 break;
393 default:
394 seq_puts(m, "unknown");
395 break;
396 }
397 seq_putc(m, '\n');
398}
399
400static inline void task_context_switch_counts(struct seq_file *m,
401 struct task_struct *p)
402{
403 seq_put_decimal_ull(m, "voluntary_ctxt_switches:\t", p->nvcsw);
404 seq_put_decimal_ull(m, "\nnonvoluntary_ctxt_switches:\t", p->nivcsw);
405 seq_putc(m, '\n');
406}
407
408static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
409{
410 seq_printf(m, "Cpus_allowed:\t%*pb\n",
411 cpumask_pr_args(&task->cpus_mask));
412 seq_printf(m, "Cpus_allowed_list:\t%*pbl\n",
413 cpumask_pr_args(&task->cpus_mask));
414}
415
416static inline void task_core_dumping(struct seq_file *m, struct task_struct *task)
417{
418 seq_put_decimal_ull(m, "CoreDumping:\t", !!task->signal->core_state);
419 seq_putc(m, '\n');
420}
421
422static inline void task_thp_status(struct seq_file *m, struct mm_struct *mm)
423{
424 bool thp_enabled = IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE);
425
426 if (thp_enabled)
427 thp_enabled = !test_bit(MMF_DISABLE_THP, &mm->flags);
428 seq_printf(m, "THP_enabled:\t%d\n", thp_enabled);
429}
430
431int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
432 struct pid *pid, struct task_struct *task)
433{
434 struct mm_struct *mm = get_task_mm(task);
435
436 seq_puts(m, "Name:\t");
437 proc_task_name(m, task, true);
438 seq_putc(m, '\n');
439
440 task_state(m, ns, pid, task);
441
442 if (mm) {
443 task_mem(m, mm);
444 task_core_dumping(m, task);
445 task_thp_status(m, mm);
446 mmput(mm);
447 }
448 task_sig(m, task);
449 task_cap(m, task);
450 task_seccomp(m, task);
451 task_cpus_allowed(m, task);
452 cpuset_task_status_allowed(m, task);
453 task_context_switch_counts(m, task);
454 return 0;
455}
456
457static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
458 struct pid *pid, struct task_struct *task, int whole)
459{
460 unsigned long vsize, eip, esp, wchan = 0;
461 int priority, nice;
462 int tty_pgrp = -1, tty_nr = 0;
463 sigset_t sigign, sigcatch;
464 char state;
465 pid_t ppid = 0, pgid = -1, sid = -1;
466 int num_threads = 0;
467 int permitted;
468 struct mm_struct *mm;
469 unsigned long long start_time;
470 unsigned long cmin_flt = 0, cmaj_flt = 0;
471 unsigned long min_flt = 0, maj_flt = 0;
472 u64 cutime, cstime, utime, stime;
473 u64 cgtime, gtime;
474 unsigned long rsslim = 0;
475 unsigned long flags;
476 int exit_code = task->exit_code;
477
478 state = *get_task_state(task);
479 vsize = eip = esp = 0;
480 permitted = ptrace_may_access(task, PTRACE_MODE_READ_FSCREDS | PTRACE_MODE_NOAUDIT);
481 mm = get_task_mm(task);
482 if (mm) {
483 vsize = task_vsize(mm);
484
485
486
487
488
489
490
491
492
493 if (permitted && (task->flags & (PF_EXITING|PF_DUMPCORE))) {
494 if (try_get_task_stack(task)) {
495 eip = KSTK_EIP(task);
496 esp = KSTK_ESP(task);
497 put_task_stack(task);
498 }
499 }
500 }
501
502 sigemptyset(&sigign);
503 sigemptyset(&sigcatch);
504 cutime = cstime = utime = stime = 0;
505 cgtime = gtime = 0;
506
507 if (lock_task_sighand(task, &flags)) {
508 struct signal_struct *sig = task->signal;
509
510 if (sig->tty) {
511 struct pid *pgrp = tty_get_pgrp(sig->tty);
512 tty_pgrp = pid_nr_ns(pgrp, ns);
513 put_pid(pgrp);
514 tty_nr = new_encode_dev(tty_devnum(sig->tty));
515 }
516
517 num_threads = get_nr_threads(task);
518 collect_sigign_sigcatch(task, &sigign, &sigcatch);
519
520 cmin_flt = sig->cmin_flt;
521 cmaj_flt = sig->cmaj_flt;
522 cutime = sig->cutime;
523 cstime = sig->cstime;
524 cgtime = sig->cgtime;
525 rsslim = READ_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
526
527
528 if (whole) {
529 struct task_struct *t = task;
530 do {
531 min_flt += t->min_flt;
532 maj_flt += t->maj_flt;
533 gtime += task_gtime(t);
534 } while_each_thread(task, t);
535
536 min_flt += sig->min_flt;
537 maj_flt += sig->maj_flt;
538 thread_group_cputime_adjusted(task, &utime, &stime);
539 gtime += sig->gtime;
540
541 if (sig->flags & (SIGNAL_GROUP_EXIT | SIGNAL_STOP_STOPPED))
542 exit_code = sig->group_exit_code;
543 }
544
545 sid = task_session_nr_ns(task, ns);
546 ppid = task_tgid_nr_ns(task->real_parent, ns);
547 pgid = task_pgrp_nr_ns(task, ns);
548
549 unlock_task_sighand(task, &flags);
550 }
551
552 if (permitted && (!whole || num_threads < 2))
553 wchan = !task_is_running(task);
554 if (!whole) {
555 min_flt = task->min_flt;
556 maj_flt = task->maj_flt;
557 task_cputime_adjusted(task, &utime, &stime);
558 gtime = task_gtime(task);
559 }
560
561
562
563 priority = task_prio(task);
564 nice = task_nice(task);
565
566
567 start_time =
568 nsec_to_clock_t(timens_add_boottime_ns(task->start_boottime));
569
570 seq_put_decimal_ull(m, "", pid_nr_ns(pid, ns));
571 seq_puts(m, " (");
572 proc_task_name(m, task, false);
573 seq_puts(m, ") ");
574 seq_putc(m, state);
575 seq_put_decimal_ll(m, " ", ppid);
576 seq_put_decimal_ll(m, " ", pgid);
577 seq_put_decimal_ll(m, " ", sid);
578 seq_put_decimal_ll(m, " ", tty_nr);
579 seq_put_decimal_ll(m, " ", tty_pgrp);
580 seq_put_decimal_ull(m, " ", task->flags);
581 seq_put_decimal_ull(m, " ", min_flt);
582 seq_put_decimal_ull(m, " ", cmin_flt);
583 seq_put_decimal_ull(m, " ", maj_flt);
584 seq_put_decimal_ull(m, " ", cmaj_flt);
585 seq_put_decimal_ull(m, " ", nsec_to_clock_t(utime));
586 seq_put_decimal_ull(m, " ", nsec_to_clock_t(stime));
587 seq_put_decimal_ll(m, " ", nsec_to_clock_t(cutime));
588 seq_put_decimal_ll(m, " ", nsec_to_clock_t(cstime));
589 seq_put_decimal_ll(m, " ", priority);
590 seq_put_decimal_ll(m, " ", nice);
591 seq_put_decimal_ll(m, " ", num_threads);
592 seq_put_decimal_ull(m, " ", 0);
593 seq_put_decimal_ull(m, " ", start_time);
594 seq_put_decimal_ull(m, " ", vsize);
595 seq_put_decimal_ull(m, " ", mm ? get_mm_rss(mm) : 0);
596 seq_put_decimal_ull(m, " ", rsslim);
597 seq_put_decimal_ull(m, " ", mm ? (permitted ? mm->start_code : 1) : 0);
598 seq_put_decimal_ull(m, " ", mm ? (permitted ? mm->end_code : 1) : 0);
599 seq_put_decimal_ull(m, " ", (permitted && mm) ? mm->start_stack : 0);
600 seq_put_decimal_ull(m, " ", esp);
601 seq_put_decimal_ull(m, " ", eip);
602
603
604
605
606 seq_put_decimal_ull(m, " ", task->pending.signal.sig[0] & 0x7fffffffUL);
607 seq_put_decimal_ull(m, " ", task->blocked.sig[0] & 0x7fffffffUL);
608 seq_put_decimal_ull(m, " ", sigign.sig[0] & 0x7fffffffUL);
609 seq_put_decimal_ull(m, " ", sigcatch.sig[0] & 0x7fffffffUL);
610
611
612
613
614
615
616
617
618 seq_put_decimal_ull(m, " ", wchan);
619
620 seq_put_decimal_ull(m, " ", 0);
621 seq_put_decimal_ull(m, " ", 0);
622 seq_put_decimal_ll(m, " ", task->exit_signal);
623 seq_put_decimal_ll(m, " ", task_cpu(task));
624 seq_put_decimal_ull(m, " ", task->rt_priority);
625 seq_put_decimal_ull(m, " ", task->policy);
626 seq_put_decimal_ull(m, " ", delayacct_blkio_ticks(task));
627 seq_put_decimal_ull(m, " ", nsec_to_clock_t(gtime));
628 seq_put_decimal_ll(m, " ", nsec_to_clock_t(cgtime));
629
630 if (mm && permitted) {
631 seq_put_decimal_ull(m, " ", mm->start_data);
632 seq_put_decimal_ull(m, " ", mm->end_data);
633 seq_put_decimal_ull(m, " ", mm->start_brk);
634 seq_put_decimal_ull(m, " ", mm->arg_start);
635 seq_put_decimal_ull(m, " ", mm->arg_end);
636 seq_put_decimal_ull(m, " ", mm->env_start);
637 seq_put_decimal_ull(m, " ", mm->env_end);
638 } else
639 seq_puts(m, " 0 0 0 0 0 0 0");
640
641 if (permitted)
642 seq_put_decimal_ll(m, " ", exit_code);
643 else
644 seq_puts(m, " 0");
645
646 seq_putc(m, '\n');
647 if (mm)
648 mmput(mm);
649 return 0;
650}
651
652int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
653 struct pid *pid, struct task_struct *task)
654{
655 return do_task_stat(m, ns, pid, task, 0);
656}
657
658int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
659 struct pid *pid, struct task_struct *task)
660{
661 return do_task_stat(m, ns, pid, task, 1);
662}
663
664int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
665 struct pid *pid, struct task_struct *task)
666{
667 struct mm_struct *mm = get_task_mm(task);
668
669 if (mm) {
670 unsigned long size;
671 unsigned long resident = 0;
672 unsigned long shared = 0;
673 unsigned long text = 0;
674 unsigned long data = 0;
675
676 size = task_statm(mm, &shared, &text, &data, &resident);
677 mmput(mm);
678
679
680
681
682
683
684
685 seq_put_decimal_ull(m, "", size);
686 seq_put_decimal_ull(m, " ", resident);
687 seq_put_decimal_ull(m, " ", shared);
688 seq_put_decimal_ull(m, " ", text);
689 seq_put_decimal_ull(m, " ", 0);
690 seq_put_decimal_ull(m, " ", data);
691 seq_put_decimal_ull(m, " ", 0);
692 seq_putc(m, '\n');
693 } else {
694 seq_write(m, "0 0 0 0 0 0 0\n", 14);
695 }
696 return 0;
697}
698
699#ifdef CONFIG_PROC_CHILDREN
700static struct pid *
701get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos)
702{
703 struct task_struct *start, *task;
704 struct pid *pid = NULL;
705
706 read_lock(&tasklist_lock);
707
708 start = pid_task(proc_pid(inode), PIDTYPE_PID);
709 if (!start)
710 goto out;
711
712
713
714
715
716 if (pid_prev) {
717 task = pid_task(pid_prev, PIDTYPE_PID);
718 if (task && task->real_parent == start &&
719 !(list_empty(&task->sibling))) {
720 if (list_is_last(&task->sibling, &start->children))
721 goto out;
722 task = list_first_entry(&task->sibling,
723 struct task_struct, sibling);
724 pid = get_pid(task_pid(task));
725 goto out;
726 }
727 }
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744 list_for_each_entry(task, &start->children, sibling) {
745 if (pos-- == 0) {
746 pid = get_pid(task_pid(task));
747 break;
748 }
749 }
750
751out:
752 read_unlock(&tasklist_lock);
753 return pid;
754}
755
756static int children_seq_show(struct seq_file *seq, void *v)
757{
758 struct inode *inode = file_inode(seq->file);
759
760 seq_printf(seq, "%d ", pid_nr_ns(v, proc_pid_ns(inode->i_sb)));
761 return 0;
762}
763
764static void *children_seq_start(struct seq_file *seq, loff_t *pos)
765{
766 return get_children_pid(file_inode(seq->file), NULL, *pos);
767}
768
769static void *children_seq_next(struct seq_file *seq, void *v, loff_t *pos)
770{
771 struct pid *pid;
772
773 pid = get_children_pid(file_inode(seq->file), v, *pos + 1);
774 put_pid(v);
775
776 ++*pos;
777 return pid;
778}
779
780static void children_seq_stop(struct seq_file *seq, void *v)
781{
782 put_pid(v);
783}
784
785static const struct seq_operations children_seq_ops = {
786 .start = children_seq_start,
787 .next = children_seq_next,
788 .stop = children_seq_stop,
789 .show = children_seq_show,
790};
791
792static int children_seq_open(struct inode *inode, struct file *file)
793{
794 return seq_open(file, &children_seq_ops);
795}
796
797const struct file_operations proc_tid_children_operations = {
798 .open = children_seq_open,
799 .read = seq_read,
800 .llseek = seq_lseek,
801 .release = seq_release,
802};
803#endif
804