2018年2月13日 星期二

Linux kernel - 建立/sys文件系统獲取所有行程狀態

#include <linux/module.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/sched.h>

MODULE_LICENSE("Dual BSD/GPL");

#define PROCNAME "sample"

static void *as_start(struct seq_file *m, loff_t *pos)
{
 loff_t n = *pos;
 struct task_struct *tp = NULL;

 seq_printf(m, "%lld (%s)\n", n, __func__);

 if (n == 0)
  seq_printf(m, "=== seq_file header ===\n");

 rcu_read_lock();

 if (n == 0)
  return (&init_task);

 for_each_process(tp) {
  n--;
  if (n <= 0) {
   return (tp);
  }
 }
 
 return 0;
}

static void *as_next(struct seq_file *m, void *p, loff_t *pos)
{
 struct task_struct *tp = (struct task_struct *) p;

 seq_printf(m, "%lld (%s)\n", *pos, __func__);

 (*pos)++;

 tp = next_task(tp);

 if (tp == &init_task)
  return NULL;
 
 return (tp);
}

static void as_stop(struct seq_file *m, void *p)
{
 seq_printf(m, "%p (%s)\n", p, __func__);

 rcu_read_unlock();
}

static int as_show(struct seq_file *m, void *p)
{
 struct task_struct *tp = (struct task_struct *) p;

 seq_printf(m, "%p (%s)\n", tp, __func__);

 seq_printf(m, "[%s] pid = %d\n", tp->comm, tp->pid);
#if 0
 seq_printf(m, "     tgid = %d\n", tp->tgid);
 seq_printf(m, "     state = %ld\n", tp->state);
 seq_printf(m, "     mm = 0x%p\n", tp->mm);
 seq_printf(m, "     utime = %lu\n", tp->utime);
 seq_printf(m, "     stime = %lu\n", tp->stime);
 seq_printf(m, "     oomkilladj = %d\n", tp->oomkilladj);
#endif
 seq_printf(m, "\n");

 return 0;
}

/* seq_file handler */
static struct seq_operations sample_seq_op = {
 .start  = as_start,
 .next  = as_next,
 .stop  = as_stop,
 .show  = as_show,
};

static int sample_proc_open(struct inode *inode, struct file *file)
{
 return seq_open(file, &sample_seq_op);
}

/* procfs handler */
static struct file_operations sample_proc_fops = {
 .open  = sample_proc_open,
 .read  = seq_read,
 .llseek  = seq_lseek,
 .release = seq_release,
};

static int sample_init(void)
{
#if 1
 struct proc_dir_entry *entry;
 
 entry = create_proc_entry(PROCNAME, S_IRUGO | S_IWUGO, NULL);

 if (entry)
  entry->proc_fops = &sample_proc_fops;
#else
 proc_create(PROCNAME, 0, NULL, &sample_proc_fops);
#endif

 printk(KERN_INFO "driver loaded\n");

 return 0;
}

static void sample_exit(void)
{
 remove_proc_entry(PROCNAME, NULL);

 printk(KERN_INFO "driver unloaded\n");
}
module_init(sample_init);
module_exit(sample_exit);

沒有留言:

張貼留言