/* * snicpumon.c - create a "file" in /proc * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define procfs_name "cpuutil" #define LOAD_INT(x) ((x) >> FSHIFT) #define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100) extern void *sys_call_table[]; static int uid; module_param(uid, int, 0644); /** * This structure hold information about the /proc file * */ struct proc_dir_entry *Our_Proc_File; static int show_stat(struct seq_file *p, void *v) { int i; unsigned long jif; cputime64_t user, nice, system, idle; u64 sum = 0; int a, b, c; user = nice = system = idle = cputime64_zero; jif = - wall_to_monotonic.tv_sec; if (wall_to_monotonic.tv_nsec) --jif; a = avenrun[0] + (FIXED_1/200); b = avenrun[1] + (FIXED_1/200); c = avenrun[2] + (FIXED_1/200); seq_printf(p, "%d%% %d%% %d%%\n", LOAD_INT(a)*100 + LOAD_FRAC(a), LOAD_INT(b)*100 + LOAD_FRAC(b), LOAD_INT(c)*100 + LOAD_FRAC(c)); for_each_cpu(i) { int j; user = cputime64_add(user, kstat_cpu(i).cpustat.user); nice = cputime64_add(nice, kstat_cpu(i).cpustat.nice); system = cputime64_add(system, kstat_cpu(i).cpustat.system); idle = cputime64_add(idle, kstat_cpu(i).cpustat.idle); for (j = 0 ; j < NR_IRQS ; j++) sum += kstat_cpu(i).irqs[j]; } seq_printf(p, "%llu %llu %llu %llu\n", (unsigned long long)cputime64_to_clock_t(user), (unsigned long long)cputime64_to_clock_t(nice), (unsigned long long)cputime64_to_clock_t(system), (unsigned long long)cputime64_to_clock_t(idle)); if (sys_call_table[289] != NULL) { seq_printf(p, "289 Available\n"); } return 0; } static int stat_open(struct inode *inode, struct file *file) { unsigned size = 4096 * (1 + num_possible_cpus() / 32); char *buf; struct seq_file *m; int res; /* don't ask for more than the kmalloc() max size, currently 128 KB */ if (size > 128 * 1024) size = 128 * 1024; buf = kmalloc(size, GFP_KERNEL); if (!buf) return -ENOMEM; res = single_open(file, show_stat, NULL); if (!res) { m = file->private_data; m->buf = buf; m->size = size; } else kfree(buf); return res; } static struct file_operations proc_stat_operations = { .open = stat_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; int init_module() { Our_Proc_File = create_proc_entry(procfs_name, 0644, NULL); if (Our_Proc_File == NULL) { remove_proc_entry(procfs_name, &proc_root); printk(KERN_ALERT "Error: Could not initialize /proc/%s\n", procfs_name); return -ENOMEM; } Our_Proc_File->proc_fops = &proc_stat_operations; Our_Proc_File->owner = THIS_MODULE; Our_Proc_File->mode = S_IFREG | S_IRUGO; Our_Proc_File->uid = 0; Our_Proc_File->gid = 0; Our_Proc_File->size = 0; printk(KERN_INFO "/proc/%s created\n", procfs_name); return 0; /* everything is ok */ } void cleanup_module() { remove_proc_entry(procfs_name, &proc_root); printk(KERN_INFO "/proc/%s removed\n", procfs_name); }