學習HMFS源碼(一):編譯、安裝HMFS與觀察HMFS的運行狀態參數

HMFS是一個Linux的內存文件系統,它的實現參考了PMFS與F2FS,因此在閱讀HMFS代碼之前,可以先熟悉這兩個文件系統的論文PMFSF2FS。下面介紹一下怎麼編譯安裝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 update
sudo apt-get install build-essential -y
sudo 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就可以了。

然後就可以編譯內核了

make
sudo make modules_install
sudo 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_DEBUG
ccflags-y += -DCONFIG_HMFS_DEBUG_GC
ccflags-y += -DCONFIG_HMFS_XATTR
#ccflags-y += -DCONFIG_HMFS_FAST_READ
ccflags-y += -DCONFIG_HMFS_ACL
ccflags-y += -DCONFIG_HMFS_DEBUG_RW_LOCK


obj-m += hmfs.o

hmfs-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.o

hmfs-objs += debug.o
hmfs-objs += xattr.o
hmfs-objs += util.o
hmfs-objs += acl.o

all:
	make -C /lib/modules/`uname -r`/build M=`pwd` modules
clean:
	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用戶

su
cd /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信息。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章