Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
array.c
Go to the documentation of this file.
1 /*
2  * linux/fs/proc/array.c
3  *
4  * Copyright (C) 1992 by Linus Torvalds
5  * based on ideas by Darren Senn
6  *
7  * Fixes:
8  * Michael. K. Johnson: stat,statm extensions.
10  *
11  * Pauline Middelink : Made cmdline,envline only break at '\0's, to
12  * make sure SET_PROCTITLE works. Also removed
13  * bad '!' which forced address recalculation for
14  * EVERY character on the current page.
16  *
17  * Danny ter Haar : added cpuinfo
19  *
20  * Alessandro Rubini : profile extension.
22  *
23  * Jeff Tranter : added BogoMips field to cpuinfo
25  *
26  * Bruno Haible : remove 4K limit for the maps file
28  *
29  * Yves Arrouye : remove removal of trailing spaces in get_array.
31  *
32  * Jerome Forissier : added per-CPU time information to /proc/stat
33  * and /proc/<pid>/cpu extension
35  * - Incorporation and non-SMP safe operation
36  * of forissier patch in 2.1.78 by
37  * Hans Marcus <[email protected]>
38  *
39  * [email protected] : /proc/partitions
40  *
41  *
42  * Alan Cox : security fixes.
44  *
45  * Al Viro : safe handling of mm_struct
46  *
47  * Gerhard Wichert : added BIGMEM support
48  * Siemens AG <[email protected]>
49  *
50  * Al Viro & Jeff Garzik : moved most of the thing into base.c and
51  * : proc_misc.c. The rest may eventually go into
52  * : base.c too.
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 #include <linux/user_namespace.h>
85 
86 #include <asm/pgtable.h>
87 #include <asm/processor.h>
88 #include "internal.h"
89 
90 static inline void task_name(struct seq_file *m, struct task_struct *p)
91 {
92  int i;
93  char *buf, *end;
94  char *name;
95  char tcomm[sizeof(p->comm)];
96 
97  get_task_comm(tcomm, p);
98 
99  seq_puts(m, "Name:\t");
100  end = m->buf + m->size;
101  buf = m->buf + m->count;
102  name = tcomm;
103  i = sizeof(tcomm);
104  while (i && (buf < end)) {
105  unsigned char c = *name;
106  name++;
107  i--;
108  *buf = c;
109  if (!c)
110  break;
111  if (c == '\\') {
112  buf++;
113  if (buf < end)
114  *buf++ = c;
115  continue;
116  }
117  if (c == '\n') {
118  *buf++ = '\\';
119  if (buf < end)
120  *buf++ = 'n';
121  continue;
122  }
123  buf++;
124  }
125  m->count = buf - m->buf;
126  seq_putc(m, '\n');
127 }
128 
129 /*
130  * The task state array is a strange "bitmap" of
131  * reasons to sleep. Thus "running" is zero, and
132  * you can test for combinations of others with
133  * simple bit tests.
134  */
135 static const char * const task_state_array[] = {
136  "R (running)", /* 0 */
137  "S (sleeping)", /* 1 */
138  "D (disk sleep)", /* 2 */
139  "T (stopped)", /* 4 */
140  "t (tracing stop)", /* 8 */
141  "Z (zombie)", /* 16 */
142  "X (dead)", /* 32 */
143  "x (dead)", /* 64 */
144  "K (wakekill)", /* 128 */
145  "W (waking)", /* 256 */
146 };
147 
148 static inline const char *get_task_state(struct task_struct *tsk)
149 {
150  unsigned int state = (tsk->state & TASK_REPORT) | tsk->exit_state;
151  const char * const *p = &task_state_array[0];
152 
153  BUILD_BUG_ON(1 + ilog2(TASK_STATE_MAX) != ARRAY_SIZE(task_state_array));
154 
155  while (state) {
156  p++;
157  state >>= 1;
158  }
159  return *p;
160 }
161 
162 static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
163  struct pid *pid, struct task_struct *p)
164 {
165  struct user_namespace *user_ns = current_user_ns();
166  struct group_info *group_info;
167  int g;
168  struct fdtable *fdt = NULL;
169  const struct cred *cred;
170  pid_t ppid, tpid;
171 
172  rcu_read_lock();
173  ppid = pid_alive(p) ?
175  tpid = 0;
176  if (pid_alive(p)) {
177  struct task_struct *tracer = ptrace_parent(p);
178  if (tracer)
179  tpid = task_pid_nr_ns(tracer, ns);
180  }
181  cred = get_task_cred(p);
182  seq_printf(m,
183  "State:\t%s\n"
184  "Tgid:\t%d\n"
185  "Pid:\t%d\n"
186  "PPid:\t%d\n"
187  "TracerPid:\t%d\n"
188  "Uid:\t%d\t%d\t%d\t%d\n"
189  "Gid:\t%d\t%d\t%d\t%d\n",
190  get_task_state(p),
191  task_tgid_nr_ns(p, ns),
192  pid_nr_ns(pid, ns),
193  ppid, tpid,
194  from_kuid_munged(user_ns, cred->uid),
195  from_kuid_munged(user_ns, cred->euid),
196  from_kuid_munged(user_ns, cred->suid),
197  from_kuid_munged(user_ns, cred->fsuid),
198  from_kgid_munged(user_ns, cred->gid),
199  from_kgid_munged(user_ns, cred->egid),
200  from_kgid_munged(user_ns, cred->sgid),
201  from_kgid_munged(user_ns, cred->fsgid));
202 
203  task_lock(p);
204  if (p->files)
205  fdt = files_fdtable(p->files);
206  seq_printf(m,
207  "FDSize:\t%d\n"
208  "Groups:\t",
209  fdt ? fdt->max_fds : 0);
210  rcu_read_unlock();
211 
212  group_info = cred->group_info;
213  task_unlock(p);
214 
215  for (g = 0; g < min(group_info->ngroups, NGROUPS_SMALL); g++)
216  seq_printf(m, "%d ",
217  from_kgid_munged(user_ns, GROUP_AT(group_info, g)));
218  put_cred(cred);
219 
220  seq_putc(m, '\n');
221 }
222 
223 static void render_sigset_t(struct seq_file *m, const char *header,
224  sigset_t *set)
225 {
226  int i;
227 
228  seq_puts(m, header);
229 
230  i = _NSIG;
231  do {
232  int x = 0;
233 
234  i -= 4;
235  if (sigismember(set, i+1)) x |= 1;
236  if (sigismember(set, i+2)) x |= 2;
237  if (sigismember(set, i+3)) x |= 4;
238  if (sigismember(set, i+4)) x |= 8;
239  seq_printf(m, "%x", x);
240  } while (i >= 4);
241 
242  seq_putc(m, '\n');
243 }
244 
245 static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
246  sigset_t *catch)
247 {
248  struct k_sigaction *k;
249  int i;
250 
251  k = p->sighand->action;
252  for (i = 1; i <= _NSIG; ++i, ++k) {
253  if (k->sa.sa_handler == SIG_IGN)
254  sigaddset(ign, i);
255  else if (k->sa.sa_handler != SIG_DFL)
256  sigaddset(catch, i);
257  }
258 }
259 
260 static inline void task_sig(struct seq_file *m, struct task_struct *p)
261 {
262  unsigned long flags;
263  sigset_t pending, shpending, blocked, ignored, caught;
264  int num_threads = 0;
265  unsigned long qsize = 0;
266  unsigned long qlim = 0;
267 
268  sigemptyset(&pending);
269  sigemptyset(&shpending);
270  sigemptyset(&blocked);
271  sigemptyset(&ignored);
272  sigemptyset(&caught);
273 
274  if (lock_task_sighand(p, &flags)) {
275  pending = p->pending.signal;
276  shpending = p->signal->shared_pending.signal;
277  blocked = p->blocked;
278  collect_sigign_sigcatch(p, &ignored, &caught);
279  num_threads = get_nr_threads(p);
280  rcu_read_lock(); /* FIXME: is this correct? */
281  qsize = atomic_read(&__task_cred(p)->user->sigpending);
282  rcu_read_unlock();
283  qlim = task_rlimit(p, RLIMIT_SIGPENDING);
284  unlock_task_sighand(p, &flags);
285  }
286 
287  seq_printf(m, "Threads:\t%d\n", num_threads);
288  seq_printf(m, "SigQ:\t%lu/%lu\n", qsize, qlim);
289 
290  /* render them all */
291  render_sigset_t(m, "SigPnd:\t", &pending);
292  render_sigset_t(m, "ShdPnd:\t", &shpending);
293  render_sigset_t(m, "SigBlk:\t", &blocked);
294  render_sigset_t(m, "SigIgn:\t", &ignored);
295  render_sigset_t(m, "SigCgt:\t", &caught);
296 }
297 
298 static void render_cap_t(struct seq_file *m, const char *header,
299  kernel_cap_t *a)
300 {
301  unsigned __capi;
302 
303  seq_puts(m, header);
304  CAP_FOR_EACH_U32(__capi) {
305  seq_printf(m, "%08x",
306  a->cap[(_KERNEL_CAPABILITY_U32S-1) - __capi]);
307  }
308  seq_putc(m, '\n');
309 }
310 
311 static inline void task_cap(struct seq_file *m, struct task_struct *p)
312 {
313  const struct cred *cred;
315 
316  rcu_read_lock();
317  cred = __task_cred(p);
318  cap_inheritable = cred->cap_inheritable;
319  cap_permitted = cred->cap_permitted;
320  cap_effective = cred->cap_effective;
321  cap_bset = cred->cap_bset;
322  rcu_read_unlock();
323 
324  render_cap_t(m, "CapInh:\t", &cap_inheritable);
325  render_cap_t(m, "CapPrm:\t", &cap_permitted);
326  render_cap_t(m, "CapEff:\t", &cap_effective);
327  render_cap_t(m, "CapBnd:\t", &cap_bset);
328 }
329 
330 static inline void task_context_switch_counts(struct seq_file *m,
331  struct task_struct *p)
332 {
333  seq_printf(m, "voluntary_ctxt_switches:\t%lu\n"
334  "nonvoluntary_ctxt_switches:\t%lu\n",
335  p->nvcsw,
336  p->nivcsw);
337 }
338 
339 static void task_cpus_allowed(struct seq_file *m, struct task_struct *task)
340 {
341  seq_puts(m, "Cpus_allowed:\t");
342  seq_cpumask(m, &task->cpus_allowed);
343  seq_putc(m, '\n');
344  seq_puts(m, "Cpus_allowed_list:\t");
345  seq_cpumask_list(m, &task->cpus_allowed);
346  seq_putc(m, '\n');
347 }
348 
349 int proc_pid_status(struct seq_file *m, struct pid_namespace *ns,
350  struct pid *pid, struct task_struct *task)
351 {
352  struct mm_struct *mm = get_task_mm(task);
353 
354  task_name(m, task);
355  task_state(m, ns, pid, task);
356 
357  if (mm) {
358  task_mem(m, mm);
359  mmput(mm);
360  }
361  task_sig(m, task);
362  task_cap(m, task);
363  task_cpus_allowed(m, task);
365  task_context_switch_counts(m, task);
366  return 0;
367 }
368 
369 static int do_task_stat(struct seq_file *m, struct pid_namespace *ns,
370  struct pid *pid, struct task_struct *task, int whole)
371 {
372  unsigned long vsize, eip, esp, wchan = ~0UL;
373  int priority, nice;
374  int tty_pgrp = -1, tty_nr = 0;
375  sigset_t sigign, sigcatch;
376  char state;
377  pid_t ppid = 0, pgid = -1, sid = -1;
378  int num_threads = 0;
379  int permitted;
380  struct mm_struct *mm;
381  unsigned long long start_time;
382  unsigned long cmin_flt = 0, cmaj_flt = 0;
383  unsigned long min_flt = 0, maj_flt = 0;
384  cputime_t cutime, cstime, utime, stime;
385  cputime_t cgtime, gtime;
386  unsigned long rsslim = 0;
387  char tcomm[sizeof(task->comm)];
388  unsigned long flags;
389 
390  state = *get_task_state(task);
391  vsize = eip = esp = 0;
393  mm = get_task_mm(task);
394  if (mm) {
395  vsize = task_vsize(mm);
396  if (permitted) {
397  eip = KSTK_EIP(task);
398  esp = KSTK_ESP(task);
399  }
400  }
401 
402  get_task_comm(tcomm, task);
403 
404  sigemptyset(&sigign);
405  sigemptyset(&sigcatch);
406  cutime = cstime = utime = stime = 0;
407  cgtime = gtime = 0;
408 
409  if (lock_task_sighand(task, &flags)) {
410  struct signal_struct *sig = task->signal;
411 
412  if (sig->tty) {
413  struct pid *pgrp = tty_get_pgrp(sig->tty);
414  tty_pgrp = pid_nr_ns(pgrp, ns);
415  put_pid(pgrp);
416  tty_nr = new_encode_dev(tty_devnum(sig->tty));
417  }
418 
419  num_threads = get_nr_threads(task);
420  collect_sigign_sigcatch(task, &sigign, &sigcatch);
421 
422  cmin_flt = sig->cmin_flt;
423  cmaj_flt = sig->cmaj_flt;
424  cutime = sig->cutime;
425  cstime = sig->cstime;
426  cgtime = sig->cgtime;
427  rsslim = ACCESS_ONCE(sig->rlim[RLIMIT_RSS].rlim_cur);
428 
429  /* add up live thread stats at the group level */
430  if (whole) {
431  struct task_struct *t = task;
432  do {
433  min_flt += t->min_flt;
434  maj_flt += t->maj_flt;
435  gtime += t->gtime;
436  t = next_thread(t);
437  } while (t != task);
438 
439  min_flt += sig->min_flt;
440  maj_flt += sig->maj_flt;
441  thread_group_times(task, &utime, &stime);
442  gtime += sig->gtime;
443  }
444 
445  sid = task_session_nr_ns(task, ns);
446  ppid = task_tgid_nr_ns(task->real_parent, ns);
447  pgid = task_pgrp_nr_ns(task, ns);
448 
449  unlock_task_sighand(task, &flags);
450  }
451 
452  if (permitted && (!whole || num_threads < 2))
453  wchan = get_wchan(task);
454  if (!whole) {
455  min_flt = task->min_flt;
456  maj_flt = task->maj_flt;
457  task_times(task, &utime, &stime);
458  gtime = task->gtime;
459  }
460 
461  /* scale priority and nice values from timeslices to -20..20 */
462  /* to make it look like a "normal" Unix priority/nice value */
463  priority = task_prio(task);
464  nice = task_nice(task);
465 
466  /* Temporary variable needed for gcc-2.96 */
467  /* convert timespec -> nsec*/
468  start_time =
469  (unsigned long long)task->real_start_time.tv_sec * NSEC_PER_SEC
470  + task->real_start_time.tv_nsec;
471  /* convert nsec -> ticks */
472  start_time = nsec_to_clock_t(start_time);
473 
474  seq_printf(m, "%d (%s) %c", pid_nr_ns(pid, ns), tcomm, state);
475  seq_put_decimal_ll(m, ' ', ppid);
476  seq_put_decimal_ll(m, ' ', pgid);
477  seq_put_decimal_ll(m, ' ', sid);
478  seq_put_decimal_ll(m, ' ', tty_nr);
479  seq_put_decimal_ll(m, ' ', tty_pgrp);
480  seq_put_decimal_ull(m, ' ', task->flags);
481  seq_put_decimal_ull(m, ' ', min_flt);
482  seq_put_decimal_ull(m, ' ', cmin_flt);
483  seq_put_decimal_ull(m, ' ', maj_flt);
484  seq_put_decimal_ull(m, ' ', cmaj_flt);
485  seq_put_decimal_ull(m, ' ', cputime_to_clock_t(utime));
486  seq_put_decimal_ull(m, ' ', cputime_to_clock_t(stime));
487  seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cutime));
488  seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cstime));
489  seq_put_decimal_ll(m, ' ', priority);
490  seq_put_decimal_ll(m, ' ', nice);
491  seq_put_decimal_ll(m, ' ', num_threads);
492  seq_put_decimal_ull(m, ' ', 0);
493  seq_put_decimal_ull(m, ' ', start_time);
494  seq_put_decimal_ull(m, ' ', vsize);
495  seq_put_decimal_ull(m, ' ', mm ? get_mm_rss(mm) : 0);
496  seq_put_decimal_ull(m, ' ', rsslim);
497  seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->start_code : 1) : 0);
498  seq_put_decimal_ull(m, ' ', mm ? (permitted ? mm->end_code : 1) : 0);
499  seq_put_decimal_ull(m, ' ', (permitted && mm) ? mm->start_stack : 0);
500  seq_put_decimal_ull(m, ' ', esp);
501  seq_put_decimal_ull(m, ' ', eip);
502  /* The signal information here is obsolete.
503  * It must be decimal for Linux 2.0 compatibility.
504  * Use /proc/#/status for real-time signals.
505  */
506  seq_put_decimal_ull(m, ' ', task->pending.signal.sig[0] & 0x7fffffffUL);
507  seq_put_decimal_ull(m, ' ', task->blocked.sig[0] & 0x7fffffffUL);
508  seq_put_decimal_ull(m, ' ', sigign.sig[0] & 0x7fffffffUL);
509  seq_put_decimal_ull(m, ' ', sigcatch.sig[0] & 0x7fffffffUL);
510  seq_put_decimal_ull(m, ' ', wchan);
511  seq_put_decimal_ull(m, ' ', 0);
512  seq_put_decimal_ull(m, ' ', 0);
513  seq_put_decimal_ll(m, ' ', task->exit_signal);
514  seq_put_decimal_ll(m, ' ', task_cpu(task));
515  seq_put_decimal_ull(m, ' ', task->rt_priority);
516  seq_put_decimal_ull(m, ' ', task->policy);
517  seq_put_decimal_ull(m, ' ', delayacct_blkio_ticks(task));
518  seq_put_decimal_ull(m, ' ', cputime_to_clock_t(gtime));
519  seq_put_decimal_ll(m, ' ', cputime_to_clock_t(cgtime));
520 
521  if (mm && permitted) {
522  seq_put_decimal_ull(m, ' ', mm->start_data);
523  seq_put_decimal_ull(m, ' ', mm->end_data);
524  seq_put_decimal_ull(m, ' ', mm->start_brk);
525  seq_put_decimal_ull(m, ' ', mm->arg_start);
526  seq_put_decimal_ull(m, ' ', mm->arg_end);
527  seq_put_decimal_ull(m, ' ', mm->env_start);
528  seq_put_decimal_ull(m, ' ', mm->env_end);
529  } else
530  seq_printf(m, " 0 0 0 0 0 0 0");
531 
532  if (permitted)
533  seq_put_decimal_ll(m, ' ', task->exit_code);
534  else
535  seq_put_decimal_ll(m, ' ', 0);
536 
537  seq_putc(m, '\n');
538  if (mm)
539  mmput(mm);
540  return 0;
541 }
542 
543 int proc_tid_stat(struct seq_file *m, struct pid_namespace *ns,
544  struct pid *pid, struct task_struct *task)
545 {
546  return do_task_stat(m, ns, pid, task, 0);
547 }
548 
549 int proc_tgid_stat(struct seq_file *m, struct pid_namespace *ns,
550  struct pid *pid, struct task_struct *task)
551 {
552  return do_task_stat(m, ns, pid, task, 1);
553 }
554 
555 int proc_pid_statm(struct seq_file *m, struct pid_namespace *ns,
556  struct pid *pid, struct task_struct *task)
557 {
558  unsigned long size = 0, resident = 0, shared = 0, text = 0, data = 0;
559  struct mm_struct *mm = get_task_mm(task);
560 
561  if (mm) {
562  size = task_statm(mm, &shared, &text, &data, &resident);
563  mmput(mm);
564  }
565  /*
566  * For quick read, open code by putting numbers directly
567  * expected format is
568  * seq_printf(m, "%lu %lu %lu %lu 0 %lu 0\n",
569  * size, resident, shared, text, data);
570  */
571  seq_put_decimal_ull(m, 0, size);
572  seq_put_decimal_ull(m, ' ', resident);
573  seq_put_decimal_ull(m, ' ', shared);
574  seq_put_decimal_ull(m, ' ', text);
575  seq_put_decimal_ull(m, ' ', 0);
576  seq_put_decimal_ull(m, ' ', data);
577  seq_put_decimal_ull(m, ' ', 0);
578  seq_putc(m, '\n');
579 
580  return 0;
581 }
582 
583 #ifdef CONFIG_CHECKPOINT_RESTORE
584 static struct pid *
585 get_children_pid(struct inode *inode, struct pid *pid_prev, loff_t pos)
586 {
587  struct task_struct *start, *task;
588  struct pid *pid = NULL;
589 
590  read_lock(&tasklist_lock);
591 
592  start = pid_task(proc_pid(inode), PIDTYPE_PID);
593  if (!start)
594  goto out;
595 
596  /*
597  * Lets try to continue searching first, this gives
598  * us significant speedup on children-rich processes.
599  */
600  if (pid_prev) {
601  task = pid_task(pid_prev, PIDTYPE_PID);
602  if (task && task->real_parent == start &&
603  !(list_empty(&task->sibling))) {
604  if (list_is_last(&task->sibling, &start->children))
605  goto out;
606  task = list_first_entry(&task->sibling,
607  struct task_struct, sibling);
608  pid = get_pid(task_pid(task));
609  goto out;
610  }
611  }
612 
613  /*
614  * Slow search case.
615  *
616  * We might miss some children here if children
617  * are exited while we were not holding the lock,
618  * but it was never promised to be accurate that
619  * much.
620  *
621  * "Just suppose that the parent sleeps, but N children
622  * exit after we printed their tids. Now the slow paths
623  * skips N extra children, we miss N tasks." (c)
624  *
625  * So one need to stop or freeze the leader and all
626  * its children to get a precise result.
627  */
628  list_for_each_entry(task, &start->children, sibling) {
629  if (pos-- == 0) {
630  pid = get_pid(task_pid(task));
631  break;
632  }
633  }
634 
635 out:
636  read_unlock(&tasklist_lock);
637  return pid;
638 }
639 
640 static int children_seq_show(struct seq_file *seq, void *v)
641 {
642  struct inode *inode = seq->private;
643  pid_t pid;
644 
645  pid = pid_nr_ns(v, inode->i_sb->s_fs_info);
646  return seq_printf(seq, "%d ", pid);
647 }
648 
649 static void *children_seq_start(struct seq_file *seq, loff_t *pos)
650 {
651  return get_children_pid(seq->private, NULL, *pos);
652 }
653 
654 static void *children_seq_next(struct seq_file *seq, void *v, loff_t *pos)
655 {
656  struct pid *pid;
657 
658  pid = get_children_pid(seq->private, v, *pos + 1);
659  put_pid(v);
660 
661  ++*pos;
662  return pid;
663 }
664 
665 static void children_seq_stop(struct seq_file *seq, void *v)
666 {
667  put_pid(v);
668 }
669 
670 static const struct seq_operations children_seq_ops = {
671  .start = children_seq_start,
672  .next = children_seq_next,
673  .stop = children_seq_stop,
674  .show = children_seq_show,
675 };
676 
677 static int children_seq_open(struct inode *inode, struct file *file)
678 {
679  struct seq_file *m;
680  int ret;
681 
682  ret = seq_open(file, &children_seq_ops);
683  if (ret)
684  return ret;
685 
686  m = file->private_data;
687  m->private = inode;
688 
689  return ret;
690 }
691 
692 int children_seq_release(struct inode *inode, struct file *file)
693 {
694  seq_release(inode, file);
695  return 0;
696 }
697 
699  .open = children_seq_open,
700  .read = seq_read,
701  .llseek = seq_lseek,
702  .release = children_seq_release,
703 };
704 #endif /* CONFIG_CHECKPOINT_RESTORE */