1、为 Ext4 文件系统添加扩展属性
扩展属性分为以下四种:
(1)扩展的安全属性-- security
安全属性名称空间被内核用于安全模块,例如SELinux。对安全属性的读和写权限依赖于策略的设定。这策略是由安全模块载入的。如果没有载入安全模块,所有的进程都对安全属性有读权限,写权限只有那些有CAP_SYS_ADMIN(允许执行系统管理任务,如加载或卸载文件系统、设置磁盘配额等)的进程才有。
(2)扩展的系统属性-- system
扩展的系统属性被内核用来存储系统对象,比如说ACL。对系统属性的读和写权限依赖于策略的设定。
(3)受信任的扩展属性-- trusted
受信任的扩展属性只对那些有CAP_SYS_ADMIN的进程可见和可获得。这个类中的属性被用来在用户空间中保存一些普通进程无法得到的信息。
(4)扩展的用户属性-- user
扩展的用户属性被分配给文件和目录用来存储任意的附加信息,比如mime type、字符集或是文件的编码。用户属性的权限由文件权限位来定义。对于普通文件和目录,文件权限位定义文件内容的访问,对于设备文件来说,它们定义对设备的访问。扩展的用户属性只被用于普通的文件和目录,对用户属性的访问被限定于属主和那些对目录有sticky位设置的用户。
使用setfattr设置EA:
-
设置user.name为xattr_test
-
设置user.city为Beijing
包含转义字符的情况,需使用双引号:
-
无双引号时为文本
-
有双引号为转移后的值(八进制base64形式存储)
设置属性值为十六进制数时,所设置的数的位数必须为偶数,即0x 或 0X后的数字必须为偶数位,否则出错。 若设置成功,最终以十六进制数的base64编码存储:
使用在线编码器对欲设置的属性值编码:
使用编码后的值进行属性设置:
使用getfattr命令获取属性并进行text编码设置:
hex编码设置:
查看base64编码存储形式:
使用在线编码器验证:
发现user.name, user.city, user.base64都正确转化为base64格式。
2、注册一个自定义的文件系统类型
register_newfs.c:
#include <linux/module.h>
#include <linux/fs.h>
MODULE_LICENSE("GPL");
static struct file_system_type myfs_type = {
.name = "myfs",
.owner = THIS_MODULE,
};
MODULE_ALIAS_FS("myfs");
static int __init register_newfs_init(void)
{
printk("Start register_newfs module...");
return register_filesystem(&myfs_type);
}
static void __exit register_newfs_exit(void)
{
printk("Exit register_newfs module...");
unregister_filesystem(&myfs_type);
}
module_init(register_newfs_init);
module_exit(register_newfs_exit);
编译运行:
总结:加载模块之前系统中没有myfs文件系统;加载模块时,系统中出现myfs文件系统;卸载模块后myfs文件系统也消失。查看日志,对该模块重复加载、卸载过了三次。
3、在/proc下创建目录
-
/proc是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,用户可以通过这些文件查看有关系统硬件及当前正在运行进程的信息,甚至可以通过更改其中某些文件来改变内核的运行状态。
内核模块编程:
proc_mkdir.c:
#include <linux/module.h>
#include <linux/proc_fs.h>
MODULE_LICENSE("GPL");
static struct proc_dir_entry *myproc_dir;
static int __init myproc_init(void)
{
int ret = 0;
printk("Start proc_mkdir module...");
myproc_dir = proc_mkdir("myproc",NULL);
if(myproc_dir == NULL)
return -ENOMEM;
return ret;
}
static void __exit myproc_exit(void)
{
printk("Exit proc_mkdir module...");
proc_remove(myproc_dir);
}
module_init(myproc_init);
module_exit(myproc_exit);
编译运行:
总结:在加载proc_mkdir模块之前,/proc/目录中没有myproc目录;加载proc_mkdir后/proc/中出现了myproc目录;卸载该模块后myproc目录随之消失。
4、使用sysfs文件系统传递内核模块参数
sysfs_exam.c:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/stat.h>
MODULE_LICENSE("GPL");
static int a = 0;
static int b = 0;
static char * c = "Hello, World";
module_param(a, int, 0);
MODULE_PARM_DESC(a, "An invisible int under sysfs");
module_param(b, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(b, "An visible int under sysfs");
module_param(c, charp, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
MODULE_PARM_DESC(c, "An visible string under sysfs");
static int __init sysfs_exam_init(void)
{
printk("Start sysfs_exam module...");
printk("a = %d\n", a);
printk("b = %d\n", b);
printk("c = '%s'\n", c);
return 0;
}
static void __exit sysfs_exam_exit(void)
{
printk("Exit sysfs_exam module...");
printk("a = %d\n", a);
printk("b = %d\n", b);
printk("c = '%s'\n", c);
}
module_init(sysfs_exam_init);
module_exit(sysfs_exam_exit);
编译、验证:
总结:加载模块之后,系统中出现了自定义模块‘sysfs_exam’;modinfo命令能查看内核模块信息,图中包含对a、b、c的描述,内容为:
-
a在/sys中不可见;
-
b在/sys中可见;
-
c在/sys中可见。
使用echo能够修改指定参数的值,图中将c的值改为”Happy Mid Autumn Day!“。