Proc文件系统

来源:岁月联盟 编辑:exp 时间:2012-11-08

一、Proc文件系统
Proc文件系统是一种在用户态检查内核态的机制,文件的内容是动态创建的,并不在磁盘上,而是在内存中,掉电丢失。
cat /proc/meminfo/  可查看当前内存使用情况
内核描述:
[cpp] 
<span style="font-size:14px;">struct proc_dir_entry { 
    unsigned int low_ino; 
    unsigned short namelen; 
    const char *name; 
    mode_t mode; 
    nlink_t nlink; 
    uid_t uid; 
    gid_t gid; 
    loff_t size; 
    const struct inode_operations *proc_iops; 
    /*
     * NULL ->proc_fops means "PDE is going away RSN" or
     * "PDE is just created". In either case, e.g. ->read_proc won't be
     * called because it's too late or too early, respectively.
     *
     * If you're allocating ->proc_fops dynamically, save a pointer
     * somewhere.
     */ 
    const struct file_operations *proc_fops; 
    struct proc_dir_entry *next, *parent, *subdir; 
    void *data; 
    read_proc_t *read_proc; 
    write_proc_t *write_proc; 
    atomic_t count;     /* use count */ 
    int pde_users;  /* number of callers into module in progress */ 
    spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */ 
    struct completion *pde_unload_completion; 
    struct list_head pde_openers;   /* who did ->open, but not ->release */ 
};</span> 
1、创建文件:
[cpp] 
<span style="font-size:14px;">struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, 
                     struct proc_dir_entry *parent) 

    struct proc_dir_entry *ent; 
    nlink_t nlink; 
 
    if (S_ISDIR(mode)) { 
        if ((mode & S_IALLUGO) == 0) 
            mode |= S_IRUGO | S_IXUGO; 
        nlink = 2; 
    } else { 
        if ((mode & S_IFMT) == 0) 
            mode |= S_IFREG; 
        if ((mode & S_IALLUGO) == 0) 
            mode |= S_IRUGO; 
        nlink = 1; 
    } 
 
    ent = __proc_create(&parent, name, mode, nlink); 
    if (ent) { 
        if (proc_register(parent, ent) < 0) { 
            kfree(ent); 
            ent = NULL; 
        } 
    } 
    return ent; 

</span> 

 
2、创建目录:
[cpp]
<span style="font-size:14px;">struct proc_dir_entry *proc_mkdir(const char *name, 
        struct proc_dir_entry *parent) 

    return proc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent); 
}</span> 
[cpp] 
<span style="font-size:14px;">struct proc_dir_entry *proc_mkdir_mode(const char *name, mode_t mode, 
  struct proc_dir_entry *parent) 

     struct proc_dir_entry *ent; 
 
     ent = __proc_create(&parent, name, S_IFDIR | mode, 2); 
     if (ent) { 
        if (proc_register(parent, ent) < 0) { 
              kfree(ent); 
              ent = NULL; 
        } 
      } 
    return ent; 

</span> 

3、删除目录
[cpp
<span style="font-size:14px;">void remove_proc_entry(const char *name, struct proc_dir_entry *parent) 

 struct proc_dir_entry **p; 
 struct proc_dir_entry *de = NULL; 
 const char *fn = name; 
 int len; 
 
 if (xlate_proc_name(name, &parent, &fn) != 0) 
  return; 
 len = strlen(fn); 
 
 spin_lock(&proc_subdir_lock); 
 for (p = &parent->subdir; *p; p=&(*p)->next ) { 
  if (proc_match(len, fn, *p)) { 
   de = *p; 
   *p = de->next; 
   de->next = NULL; 
   break; 
  } 
 } 
 spin_unlock(&proc_subdir_lock); 
 if (!de) 
  return; 
 
 spin_lock(&de->pde_unload_lock); 
 /*
  * Stop accepting new callers into module. If you're
  * dynamically allocating ->proc_fops, save a pointer somewhere.
  */ 
 de->proc_fops = NULL; 
 /* Wait until all existing callers into module are done. */ 
 if (de->pde_users > 0) { 
  DECLARE_COMPLETION_ONSTACK(c); 
 
  if (!de->pde_unload_completion) 
   de->pde_unload_completion = &c; 
 
  spin_unlock(&de->pde_unload_lock); 
 
  wait_for_completion(de->pde_unload_completion); 
 
  goto continue_removing; 
 } 
 spin_unlock(&de->pde_unload_lock); 
 
continue_removing: 
 spin_lock(&de->pde_unload_lock); 
 while (!list_empty(&de->pde_openers)) { 
  struct pde_opener *pdeo; 
 
  pdeo = list_first_entry(&de->pde_openers, struct pde_opener, lh); 
  list_del(&pdeo->lh); 
  spin_unlock(&de->pde_unload_lock); 
  pdeo->release(pdeo->inode, pdeo->file); 
  kfree(pdeo); 
  spin_lock(&de->pde_unload_lock); 
 } 
 spin_unlock(&de->pde_unload_lock); 
 
 if (S_ISDIR(de->mode)) 
  parent->nlink--; 
 de->nlink = 0; 
 WARN(de->subdir, KERN_WARNING "%s: removing non-empty directory " 
   "'%s/%s', leaking at least '%s'/n", __func__, 
   de->parent->name, de->name, de->subdir->name); 
 if (atomic_dec_and_test(&de->count)) 
  free_proc_entry(de); 

</span> 

流程:
<1>、调用creat_proc_entry创建一个struct proc_dir_entry
<2>、对创建的struct proc_dir_entry进行赋值:read_proc、mode、owner、size、write_proc