proc文件子系统

2021-01-24, updated 2021-09-12

proc_create使用方法

函数原型

proc_create

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
static inline struct proc_dir_entry *proc_create(
    const char *name, umode_t mode, struct proc_dir_entry *parent,
    const struct file_operations *proc_fops)
{
    return proc_create_data(name, mode, parent, proc_fops, NULL);
}

struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
                    struct proc_dir_entry *parent,
                    const struct file_operations *proc_fops,
                    void *data)
{
    struct proc_dir_entry *pde;
    if ((mode & S_IFMT) == 0)
        mode |= S_IFREG;
                           
    if (!S_ISREG(mode)) {  
        WARN_ON(1); /* use proc_mkdir() */
        return NULL;
    }
    
    if ((mode & S_IALLUGO) == 0) 
        mode |= S_IRUGO;
    pde = __proc_create(&parent, name, mode, 1);
    if (!pde)
        goto out;
    pde->proc_fops = proc_fops;
    pde->data = data;
    if (proc_register(parent, pde) < 0)
        goto out_free;
    return pde;
out_free:
    kfree(pde);
out:
    return NULL;
}
EXPORT_SYMBOL(proc_create_data);

remove_proc_entry

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*   
 * Remove a /proc entry and free it if it's not currently in use.
 */
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;
    unsigned int len;

    spin_lock(&proc_subdir_lock);
    if (__xlate_proc_name(name, &parent, &fn) != 0) {
        spin_unlock(&proc_subdir_lock);
        return;
    }
    len = strlen(fn);

    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) {
        WARN(1, "name '%s'\n", name);
        return;
    }

    proc_entry_rundown(de);

    if (S_ISDIR(de->mode))
        parent->nlink--;
    de->nlink = 0;
    WARN(de->subdir, "%s: removing non-empty directory "
             "'%s/%s', leaking at least '%s'\n", __func__,
             de->parent->name, de->name, de->subdir->name);
    pde_put(de);
}
EXPORT_SYMBOL(remove_proc_entry);

.open 查看相关proc文件时执行

示例

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#include <linux/init.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

MODULE_LICENSE("GPL");

#define MYTEST_PROC_DIR "mytest"
#define MYTEST_PROC_FILE "mytest"

static int zss_test_proc_show(struct seq_file *m, void *v)
{
        seq_printf(m,"testttt");
        return 0;
}

static int zss_test_proc_open(struct inode *inode, struct file *file)
{
        return single_open(file, zss_test_proc_show, NULL);
}

static const struct file_operations zss_test_proc_fops = {
        .open       = zss_test_proc_open,
        .read       = seq_read,
        .llseek     = seq_lseek,
        .release    = single_release,
};

static int hello_init(void)
{
        printk("<0> hello world\n");
        proc_create("zss_test", 0, NULL, &zss_test_proc_fops);
        return 0;
}
static void hello_exit(void)
{
        printk("<0> goodbye\n");
        remove_proc_entry("zss_test", NULL);
}
module_init(hello_init); //该宏在模块的目标代码中增加一个特殊的段,用于说明内核初始化函数所在的位置
module_exit(hello_exit); //跟上面的宏对立
words: 510 tags: proc