make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / fs / proc / proc_misc.c
1 /*
2  *  linux/fs/proc/proc_misc.c
3  *
4  *  linux/fs/proc/array.c
5  *  Copyright (C) 1992  by Linus Torvalds
6  *  based on ideas by Darren Senn
7  *
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.
12  *
13  * Changes:
14  * Fulton Green      :  Encapsulated position metric calculations.
15  *                      <kernel@FultonGreen.com>
16  */
17
18 #include <linux/types.h>
19 #include <linux/errno.h>
20 #include <linux/sched.h>
21 #include <linux/kernel.h>
22 #include <linux/kernel_stat.h>
23 #include <linux/tty.h>
24 #include <linux/string.h>
25 #include <linux/mman.h>
26 #include <linux/proc_fs.h>
27 #include <linux/ioport.h>
28 #include <linux/config.h>
29 #include <linux/mm.h>
30 #include <linux/pagemap.h>
31 #include <linux/swap.h>
32 #include <linux/slab.h>
33 #include <linux/smp.h>
34 #include <linux/signal.h>
35 #include <linux/module.h>
36 #include <linux/init.h>
37 #include <linux/smp_lock.h>
38 #include <linux/seq_file.h>
39
40 #include <asm/uaccess.h>
41 #include <asm/pgtable.h>
42 #include <asm/io.h>
43
44 #define LOAD_INT(x) ((x) >> FSHIFT)
45 #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
46 /*
47  * Warning: stuff below (imported functions) assumes that its output will fit
48  * into one page. For some of those functions it may be wrong. Moreover, we
49  * have a way to deal with that gracefully. Right now I used straightforward
50  * wrappers, but this needs further analysis wrt potential overflows.
51  */
52 extern int get_hardware_list(char *);
53 extern int get_stram_list(char *);
54 #ifdef CONFIG_MODULES
55 extern int get_module_list(char *);
56 #endif
57 extern int get_device_list(char *);
58 extern int get_filesystem_list(char *);
59 extern int get_exec_domain_list(char *);
60 extern int get_irq_list(char *);
61 extern int get_dma_list(char *);
62 extern int get_locks_status (char *, char **, off_t, int);
63 extern int get_swaparea_info (char *);
64 #ifdef CONFIG_SGI_DS1286
65 extern int get_ds1286_status(char *);
66 #endif
67
68 void proc_sprintf(char *page, off_t *off, int *lenp, const char *format, ...)
69 {
70         int len = *lenp;
71         va_list args;
72
73         /* try to only print whole lines */
74         if (len > PAGE_SIZE-512)
75                 return;
76
77         va_start(args, format);
78         len += vsnprintf(page + len, PAGE_SIZE-len, format, args);
79         va_end(args);
80
81         if (len <= *off) {
82                 *off -= len;
83                 len = 0;
84         }
85
86         *lenp = len;
87 }
88
89 static int proc_calc_metrics(char *page, char **start, off_t off,
90                                  int count, int *eof, int len)
91 {
92         if (len <= off+count) *eof = 1;
93         *start = page + off;
94         len -= off;
95         if (len>count) len = count;
96         if (len<0) len = 0;
97         return len;
98 }
99
100 static int loadavg_read_proc(char *page, char **start, off_t off,
101                                  int count, int *eof, void *data)
102 {
103         int a, b, c;
104         int len;
105
106         a = avenrun[0] + (FIXED_1/200);
107         b = avenrun[1] + (FIXED_1/200);
108         c = avenrun[2] + (FIXED_1/200);
109         len = sprintf(page,"%d.%02d %d.%02d %d.%02d %d/%d %d\n",
110                 LOAD_INT(a), LOAD_FRAC(a),
111                 LOAD_INT(b), LOAD_FRAC(b),
112                 LOAD_INT(c), LOAD_FRAC(c),
113                 nr_running, nr_threads, last_pid);
114         return proc_calc_metrics(page, start, off, count, eof, len);
115 }
116
117 static int uptime_read_proc(char *page, char **start, off_t off,
118                                  int count, int *eof, void *data)
119 {
120         unsigned long uptime;
121         unsigned long idle;
122         int len;
123
124         uptime = jiffies;
125         idle = init_tasks[0]->times.tms_utime + init_tasks[0]->times.tms_stime;
126
127         /* The formula for the fraction parts really is ((t * 100) / HZ) % 100, but
128            that would overflow about every five days at HZ == 100.
129            Therefore the identity a = (a / b) * b + a % b is used so that it is
130            calculated as (((t / HZ) * 100) + ((t % HZ) * 100) / HZ) % 100.
131            The part in front of the '+' always evaluates as 0 (mod 100). All divisions
132            in the above formulas are truncating. For HZ being a power of 10, the
133            calculations simplify to the version in the #else part (if the printf
134            format is adapted to the same number of digits as zeroes in HZ.
135          */
136 #if HZ!=100
137         len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
138                 uptime / HZ,
139                 (((uptime % HZ) * 100) / HZ) % 100,
140                 idle / HZ,
141                 (((idle % HZ) * 100) / HZ) % 100);
142 #else
143         len = sprintf(page,"%lu.%02lu %lu.%02lu\n",
144                 uptime / HZ,
145                 uptime % HZ,
146                 idle / HZ,
147                 idle % HZ);
148 #endif
149         return proc_calc_metrics(page, start, off, count, eof, len);
150 }
151
152 static int meminfo_read_proc(char *page, char **start, off_t off,
153                                  int count, int *eof, void *data)
154 {
155         struct sysinfo i;
156         int len;
157         int pg_size ;
158
159 /*
160  * display in kilobytes.
161  */
162 #define K(x) ((x) << (PAGE_SHIFT - 10))
163 #define B(x) ((unsigned long long)(x) << PAGE_SHIFT)
164         si_meminfo(&i);
165         si_swapinfo(&i);
166         pg_size = atomic_read(&page_cache_size) - i.bufferram ;
167
168         len = sprintf(page, "        total:    used:    free:  shared: buffers:  cached:\n"
169                 "Mem:  %8Lu %8Lu %8Lu %8Lu %8Lu %8Lu\n"
170                 "Swap: %8Lu %8Lu %8Lu\n",
171                 B(i.totalram), B(i.totalram-i.freeram), B(i.freeram),
172                 B(i.sharedram), B(i.bufferram),
173                 B(pg_size), B(i.totalswap),
174                 B(i.totalswap-i.freeswap), B(i.freeswap));
175         /*
176          * Tagged format, for easy grepping and expansion.
177          * The above will go away eventually, once the tools
178          * have been updated.
179          */
180         len += sprintf(page+len,
181                 "MemTotal:     %8lu kB\n"
182                 "MemFree:      %8lu kB\n"
183                 "MemShared:    %8lu kB\n"
184                 "Buffers:      %8lu kB\n"
185                 "Cached:       %8lu kB\n"
186                 "SwapCached:   %8lu kB\n"
187                 "Active:       %8u kB\n"
188                 "Inactive:     %8u kB\n"
189                 "HighTotal:    %8lu kB\n"
190                 "HighFree:     %8lu kB\n"
191                 "LowTotal:     %8lu kB\n"
192                 "LowFree:      %8lu kB\n"
193                 "SwapTotal:    %8lu kB\n"
194                 "SwapFree:     %8lu kB\n",
195                 K(i.totalram),
196                 K(i.freeram),
197                 K(i.sharedram),
198                 K(i.bufferram),
199                 K(pg_size - swapper_space.nrpages),
200                 K(swapper_space.nrpages),
201                 K(nr_active_pages),
202                 K(nr_inactive_pages),
203                 K(i.totalhigh),
204                 K(i.freehigh),
205                 K(i.totalram-i.totalhigh),
206                 K(i.freeram-i.freehigh),
207                 K(i.totalswap),
208                 K(i.freeswap));
209
210         return proc_calc_metrics(page, start, off, count, eof, len);
211 #undef B
212 #undef K
213 }
214
215 static int qos_version_read_proc(char *page, char **start, off_t off,
216                                  int count, int *eof, void *data)
217 {
218         extern char *qos_banner;
219         int len;
220
221         strcpy(page, qos_banner);
222         len = strlen(page);
223         return proc_calc_metrics(page, start, off, count, eof, len);
224 }
225
226 static int version_read_proc(char *page, char **start, off_t off,
227                                  int count, int *eof, void *data)
228 {
229         extern char *linux_banner;
230         int len;
231
232         strcpy(page, linux_banner);
233         len = strlen(page);
234         return proc_calc_metrics(page, start, off, count, eof, len);
235 }
236
237 extern struct seq_operations cpuinfo_op;
238 static int cpuinfo_open(struct inode *inode, struct file *file)
239 {
240         return seq_open(file, &cpuinfo_op);
241 }
242 static struct file_operations proc_cpuinfo_operations = {
243         open:           cpuinfo_open,
244         read:           seq_read,
245         llseek:         seq_lseek,
246         release:        seq_release,
247 };
248
249 #ifdef CONFIG_PROC_HARDWARE
250 static int hardware_read_proc(char *page, char **start, off_t off,
251                                  int count, int *eof, void *data)
252 {
253         int len = get_hardware_list(page);
254         return proc_calc_metrics(page, start, off, count, eof, len);
255 }
256 #endif
257
258 #ifdef CONFIG_STRAM_PROC
259 static int stram_read_proc(char *page, char **start, off_t off,
260                                  int count, int *eof, void *data)
261 {
262         int len = get_stram_list(page);
263         return proc_calc_metrics(page, start, off, count, eof, len);
264 }
265 #endif
266
267 extern struct seq_operations partitions_op;
268 static int partitions_open(struct inode *inode, struct file *file)
269 {
270         return seq_open(file, &partitions_op);
271 }
272 static struct file_operations proc_partitions_operations = {
273         open:           partitions_open,
274         read:           seq_read,
275         llseek:         seq_lseek,
276         release:        seq_release,
277 };
278
279 #ifdef CONFIG_MODULES
280 static int modules_read_proc(char *page, char **start, off_t off,
281                                  int count, int *eof, void *data)
282 {
283         int len = get_module_list(page);
284         return proc_calc_metrics(page, start, off, count, eof, len);
285 }
286
287 extern struct seq_operations ksyms_op;
288 static int ksyms_open(struct inode *inode, struct file *file)
289 {
290         return seq_open(file, &ksyms_op);
291 }
292 static struct file_operations proc_ksyms_operations = {
293         open:           ksyms_open,
294         read:           seq_read,
295         llseek:         seq_lseek,
296         release:        seq_release,
297 };
298 #endif
299
300 extern struct seq_operations slabinfo_op;
301 extern ssize_t slabinfo_write(struct file *, const char *, size_t, loff_t *);
302 static int slabinfo_open(struct inode *inode, struct file *file)
303 {
304         return seq_open(file, &slabinfo_op);
305 }
306 static struct file_operations proc_slabinfo_operations = {
307         open:           slabinfo_open,
308         read:           seq_read,
309         write:          slabinfo_write,
310         llseek:         seq_lseek,
311         release:        seq_release,
312 };
313
314 static int kstat_read_proc(char *page, char **start, off_t off,
315                                  int count, int *eof, void *data)
316 {
317         int i, len = 0;
318         extern unsigned long total_forks;
319         unsigned long jif = jiffies;
320         unsigned int sum = 0, user = 0, nice = 0, system = 0;
321         int major, disk;
322
323         for (i = 0 ; i < smp_num_cpus; i++) {
324                 int cpu = cpu_logical_map(i), j;
325
326                 user += kstat.per_cpu_user[cpu];
327                 nice += kstat.per_cpu_nice[cpu];
328                 system += kstat.per_cpu_system[cpu];
329 #if !defined(CONFIG_ARCH_S390)
330                 for (j = 0 ; j < NR_IRQS ; j++)
331                         sum += kstat.irqs[cpu][j];
332 #endif
333         }
334
335         proc_sprintf(page, &off, &len,
336                       "cpu  %u %u %u %lu\n", user, nice, system,
337                       jif * smp_num_cpus - (user + nice + system));
338         for (i = 0 ; i < smp_num_cpus; i++)
339                 proc_sprintf(page, &off, &len,
340                         "cpu%d %u %u %u %lu\n",
341                         i,
342                         kstat.per_cpu_user[cpu_logical_map(i)],
343                         kstat.per_cpu_nice[cpu_logical_map(i)],
344                         kstat.per_cpu_system[cpu_logical_map(i)],
345                         jif - (  kstat.per_cpu_user[cpu_logical_map(i)] \
346                                    + kstat.per_cpu_nice[cpu_logical_map(i)] \
347                                    + kstat.per_cpu_system[cpu_logical_map(i)]));
348         proc_sprintf(page, &off, &len,
349                 "page %u %u\n"
350                 "swap %u %u\n"
351                 "intr %u",
352                         kstat.pgpgin >> 1,
353                         kstat.pgpgout >> 1,
354                         kstat.pswpin,
355                         kstat.pswpout,
356                         sum
357         );
358 #if !defined(CONFIG_ARCH_S390) && !defined(CONFIG_ALPHA)
359         for (i = 0 ; i < NR_IRQS ; i++)
360                 proc_sprintf(page, &off, &len,
361                              " %u", kstat_irqs(i));
362 #endif
363
364         proc_sprintf(page, &off, &len, "\ndisk_io: ");
365
366         for (major = 0; major < DK_MAX_MAJOR; major++) {
367                 for (disk = 0; disk < DK_MAX_DISK; disk++) {
368                         int active = kstat.dk_drive[major][disk] +
369                                 kstat.dk_drive_rblk[major][disk] +
370                                 kstat.dk_drive_wblk[major][disk];
371                         if (active)
372                                 proc_sprintf(page, &off, &len,
373                                         "(%u,%u):(%u,%u,%u,%u,%u) ",
374                                         major, disk,
375                                         kstat.dk_drive[major][disk],
376                                         kstat.dk_drive_rio[major][disk],
377                                         kstat.dk_drive_rblk[major][disk],
378                                         kstat.dk_drive_wio[major][disk],
379                                         kstat.dk_drive_wblk[major][disk]
380                         );
381                 }
382         }
383
384         proc_sprintf(page, &off, &len,
385                 "\nctxt %u\n"
386                 "btime %lu\n"
387                 "processes %lu\n",
388                 kstat.context_swtch,
389                 xtime.tv_sec - jif / HZ,
390                 total_forks);
391
392         return proc_calc_metrics(page, start, off, count, eof, len);
393 }
394
395 static int devices_read_proc(char *page, char **start, off_t off,
396                                  int count, int *eof, void *data)
397 {
398         int len = get_device_list(page);
399         return proc_calc_metrics(page, start, off, count, eof, len);
400 }
401
402 #if !defined(CONFIG_ARCH_S390)
403 static int interrupts_read_proc(char *page, char **start, off_t off,
404                                  int count, int *eof, void *data)
405 {
406         int len = get_irq_list(page);
407         return proc_calc_metrics(page, start, off, count, eof, len);
408 }
409 #endif
410
411 static int filesystems_read_proc(char *page, char **start, off_t off,
412                                  int count, int *eof, void *data)
413 {
414         int len = get_filesystem_list(page);
415         return proc_calc_metrics(page, start, off, count, eof, len);
416 }
417
418 static int dma_read_proc(char *page, char **start, off_t off,
419                                  int count, int *eof, void *data)
420 {
421         int len = get_dma_list(page);
422         return proc_calc_metrics(page, start, off, count, eof, len);
423 }
424
425 static int ioports_read_proc(char *page, char **start, off_t off,
426                                  int count, int *eof, void *data)
427 {
428         int len = get_ioport_list(page);
429         return proc_calc_metrics(page, start, off, count, eof, len);
430 }
431
432 static int cmdline_read_proc(char *page, char **start, off_t off,
433                                  int count, int *eof, void *data)
434 {
435         extern char saved_command_line[];
436         int len;
437
438         len = snprintf(page, count, "%s\n", saved_command_line);
439         return proc_calc_metrics(page, start, off, count, eof, len);
440 }
441
442 #ifdef CONFIG_SGI_DS1286
443 static int ds1286_read_proc(char *page, char **start, off_t off,
444                                  int count, int *eof, void *data)
445 {
446         int len = get_ds1286_status(page);
447         return proc_calc_metrics(page, start, off, count, eof, len);
448 }
449 #endif
450
451 static int locks_read_proc(char *page, char **start, off_t off,
452                                  int count, int *eof, void *data)
453 {
454         int len;
455         lock_kernel();
456         len = get_locks_status(page, start, off, count);
457         unlock_kernel();
458         if (len < count) *eof = 1;
459         return len;
460 }
461
462 static int execdomains_read_proc(char *page, char **start, off_t off,
463                                  int count, int *eof, void *data)
464 {
465         int len = get_exec_domain_list(page);
466         return proc_calc_metrics(page, start, off, count, eof, len);
467 }
468
469 static int swaps_read_proc(char *page, char **start, off_t off,
470                                  int count, int *eof, void *data)
471 {
472         int len = get_swaparea_info(page);
473         return proc_calc_metrics(page, start, off, count, eof, len);
474 }
475
476 static int memory_read_proc(char *page, char **start, off_t off,
477                                  int count, int *eof, void *data)
478 {
479         int len = get_mem_list(page);
480         return proc_calc_metrics(page, start, off, count, eof, len);
481 }
482
483 /*
484  * This function accesses profiling information. The returned data is
485  * binary: the sampling step and the actual contents of the profile
486  * buffer. Use of the program readprofile is recommended in order to
487  * get meaningful info out of these data.
488  */
489 static ssize_t read_profile(struct file *file, char *buf,
490                             size_t count, loff_t *ppos)
491 {
492         unsigned long p = *ppos;
493         ssize_t read;
494         char * pnt;
495         unsigned int sample_step = 1 << prof_shift;
496
497         if (p >= (prof_len+1)*sizeof(unsigned int))
498                 return 0;
499         if (count > (prof_len+1)*sizeof(unsigned int) - p)
500                 count = (prof_len+1)*sizeof(unsigned int) - p;
501         read = 0;
502
503         while (p < sizeof(unsigned int) && count > 0) {
504                 put_user(*((char *)(&sample_step)+p),buf);
505                 buf++; p++; count--; read++;
506         }
507         pnt = (char *)prof_buffer + p - sizeof(unsigned int);
508         copy_to_user(buf,(void *)pnt,count);
509         read += count;
510         *ppos += read;
511         return read;
512 }
513
514 /*
515  * Writing to /proc/profile resets the counters
516  *
517  * Writing a 'profiling multiplier' value into it also re-sets the profiling
518  * interrupt frequency, on architectures that support this.
519  */
520 static ssize_t write_profile(struct file * file, const char * buf,
521                              size_t count, loff_t *ppos)
522 {
523 #ifdef CONFIG_SMP
524         extern int setup_profiling_timer (unsigned int multiplier);
525
526         if (count==sizeof(int)) {
527                 unsigned int multiplier;
528
529                 if (copy_from_user(&multiplier, buf, sizeof(int)))
530                         return -EFAULT;
531
532                 if (setup_profiling_timer(multiplier))
533                         return -EINVAL;
534         }
535 #endif
536
537         memset(prof_buffer, 0, prof_len * sizeof(*prof_buffer));
538         return count;
539 }
540
541 static struct file_operations proc_profile_operations = {
542         read:           read_profile,
543         write:          write_profile,
544 };
545
546 struct proc_dir_entry *proc_root_kcore;
547
548 static void create_seq_entry(char *name, mode_t mode, struct file_operations *f)
549 {
550         struct proc_dir_entry *entry;
551         entry = create_proc_entry(name, mode, NULL);
552         if (entry)
553                 entry->proc_fops = f;
554 }
555
556 void __init proc_misc_init(void)
557 {
558         struct proc_dir_entry *entry;
559         static struct {
560                 char *name;
561                 int (*read_proc)(char*,char**,off_t,int,int*,void*);
562         } *p, simple_ones[] = {
563                 {"loadavg",     loadavg_read_proc},
564                 {"uptime",      uptime_read_proc},
565                 {"meminfo",     meminfo_read_proc},
566                 {"version",     version_read_proc},
567                 {"qosversion",  qos_version_read_proc},
568 #ifdef CONFIG_PROC_HARDWARE
569                 {"hardware",    hardware_read_proc},
570 #endif
571 #ifdef CONFIG_STRAM_PROC
572                 {"stram",       stram_read_proc},
573 #endif
574 #ifdef CONFIG_MODULES
575                 {"modules",     modules_read_proc},
576 #endif
577                 {"stat",        kstat_read_proc},
578                 {"devices",     devices_read_proc},
579 #if !defined(CONFIG_ARCH_S390)
580                 {"interrupts",  interrupts_read_proc},
581 #endif
582                 {"filesystems", filesystems_read_proc},
583                 {"dma",         dma_read_proc},
584                 {"ioports",     ioports_read_proc},
585                 {"cmdline",     cmdline_read_proc},
586 #ifdef CONFIG_SGI_DS1286
587                 {"rtc",         ds1286_read_proc},
588 #endif
589                 {"locks",       locks_read_proc},
590                 {"swaps",       swaps_read_proc},
591                 {"iomem",       memory_read_proc},
592                 {"execdomains", execdomains_read_proc},
593                 {NULL,}
594         };
595         for (p = simple_ones; p->name; p++)
596                 create_proc_read_entry(p->name, 0, NULL, p->read_proc, NULL);
597
598         proc_symlink("mounts", NULL, "self/mounts");
599
600         /* And now for trickier ones */
601         entry = create_proc_entry("kmsg", S_IRUSR, &proc_root);
602         if (entry)
603                 entry->proc_fops = &proc_kmsg_operations;
604         create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);
605         create_seq_entry("partitions", 0, &proc_partitions_operations);
606         create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
607 #ifdef CONFIG_MODULES
608         create_seq_entry("ksyms", 0, &proc_ksyms_operations);
609 #endif
610         proc_root_kcore = create_proc_entry("kcore", S_IRUSR, NULL);
611         if (proc_root_kcore) {
612                 proc_root_kcore->proc_fops = &proc_kcore_operations;
613                 proc_root_kcore->size =
614                                 (size_t)high_memory - PAGE_OFFSET + PAGE_SIZE;
615         }
616         if (prof_shift) {
617                 entry = create_proc_entry("profile", S_IWUSR | S_IRUGO, NULL);
618                 if (entry) {
619                         entry->proc_fops = &proc_profile_operations;
620                         entry->size = (1+prof_len) * sizeof(unsigned int);
621                 }
622         }
623 #ifdef CONFIG_PPC32
624         {
625                 extern struct file_operations ppc_htab_operations;
626                 entry = create_proc_entry("ppc_htab", S_IRUGO|S_IWUSR, NULL);
627                 if (entry)
628                         entry->proc_fops = &ppc_htab_operations;
629         }
630 #endif
631 }