This source file includes following definitions.
- read_core
- read_profile
- write_profile
- get_loadavg
- get_kstat
- get_uptime
- get_meminfo
- get_version
- get_cmdline
- get_task
- get_phys_addr
- get_array
- get_env
- get_arg
- get_wchan
- task_name
- task_state
- task_mem
- task_sig
- get_status
- get_stat
- statm_pte_range
- statm_pmd_range
- statm_pgd_range
- get_statm
- read_maps
- get_root_array
- get_process_array
- fill_array
- array_read
- arraylong_read
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 #include <linux/types.h>
31 #include <linux/errno.h>
32 #include <linux/sched.h>
33 #include <linux/kernel.h>
34 #include <linux/kernel_stat.h>
35 #include <linux/tty.h>
36 #include <linux/user.h>
37 #include <linux/a.out.h>
38 #include <linux/string.h>
39 #include <linux/mman.h>
40 #include <linux/proc_fs.h>
41 #include <linux/ioport.h>
42 #include <linux/config.h>
43 #include <linux/mm.h>
44 #include <linux/pagemap.h>
45 #include <linux/swap.h>
46
47 #include <asm/segment.h>
48 #include <asm/pgtable.h>
49 #include <asm/io.h>
50
51 #define LOAD_INT(x) ((x) >> FSHIFT)
52 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
53
54 #ifdef CONFIG_DEBUG_MALLOC
55 int get_malloc(char * buffer);
56 #endif
57
58
59 static int read_core(struct inode * inode, struct file * file,char * buf, int count)
60 {
61 unsigned long p = file->f_pos, memsize;
62 int read;
63 int count1;
64 char * pnt;
65 struct user dump;
66 #ifdef __i386__
67 # define FIRST_MAPPED PAGE_SIZE
68 #else
69 # define FIRST_MAPPED 0
70 #endif
71
72 memset(&dump, 0, sizeof(struct user));
73 dump.magic = CMAGIC;
74 dump.u_dsize = MAP_NR(high_memory);
75 #ifdef __alpha__
76 dump.start_data = PAGE_OFFSET;
77 #endif
78
79 if (count < 0)
80 return -EINVAL;
81 memsize = MAP_NR(high_memory + PAGE_SIZE) << PAGE_SHIFT;
82 if (p >= memsize)
83 return 0;
84 if (count > memsize - p)
85 count = memsize - p;
86 read = 0;
87
88 if (p < sizeof(struct user) && count > 0) {
89 count1 = count;
90 if (p + count1 > sizeof(struct user))
91 count1 = sizeof(struct user)-p;
92 pnt = (char *) &dump + p;
93 memcpy_tofs(buf,(void *) pnt, count1);
94 buf += count1;
95 p += count1;
96 count -= count1;
97 read += count1;
98 }
99
100 while (count > 0 && p < PAGE_SIZE + FIRST_MAPPED) {
101 put_user(0,buf);
102 buf++;
103 p++;
104 count--;
105 read++;
106 }
107 memcpy_tofs(buf, (void *) (PAGE_OFFSET + p - PAGE_SIZE), count);
108 read += count;
109 file->f_pos += read;
110 return read;
111 }
112
113 static struct file_operations proc_kcore_operations = {
114 NULL,
115 read_core,
116 };
117
118 struct inode_operations proc_kcore_inode_operations = {
119 &proc_kcore_operations,
120 };
121
122
123
124
125
126
127
128
129 static int read_profile(struct inode *inode, struct file *file, char *buf, int count)
130 {
131 unsigned long p = file->f_pos;
132 int read;
133 char * pnt;
134 unsigned int sample_step = 1 << prof_shift;
135
136 if (count < 0)
137 return -EINVAL;
138 if (p >= (prof_len+1)*sizeof(unsigned int))
139 return 0;
140 if (count > (prof_len+1)*sizeof(unsigned int) - p)
141 count = (prof_len+1)*sizeof(unsigned int) - p;
142 read = 0;
143
144 while (p < sizeof(unsigned int) && count > 0) {
145 put_user(*((char *)(&sample_step)+p),buf);
146 buf++; p++; count--; read++;
147 }
148 pnt = (char *)prof_buffer + p - sizeof(unsigned int);
149 memcpy_tofs(buf,(void *)pnt,count);
150 read += count;
151 file->f_pos += read;
152 return read;
153 }
154
155
156 static int write_profile(struct inode * inode, struct file * file, const char * buf, int count)
157 {
158 int i=prof_len;
159
160 while (i--)
161 prof_buffer[i]=0UL;
162 return count;
163 }
164
165 static struct file_operations proc_profile_operations = {
166 NULL,
167 read_profile,
168 write_profile,
169 };
170
171 struct inode_operations proc_profile_inode_operations = {
172 &proc_profile_operations,
173 };
174
175
176 static int get_loadavg(char * buffer)
177 {
178 int a, b, c;
179
180 a = avenrun[0] + (FIXED_1/200);
181 b = avenrun[1] + (FIXED_1/200);
182 c = avenrun[2] + (FIXED_1/200);
183 return sprintf(buffer,"%d.%02d %d.%02d %d.%02d %d/%d\n",
184 LOAD_INT(a), LOAD_FRAC(a),
185 LOAD_INT(b), LOAD_FRAC(b),
186 LOAD_INT(c), LOAD_FRAC(c),
187 nr_running, nr_tasks);
188 }
189
190 static int get_kstat(char * buffer)
191 {
192 int i, len;
193 unsigned sum = 0;
194 extern unsigned long total_forks;
195
196 for (i = 0 ; i < NR_IRQS ; i++)
197 sum += kstat.interrupts[i];
198 len = sprintf(buffer,
199 "cpu %u %u %u %lu\n"
200 "disk %u %u %u %u\n"
201 "disk_rio %u %u %u %u\n"
202 "disk_wio %u %u %u %u\n"
203 "disk_rblk %u %u %u %u\n"
204 "disk_wblk %u %u %u %u\n"
205 "page %u %u\n"
206 "swap %u %u\n"
207 "intr %u",
208 kstat.cpu_user,
209 kstat.cpu_nice,
210 kstat.cpu_system,
211 jiffies - (kstat.cpu_user + kstat.cpu_nice + kstat.cpu_system),
212 kstat.dk_drive[0], kstat.dk_drive[1],
213 kstat.dk_drive[2], kstat.dk_drive[3],
214 kstat.dk_drive_rio[0], kstat.dk_drive_rio[1],
215 kstat.dk_drive_rio[2], kstat.dk_drive_rio[3],
216 kstat.dk_drive_wio[0], kstat.dk_drive_wio[1],
217 kstat.dk_drive_wio[2], kstat.dk_drive_wio[3],
218 kstat.dk_drive_rblk[0], kstat.dk_drive_rblk[1],
219 kstat.dk_drive_rblk[2], kstat.dk_drive_rblk[3],
220 kstat.dk_drive_wblk[0], kstat.dk_drive_wblk[1],
221 kstat.dk_drive_wblk[2], kstat.dk_drive_wblk[3],
222 kstat.pgpgin,
223 kstat.pgpgout,
224 kstat.pswpin,
225 kstat.pswpout,
226 sum);
227 for (i = 0 ; i < NR_IRQS ; i++)
228 len += sprintf(buffer + len, " %u", kstat.interrupts[i]);
229 len += sprintf(buffer + len,
230 "\nctxt %u\n"
231 "btime %lu\n"
232 "processes %lu\n",
233 kstat.context_swtch,
234 xtime.tv_sec - jiffies / HZ,
235 total_forks);
236 return len;
237 }
238
239
240 static int get_uptime(char * buffer)
241 {
242 unsigned long uptime;
243 unsigned long idle;
244
245 uptime = jiffies;
246 idle = task[0]->utime + task[0]->stime;
247
248
249
250
251
252
253
254
255
256
257 #if HZ!=100
258 return sprintf(buffer,"%lu.%02lu %lu.%02lu\n",
259 uptime / HZ,
260 (((uptime % HZ) * 100) / HZ) % 100,
261 idle / HZ,
262 (((idle % HZ) * 100) / HZ) % 100);
263 #else
264 return sprintf(buffer,"%lu.%02lu %lu.%02lu\n",
265 uptime / HZ,
266 uptime % HZ,
267 idle / HZ,
268 idle % HZ);
269 #endif
270 }
271
272 static int get_meminfo(char * buffer)
273 {
274 struct sysinfo i;
275 int len;
276
277 si_meminfo(&i);
278 si_swapinfo(&i);
279 len = sprintf(buffer, " total: used: free: shared: buffers: cached:\n"
280 "Mem: %8lu %8lu %8lu %8lu %8lu %8lu\n"
281 "Swap: %8lu %8lu %8lu\n",
282 i.totalram, i.totalram-i.freeram, i.freeram, i.sharedram, i.bufferram, page_cache_size*PAGE_SIZE,
283 i.totalswap, i.totalswap-i.freeswap, i.freeswap);
284
285
286
287
288 return len + sprintf(buffer+len,
289 "MemTotal: %8lu kB\n"
290 "MemFree: %8lu kB\n"
291 "MemShared: %8lu kB\n"
292 "Buffers: %8lu kB\n"
293 "Cached: %8lu kB\n"
294 "SwapTotal: %8lu kB\n"
295 "SwapFree: %8lu kB\n",
296 i.totalram >> 10,
297 i.freeram >> 10,
298 i.sharedram >> 10,
299 i.bufferram >> 10,
300 page_cache_size << (PAGE_SHIFT - 10),
301 i.totalswap >> 10,
302 i.freeswap >> 10);
303 }
304
305 static int get_version(char * buffer)
306 {
307 extern char *linux_banner;
308
309 strcpy(buffer, linux_banner);
310 return strlen(buffer);
311 }
312
313 static int get_cmdline(char * buffer)
314 {
315 extern char saved_command_line[];
316
317 return sprintf(buffer, "%s\n", saved_command_line);
318 }
319
320 static struct task_struct ** get_task(pid_t pid)
321 {
322 struct task_struct ** p;
323
324 p = task;
325 while (++p < task+NR_TASKS) {
326 if (*p && (*p)->pid == pid)
327 return p;
328 }
329 return NULL;
330 }
331
332 static unsigned long get_phys_addr(struct task_struct * p, unsigned long ptr)
333 {
334 pgd_t *page_dir;
335 pmd_t *page_middle;
336 pte_t pte;
337
338 if (!p || !p->mm || ptr >= TASK_SIZE)
339 return 0;
340 page_dir = pgd_offset(p->mm,ptr);
341 if (pgd_none(*page_dir))
342 return 0;
343 if (pgd_bad(*page_dir)) {
344 printk("bad page directory entry %08lx\n", pgd_val(*page_dir));
345 pgd_clear(page_dir);
346 return 0;
347 }
348 page_middle = pmd_offset(page_dir,ptr);
349 if (pmd_none(*page_middle))
350 return 0;
351 if (pmd_bad(*page_middle)) {
352 printk("bad page middle entry %08lx\n", pmd_val(*page_middle));
353 pmd_clear(page_middle);
354 return 0;
355 }
356 pte = *pte_offset(page_middle,ptr);
357 if (!pte_present(pte))
358 return 0;
359 return pte_page(pte) + (ptr & ~PAGE_MASK);
360 }
361
362 static int get_array(struct task_struct ** p, unsigned long start, unsigned long end, char * buffer)
363 {
364 unsigned long addr;
365 int size = 0, result = 0;
366 char c;
367
368 if (start >= end)
369 return result;
370 for (;;) {
371 addr = get_phys_addr(*p, start);
372 if (!addr)
373 goto ready;
374 do {
375 c = *(char *) addr;
376 if (!c)
377 result = size;
378 if (size < PAGE_SIZE)
379 buffer[size++] = c;
380 else
381 goto ready;
382 addr++;
383 start++;
384 if (!c && start >= end)
385 goto ready;
386 } while (addr & ~PAGE_MASK);
387 }
388 ready:
389
390 while (result>0 && buffer[result-1]==' ')
391 result--;
392 return result;
393 }
394
395 static int get_env(int pid, char * buffer)
396 {
397 struct task_struct ** p = get_task(pid);
398
399 if (!p || !*p || !(*p)->mm)
400 return 0;
401 return get_array(p, (*p)->mm->env_start, (*p)->mm->env_end, buffer);
402 }
403
404 static int get_arg(int pid, char * buffer)
405 {
406 struct task_struct ** p = get_task(pid);
407
408 if (!p || !*p || !(*p)->mm)
409 return 0;
410 return get_array(p, (*p)->mm->arg_start, (*p)->mm->arg_end, buffer);
411 }
412
413 static unsigned long get_wchan(struct task_struct *p)
414 {
415 if (!p || p == current || p->state == TASK_RUNNING)
416 return 0;
417 #if defined(__i386__)
418 {
419 unsigned long ebp, eip;
420 unsigned long stack_page;
421 int count = 0;
422
423 stack_page = p->kernel_stack_page;
424 if (!stack_page)
425 return 0;
426 ebp = p->tss.ebp;
427 do {
428 if (ebp < stack_page || ebp >= 4092+stack_page)
429 return 0;
430 eip = *(unsigned long *) (ebp+4);
431 if ((void *)eip != sleep_on &&
432 (void *)eip != interruptible_sleep_on)
433 return eip;
434 ebp = *(unsigned long *) ebp;
435 } while (count++ < 16);
436 }
437 #elif defined(__alpha__)
438
439
440
441
442
443
444
445
446
447 {
448 unsigned long schedule_frame;
449 unsigned long pc;
450
451 pc = thread_saved_pc(&p->tss);
452 if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) {
453 schedule_frame = ((unsigned long *)p->tss.ksp)[6];
454 return ((unsigned long *)schedule_frame)[12];
455 }
456 return pc;
457 }
458 #endif
459 return 0;
460 }
461
462 #if defined(__i386__)
463 # define KSTK_EIP(tsk) (((unsigned long *)tsk->kernel_stack_page)[1019])
464 # define KSTK_ESP(tsk) (((unsigned long *)tsk->kernel_stack_page)[1022])
465 #elif defined(__alpha__)
466
467
468
469 # define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \
470 + (long)&((struct pt_regs *)0)->reg)
471 # define KSTK_EIP(tsk) (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(pc)))
472 # define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
473 #endif
474
475
476 #define ADDBUF(buffer, string) \
477 do { memcpy(buffer, string, strlen(string)); \
478 buffer += strlen(string); } while (0)
479
480 static inline char * task_name(struct task_struct *p, char * buf)
481 {
482 int i;
483 char * name;
484
485 ADDBUF(buf, "Name:\t");
486 name = p->comm;
487 i = sizeof(p->comm);
488 do {
489 unsigned char c = *name;
490 name++;
491 i--;
492 *buf = c;
493 if (!c)
494 break;
495 if (c == '\\') {
496 buf[1] = c;
497 buf += 2;
498 continue;
499 }
500 if (c == '\n') {
501 buf[0] = '\\';
502 buf[1] = 'n';
503 buf += 2;
504 continue;
505 }
506 buf++;
507 } while (i);
508 *buf = '\n';
509 return buf+1;
510 }
511
512 static inline char * task_state(struct task_struct *p, char *buffer)
513 {
514 #define NR_STATES (sizeof(states)/sizeof(const char *))
515 unsigned int n = p->state;
516 static const char * states[] = {
517 "R (running)",
518 "S (sleeping)",
519 "D (disk sleep)",
520 "Z (zombie)",
521 "T (stopped)",
522 "W (paging)",
523 ". Huh?"
524 };
525
526 if (n >= NR_STATES)
527 n = NR_STATES-1;
528
529 buffer += sprintf(buffer,
530 "State:\t%s\n"
531 "Pid:\t%d\n"
532 "PPid:\t%d\n"
533 "Uid:\t%d\t%d\t%d\t%d\n"
534 "Gid:\t%d\t%d\t%d\t%d\n",
535 states[n],
536 p->pid, p->p_pptr->pid,
537 p->uid, p->euid, p->suid, p->fsuid,
538 p->gid, p->egid, p->sgid, p->fsgid);
539 return buffer;
540 }
541
542 static inline char * task_mem(struct task_struct *p, char *buffer)
543 {
544 struct mm_struct * mm = p->mm;
545
546 if (mm && mm != &init_mm) {
547 struct vm_area_struct * vma = mm->mmap;
548 unsigned long data = 0, stack = 0;
549 unsigned long exec = 0, lib = 0;
550
551 for (vma = mm->mmap; vma; vma = vma->vm_next) {
552 unsigned long len = (vma->vm_end - vma->vm_start) >> 10;
553 if (!vma->vm_inode) {
554 data += len;
555 if (vma->vm_flags & VM_GROWSDOWN)
556 stack += len;
557 continue;
558 }
559 if (vma->vm_flags & VM_WRITE)
560 continue;
561 if (vma->vm_flags & VM_EXEC) {
562 exec += len;
563 if (vma->vm_flags & VM_EXECUTABLE)
564 continue;
565 lib += len;
566 }
567 }
568 buffer += sprintf(buffer,
569 "VmSize:\t%8lu kB\n"
570 "VmLck:\t%8lu kB\n"
571 "VmRSS:\t%8lu kB\n"
572 "VmData:\t%8lu kB\n"
573 "VmStk:\t%8lu kB\n"
574 "VmExe:\t%8lu kB\n"
575 "VmLib:\t%8lu kB\n",
576 mm->total_vm << (PAGE_SHIFT-10),
577 mm->locked_vm << (PAGE_SHIFT-10),
578 mm->rss << (PAGE_SHIFT-10),
579 data - stack, stack,
580 exec - lib, lib);
581 }
582 return buffer;
583 }
584
585 static inline char * task_sig(struct task_struct *p, char *buffer)
586 {
587 buffer += sprintf(buffer,
588 "SigPnd:\t%08lx\n"
589 "SigBlk:\t%08lx\n",
590 p->signal, p->blocked);
591 if (p->sig) {
592 struct sigaction * action = p->sig->action;
593 unsigned long sig_ign = 0, sig_caught = 0;
594 unsigned long bit = 1;
595 int i;
596
597 for (i = 0; i < 32; i++) {
598 switch((unsigned long) action->sa_handler) {
599 case 0:
600 break;
601 case 1:
602 sig_ign |= bit;
603 break;
604 default:
605 sig_caught |= bit;
606 }
607 bit <<= 1;
608 action++;
609 }
610
611 buffer += sprintf(buffer,
612 "SigIgn:\t%08lx\n"
613 "SigCgt:\t%08lx\n",
614 sig_ign, sig_caught);
615 }
616 return buffer;
617 }
618
619 static int get_status(int pid, char * buffer)
620 {
621 char * orig = buffer;
622 struct task_struct ** p = get_task(pid), *tsk;
623
624 if (!p || (tsk = *p) == NULL)
625 return 0;
626 buffer = task_name(tsk, buffer);
627 buffer = task_state(tsk, buffer);
628 buffer = task_mem(tsk, buffer);
629 buffer = task_sig(tsk, buffer);
630 return buffer - orig;
631 }
632
633 static int get_stat(int pid, char * buffer)
634 {
635 struct task_struct ** p = get_task(pid), *tsk;
636 unsigned long sigignore=0, sigcatch=0, wchan;
637 unsigned long vsize, eip, esp;
638 long priority, nice;
639 int i,tty_pgrp;
640 char state;
641
642 if (!p || (tsk = *p) == NULL)
643 return 0;
644 if (tsk->state < 0 || tsk->state > 5)
645 state = '.';
646 else
647 state = "RSDZTW"[tsk->state];
648 vsize = eip = esp = 0;
649 if (tsk->mm && tsk->mm != &init_mm) {
650 struct vm_area_struct *vma = tsk->mm->mmap;
651 while (vma) {
652 vsize += vma->vm_end - vma->vm_start;
653 vma = vma->vm_next;
654 }
655 if (tsk->kernel_stack_page) {
656 eip = KSTK_EIP(tsk);
657 esp = KSTK_ESP(tsk);
658 }
659 }
660 wchan = get_wchan(tsk);
661 if (tsk->sig) {
662 unsigned long bit = 1;
663 for(i=0; i<32; ++i) {
664 switch((unsigned long) tsk->sig->action[i].sa_handler) {
665 case 0:
666 break;
667 case 1:
668 sigignore |= bit;
669 break;
670 default:
671 sigcatch |= bit;
672 }
673 bit <<= 1;
674 }
675 }
676 if (tsk->tty)
677 tty_pgrp = tsk->tty->pgrp;
678 else
679 tty_pgrp = -1;
680
681
682
683 priority = tsk->counter;
684 priority = 20 - (priority * 10 + DEF_PRIORITY / 2) / DEF_PRIORITY;
685 nice = tsk->priority;
686 nice = 20 - (nice * 20 + DEF_PRIORITY / 2) / DEF_PRIORITY;
687
688 return sprintf(buffer,"%d (%s) %c %d %d %d %d %d %lu %lu \
689 %lu %lu %lu %ld %ld %ld %ld %ld %ld %lu %lu %ld %lu %lu %lu %lu %lu %lu %lu %lu %lu \
690 %lu %lu %lu %lu\n",
691 pid,
692 tsk->comm,
693 state,
694 tsk->p_pptr->pid,
695 tsk->pgrp,
696 tsk->session,
697 tsk->tty ? kdev_t_to_nr(tsk->tty->device) : 0,
698 tty_pgrp,
699 tsk->flags,
700 tsk->min_flt,
701 tsk->cmin_flt,
702 tsk->maj_flt,
703 tsk->cmaj_flt,
704 tsk->utime,
705 tsk->stime,
706 tsk->cutime,
707 tsk->cstime,
708 priority,
709 nice,
710 tsk->timeout,
711 tsk->it_real_value,
712 tsk->start_time,
713 vsize,
714 tsk->mm ? tsk->mm->rss : 0,
715 tsk->rlim ? tsk->rlim[RLIMIT_RSS].rlim_cur : 0,
716 tsk->mm ? tsk->mm->start_code : 0,
717 tsk->mm ? tsk->mm->end_code : 0,
718 tsk->mm ? tsk->mm->start_stack : 0,
719 esp,
720 eip,
721 tsk->signal,
722 tsk->blocked,
723 sigignore,
724 sigcatch,
725 wchan);
726 }
727
728 static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size,
729 int * pages, int * shared, int * dirty, int * total)
730 {
731 pte_t * pte;
732 unsigned long end;
733
734 if (pmd_none(*pmd))
735 return;
736 if (pmd_bad(*pmd)) {
737 printk("statm_pte_range: bad pmd (%08lx)\n", pmd_val(*pmd));
738 pmd_clear(pmd);
739 return;
740 }
741 pte = pte_offset(pmd, address);
742 address &= ~PMD_MASK;
743 end = address + size;
744 if (end > PMD_SIZE)
745 end = PMD_SIZE;
746 do {
747 pte_t page = *pte;
748
749 address += PAGE_SIZE;
750 pte++;
751 if (pte_none(page))
752 continue;
753 ++*total;
754 if (!pte_present(page))
755 continue;
756 ++*pages;
757 if (pte_dirty(page))
758 ++*dirty;
759 if (pte_page(page) >= high_memory)
760 continue;
761 if (mem_map[MAP_NR(pte_page(page))].count > 1)
762 ++*shared;
763 } while (address < end);
764 }
765
766 static inline void statm_pmd_range(pgd_t * pgd, unsigned long address, unsigned long size,
767 int * pages, int * shared, int * dirty, int * total)
768 {
769 pmd_t * pmd;
770 unsigned long end;
771
772 if (pgd_none(*pgd))
773 return;
774 if (pgd_bad(*pgd)) {
775 printk("statm_pmd_range: bad pgd (%08lx)\n", pgd_val(*pgd));
776 pgd_clear(pgd);
777 return;
778 }
779 pmd = pmd_offset(pgd, address);
780 address &= ~PGDIR_MASK;
781 end = address + size;
782 if (end > PGDIR_SIZE)
783 end = PGDIR_SIZE;
784 do {
785 statm_pte_range(pmd, address, end - address, pages, shared, dirty, total);
786 address = (address + PMD_SIZE) & PMD_MASK;
787 pmd++;
788 } while (address < end);
789 }
790
791 static void statm_pgd_range(pgd_t * pgd, unsigned long address, unsigned long end,
792 int * pages, int * shared, int * dirty, int * total)
793 {
794 while (address < end) {
795 statm_pmd_range(pgd, address, end - address, pages, shared, dirty, total);
796 address = (address + PGDIR_SIZE) & PGDIR_MASK;
797 pgd++;
798 }
799 }
800
801 static int get_statm(int pid, char * buffer)
802 {
803 struct task_struct ** p = get_task(pid), *tsk;
804 int size=0, resident=0, share=0, trs=0, lrs=0, drs=0, dt=0;
805
806 if (!p || (tsk = *p) == NULL)
807 return 0;
808 if (tsk->mm && tsk->mm != &init_mm) {
809 struct vm_area_struct * vma = tsk->mm->mmap;
810
811 while (vma) {
812 pgd_t *pgd = pgd_offset(tsk->mm, vma->vm_start);
813 int pages = 0, shared = 0, dirty = 0, total = 0;
814
815 statm_pgd_range(pgd, vma->vm_start, vma->vm_end, &pages, &shared, &dirty, &total);
816 resident += pages;
817 share += shared;
818 dt += dirty;
819 size += total;
820 if (vma->vm_flags & VM_EXECUTABLE)
821 trs += pages;
822 else if (vma->vm_flags & VM_GROWSDOWN)
823 drs += pages;
824 else if (vma->vm_end > 0x60000000)
825 lrs += pages;
826 else
827 drs += pages;
828 vma = vma->vm_next;
829 }
830 }
831 return sprintf(buffer,"%d %d %d %d %d %d %d\n",
832 size, resident, share, trs, lrs, drs, dt);
833 }
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851 #define MAPS_LINE_LENGTH 1024
852 #define MAPS_LINE_SHIFT 10
853
854
855
856
857 #define MAPS_LINE_FORMAT "%08lx-%08lx %s %08lx %s %lu\n"
858 #define MAPS_LINE_MAX 49
859
860 static int read_maps (int pid, struct file * file, char * buf, int count)
861 {
862 struct task_struct ** p = get_task(pid);
863 char * destptr;
864 loff_t lineno;
865 int column;
866 struct vm_area_struct * map;
867 int i;
868
869 if (!p || !*p)
870 return -EINVAL;
871
872 if (!(*p)->mm || (*p)->mm == &init_mm || count == 0)
873 return 0;
874
875
876 lineno = file->f_pos >> MAPS_LINE_SHIFT;
877 column = file->f_pos & (MAPS_LINE_LENGTH-1);
878
879
880 for (map = (*p)->mm->mmap, i = 0; map && (i < lineno); map = map->vm_next, i++)
881 continue;
882
883 destptr = buf;
884
885 for ( ; map ; ) {
886
887 char line[MAPS_LINE_MAX+1];
888 char str[5], *cp = str;
889 int flags;
890 kdev_t dev;
891 unsigned long ino;
892 int len;
893
894 flags = map->vm_flags;
895
896 *cp++ = flags & VM_READ ? 'r' : '-';
897 *cp++ = flags & VM_WRITE ? 'w' : '-';
898 *cp++ = flags & VM_EXEC ? 'x' : '-';
899 *cp++ = flags & VM_MAYSHARE ? 's' : 'p';
900 *cp++ = 0;
901
902 if (map->vm_inode != NULL) {
903 dev = map->vm_inode->i_dev;
904 ino = map->vm_inode->i_ino;
905 } else {
906 dev = 0;
907 ino = 0;
908 }
909
910 len = sprintf(line, MAPS_LINE_FORMAT,
911 map->vm_start, map->vm_end, str, map->vm_offset,
912 kdevname(dev), ino);
913
914 if (column >= len) {
915 column = 0;
916 lineno++;
917 map = map->vm_next;
918 continue;
919 }
920
921 i = len-column;
922 if (i > count)
923 i = count;
924 memcpy_tofs(destptr, line+column, i);
925 destptr += i; count -= i;
926 column += i;
927 if (column >= len) {
928 column = 0;
929 lineno++;
930 map = map->vm_next;
931 }
932
933
934 if (count == 0)
935 break;
936
937
938
939
940 if (*p != current)
941 break;
942 }
943
944
945 file->f_pos = (lineno << MAPS_LINE_SHIFT) + column;
946
947 return destptr-buf;
948 }
949
950 #ifdef CONFIG_MODULES
951 extern int get_module_list(char *);
952 extern int get_ksyms_list(char *, char **, off_t, int);
953 #endif
954 extern int get_device_list(char *);
955 extern int get_filesystem_list(char *);
956 extern int get_filesystem_info( char * );
957 extern int get_irq_list(char *);
958 extern int get_dma_list(char *);
959 extern int get_cpuinfo(char *);
960 extern int get_pci_list(char*);
961 extern int get_md_status (char *);
962 extern int get_rtc_status (char *);
963 #ifdef __SMP_PROF__
964 extern int get_smp_prof_list(char *);
965 #endif
966
967 static int get_root_array(char * page, int type, char **start, off_t offset, int length)
968 {
969 switch (type) {
970 case PROC_LOADAVG:
971 return get_loadavg(page);
972
973 case PROC_UPTIME:
974 return get_uptime(page);
975
976 case PROC_MEMINFO:
977 return get_meminfo(page);
978
979 #ifdef CONFIG_PCI
980 case PROC_PCI:
981 return get_pci_list(page);
982 #endif
983
984 case PROC_CPUINFO:
985 return get_cpuinfo(page);
986
987 case PROC_VERSION:
988 return get_version(page);
989
990 #ifdef CONFIG_DEBUG_MALLOC
991 case PROC_MALLOC:
992 return get_malloc(page);
993 #endif
994
995 #ifdef CONFIG_MODULES
996 case PROC_MODULES:
997 return get_module_list(page);
998
999 case PROC_KSYMS:
1000 return get_ksyms_list(page, start, offset, length);
1001 #endif
1002
1003 case PROC_STAT:
1004 return get_kstat(page);
1005
1006 case PROC_DEVICES:
1007 return get_device_list(page);
1008
1009 case PROC_INTERRUPTS:
1010 return get_irq_list(page);
1011
1012 case PROC_FILESYSTEMS:
1013 return get_filesystem_list(page);
1014
1015 case PROC_DMA:
1016 return get_dma_list(page);
1017
1018 case PROC_IOPORTS:
1019 return get_ioport_list(page);
1020 #ifdef CONFIG_BLK_DEV_MD
1021 case PROC_MD:
1022 return get_md_status(page);
1023 #endif
1024 #ifdef __SMP_PROF__
1025 case PROC_SMP_PROF:
1026 return get_smp_prof_list(page);
1027 #endif
1028 case PROC_CMDLINE:
1029 return get_cmdline(page);
1030
1031 case PROC_MTAB:
1032 return get_filesystem_info( page );
1033 #ifdef CONFIG_RTC
1034 case PROC_RTC:
1035 return get_rtc_status(page);
1036 #endif
1037 }
1038 return -EBADF;
1039 }
1040
1041 static int get_process_array(char * page, int pid, int type)
1042 {
1043 switch (type) {
1044 case PROC_PID_STATUS:
1045 return get_status(pid, page);
1046 case PROC_PID_ENVIRON:
1047 return get_env(pid, page);
1048 case PROC_PID_CMDLINE:
1049 return get_arg(pid, page);
1050 case PROC_PID_STAT:
1051 return get_stat(pid, page);
1052 case PROC_PID_STATM:
1053 return get_statm(pid, page);
1054 }
1055 return -EBADF;
1056 }
1057
1058
1059 static inline int fill_array(char * page, int pid, int type, char **start, off_t offset, int length)
1060 {
1061 if (pid)
1062 return get_process_array(page, pid, type);
1063 return get_root_array(page, type, start, offset, length);
1064 }
1065
1066 #define PROC_BLOCK_SIZE (3*1024)
1067
1068 static int array_read(struct inode * inode, struct file * file,char * buf, int count)
1069 {
1070 unsigned long page;
1071 char *start;
1072 int length;
1073 int end;
1074 unsigned int type, pid;
1075 struct proc_dir_entry *dp;
1076
1077 if (count < 0)
1078 return -EINVAL;
1079 if (count > PROC_BLOCK_SIZE)
1080 count = PROC_BLOCK_SIZE;
1081 if (!(page = __get_free_page(GFP_KERNEL)))
1082 return -ENOMEM;
1083 type = inode->i_ino;
1084 pid = type >> 16;
1085 type &= 0x0000ffff;
1086 start = NULL;
1087 dp = (struct proc_dir_entry *) inode->u.generic_ip;
1088 if (dp->get_info)
1089 length = dp->get_info((char *)page, &start, file->f_pos,
1090 count, 0);
1091 else
1092 length = fill_array((char *) page, pid, type,
1093 &start, file->f_pos, count);
1094 if (length < 0) {
1095 free_page(page);
1096 return length;
1097 }
1098 if (start != NULL) {
1099
1100 memcpy_tofs(buf, start, length);
1101 file->f_pos += length;
1102 count = length;
1103 } else {
1104
1105 if (file->f_pos >= length) {
1106 free_page(page);
1107 return 0;
1108 }
1109 if (count + file->f_pos > length)
1110 count = length - file->f_pos;
1111 end = count + file->f_pos;
1112 memcpy_tofs(buf, (char *) page + file->f_pos, count);
1113 file->f_pos = end;
1114 }
1115 free_page(page);
1116 return count;
1117 }
1118
1119 static struct file_operations proc_array_operations = {
1120 NULL,
1121 array_read,
1122 NULL,
1123 NULL,
1124 NULL,
1125 NULL,
1126 NULL,
1127 NULL,
1128 NULL,
1129 NULL
1130 };
1131
1132 struct inode_operations proc_array_inode_operations = {
1133 &proc_array_operations,
1134 NULL,
1135 NULL,
1136 NULL,
1137 NULL,
1138 NULL,
1139 NULL,
1140 NULL,
1141 NULL,
1142 NULL,
1143 NULL,
1144 NULL,
1145 NULL,
1146 NULL,
1147 NULL,
1148 NULL,
1149 NULL
1150 };
1151
1152 static int arraylong_read (struct inode * inode, struct file * file, char * buf, int count)
1153 {
1154 unsigned int pid = inode->i_ino >> 16;
1155 unsigned int type = inode->i_ino & 0x0000ffff;
1156
1157 if (count < 0)
1158 return -EINVAL;
1159
1160 switch (type) {
1161 case PROC_PID_MAPS:
1162 return read_maps(pid, file, buf, count);
1163 }
1164 return -EINVAL;
1165 }
1166
1167 static struct file_operations proc_arraylong_operations = {
1168 NULL,
1169 arraylong_read,
1170 NULL,
1171 NULL,
1172 NULL,
1173 NULL,
1174 NULL,
1175 NULL,
1176 NULL,
1177 NULL
1178 };
1179
1180 struct inode_operations proc_arraylong_inode_operations = {
1181 &proc_arraylong_operations,
1182 NULL,
1183 NULL,
1184 NULL,
1185 NULL,
1186 NULL,
1187 NULL,
1188 NULL,
1189 NULL,
1190 NULL,
1191 NULL,
1192 NULL,
1193 NULL,
1194 NULL,
1195 NULL,
1196 NULL,
1197 NULL
1198 };