操作系统实验-文件系统
前言
- 用于操作系统课程的实验记录以便后续回顾
- 建议使用xshell远程连接编辑,具体可以看前文内核编译的部分
- 文中文本编辑部分使用vim,可以参考前文进程管理部分
实验操作
任务1:为 Ext4 文件系统添加扩展属性
环境准备,安装libattr
dnf install -y libattr
查看当前文件系统类型

检查当前文件系统是否支持文件扩展属性:
- 查看硬盘分区信息
fdisk -l

- 检查特定分区是否支持扩展属性
tune2fs -l /dev/sda1 | grep user_xattr

创建文件并设置扩展属性:
# 创建测试文件
touch file.txt
# 设置简单扩展属性(user命名空间)
setfattr -n user.myattr -v "simple value" file.txt
# 查看设置的属性
getfattr -d file.txt

设置八进制数属性值:
# 设置八进制值(\012表示换行符)
setfattr -n user.octal_attr -v "\012" file.txt
# 查看base64编码存储的结果
getfattr -d file.txt

设置十六进制数属性值:
# 设置十六进制值(0x0a表示换行符)
setfattr -n user.hex_attr -v "0x0a" file.txt
# 查看base64编码存储的结果
getfattr -d file.txt

设置base64编码属性值:
# 这里使用hello的编码结果aGVsbG8=
setfattr -n user.base64_attr -v "0saGVsbG8=" file.txt
# 查看存储结果
getfattr -d file.txt

使用getfatter查看不同的编码格式
# 保持原编码设置
getfattr -d file.txt
# 以text格式查看
getfattr -d -e text file.txt
# 以hex格式查看
getfattr -d -e hex file.txt
# 以base64格式查看
getfattr -d -e base64 file.txt

任务2:注册一个自定义的文件系统类型
查看当前已经注册的文件系统
cat /proc/filesystems

编写自定义文件系统模块:
文件编辑这里使用vim,创建文件并打开为
vim [文件名],打开后按I进入编辑,完成后ESC退出编辑,输入:wq保存并退出,没有下载的话yum install vim下载
- myfs.c
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/kernel.h>
#define MYFS_MAGIC 0x13131313 // 自定义魔数(用于识别文件系统)
static struct file_system_type myfs_type = {
.owner = THIS_MODULE, // 指向当前模块
.name = "myfs", // 文件系统名称
.mount = NULL, // 挂载函数(暂不实现)
.kill_sb = NULL, // 卸载函数(暂不实现)
};
static int __init myfs_init(void)
{
int ret;
printk(KERN_INFO "Registering myfs filesystem...\n");
ret = register_filesystem(&myfs_type);
if (ret != 0) {
printk(KERN_ERR "Failed to register myfs: %d\n", ret);
return ret;
}
printk(KERN_INFO "myfs filesystem registered successfully!\n");
return 0;
}
static void __exit myfs_exit(void)
{
printk(KERN_INFO "Unregistering myfs filesystem...\n");
unregister_filesystem(&myfs_type);
printk(KERN_INFO "myfs filesystem unregistered.\n");
}
module_init(myfs_init);
module_exit(myfs_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("A simple custom filesystem");
- Makefile(注意tab)
obj-m := myfs.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
编译源文件:
make

查看加载内核后结果
- 加载模块
sudo insmod myfs.ko
- 查看内核日志(应该能看到类似红框中的结果)
dmesg | tail -n 5

- 检查
/proc/filesystems
cat /proc/filesystems | grep myfs

卸载模块并查看结果
- 卸载模块
sudo rmmod myfs
- 查看内核日志(应该能看到类似红框中的结果)

- 检查
proc/filesystem

没有输出,说明myfs被注销
任务3:在 /proc 下创建目录
相关代码(注意不要和上一次的代码放在同一位置):
- myproc.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#define PROC_DIR_NAME "myproc_dir" // 自定义目录名
static struct proc_dir_entry *my_proc_dir = NULL;
static int __init myproc_init(void)
{
printk(KERN_INFO "Creating /proc/%s...\n", PROC_DIR_NAME);
// 在 /proc 下创建目录
my_proc_dir = proc_mkdir(PROC_DIR_NAME, NULL);
if (!my_proc_dir) {
printk(KERN_ERR "Failed to create /proc/%s\n", PROC_DIR_NAME);
return -ENOMEM;
}
printk(KERN_INFO "/proc/%s created successfully!\n", PROC_DIR_NAME);
return 0;
}
static void __exit myproc_exit(void)
{
printk(KERN_INFO "Removing /proc/%s...\n", PROC_DIR_NAME);
if (my_proc_dir) {
proc_remove(my_proc_dir); // 删除目录
printk(KERN_INFO "/proc/%s removed.\n", PROC_DIR_NAME);
}
}
module_init(myproc_init);
module_exit(myproc_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Create and remove a directory in /proc");
- Makefile
obj-m := myproc.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
编译源文件
make

加载内核查看结果
# 加载内核
sudo insmod myproc.ko
# 查看日志
dmesg | tail -n 5
# 检查/proc目录
ls /proc | grep myproc_dir

卸载模块查看结果
# 卸载模块
sudo rmmod myproc
# 查看日志
dmesg | tail -n 5
# 检查/proc目录
ls /proc | grep myproc_dir

任务4:使用 sysfs 文件系统传递内核模块参数
相关代码:
- mysysfs.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
// 定义模块参数
static int my_int = 100;
static char *my_string = "default";
static bool my_bool = true;
// 注册模块参数(使其在 /sys/module/mysysfs/parameters/ 下可见)
module_param(my_int, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
module_param(my_string, charp, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
module_param(my_bool, bool, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
// 参数描述(可通过 `modinfo mysysfs.ko` 查看)
MODULE_PARM_DESC(my_int, "An integer parameter");
MODULE_PARM_DESC(my_string, "A string parameter");
MODULE_PARM_DESC(my_bool, "A boolean parameter");
static int __init mysysfs_init(void)
{
printk(KERN_INFO "mysysfs module loaded\n");
printk(KERN_INFO "Initial values: my_int=%d, my_string=%s, my_bool=%d\n",
my_int, my_string, my_bool);
return 0;
}
static void __exit mysysfs_exit(void)
{
printk(KERN_INFO "mysysfs module unloaded\n");
printk(KERN_INFO "Final values: my_int=%d, my_string=%s, my_bool=%d\n",
my_int, my_string, my_bool);
}
module_init(mysysfs_init);
module_exit(mysysfs_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Your Name");
MODULE_DESCRIPTION("Demonstrate sysfs module parameters");
- Makefile
obj-m := mysysfs.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
make -C $(KDIR) M=$(PWD) clean
编译
make

加载模块并查看
sudo insmod mysysfs.ko
dmesg | tail -n 5
ls /sys/module/mysysfs/parameters/

修改参数并查看
- 修改参数
echo 200 | sudo tee /sys/module/mysysfs/parameters/my_int
echo -n "new_value" | sudo tee /sys/module/mysysfs/parameters/my_string
echo N | sudo tee /sys/module/mysysfs/parameters/my_bool
- 查看日志
dmesg | tail -n 10

卸载模块并查看
sudo rmmod mysysfs
dmesg | tail -n 5
ls /sys/module | grep mysysfs


浙公网安备 33010602011771号