一、理論部分
首先建議讀一下這篇簡單有趣的文章:《這破玩意兒叫文件系統》
總結起來就是下面兩張圖:
除此之外,ext4文件系統還有group表即GDT(塊組描述符表)
最終的文件系統模型是:
====================================================================
所以要找到/var/log/messages的過程是:
- 找到根文件系統的塊組描述符表所在的blocks,讀取GDT(已在內存中)找到inode table的block號
- 在inode table的block中定位到根"/"的inode,找出"/"指向的data block。
- 在"/"的datablock中記錄了var目錄名和指向var目錄文件inode的指針,並找到該inode記錄,inode記錄中存儲了指向var的block指針,所以也就找到了var目錄文件的data block。
- 在var的data block中記錄了log目錄名和其inode指針,通過該指針定位到該inode所在的塊組及所在的inode table,並根據該inode記錄找到log的data block。
- 在log目錄文件的data block中記錄了messages文件名和對應的inode指針,通過該指針定位到該inode所在的塊組及所在的inode table,並根據該inode記錄找到messages的data block。
- 最后讀取messages對應的datablock。
簡言之:找到GDT-->找到"/"的inode-->找到/的數據塊讀取var的inode-->找到var的數據塊讀取log的inode-->找到log的數據塊讀取messages的inode-->找到messages的數據塊並讀取它們。
二、實踐
准備:虛擬機增加一塊盤sdb;有一個5G分區sdb1,文件系統為ext4,掛載在/media。/media下有個文件:/media/log
實驗:通過inode查詢log,就相當於cat /media/log 背后的操作,便於理解上面查看/var/log/messages那段話
首先要獲取文件系統的基本信息:dump2fs /dev/sdb1
block size=4k 一個塊的大小是4k
inode size=256B 一個inode的大小是256B,所以一個塊有4K/256B=16個inode
group0的 Inode table at 673-1184 (+673) 即塊號(673-1184)存放的是inode和數據塊
根的inode是從2號inode開始的(inode1被用作統計壞塊了: Inode 1 is used to keep track of any bad blocks on the disk)
[root@shenlin ~]# stat /media (這里/media就是sdb1的根)
File: ‘/media’
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: 811h/2065d Inode: 2 Links: 4
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
每個塊的地址是從(0x0000~0x1000)
綜上inode2在第673號block,偏移量offset=(inode-1)*256B=256B換算成16進制就是0x0100;即inode2的范圍是(0x0100~0x0200)
使用:dd if=/dev/sdb1 bs=4096 skip=673|hexdump -C -n 4096 顯示第673號塊的二進制數據
根據inode的定義(參見inode結構體),該inode指向的塊是00 00 22 a1 (從右往左)換算成十進制是8865號塊
dd if=/dev/sdb1 bs=4096 skip=8865 |hexdump -C -n 4096
根據inode的定義,找到log的inode號為0c轉換成十進制為:12
inode12的地址偏移量是(12-1)*256B=2816 轉換成十六進制是0xb00,即inode12在第673號block,地址范圍是(0xb00~0xc00)
inode12指向的數據塊地址為00008281,轉換為十進制33409
至此,我們成功通過inode找到了log文件!
參考鏈接:
https://blog.csdn.net/Chasing_Chasing/article/details/82260641
https://www.cnblogs.com/sstjustdoit/p/10135281.html