注,本文中用到的图片来《自存储技术原理分析》一书)
sysfs文件系统
sysfs核心负责为内核中的内部表示和用户空间的外部呈现建立对应关系
1 内核对象被映射为用户空间的目录;
2 对象属性被映射为用户空间的常规文件
3 对象关系被映射为用户空间的符号链接
sysfs代码在fs/sysfs中,他提供两种构件,也就是两个方面的API,一是内核编程接口,用于向内核其他模块提供构建内部树的API,另一是文件系统接口,使得用户空间可以查看并操作对应的内核对象
构建内核对象,对象属性和对象关系的内部数
sysfs内部树中有4中类型的节点:目录节点,链接节点,属性节点和二进制属性节点,分别对应内核对象,对象关系,对象属性,
内部树的所有节点都是用sysfs_dirent描述符表示,根保存在全局变量sysfs_root中
struct sysfs_dirent {
atomic_t s_count;//该节点的引用计数,当为0该节点被释放
atomic_t s_active;//该节点的活动引用计数
58 #ifdef CONFIG_DEBUG_LOCK_ALLOC
59 struct lockdep_map dep_map;
60 #endif
61 struct sysfs_dirent *s_parent;//指向父亲节点
62 const char *s_name;//对于目录,是内核对象名字;对于常规文件是属性的名字;对于符号链接是链接的名字
63
64 struct rb_node s_rb;
65
66 union {
67 struct completion *completion;
68 struct sysfs_dirent *removed_list;
69 } u;
70
71 const void *s_ns; /* namespace tag */
72 unsigned int s_hash; /* ns + name hash */
73 union {
74 struct sysfs_elem_dir s_dir;//当该节点表示一个目录是
75 struct sysfs_elem_symlink s_symlink;
76 struct sysfs_elem_attr s_attr;
77 struct sysfs_elem_bin_attr s_bin_attr;//当该节点表示一个二进制属性时
78 };
79
80 unsigned short s_flags;
81 umode_t s_mode;
82 unsigned int s_ino;//该节点的唯一标号
83 struct sysfs_inode_attrs *s_iattr;
84 };
内核对象
在内部用一个目录节点表示,由sysfs文件系统作为目录输出到用户空间,由于是目录节点,他下面将会创建其他的节点(链接节点,属性节点,二进制节点)。表示目录节点的数据结构是sysfs_elem_dir,其children域指向他第一个孩子节点,沿着孩子节点的s_sibling组成一个链表
sysfs核心向linux内核其他模块提供两个API
int sysfs_create_dir(struct kobject*kobj):为一个内核对象创建目录节点,步骤:在内存中为目录节点分配一个sysfs_dirent描述符,节点名字为内核对象名,标志是目录;建立内核对象和目录节点之间的关系;将目录节点链入sysfs内部树,如果内核对象的parent不是null,则目录节点会作为其父内核节点的子节点;否则目录节点会被作为sysfs_root子节点。
void sysfs_remove_dir(struct kobject*kobj)删除一个内核对象的目录节点,他会将目录节点下面的属性节点一并删除
2 对象属性
对象属性在内部用一个属性节点表示,由sysfs作为常规文件输出到用户空间,用sysfs_elem_attr表示,而他又有一个指向属性描述符(attribute结构,在kobj_type中)的指针域
int sysfs_create_file(struct kobject*kobj,const struct attribute *attr)为内核对象的属性创建一个属性节点,在内存中分配一个sysfs_dirent描述符,节点的名字是属性名,标志是属性,将属性节点链入sysfs内部树作为内核对象对应目录节点的子节点。
void sysfs_remove_file(struct kobject*kobj,const struct attribute *attr)删除内核对象和属性节点。
3 对象链接
对象链接反映了内核对象之间的关系,在内部用链接节点表示,在sysfs文件系统中,他对应一个符号链接文件,而在内核,是两个不同内核对象之间的关联节点,在一个内核对象目录下创建的链接节点用target_sd指向另一个内核对象目录节点
sysfs_elem_symlink
类型 |
域 |
描述 |
struct sysfs_dirent* |
target_sd |
指向目标节点 |
int sysfs_crreate_link(strtuct kobject*kobj,struct kobject *target ,const char* name):在两个内核对象之间创建用于关联的链接节点,在内存中,为链接节点分配一个sysfs_dirent描述符,节点名name 标志是链接点解,节点的父亲为kobj所对应的目录节点,节点的target_sd指向target所对应的目录节点,这个链接节点被链入sysfs内部树,反映到sysfs文件系统上,这将在kobj所对应的目录下创建名字为name的符号链接文件,指向target所对应的目录。
void sysfs_remove_link(struct kobject *kobj,const char*name)
对sysfs文件的读写转化为对属性的show及store操作
最后附上sysfs目录层次图: