我們這個自制文件系統,就是想從形意結合,讓讀者朋友能夠跟隨著筆者一起經歷一次文件系統由 0 到 1 的過程,構建好知識框架,后續的深造將會得心應手。
好,話不多說,我們先從什么是文件系統講起,簡單介紹一些探索文件系統的基礎知識。
1 查看現有文件系統實例
Linux 文件系統相比大家都使用過。大家在自己的 Linux 上機器上執行 mount 命令就能看到當前系統上掛載的所有文件系統:
mount
示例如下:
root@localhost:~# mount
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime,seclabel)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
/dev/mapper/cl-root on / type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
。。。。
比如通過這一行信息我們能看出來:
sysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime)
信息拆解分析:
sysfs:文件系統名稱;
/sys :文件系統目錄掛載點;
sysfs:文件系統類型
(ro,nosuid,nodev,noexec,relatime):掛載參數
這里蘊含的重要信息:
同一個文件系統類型可以創建多個實例,掛載在不同的掛載點,就跟面向對象里的類和實例的關系;
掛載點必須是目錄;
其實,mount 這個命令很強大,不僅能 list 所有的文件系統,還能掛載文件系統。如下:
掛載文件系統命令:
# 把已經格式化好的 /dev/sdb1 盤掛到 /mnt 目錄上
mount -t ext4 /dev/sdb1 /mnt/
對應卸載文件系統命令:
# 卸載 /mnt 的掛載點
umount /mnt
2 查看目錄掛載的文件系統用量
mount 命令能看到所有的掛載列表,但是如果你想要看到所有文件系統的使用情況,則需要另一個命令:df。df 命令用來查看當前操作系統掛載的文件系統和使用情況:
df -Tha
-T 參數能夠讓你看到所有的文件系統實例的類型;
-h 參數能夠以更符合人類的友好的形式展示數據;
-a 參數展示所有的文件系統,包括 0 Blocks 的文件系統(默認是會過濾掉的);
示例如下:
root@localhost:~# df -ahT
Filesystem Type Size Used Avail Use% Mounted on
sysfs sysfs 0 0 0 - /sys
proc proc 0 0 0 - /proc
/dev/mapper/cl-root xfs 17G 11G 7.0G 60% /
。。。
注意,如果 df 沒有加 -a 參數,類似于上面 sysfs,proc 這種用量 0 的會被過濾掉。這也是 mount 和 df 兩個命令默認顯式信息的區別。
3 查看文件系統掛載配置
文件系統掛載可以通過 mount 命令直接掛載,但是 mount 命令掛載并沒有持久化,關機重啟就沒了。所以想要關機重啟之后,還能自動掛載到指定目錄,那么就要把掛載規則寫到 /etc/fstab 文件中,fstab 就是 fs table 的縮寫,很容易理解。
操作系統在啟動的時候,就會解析這個文件,并按照這個文件里的配置,自動掛載文件系統了。
如下:
root@localhost:~# cat /etc/fstab
/dev/mapper/cl-root / xfs defaults 0 0
UUID=600e3771-af4a-48ca-a557-02204c9a48a5 /boot ext4 defaults 1 2
/dev/mapper/cl-swap swap swap defaults 0 0
fstab 的文件格式:
《設備標識》 《掛載目錄》 《文件系統類型》 《掛載參數》 《dump選項》 《fsck選項》
從左到右參數拆解:
設備標識:能夠標識到唯一的文件系統所在的設備,這里可以是設備路徑,也可以是 LABEL,或者 UUID;
掛載目錄:文件系統掛載的目錄點;
文件系統類型:比如 ext4,ext2,xfs 之類的;
掛載參數:可以填 defaults,也可以精細化配置,比如只讀還是可寫(rw/ro),同步刷盤還是異步(async/sync),等等;
dump選項:讓你能控制文件系統備份的頻率,0 表示不備份;
fsck選項:讓你控制是否開機用 fsck 自檢,0 表示不要;
4 查看內核支持的文件系統
這個直接去看內核模塊即可:
ls /lib/modules/${kernel_version}/kernel/fs/
不同的 Linux 發行版略有不同,比如,centos 一般為:
ls -l /lib/modules/4.18.0-80.el8.x86_64/kernel/fs/
ubuntu 一般為:
ls -l /lib/modules/4.4.0-142-generic/kernel/fs/
在對應的目錄找到對應的 .ko 模塊,比如 ext4.ko ,如果想看內核已經加載的內核模塊,可以調用 lsmod 看到。
簡單普及一下 .ko 模塊的知識:
ko 其實是 kernel object 的縮寫,這類文件存在的意義其實和用戶態的 .so 庫類似,都是為了模塊化的編程實踐。內核把核心主干框架之外的功能拆解成模塊,需要的時候就加載 ko 模塊,不需要的時候卸載即可。這樣帶來的好處就是方便開發和使用,保持內核的核心代碼極度精煉。
類似于文件系統,硬件驅動等等,都是以這種形式來加載使用的。
開發文件系統為什么難?
為什么文件系統的開發大家會覺得非常難?原因其實不在于實現,而在于調試和排障,因為早期文件系統的開發只能在內核之中,這個帶來了非常高的門檻。
1 內核文件系統
因為在此之前我們看到了文件系統是位于內核之中, vfs 之下,塊存儲模塊之上的一個位置。對外呈現文件存儲實現,對下管理裸塊設備。劃重點,文件系統是位于內核的一個模塊,那就可以理解了,內核模塊的開發之所以艱難就是難在調試和排障,用戶態的程序你可以隨意 debug,出問題最多也就是 panic,coredump,內核態的程序出了文件就是宕機,所有現場都丟失,你只能通過日志,kdump 等手段來排查。并且內核態程序的編寫是要注意非常多的規范的,比如內存分配,比用戶態的要謹慎的多。
那怎么辦?我們本次的目標是要自制實現一個極簡的文件系統,但總不能帶大家趟一次內核開發的坑吧!那可是要嚇退 99% 的小伙伴。
有辦法的,內核開發者考慮到了這個問題,又考慮到文件系統的需求是千變萬化的,所以提供了一種手段,把 IO 路徑導向用戶態,由用戶態程序捕獲到 IO ,從而實現文件的存儲,這個機制就叫 FUSE 機制。
2 FUSE 文件系統
作為自制 FS 系列第一篇,我們不講 FUSE 的實現,而是通過一個動畫來演示 IO 的旅途:
這里的路徑做了一些簡化,簡化了用戶態之上的邏輯處理,為什么路徑是這樣子?什么是 FUSE ?下篇專題解釋。
總結
本篇文章是為后續鋪墊一些基礎知識,從形的方面,系統介紹了一些命令,告訴你文件系統怎么配置,怎么掛載,怎么查看,怎么獲取到使用詳情。這些基礎知識在后面自制文件系統的時候,都要用上。這些 Linux 命令都是幫助我們從文件系統的外圍去用,去摸,去嗅,從而再去深入理解。
我們目標不止如此,我們是要親手做一個文件系統,動手做過一遍的東西,你對它理解也將會突飛猛進,更加深刻。
下面總結一下上面的基礎以上的知識:
mount 用來列舉查看當前所有文件系統實例,也能支持掛載命令(但 mount 掛載不會持久化,重啟就沒了),umount 用來卸載;
/etc/fstab 是用來配置文件系統掛載規則的,是持久化的配置,重啟不丟;
df -aTh 用來查看每個文件系統掛載目錄的詳情,包括空間使用量,總量,掛載點等信息;
內核模塊的功能以 ko 文件的形式體現,在 /lib/modules/${kernel_version}/kernel/fs/ 目錄可以看到支持的內核文件系統模塊,lsmod 命令可以看到已經加載的內核模塊;
文件系統開發之所以難?是因為之前在內核中開發,內核開發最難的在于調試和排障手段不方便。那文件系統還有出路嗎?有,奇伢帶你自制一個極簡的文件系統,基于 Linux 系統使用純 Go 語言來做哦,敬請期待后續,自己動手,理解更深。
責任編輯:lq6
-
Linux
+關注
關注
87文章
11292瀏覽量
209332 -
文件系統
+關注
關注
0文章
284瀏覽量
19904
原文標題:自制文件系統:文件系統的樣子
文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論