学习HMFS源码(一):编译、安装HMFS与观察HMFS的运行状态参数

来源:互联网 发布:软件资格 编辑:程序博客网 时间:2024/05/21 09:23

HMFS是一个Linux的内存文件系统,它的实现参考了PMFS与F2FS,因此在阅读HMFS代码之前,可以先熟悉这两个文件系统的论文PMFS和F2FS。下面介绍一下怎么编译安装HMFS。首先,你需要安装一个64位Linux操作系统,注意,一定要64位的,最好安装到虚拟机上,因为编译内核的过程中,容易出现很多问题,虚拟机有助于你快速重启。虚拟机推荐使用virtualbox。如果使用虚拟机安装Linux时,首先要开启BIOS虚拟化,当然如果在virtualbox中找到64位系统的安装选项,说明已经开启了。假设你已经安装好了64位Ubuntu,那么就可以开始了。

HMFS代码位于github上面,链接为https://github.com/timemath/hmfs.git,因此我们使用git工具把它下载下来。先安装git,

sudo apt-get install git
安装好后,在home目录下下载HMFS源码。

git clone https://github.com/timemath/hmfs.git

这个下载要几分钟,在下载的过程中,我们把编译内核需要的一些库安装好。

sudo apt-get updatesudo apt-get install build-essential -ysudo apt-get install libncurses-dev 
sudo apt-get install initramfs-tools -y
然后,可以为root用户设置一下密码

sudo passwd root
输入2-3遍密码就可以了。做完这些,git差不多下载好了。

然后进入Linux源码根目录,运行一下Linux内核的配置工具,这里可以使用两种配置文件,一个是现在的内核的配置文件,它在/boot下面,名为config-x.xx.x的文件,xx就是现在的内核版本,一个是适合开发内核模块的配置文件,这个配置文件位于fs/hmfs/config-3.11.0+,他添加了很多debug相关的选项,因此这个配置下的内核运行速度较慢。假设使用现在内核的配置文件,将它拷贝到Linux源码根目录下,

cp /boot/config-x.xx.x .config
然后

make menuconfig
然后选择Save,然后Exit就可以了。

然后就可以编译内核了

makesudo make modules_installsudo make install
编译完成后,需要修改grub配置文件,让系统预留一部分内存给HMFS使用。使用gedit工具打开配置文件,

sudo gedit /boot/grub/grub.cfg
我们编译的内核版本是3.11.0+,在文件里找到相应的启动项(根据3.11.0+去找就可以了),一般是这个样子的


因为现在安装的系统的内核版本比3.11.0新,他们的menuentry会排在前面,为了方便选择,我们可以把这个menuentry剪切到其他menuentry的前面。然后注意到倒数第三行,linux /boot/vmlinuz...这里,添加启动参数memmap=2G\$1G,这个参数说明,从内存物理地址1G开始,预留2G的内存出来,这个数值可以根据你们虚拟机的内存大小做相应改动。一般来说,如果是ubuntu最新发行版的话,就需要在$前面加个\,这个跟grub的版本有关。设置完毕后,保存,重启。在grub界面选择内核时注意选择3.11的内核。重启完后,可以在命令行下用命令查看当前内核是不是64位,是不是3.11.0+的。


做完这些,准备工作就完成了。进入到HMFS的目录,它位于fs/hmfs下面。查看他的Makefile

ccflags-y += -DCONFIG_HMFS_DEBUGccflags-y += -DCONFIG_HMFS_DEBUG_GCccflags-y += -DCONFIG_HMFS_XATTR#ccflags-y += -DCONFIG_HMFS_FAST_READccflags-y += -DCONFIG_HMFS_ACLccflags-y += -DCONFIG_HMFS_DEBUG_RW_LOCKobj-m += hmfs.ohmfs-objs := super.o node.o inode.o checkpoint.o file.o data.o namei.o segment.o hash.o dir.o symlink.o gc.o recovery.ohmfs-objs += debug.ohmfs-objs += xattr.ohmfs-objs += util.ohmfs-objs += acl.oall:make -C /lib/modules/`uname -r`/build M=`pwd` modulesclean:make -C /lib/modules/`uname -r`/build M=`pwd` clean
ccflags是传递给编译器的参数,条件控制文件系统的编译,前面加个#表示把这个语句注释掉了。

CONFIG_HMFS_DEBUG: 控制HMFS debug信息的编译,包括输出到debugfs的信息,一些关键数据结构的断言。

CONFIG_HMFS_DEBUG_GC:控制是否记录垃圾回收有关的运行信息,理论上说,记录debug信息会影响文件系统的运行效率,需要增加额外的存储空间

CONFIG_HMFS_XATTR:是否支持扩展属性

CONFIG_HMFS_FAST_READ:是否支持利用mmu,对只读文件的读实行快速读的功能。意思是,如果开启这个选项,HMFS在处理读文件行为时,会把文件数据映射到内核的VMALLOC区域上,这样可以屏蔽掉查找数据块的开销,原理与mmap调用一样。

CONFIG_HMFS_ACL:是否启用ACL功能。

然后看看这里一共有24个代码文件:

acl.c acl.h:文件系统acl功能相关的代码

checkpoint.c:实现文件系统检查点的写入,恢复

data.c:数据块的分配管理,这里的数据块就是文件的数据块

debug.c:向debugfs输出文件系统的运行信息

dir.c:实现跟文件夹有关的操作,比如说在文件夹的数据块下查找文件,添加文件,删除文件的具体实现

file.c:实现文件的读、写、truncate等

gc.c gc,h:垃圾回收

hash.c:略

hmfs.h: HMFS里存储在DRAM上的数据结构

hmfs_fs.h: HMFS里存储在“NVM”的数据结构,如inode,super_block,checkpoint

inode.c:inode的初始化,读取,同步

namei.c:文件系统的基本操作,open,mkdir,mknod,create,setattr等

node.c  node.h:node结点的分配,如inode,direct node,nat node等

recovery.c:Crash恢复的实现

segment.c segment.h:负责segment的分配,新block的分配

super.c:文件系统的挂载、格式化,inode的分配、销毁

xattr.c xattr.h:扩展属性的实现

util.c util.h:略

看完了代码文件,可以直接make了,在命令行输入make命令

make all
没有错误的话,将会生成hmfs.ko。然后安装模块

sudo insmod hmfs.ko
然后可以使用命令挂载了,挂载之前,先在home下创建一个挂载点,

mkdir ~/mnt-hmfs
最简单的挂载命令:

sudo mount -t hmfs -o physaddr=0x40000000,init=2G,gid=1000,uid=1000 none ~/mnt-hmfs
当然也有比较复杂的挂载命令,添加更多的参数:

sudo mount -t hmfs -o physaddr=0x40000000,init=2G,uid=1000,gid=1000,bg_gc=0,gc_min_time=3000,gc_max_time=6000,gc_time_step=1000,deep_fmt=1,user_xattr=0,acl=0,inline=0 none ~/mnt-hmfs
看看这些挂载参数,

physaddr=0x40000000:是你预留出来的内存的启示地址,跟grub里面memmap=2G\$1G对应,这里0x40000000就是1G的16进制表示,因此这个选项要根据你的grub配置做相应修改

init=2G:这是预留了2G内存,也是对应于memmap=2G\$1G这个启动参数。如果设置这个参数,即使你挂载的内存区域存在有效的super block,也会对该区域进行格式化。

uid=1000,gid=1000:这是你的用户id和用户组id,使用命令id查看,做相应修改

bg_gc=0:不开启后台垃圾回收线程

gc_min_time=3000,gc_max_time=6000,gc_time_step=1000:垃圾回收线程最短的睡眠时间是3秒,最长的睡眠时间是6秒,睡眠时间增量是1秒。

deep_fmt=1:如果进行格式化的话,则要深度格式化

user_xattr=0:不开启扩展属性功能

acl=0:不开启acl功能

inline=0:不开启文件数据inline功能

~/mnt-hmfs:将文件系统挂载到~/mnt-hmfs下

这些挂载参数的源码在super.c/hmfs_parse_options

挂载成功后,我们可以查看debugfs下面的文件系统运行信息,需要切换到root用户

sucd /sys/kernel/debug/hmfs/xxx/
xxx与你挂载的物理地址有关,如果挂在了多个内存区域,则有多个相应的文件夹。进入文件夹后,我们看到了三个文件,status,info和vblocks。

可以查看status,他记录了文件系统的参数

cat status

physical address: 文件系统的起始地址(物理地址)

virtual address:文件系统的起始地址(虚拟地址)

initial size:文件系统区域的大小

page count:可用的page(4k)数量

segment count:所有segment数量

valid_block_count:有效块的数量,包括数据块,结点块,cp块等

free_block_count:可用的块的数量

alloc_block_count:已分配的块的数量,一般比valid_block_count大,因为已分配的块里可以有部分块是无效的

valid_node_count:有效的结点数量

valid_inode_count:有效的inode数量

SSA start address:SSA的起始地址

SIT start address:SIT的起始地址

main area range:这就是文件的数据和元数据的存储区域

limit invalid blocks,limit free blocks,limit severe free blocks:这是控制垃圾回收行为的空闲块数量的阈值

overprovision blocks:这是给垃圾回收预留的块的数量,也就是说,当空闲块数量少于这个值后,只有垃圾回收可以申请到空闲块

GC Real:实际进行垃圾回收的次数

GC Try:尝试进行垃圾回收的次数

nr gc blocks:垃圾回收的块的数量

nr_gc_blocks_range[a-b]:这是统计每次垃圾回收块的数量的分布,这个值说明回收块的数量在a-b之间的次数。

查看vblocks

cat vblocks

这里首先用#*^@这四个符号表示每个segment的使用状态,然后列出每个segment的有效块,比如说0:5 5,说明第0 segment目前有5个有效块,这是一个node segment,是文件系统刚格式化时的状态,如果看过了格式化的过程的话,就可以知道这5个分别是什么了。第一个5是记录在SIT中的有效块的数量,第二个5是根据SSA的信息生成的有效块数量,这两个值一定要相等,否则,文件系统存在bug。

然后还有info,查看info的信息需要先向里面写入你想查看的信息。比如说

echo "ssa 0" > info & cat info
这里向info写入ssa 0,然后打印info内容,意思是查看第0个segment的ssa信息。


3 0