Import 2.3.26pre2
[davej-history.git] / fs / proc / proc_misc.c
blob7826d9fa913de4750c6614dbb38e3ff2ec54b5c6
1 /*
2 * linux/fs/proc/proc_misc.c
4 * linux/fs/proc/array.c
5 * Copyright (C) 1992 by Linus Torvalds
6 * based on ideas by Darren Senn
8 * This used to be the part of array.c. See the rest of history and credits
9 * there. I took this into a separate file and switched the thing to generic
10 * proc_file_inode_operations, leaving in array.c only per-process stuff.
11 * Inumbers allocation made dynamic (via create_proc_entry()). AV, May 1999.
14 #include <linux/types.h>
15 #include <linux/errno.h>
16 #include <linux/sched.h>
17 #include <linux/kernel.h>
18 #include <linux/kernel_stat.h>
19 #include <linux/tty.h>
20 #include <linux/user.h>
21 #include <linux/a.out.h>
22 #include <linux/string.h>
23 #include <linux/mman.h>
24 #include <linux/proc_fs.h>
25 #include <linux/ioport.h>
26 #include <linux/config.h>
27 #include <linux/mm.h>
28 #include <linux/pagemap.h>
29 #include <linux/swap.h>
30 #include <linux/slab.h>
31 #include <linux/smp.h>
32 #include <linux/signal.h>
34 #include <asm/uaccess.h>
35 #include <asm/pgtable.h>
36 #include <asm/io.h>
39 #define LOAD_INT(x) ((x) >> FSHIFT)
40 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
42 * Warning: stuff below (imported functions) assumes that its output will fit
43 * into one page. For some of those functions it may be wrong. Moreover, we
44 * have a way to deal with that gracefully. Right now I used straightforward
45 * wrappers, but this needs further analysis wrt potential overflows.
47 extern int get_cpuinfo(char *);
48 extern int get_hardware_list(char *);
49 extern int get_stram_list(char *);
50 #ifdef CONFIG_DEBUG_MALLOC
51 extern int get_malloc(char * buffer);
52 #endif
53 #ifdef CONFIG_MODULES
54 extern int get_module_list(char *);
55 extern int get_ksyms_list(char *, char **, off_t, int);
56 #endif
57 extern int get_device_list(char *);
58 extern int get_partition_list(char *);
59 extern int get_filesystem_list(char *);
60 extern int get_filesystem_info(char *);
61 extern int get_exec_domain_list(char *);
62 extern int get_irq_list(char *);
63 extern int get_dma_list(char *);
64 extern int get_rtc_status (char *);
65 extern int get_locks_status (char *, char **, off_t, int);
66 extern int get_swaparea_info (char *);
67 #ifdef CONFIG_SGI_DS1286
68 extern int get_ds1286_status(char *);
69 #endif
71 static int loadavg_read_proc(char *page, char **start, off_t off,
72 int count, int *eof, void *data)
74 int a, b, c;
75 int len;
77 a = avenrun[0] + (FIXED_1/200);
78 b = avenrun[1] + (FIXED_1/200);
79 c = avenrun[2] + (FIXED_1/200);
80 len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
81 LOAD_INT(a), LOAD_FRAC(a),
82 LOAD_INT(b), LOAD_FRAC(b),
83 LOAD_INT(c), LOAD_FRAC(c),
84 nr_running, nr_threads, last_pid);
85 if (len <= off+count) *eof = 1;
86 *start = page + off;
87 len -= off;
88 if (len>count) len = count;
89 if (len<0) len = 0;
90 return len;
93 static int uptime_read_proc(char *page, char **start, off_t off,
94 int count, int *eof, void *data)
96 unsigned long uptime;
97 unsigned long idle;
98 int len;
100 uptime = jiffies;
101 idle = init_tasks[0]->times.tms_utime + init_tasks[0]->times.tms_stime;
103 /* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but
104 that would overflow about every five days at HZ == 100.
105 Therefore the identity a = (a / b) * b + a % b is used so that it is
106 calculated as (((t / HZ) * 100) + ((t % HZ) * 100) / HZ) % 100.
107 The part in front of the '+' always evaluates as 0 (mod 100). All divisions
108 in the above formulas are truncating. For HZ being a power of 10, the
109 calculations simplify to the version in the #else part (if the printf
110 format is adapted to the same number of digits as zeroes in HZ.
112 #if HZ!=100
113 len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
114 uptime / HZ,
115 (((uptime % HZ) * 100) / HZ) % 100,
116 idle / HZ,
117 (((idle % HZ) * 100) / HZ) % 100);
118 #else
119 len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
120 uptime / HZ,
121 uptime % HZ,
122 idle / HZ,
123 idle % HZ);
124 #endif
125 if (len <= off+count) *eof = 1;
126 *start = page + off;
127 len -= off;
128 if (len>count) len = count;
129 if (len<0) len = 0;
130 return len;
133 static int meminfo_read_proc(char *page, char **start, off_t off,
134 int count, int *eof, void *data)
136 struct sysinfo i;
137 int len;
140 * display in kilobytes.
142 #define K(x) ((x) << (PAGE_SHIFT - 10))
143 #define B(x) ((x) << PAGE_SHIFT)
144 si_meminfo(&i);
145 si_swapinfo(&i);
146 len = sprintf(page, " total: used: free: shared: buffers: cached:\n"
147 "Mem: %8lu %8lu %8lu %8lu %8lu %8u\n"
148 "Swap: %8lu %8lu %8lu\n",
149 B(i.totalram), B(i.totalram-i.freeram), B(i.freeram),
150 B(i.sharedram), B(i.bufferram),
151 B(atomic_read(&page_cache_size)), B(i.totalswap),
152 B(i.totalswap-i.freeswap), B(i.freeswap));
154 * Tagged format, for easy grepping and expansion.
155 * The above will go away eventually, once the tools
156 * have been updated.
158 len += sprintf(page+len,
159 "MemTotal: %8lu kB\n"
160 "MemFree: %8lu kB\n"
161 "MemShared: %8lu kB\n"
162 "Buffers: %8lu kB\n"
163 "Cached: %8u kB\n"
164 "HighTotal: %8lu kB\n"
165 "HighFree: %8lu kB\n"
166 "SwapTotal: %8lu kB\n"
167 "SwapFree: %8lu kB\n",
168 K(i.totalram),
169 K(i.freeram),
170 K(i.sharedram),
171 K(i.bufferram),
172 K(atomic_read(&page_cache_size)),
173 K(i.totalhigh),
174 K(i.freehigh),
175 K(i.totalswap),
176 K(i.freeswap));
178 if (len <= off+count) *eof = 1;
179 *start = page + off;
180 len -= off;
181 if (len>count) len = count;
182 if (len<0) len = 0;
183 return len;
184 #undef B
185 #undef K
188 static int version_read_proc(char *page, char **start, off_t off,
189 int count, int *eof, void *data)
191 extern char *linux_banner;
192 int len;
194 strcpy(page, linux_banner);
195 len = strlen(page);
196 if (len <= off+count) *eof = 1;
197 *start = page + off;
198 len -= off;
199 if (len>count) len = count;
200 if (len<0) len = 0;
201 return len;
204 static int cpuinfo_read_proc(char *page, char **start, off_t off,
205 int count, int *eof, void *data)
207 int len = get_cpuinfo(page);
208 if (len <= off+count) *eof = 1;
209 *start = page + off;
210 len -= off;
211 if (len>count) len = count;
212 if (len<0) len = 0;
213 return len;
216 #ifdef CONFIG_PROC_HARDWARE
217 static int hardware_read_proc(char *page, char **start, off_t off,
218 int count, int *eof, void *data)
220 int len = get_hardware_list(page);
221 if (len <= off+count) *eof = 1;
222 *start = page + off;
223 len -= off;
224 if (len>count) len = count;
225 if (len<0) len = 0;
226 return len;
228 #endif
230 #ifdef CONFIG_STRAM_PROC
231 static int stram_read_proc(char *page, char **start, off_t off,
232 int count, int *eof, void *data)
234 int len = get_stram_list(page);
235 if (len <= off+count) *eof = 1;
236 *start = page + off;
237 len -= off;
238 if (len>count) len = count;
239 if (len<0) len = 0;
240 return len;
242 #endif
244 #ifdef CONFIG_DEBUG_MALLOC
245 static int malloc_read_proc(char *page, char **start, off_t off,
246 int count, int *eof, void *data)
248 int len = get_malloc(page);
249 if (len <= off+count) *eof = 1;
250 *start = page + off;
251 len -= off;
252 if (len>count) len = count;
253 if (len<0) len = 0;
254 return len;
256 #endif
258 #ifdef CONFIG_MODULES
259 static int modules_read_proc(char *page, char **start, off_t off,
260 int count, int *eof, void *data)
262 int len = get_module_list(page);
263 if (len <= off+count) *eof = 1;
264 *start = page + off;
265 len -= off;
266 if (len>count) len = count;
267 if (len<0) len = 0;
268 return len;
271 static int ksyms_read_proc(char *page, char **start, off_t off,
272 int count, int *eof, void *data)
274 int len = get_ksyms_list(page, start, off, count);
275 if (len < count) *eof = 1;
276 return len;
278 #endif
280 static int kstat_read_proc(char *page, char **start, off_t off,
281 int count, int *eof, void *data)
283 int i, len;
284 unsigned sum = 0;
285 extern unsigned long total_forks;
286 unsigned long jif = jiffies;
288 for (i = 0 ; i < NR_IRQS ; i++)
289 sum += kstat_irqs(i);
291 #ifdef __SMP__
292 len = sprintf(page,
293 "cpu %u %u %u %lu\n",
294 kstat.cpu_user,
295 kstat.cpu_nice,
296 kstat.cpu_system,
297 jif*smp_num_cpus - (kstat.cpu_user + kstat.cpu_nice + kstat.cpu_system));
298 for (i = 0 ; i < smp_num_cpus; i++)
299 len += sprintf(page + len, "cpu%d %u %u %u %lu\n",
301 kstat.per_cpu_user[cpu_logical_map(i)],
302 kstat.per_cpu_nice[cpu_logical_map(i)],
303 kstat.per_cpu_system[cpu_logical_map(i)],
304 jif - ( kstat.per_cpu_user[cpu_logical_map(i)] \
305 + kstat.per_cpu_nice[cpu_logical_map(i)] \
306 + kstat.per_cpu_system[cpu_logical_map(i)]));
307 len += sprintf(page + len,
308 "disk %u %u %u %u\n"
309 "disk_rio %u %u %u %u\n"
310 "disk_wio %u %u %u %u\n"
311 "disk_rblk %u %u %u %u\n"
312 "disk_wblk %u %u %u %u\n"
313 "page %u %u\n"
314 "swap %u %u\n"
315 "intr %u",
316 #else
317 len = sprintf(page,
318 "cpu %u %u %u %lu\n"
319 "disk %u %u %u %u\n"
320 "disk_rio %u %u %u %u\n"
321 "disk_wio %u %u %u %u\n"
322 "disk_rblk %u %u %u %u\n"
323 "disk_wblk %u %u %u %u\n"
324 "page %u %u\n"
325 "swap %u %u\n"
326 "intr %u",
327 kstat.cpu_user,
328 kstat.cpu_nice,
329 kstat.cpu_system,
330 jif*smp_num_cpus - (kstat.cpu_user + kstat.cpu_nice + kstat.cpu_system),
331 #endif
332 kstat.dk_drive[0], kstat.dk_drive[1],
333 kstat.dk_drive[2], kstat.dk_drive[3],
334 kstat.dk_drive_rio[0], kstat.dk_drive_rio[1],
335 kstat.dk_drive_rio[2], kstat.dk_drive_rio[3],
336 kstat.dk_drive_wio[0], kstat.dk_drive_wio[1],
337 kstat.dk_drive_wio[2], kstat.dk_drive_wio[3],
338 kstat.dk_drive_rblk[0], kstat.dk_drive_rblk[1],
339 kstat.dk_drive_rblk[2], kstat.dk_drive_rblk[3],
340 kstat.dk_drive_wblk[0], kstat.dk_drive_wblk[1],
341 kstat.dk_drive_wblk[2], kstat.dk_drive_wblk[3],
342 kstat.pgpgin,
343 kstat.pgpgout,
344 kstat.pswpin,
345 kstat.pswpout,
346 sum);
347 for (i = 0 ; i < NR_IRQS ; i++)
348 len += sprintf(page + len, " %u", kstat_irqs(i));
349 len += sprintf(page + len,
350 "\nctxt %u\n"
351 "btime %lu\n"
352 "processes %lu\n",
353 kstat.context_swtch,
354 xtime.tv_sec - jif / HZ,
355 total_forks);
356 if (len <= off+count) *eof = 1;
357 *start = page + off;
358 len -= off;
359 if (len>count) len = count;
360 if (len<0) len = 0;
361 return len;
364 static int devices_read_proc(char *page, char **start, off_t off,
365 int count, int *eof, void *data)
367 int len = get_device_list(page);
368 if (len <= off+count) *eof = 1;
369 *start = page + off;
370 len -= off;
371 if (len>count) len = count;
372 if (len<0) len = 0;
373 return len;
376 static int partitions_read_proc(char *page, char **start, off_t off,
377 int count, int *eof, void *data)
379 int len = get_partition_list(page);
380 if (len <= off+count) *eof = 1;
381 *start = page + off;
382 len -= off;
383 if (len>count) len = count;
384 if (len<0) len = 0;
385 return len;
388 static int interrupts_read_proc(char *page, char **start, off_t off,
389 int count, int *eof, void *data)
391 int len = get_irq_list(page);
392 if (len <= off+count) *eof = 1;
393 *start = page + off;
394 len -= off;
395 if (len>count) len = count;
396 if (len<0) len = 0;
397 return len;
400 static int filesystems_read_proc(char *page, char **start, off_t off,
401 int count, int *eof, void *data)
403 int len = get_filesystem_list(page);
404 if (len <= off+count) *eof = 1;
405 *start = page + off;
406 len -= off;
407 if (len>count) len = count;
408 if (len<0) len = 0;
409 return len;
412 static int dma_read_proc(char *page, char **start, off_t off,
413 int count, int *eof, void *data)
415 int len = get_dma_list(page);
416 if (len <= off+count) *eof = 1;
417 *start = page + off;
418 len -= off;
419 if (len>count) len = count;
420 if (len<0) len = 0;
421 return len;
424 static int ioports_read_proc(char *page, char **start, off_t off,
425 int count, int *eof, void *data)
427 int len = get_ioport_list(page);
428 if (len <= off+count) *eof = 1;
429 *start = page + off;
430 len -= off;
431 if (len>count) len = count;
432 if (len<0) len = 0;
433 return len;
436 static int cmdline_read_proc(char *page, char **start, off_t off,
437 int count, int *eof, void *data)
439 extern char saved_command_line[];
440 int len;
442 len = sprintf(page, "%s\n", saved_command_line);
443 len = strlen(page);
444 if (len <= off+count) *eof = 1;
445 *start = page + off;
446 len -= off;
447 if (len>count) len = count;
448 if (len<0) len = 0;
449 return len;
452 #ifdef CONFIG_RTC
453 static int rtc_read_proc(char *page, char **start, off_t off,
454 int count, int *eof, void *data)
456 int len = get_rtc_status(page);
457 if (len <= off+count) *eof = 1;
458 *start = page + off;
459 len -= off;
460 if (len>count) len = count;
461 if (len<0) len = 0;
462 return len;
464 #endif
466 #ifdef CONFIG_SGI_DS1286
467 static int ds1286_read_proc(char *page, char **start, off_t off,
468 int count, int *eof, void *data)
470 int len = get_ds1286_status(page);
471 if (len <= off+count) *eof = 1;
472 *start = page + off;
473 len -= off;
474 if (len>count) len = count;
475 if (len<0) len = 0;
476 return len;
478 #endif
480 static int locks_read_proc(char *page, char **start, off_t off,
481 int count, int *eof, void *data)
483 int len = get_locks_status(page, start, off, count);
484 if (len < count) *eof = 1;
485 return len;
488 static int mounts_read_proc(char *page, char **start, off_t off,
489 int count, int *eof, void *data)
491 int len = get_filesystem_info(page);
492 if (len <= off+count) *eof = 1;
493 *start = page + off;
494 len -= off;
495 if (len>count) len = count;
496 if (len<0) len = 0;
497 return len;
500 static int execdomains_read_proc(char *page, char **start, off_t off,
501 int count, int *eof, void *data)
503 int len = get_exec_domain_list(page);
504 if (len <= off+count) *eof = 1;
505 *start = page + off;
506 len -= off;
507 if (len>count) len = count;
508 if (len<0) len = 0;
509 return len;
512 static int swaps_read_proc(char *page, char **start, off_t off,
513 int count, int *eof, void *data)
515 int len = get_swaparea_info(page);
516 if (len <= off+count) *eof = 1;
517 *start = page + off;
518 len -= off;
519 if (len>count) len = count;
520 if (len<0) len = 0;
521 return len;
524 static int slabinfo_read_proc(char *page, char **start, off_t off,
525 int count, int *eof, void *data)
527 int len = get_slabinfo(page);
528 if (len <= off+count) *eof = 1;
529 *start = page + off;
530 len -= off;
531 if (len>count) len = count;
532 if (len<0) len = 0;
533 return len;
536 static int memory_read_proc(char *page, char **start, off_t off,
537 int count, int *eof, void *data)
539 int len = get_mem_list(page);
540 if (len <= off+count) *eof = 1;
541 *start = page + off;
542 len -= off;
543 if (len>count) len = count;
544 if (len<0) len = 0;
545 return len;
548 static struct proc_dir_entry proc_root_kmsg = {
549 0, 4, "kmsg",
550 S_IFREG | S_IRUSR, 1, 0, 0,
551 0, &proc_kmsg_inode_operations
553 static struct proc_dir_entry proc_root_kcore = {
554 0, 5, "kcore",
555 S_IFREG | S_IRUSR, 1, 0, 0,
556 0, &proc_kcore_inode_operations
558 static struct proc_dir_entry proc_root_profile = {
559 0, 7, "profile",
560 S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
561 0, &proc_profile_inode_operations
564 void proc_misc_init(void)
566 static struct {
567 char *name;
568 int (*read_proc)(char*,char**,off_t,int,int*,void*);
569 } *p, simple_ones[] = {
570 {"loadavg", loadavg_read_proc},
571 {"uptime", uptime_read_proc},
572 {"meminfo", meminfo_read_proc},
573 {"version", version_read_proc},
574 {"cpuinfo", cpuinfo_read_proc},
575 #ifdef CONFIG_PROC_HARDWARE
576 {"hardware", hardware_read_proc},
577 #endif
578 #ifdef CONFIG_STRAM_PROC
579 {"stram", stram_read_proc},
580 #endif
581 #ifdef CONFIG_DEBUG_MALLOC
582 {"malloc", malloc_read_proc},
583 #endif
584 #ifdef CONFIG_MODULES
585 {"modules", modules_read_proc},
586 {"ksyms", ksyms_read_proc},
587 #endif
588 {"stat", kstat_read_proc},
589 {"devices", devices_read_proc},
590 {"partitions", partitions_read_proc},
591 {"interrupts", interrupts_read_proc},
592 {"filesystems", filesystems_read_proc},
593 {"dma", dma_read_proc},
594 {"ioports", ioports_read_proc},
595 {"cmdline", cmdline_read_proc},
596 #ifdef CONFIG_RTC
597 {"rtc", rtc_read_proc},
598 #endif
599 #ifdef CONFIG_SGI_DS1286
600 {"rtc", ds1286_read_proc},
601 #endif
602 {"locks", locks_read_proc},
603 {"mounts", mounts_read_proc},
604 {"swaps", swaps_read_proc},
605 {"slabinfo", slabinfo_read_proc},
606 {"iomem", memory_read_proc},
607 {"execdomains", execdomains_read_proc},
608 {NULL,NULL}
610 for(p=simple_ones;p->name;p++)
611 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
613 /* And now for trickier ones */
614 proc_register(&proc_root, &proc_root_kmsg);
615 proc_register(&proc_root, &proc_root_kcore);
616 proc_root_kcore.size = (MAP_NR(high_memory) << PAGE_SHIFT) + PAGE_SIZE;
617 if (prof_shift) {
618 proc_register(&proc_root, &proc_root_profile);
619 proc_root_profile.size = (1+prof_len) * sizeof(unsigned int);