Seq_file File System实例剖析

转载 2011年01月23日 23:41:00

Seq_file File System
针对proc文件的不足而诞生了Seq_file。
Seq_file的实现基于proc文件。使用Seq_file,用户必须抽象出一个链接对象,然后可以依次遍历这个链接对象。这个链接对象可以是链表,数组,哈希表等等。
编程接口
Seq_file必须实现四个操作函数:start(), next(), show(), stop()

struct seq_operations {
    void * (*start) (struct seq_file *m, loff_t *pos);
    void (*stop) (struct seq_file *m, void *v);
    void * (*next) (struct seq_file *m, void *v, loff_t *pos);
    int (*show) (struct seq_file *m, void *v);
};

start()
主要实现初始化工作,在遍历一个链接对象开始时,调用。返回一个链接对象的偏移或者SEQ_START_TOKEN(表征这是所有循环的开始)。出错返回ERR_PTR。
stop():
当所有链接对象遍历结束时调用。主要完成一些清理工作。
next():
用来在遍历中寻找下一个链接对象。返回下一个链接对象或者NULL(遍历结束)。
show():
对遍历对象进行操作的函数。主要是调用seq_printf(), seq_puts()之类的函数,打印出这个对象节点的信息。
下图描述了seq_file函数对一个链表的遍历。

2、重要的数据结构
除了struct seq_operations以外,另一个最重要的数据结构是struct seq_file:
struct seq_file {
        char *buf;
        size_t size;
        size_t from;
        size_t count;
        loff_t index;
        u64 version;
        struct mutex lock;
        const struct seq_operations *op;
        void *private;
};
该结构会在seq_open函数调用中分配,然后作为参数传递给每个seq_file的操作函数。Privat变量可以用来在各个操作函数之间传递参数。

seq_hello.c
#include <net/net_namespace.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>

#define PROC_NAME "test_proc"
#define MAX_LINES 10

typedef struct item
{
    unsigned long key;
    unsigned char value;
}user_item;

user_item items[4];

MODULE_AUTHOR("ZHANG JIE:iptabler@mail.com");
MODULE_LICENSE("GPL");

static void *my_seq_start(struct seq_file *s, loff_t *pos)
{
        static unsigned long counter = 0;
        printk(KERN_INFO"Invoke start/n");

        if ( *pos == 0 )
        {
                /* yes => return a non null value to begin the sequence */
                return &counter;
        }
        else
        {
                /* no => it's the end of the sequence, return end to stop reading */
                *pos = 0;
                return NULL;
        }
}

static void *my_seq_next(struct seq_file *s, void *v, loff_t *pos)
{
    unsigned long *tmp_v = (unsigned long *)v;
     if (*pos < MAX_LINES) {
        (*tmp_v)++;
        (*pos)++;
        return tmp_v;
        }
    else
    {
        *pos = 0;
        return NULL;
    }
}

static void my_seq_stop(struct seq_file *s, void *v)
{
    printk("Invoke stop/n");
}

static int my_seq_show(struct seq_file *s, void *v)
{
       int i;
        loff_t *spos = (loff_t *) v;
    for (i = 0; i < 4; i++)
    {
     items[i].key = *spos;
    }
      items[0].value = '0';
      items[1].value = '1';
      items[2].value = '2';
      items[3].value = '3';
      seq_printf(s, "%ld=%c,%ld=%c,%ld=%c,%ld=%c;/n", items[0].key,
         items[0].value, items[1].key, items[1].value, items[2].key,
         items[2].value, items[3].key, items[3].value);
        return 0;
}

static struct seq_operations my_seq_ops = {
        .start = my_seq_start,
        .next = my_seq_next,
        .stop = my_seq_stop,
        .show = my_seq_show
};

static int my_open(struct inode *inode, struct file *file)
{
        return seq_open(file, &my_seq_ops);
};

static struct file_operations my_file_ops = {
        .owner = THIS_MODULE,
        .open = my_open,
        .read = seq_read,
        .llseek = seq_lseek,
        .release = seq_release
};

int init_module(void)
{
        struct proc_dir_entry *entry;
        entry = create_proc_entry(PROC_NAME, 0, init_net.proc_net);
        if (entry) {
                entry->proc_fops = &my_file_ops;
        }
        printk(KERN_INFO"Initialze /proc/net/test_proc success!/n");
        return 0;
}

