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 #ifdef __SMP_PROF__
963 extern int get_smp_prof_list(char *);
964 #endif
965
966 static int get_root_array(char * page, int type, char **start, off_t offset, int length)
967 {
968 switch (type) {
969 case PROC_LOADAVG:
970 return get_loadavg(page);
971
972 case PROC_UPTIME:
973 return get_uptime(page);
974
975 case PROC_MEMINFO:
976 return get_meminfo(page);
977
978 #ifdef CONFIG_PCI
979 case PROC_PCI:
980 return get_pci_list(page);
981 #endif
982
983 case PROC_CPUINFO:
984 return get_cpuinfo(page);
985
986 case PROC_VERSION:
987 return get_version(page);
988
989 #ifdef CONFIG_DEBUG_MALLOC
990 case PROC_MALLOC:
991 return get_malloc(page);
992 #endif
993
994 #ifdef CONFIG_MODULES
995 case PROC_MODULES:
996 return get_module_list(page);
997
998 case PROC_KSYMS:
999 return get_ksyms_list(page, start, offset, length);
1000 #endif
1001
1002 case PROC_STAT:
1003 return get_kstat(page);
1004
1005 case PROC_DEVICES:
1006 return get_device_list(page);
1007
1008 case PROC_INTERRUPTS:
1009 return get_irq_list(page);
1010
1011 case PROC_FILESYSTEMS:
1012 return get_filesystem_list(page);
1013
1014 case PROC_DMA:
1015 return get_dma_list(page);
1016
1017 case PROC_IOPORTS:
1018 return get_ioport_list(page);
1019 #ifdef CONFIG_BLK_DEV_MD
1020 case PROC_MD:
1021 return get_md_status(page);
1022 #endif
1023 #ifdef __SMP_PROF__
1024 case PROC_SMP_PROF:
1025 return get_smp_prof_list(page);
1026 #endif
1027 case PROC_CMDLINE:
1028 return get_cmdline(page);
1029
1030 case PROC_MTAB:
1031 return get_filesystem_info( page );
1032 }
1033 return -EBADF;
1034 }
1035
1036 static int get_process_array(char * page, int pid, int type)
1037 {
1038 switch (type) {
1039 case PROC_PID_STATUS:
1040 return get_status(pid, page);
1041 case PROC_PID_ENVIRON:
1042 return get_env(pid, page);
1043 case PROC_PID_CMDLINE:
1044 return get_arg(pid, page);
1045 case PROC_PID_STAT:
1046 return get_stat(pid, page);
1047 case PROC_PID_STATM:
1048 return get_statm(pid, page);
1049 }
1050 return -EBADF;
1051 }
1052
1053
1054 static inline int fill_array(char * page, int pid, int type, char **start, off_t offset, int length)
1055 {
1056 if (pid)
1057 return get_process_array(page, pid, type);
1058 return get_root_array(page, type, start, offset, length);
1059 }
1060
1061 #define PROC_BLOCK_SIZE (3*1024)
1062
1063 static int array_read(struct inode * inode, struct file * file,char * buf, int count)
1064 {
1065 unsigned long page;
1066 char *start;
1067 int length;
1068 int end;
1069 unsigned int type, pid;
1070 struct proc_dir_entry *dp;
1071
1072 if (count < 0)
1073 return -EINVAL;
1074 if (count > PROC_BLOCK_SIZE)
1075 count = PROC_BLOCK_SIZE;
1076 if (!(page = __get_free_page(GFP_KERNEL)))
1077 return -ENOMEM;
1078 type = inode->i_ino;
1079 pid = type >> 16;
1080 type &= 0x0000ffff;
1081 start = NULL;
1082 dp = (struct proc_dir_entry *) inode->u.generic_ip;
1083 if (dp->get_info)
1084 length = dp->get_info((char *)page, &start, file->f_pos,
1085 count, 0);
1086 else
1087 length = fill_array((char *) page, pid, type,
1088 &start, file->f_pos, count);
1089 if (length < 0) {
1090 free_page(page);
1091 return length;
1092 }
1093 if (start != NULL) {
1094
1095 memcpy_tofs(buf, start, length);
1096 file->f_pos += length;
1097 count = length;
1098 } else {
1099
1100 if (file->f_pos >= length) {
1101 free_page(page);
1102 return 0;
1103 }
1104 if (count + file->f_pos > length)
1105 count = length - file->f_pos;
1106 end = count + file->f_pos;
1107 memcpy_tofs(buf, (char *) page + file->f_pos, count);
1108 file->f_pos = end;
1109 }
1110 free_page(page);
1111 return count;
1112 }
1113
1114 static struct file_operations proc_array_operations = {
1115 NULL,
1116 array_read,
1117 NULL,
1118 NULL,
1119 NULL,
1120 NULL,
1121 NULL,
1122 NULL,
1123 NULL,
1124 NULL
1125 };
1126
1127 struct inode_operations proc_array_inode_operations = {
1128 &proc_array_operations,
1129 NULL,
1130 NULL,
1131 NULL,
1132 NULL,
1133 NULL,
1134 NULL,
1135 NULL,
1136 NULL,
1137 NULL,
1138 NULL,
1139 NULL,
1140 NULL,
1141 NULL,
1142 NULL,
1143 NULL,
1144 NULL
1145 };
1146
1147 static int arraylong_read (struct inode * inode, struct file * file, char * buf, int count)
1148 {
1149 unsigned int pid = inode->i_ino >> 16;
1150 unsigned int type = inode->i_ino & 0x0000ffff;
1151
1152 if (count < 0)
1153 return -EINVAL;
1154
1155 switch (type) {
1156 case PROC_PID_MAPS:
1157 return read_maps(pid, file, buf, count);
1158 }
1159 return -EINVAL;
1160 }
1161
1162 static struct file_operations proc_arraylong_operations = {
1163 NULL,
1164 arraylong_read,
1165 NULL,
1166 NULL,
1167 NULL,
1168 NULL,
1169 NULL,
1170 NULL,
1171 NULL,
1172 NULL
1173 };
1174
1175 struct inode_operations proc_arraylong_inode_operations = {
1176 &proc_arraylong_operations,
1177 NULL,
1178 NULL,
1179 NULL,
1180 NULL,
1181 NULL,
1182 NULL,
1183 NULL,
1184 NULL,
1185 NULL,
1186 NULL,
1187 NULL,
1188 NULL,
1189 NULL,
1190 NULL,
1191 NULL,
1192 NULL
1193 };