第10章 无持久存储的文件系统 (3)

目录

10.2 简单文件系统

10.2.1 顺序文件

10.2.2 用libfs编写文件系统

10.2.3 调试文件系统

10.2.4 伪文件系统

10.3 sysfs

10.3.1 概述

10.3.2 数据结构

10.3.3 装载文件系统

10.3.4 文件和目录操作

10.3.5 向sysfs添加内容

10.4 小结


本专栏文章将有70篇左右,欢迎+关注,查看后续文章。

10.2 简单文件系统

如:libfs,seq_file,debugfs。

10.2.1 顺序文件

读写 proc 文件时,默认只使用一页内存。若proc文件太大,则用 seq_file。

seq_file优点:

        不需要开发者直接管理保存数据的内存缓冲区。

        简化了向用户空间输出内核数据。

1. 编写顺序文件处理函数

proc_create("netlink",   0,   net->proc_net,   &netlink_seq_fops);

struct   file_operations    netlink_seq_fops   =   {

        .open    =    netlink_seq_open,

        .read    =    seq_read,

                //将调用struct   seq_operations 中 start,next,stop,show等函数指针。

        .llseek  =    seq_lseek,

};

struct   seq_operations   netlink_seq_ops   =   {

        .start    =    netlink_seq_start,         //开始读数据项。

        .stop    =    netlink_seq_stop,         //停止数据项。

        .next    =    netlink_seq_next,         //遍历下一个要处理的数据项。

        .show   =    netlink_seq_show,         //打印数据项到临时缓冲区。

};

若 file_operations 中 .llseek   =   no_llseek() ;

        表示设备无法seek。

Kprobe介绍:

        作用:

                1. 内核调试。

                2. 收集内核和应用程序的性能信息,如函数执行时间、调用次数等。

        原理:

                在指定函数中插入探测点,可在探测点前或探测点后执行对应回调函数。

        注意:

                需要硬件架构支持。

struct   kprobe   {

        kprobe_opcode_t            *addr;                      // 探测点位置。

        kprobe_pre_handler_t     pre_handler;           // 探测指令被执行前的回调。

        kprobe_post_handler_t    post_handler;         // 探测指令执行完毕后的回调。

        kprobe_fault_handler_t    fault_handler;         // 当内存访问出错时被调用。

}

struct   file_operations    debugfs_kprobes_operations   =   {

        .open     =    kprobes_open,

        .read      =    seq_read,

        .llseek    =    seq_lseek,

        .release  =    seq_release,

};

struct    seq_operations    kprobes_seq_ops   =   {

        .start    =   kprobe_seq_start,

        .next    =   kprobe_seq_next,             // 偏移+1=索引+1。

        .stop    =   kprobe_seq_stop,             // 什么也不做。

        .show   =  show_kprobe_addr,        // 生成文件内容。

};

int   kprobes_open(struct   inode    *inode,    struct   file    *filp)

{

        return    seq_open(filp,   &kprobes_seq_ops);

}

Kprobe将事件发生时将相关数据记录到文件中。

举例:

使用Kprobe跟踪网络流量。

        1. 跟踪TCP连接事件:

                使用Kprobe在内核TCP连接函数中插入断点,当TCP连接建立或关闭时,将信息记录到顺序文件中。

                记录的信息包括:源地址、目标地址、连接建立 / 关闭时间戳等。

        2. 跟踪收发包:

                在收发包函数中插入断点,当有数据传输时,记录相关信息到顺序文件中。

                记录的信息包括:源地址、目标地址、数据包大小、协议类型等信息。

Jprobe:Kprobe一个扩展。

编程举例:

struct   jprobe    tcp_conn_open_probe   =   {

        .entry   =   (kprobe_opcode_t *) tcp_conn_open,         //自定义的断点处理函数。

        .kp       =     {

                .symbol_name     =    "tcp_v4_connect",             //需要跟踪的内核函数。

        },

};

struct   jprobe    tcp_conn_close_probe   =   {

        .entry    =    (kprobe_opcode_t *) tcp_conn_close,

        .kp        =     {

                .symbol_name    =   "inet_csk_destroy_sock",

        },

};

int    tcp_conn_init(void)

{

        register_jprobe( &tcp_conn_open_probe );

        register_jprobe( &tcp_conn_close_probe );

}