void cleanup_module(void)
{
        remove_proc_entry(PROC_NAME, init_net.proc_net);
        printk(KERN_INFO"Remove /proc/net/test_proc success!/n");
}

Makefile
obj-m := seq_hello.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

default:
    $(MAKE) -C $(KDIR) M=$(PWD) modules
clean:
    $(RM) *.o *.mod.c *.ko *.symvers *.markers *.order

[root@zj:~/Desktop/net/seq]# cat /proc/net/test_proc
0=0,0=1,0=2,0=3;
1=0,1=1,1=2,1=3;
2=0,2=1,2=2,2=3;
3=0,3=1,3=2,3=3;
4=0,4=1,4=2,4=3;
5=0,5=1,5=2,5=3;
6=0,6=1,6=2,6=3;
7=0,7=1,7=2,7=3;
8=0,8=1,8=2,8=3;
9=0,9=1,9=2,9=3;
10=0,10=1,10=2,10=3;

Seq_file文件系统实例剖析

Seq_file File System针对proc文件的不足而诞生了Seq_file。Seq_file的实现基于proc文件。使用Seq_file,用户必须抽象出一个链接对象,然后可以依次遍历这个链...
  • liuqiang_mail
  • liuqiang_mail
  • 2012年08月21日 13:58
  • 213

序列文件(seq_file)接口

序列文件(seq_file)接口 2009-09-28 11:01 93人阅读 评论(0) 收藏 举报 内容简介: 本文主要讲述序列文件(seq_file)接口的内核实现,如何使用它...
  • gangyanliang
  • gangyanliang
  • 2012年02月09日 10:49
  • 4298

linux 读取proc文件之seq_file浅析1

在linux中通过proc文件系统
  • zhanshenwu
  • zhanshenwu
  • 2014年04月26日 23:52
  • 1487

seq_file工作机制实例

分类: LINUX 内容简介 本文主要讲述序列文件(seq_file)接口的内核实现,如何使用它将Linux内核里面常用的数据结构通过文件(主要关注proc文件)导出到用户空间,最...
  • liaokesen168
  • liaokesen168
  • 2015年10月16日 20:59
  • 469

seq_file实例

#ifndef __REGULATOR_JZ_DEBUG__ #define __REGULATOR_JZ_DEBUG__ #endif #define INFO_PRINTF(seq, sw, f...
  • liaokesen168
  • liaokesen168
  • 2015年10月16日 21:03
  • 325

Linux中seq_file文件系统实例剖析

Linux中seq_file文件系统实例剖析 1、seq_file介绍    针对proc文件的不足而诞生了Seq_file。 Seq_file的实现基于proc文件。使用Seq_fil...
  • chenglinhust
  • chenglinhust
  • 2012年11月27日 15:48
  • 888

seq_file的用法

/* 初始化代码 */ entry = create_proc_entry(cache_file_path, 0, NULL); if (entry) { entry->pr...
  • andrew_viking
  • andrew_viking
  • 2012年03月29日 20:44
  • 1403

周四见|《经典SQL优化实例剖析》公开课

看到这个标题,突然灵光一闪,好像似曾相识... 对的,郑老师的SQL优化已然出神入化 经常为学员排忧解难,并已多次分享 下面回顾一下郑老师风采 案例分享:SQL优化案例精彩连载(一) 上次公...
  • n88Lpo
  • n88Lpo
  • 2017年07月24日 08:47
  • 47

Linux内核学习笔记之seq_file接口创建可读写proc文件

学习笔记与个人理解,如有错误,欢迎指正。 温馨提示:建议跟着注释中的编号顺序阅读代码 测试方法:cat /proc/abc_proc                    echo 任意字符串 >/...
  • mumufan05
  • mumufan05
  • 2015年05月17日 23:56
  • 4626

谷歌三大核心技术(一)Google File System中文版

The Google File System中文版 译者:alex 摘要 我们设计并实现了Google GFS文件系统,一个面向大规模数据密集型应用的、可伸缩的分布式文件系统。GFS...
  • hsbirenjie
  • hsbirenjie
  • 2015年02月05日 20:27
  • 2368
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Seq_file File System实例剖析
举报原因:
原因补充:

(最多只允许输入30个字)