2016年4月25日 星期一

Hard Link & Soft Link

Hard Link & Soft Link

前言

Where is the real Data?
What's the different between Hard Link & Soft Link?
Link() ? Symlink()? rename()?

以上幾點為這次討論的議題。

因為有許多人在寫C Code的時候會使用到一些C standard API。 但是這些function 偏偏就是有些許的限制。 那該怎麼處理? 有什麼替代方案。 那原理到底是什麼? 有沒有需要知道呢!




實際操作Link


首先
1. 需要知道你將系統分成幾個槽或是parition
root@benny-VirtualBox:/home# blkid
/dev/sda1: UUID="29a0bfb0-2a98-45ca-a02b-2ff7e741c530" TYPE="ext4"
/dev/sda3: UUID="a80bf4f1-2e62-41e2-86cf-d8c7d2392eaa" TYPE="ext4"
/dev/sda5: UUID="c6c68dd2-35ae-48c8-9235-3b08c7c602dc" TYPE="swap"


以上就可以看到有兩個parition 被format成ext4,這兩個parition是我自己切成for "root directory" and /home

benny@benny-VirtualBox:~/linux_source_code/kernel$ df -h
檔案系統        容量  已用  可用 已用% 掛載點
/dev/sda3        60G   20G   37G   35% /
none            4.0K     0  4.0K    0% /sys/fs/cgroup
udev            991M   12K  991M    1% /dev
tmpfs           201M  996K  200M    1% /run
none            5.0M     0  5.0M    0% /run/lock
none           1001M  588K 1001M    1% /run/shm
none            100M   96K  100M    1% /run/user
/dev/sda1       1.9T   58G  1.8T    4% /home



2. 使用 dumpe2fs /dev/sda1 | more
將所有superblock / block / ...的資訊全都撈出來
圖1,Group 0的結構圖。還未新增檔案時的樣貌。

以上為我擷取的一個小段落,就是我想要知道/home底下的group 0的位置,還有多少inode我可以做使用,並且想要知道inode跟新增檔案時,會使用到的block有什麼關係。

ls -ali

       2 drwxr-xr-x  6 root   root    4096  4月 25 15:48 .
       2 drwxr-xr-x 25 root   root    4096  8月 19  2015 ..
  131073 drwxr-xr-x 47 benny  benny   4096  4月 14 19:59 benny
      12 drwxr-xr-x  2 deploy deploy  4096 10月 15  2015 deploy
12320769 drwxr-xr-x  3 root   root    4096 11月  9 15:24 ftp
      11 drwx------  2 root   root   16384 12月 10  2013 lost+found


接下來你可以發現有三個目錄 (benny, deploy, ftp),我不確定為什麼lost+found沒有被算成多一個目錄。

那free node就如同上面所示為 8175個(未被使用),block 為23512個。

那假如要新增一個檔案,會發生什麼事情呢?

3.
touch inode
ln inode i
ln -s inode is
目錄內會出現以下結果
       2 drwxr-xr-x  6 root   root    4096  4月 25 15:48 .
       2 drwxr-xr-x 25 root   root    4096  8月 19  2015 ..
  131073 drwxr-xr-x 47 benny  benny   4096  4月 14 19:59 benny
      12 drwxr-xr-x  2 deploy deploy  4096 10月 15  2015 deploy
12320769 drwxr-xr-x  3 root   root    4096 11月  9 15:24 ftp
      18 -rw-r--r--  2 root   root       0  4月 25 15:48 i
      18 -rw-r--r--  2 root   root       0  4月 25 15:48 inode
      19 lrwxrwxrwx  1 root   root       5  4月 25 15:48 is -> inode
      11 drwx------  2 root   root   16384 12月 10  2013 lost+found



4. 那這個時候的superblock會出現什麼結果呢?
圖2,Group 0的結構圖。新增檔案時的樣貌。

可以發現Free inode已經變成20-8192,原因就在file 最前面的 18跟19的inode number被使用掉了喔~~~

從上述可以得知,當你要做link (無論是soft link 或 Hard link)都會從superblock裡面的block 0的位置取出Free inode number來使用。


架構原理

Partition


那接下來就是,既然已經知道superblock他是儲存在Group 0的位置。那抽像圖就會如下圖所示。
圖3,Disk切割 -> Group Block -> SuperBlock。
從上圖可以得知,原本的第一排,為Disk上的分割區,這些分割區可能都有各自安裝一組自己的OS,所以可以透過MBR裡安裝的開機啟動程序來完成多OS的開機流程。
(More detailed: http://dywang.csie.cyut.edu.tw/dywang/linuxSystem/node81.html)


而第二排的圖片。

就是我們這次透過dumpe2fs /dev/sda1所抓出來的實際資料內容。 /dev/sda1/也可以當作partition 1。內容可以同等下圖。
圖4,針對sda1 Partition所擷取出的superblock資訊。



而第三排的圖片。

資料也同等於下圖。[註1]
圖5,Group 0中針對Block 放置的類型。

Group 0: Partition中第一塊Block 的位置。
CheckSum: 檢查碼,應該不用多做解釋吧!
unused inodes 8175: 指目前這個block中,還有8175個inode數可以背建造。
Primary superblock at 0: 指superblock的位置在 block 0的位置
Group Descriptors at 1-122: 會記錄一些資訊,如block bitmap block, Inode bitmap block, inode table block, free block count, free inode count, directories count.
Reserved GDT block: 被保留於被允許可以做resizeing(on-line resizing)
inode bitmap: 記錄有哪些inode number未被使用及使用。
block bitmap: 記錄有哪些block是否為empty的。
Inode Table: 在最後一節會詳細說明,並且與inode做相對應的區別分析。

以上是相對應的介紹,但是沒有講到非常的細節! 如果想知道在互相討論一下吧!

另外Group 0的block大小為32768個blocks,因為有同事有提到這個問題,一個Group會切割多大,其實這也是預設的切割方法。 而這個數值是根據1K/2K/4K去做變動的。
如果以code來說,計算這個blocks per group其實是有公式的。

再ext4_super_block的struct中,會有個變數為s_first_data_block,這個數值,是用來計算superblock的大小,同等於後續的Group會為多少的上限。

/* calculate the first block number of the group */
1808 static inline ext4_fsblk_t
1809 ext4_group_first_block_no(struct super_block *sb, ext4_group_t group_no)
1810 {
1811     return group_no * (ext4_fsblk_t)EXT4_BLOCKS_PER_GROUP(sb) +
1812         le32_to_cpu(EXT4_SB(sb)->s_es->s_first_data_block);
1813 }

(Ref: http://osxr.org:8080/linux/source/fs/ext4/ext4.h)

如此一來,只要根據這個funcion算出來的值,將會是表示一個filesys再切割group block的時候應該會怎麼做計算。

那Group 0 = 32768 個Block。內容的切割會分成幾個呢?
SuperBlock: 1 Block
Group Descriptors: n blocks, 我的切割圖下為122 Blocks
Data Block Bitmap: 1 Block
Inode Block Bitmap: 1 Block
Inode Table: n Blocks,我的切割圖下為512 Blocks
Data Block: n Block,我的切割圖下為32131 Blocks

註: EXT2/3/4 Block 的Size可以分為以下三種。
1K : 8192 Block per Block Group
2K : 16384 Block per Block Group
4K : 32768 Block per Block Group

而每個file system的資料都會儲存在Group 0的superblock裡面。那其他group將會儲存該superblock的backup。  如下圖所示。

圖6,針對Backup Block時,Group Block內容擺放的資料。


可以看到第三行有Backup superblock at 32768.......。
這個superblock不會出現在每一個Group中。
所以可以透過此Command Line的方式進行Print
benny@benny-VirtualBox:~/linux_source_code/kernel$ sudo dumpe2fs /dev/sda1 | grep -i "superblock"

就可以取得下表格

dumpe2fs 1.42.9 (4-Feb-2014)
  Primary superblock at 0, Group descriptors at 1-122
  Backup superblock at 32768, Group descriptors at 32769-32890
  Backup superblock at 98304, Group descriptors at 98305-98426
  Backup superblock at 163840, Group descriptors at 163841-163962
  Backup superblock at 229376, Group descriptors at 229377-229498
  Backup superblock at 294912, Group descriptors at 294913-295034
  Backup superblock at 819200, Group descriptors at 819201-819322
  Backup superblock at 884736, Group descriptors at 884737-884858
  Backup superblock at 1605632, Group descriptors at 1605633-1605754
  Backup superblock at 2654208, Group descriptors at 2654209-2654330
  Backup superblock at 4096000, Group descriptors at 4096001-4096122
  Backup superblock at 7962624, Group descriptors at 7962625-7962746
  Backup superblock at 11239424, Group descriptors at 11239425-11239546
  Backup superblock at 20480000, Group descriptors at 20480001-20480122
  Backup superblock at 23887872, Group descriptors at 23887873-23887994
  Backup superblock at 71663616, Group descriptors at 71663617-71663738
  Backup superblock at 78675968, Group descriptors at 78675969-78676090
  Backup superblock at 102400000, Group descriptors at 102400001-102400122
  Backup superblock at 214990848, Group descriptors at 214990849-214990970

註1:
在網路上我有找到一些資料,說明superblock跟Group Descriptors會一直反覆出現在每個Block Group中。 但是我發現在我的sda1內是沒有一直反覆出現的。 如下Group 2
Group 2: (Blocks 65536-98303) [INODE_UNINIT, ITABLE_ZEROED]
  Checksum 0x0f4e, unused inodes 8192
  Block bitmap at 1027 (bg #0 + 1027), Inode bitmap at 1043 (bg #0 + 1043)
  Inode table at 2081-2592 (bg #0 + 2081)
  4073 free blocks, 8192 free inodes, 0 directories, 8192 unused inodes
  Free blocks: 65537-65543, 65545-65551, 66757, 67440-67455, 67523-67551, 67580-67583, 68789, 68854-69119, 69121-69127, 69633-69639, 69641-69647, 70719, 71297-71327, 71356-71359, 71393-71679, 74364-74367,
74418-74431, 74466-74751, 75068-75071, 75112-75135, 75190-75199, 75254-75775, 81756-81759, 81778-81791, 81846-81855, 81890-81919, 87230-87231, 87281-87551, 88065-88071, 88073-88079, 89285, 89863-89919, 899
81-89983, 90020-90047, 90083-91519, 91554-91583, 91620-91647, 91744-91775, 91811-92159, 92161-92167, 92169-92175, 93381, 93959-94015, 94056-94207
  Free inodes: 16385-24576


inode table & inode 

Inode Table

根據圖4,可以知道Inode Size為256 Bytes。 並且透過圖5,可以知道Inode Table放置的Block位置。

那接下來,Inode應該會長怎樣呢?

以下為抽像圖。


當看到這張圖的時候,應該會覺得很困惑,為什麼他長得特別奇怪?  其實這就是真實中,如果我要建立一個File 可能會出現的樣子。

接下來要開始針對每一個部分去逐步解釋囉!!

首先你會先看到第一排有很多數字的 0~8191,共8192個位置,其實這也是算出來的數值喔。 而這個連續性的數值,整體表現出來就是指Inode Table的意思喔!

因為Inode Table的意義就是Multiple consecutive blocks, each of which contains a predefined number of inodes。


這個算法非常簡單,如果以4K的Block大小來做計算。
而我們Inode Table有512 Blocks來做儲存。
Inode需要256 Bytes。
那我們這個Group Block 0會有幾個Inode呢?

4096 / 256 = 16個inode per Block。
512 * 16 = 8192 個Blocks。

這樣是不是很簡單呢! 其實算法都差不多。 就是根據你安裝的設定去計算每一個Group 會擁有多少Inode數。


接下來就是最複雜的Inode了!!


大家可以看到這個位置共有 15 個位置,可以做使用。








沒有留言:

張貼留言