void   tcp_conn_exit(void)

{

        // 取消注册Kprobe

        unregister_jprobe(&tcp_conn_open_probe);

        unregister_jprobe(&tcp_conn_close_probe);

}

10.2.2 用libfs编写文件系统

libfs:一个库,用于创建特定用途的小型文件系统,适合无后备存储器。

编程举例:

struct   file_operations    simple_dir_operations   =   {

        .open         =    dcache_dir_open,

        .release     =   dcache_dir_close,

        .llseek        =   dcache_dir_lseek,

        .read          =   generic_read_dir,

        .readdir      =   dcache_readdir,

        .fsync         =   noop_fsync,

};

struct   inode_operations    simple_dir_inode_operations = {

        .lookup   =   simple_lookup;

};

10.2.3 调试文件系统

DebugFS:

        原理:

                基于libfs实现。

        使用场景:

                快速查看或修改模块/内核的变量,无需重新编译内核或模块。

        对应目录:

                /sys/kernel/debug

        编译选项:

                CONFIG_DEBUG_FS

        编程接口:

                debugfs_kprobe_init

                debugfs_create_file

                debugfs_create_dir

                debugfs_create_symlink

10.2.4 伪文件系统

如:bdev文件系统。

bdev作用:

        集群块设备所有的inode,只有内核可见。

struct   file_system_type     bd_type   =   {

        .name     =    "bdev",

        .mount    =    bd_mount,

        .kill_sb    =    kill_anon_super,

}

struct   dentry    *bd_mount(struct   file_system_type    *fs_type,    int    flags,    char    *dev_name,  void    *data)

{

        return    mount_pseudo(fs_type,   "bdev:",   &bdev_sops,   NULL,   BDEVFS_MAGIC);

}

10.3 sysfs

作用:

        向用户层导出内核对象。

        显示kobject拓扑。

        提供装载点/sys。

10.3.1 概述

kobject被层次化组织。

如果一个kobject没有父对象,将其放置到所在kset所属的kobject对应目录中。

每个kobject表示sysfs中一个目录。而attribute表示sysfs中一个文件。

kobject_add函数

        作用:导出kobject到sys文件系统。

10.3.2 数据结构

属性:

struct   attribute    {         //代表sysfs中一个文件

        const char         *name;

        umode_t            mode;          //文件访问权限。

};

10.3.3 装载文件系统

struct   file_system_type    sysfs_fs_type   =   {

        .name    =   "sysfs",

        .mount   =   sysfs_mount,

        .kill_sb   =   sysfs_kill_sb,

};

sysfs_mount -> sysfs_fill_super

创建根目录的inode

int  sysfs_fill_super(struct super_block   *sb,    void  *data,    int  silent)

{

        inode   =   sysfs_get_inode(sb,   &sysfs_root);

        //inode->i_fop   =   &sysfs_file_operations;

}

sysfs_file_operations:后续介绍

10.3.4 文件和目录操作

struct  file_operations    sysfs_file_operations   =   {

        .read   =   sysfs_read_file,

                //调用ops->show(kobj, attr_sd->s_attr.attr, buffer->page);

        .write   =   sysfs_write_file,

        .open   =   sysfs_open_file,

}

struct   kobj_type   brport_ktype   =   {

        .sysfs_ops   =   &brport_sysfs_ops,

};

ops->show();为不同文件自定义,如/sys/bridge

struct   sysfs_ops   brport_sysfs_ops   =   {

        .show   =   brport_show, //调用brport_attr->show(p, buf);

        .store   =   brport_store,

};

而 brport_attr->show(p,   buf); 是/sys/bridge下不同文件各自定义的,如:

BRPORT_ATTR(multicast_router,   S_IRUGO | S_IWUSR,   show_multicast_router,   store_multicast_router)

10.3.5 向sysfs添加内容

struct   kobj_attribute   {

        struct attribute         attr;         //包括文件名,文件权限。

        ssize_t (*show)(struct kobject  *kobj,   struct kobj_attribute  *attr,  char  *buf);

        ssize_t (*store)(struct kobject  *kobj,   struct kobj_attribute  *attr,   const char  *buf,   size_t count);

};

10.4 小结

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山下小童

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值