6.1 FreeBSD 的檔案系統架構
我們知道在 UNIX 系統中,檔案系統結構是一個樹狀結構,一個目錄下還有很多的目錄及檔案,而這些目錄下又會有更多的目錄及檔案,就像是一顆樹一樣,從根開始往上擴展。
對於硬碟的使用,在 UNIX 系統中,硬碟分割區會被掛在一個目錄下,在存取磁碟前,「掛入」(mount) 是必要的過程。也就是說,系統會將一個硬碟的分割區掛在一個目錄下,就好像 Windows 會將硬碟分割區放在 C:、D: 同樣意思。所以,在 UNIX 系統中,磁碟分割區會和現有的系統目錄合併。
在說明 FreeBSD 如何硬碟掛在目錄下使用之前,我們先來看一下 FreeBSD 對於儲存裝置的命名規則。FreeBSD 會給每個硬碟、光碟機的儲存裝置一個代號,並在 /dev 目錄下產生一個相對映的裝置檔。例如,我們的 IDE 硬碟代號就是 ad。以下為常見的儲存裝置代號:
- ad:IDE 硬碟。
- acd:IDE 光碟機。
- da:SCSI 硬碟、USB 硬碟及大姆哥。
- cd:SCSI 光碟機。
- fd:軟碟機。
- sa:SCSI 磁帶機。
- ast:IDE 磁帶機。
裝置的代號由 0 開始算,第一個 IDE 硬碟的代號是 ad0,第二個是 ad1,依此類推。如果您有一個 IDE 硬碟,則可以在 /dev/ 中看到一個檔名為 /dev/ad0 的裝置檔。
大多數的作業系統都支援將一個硬碟分割成多個磁區,以 Windows 而言,我們可以將一個硬碟分割成 C:、D: 等多個磁區。在 Windows 中,我們稱這個分割區為 Partition。然而,在 FreeBSD 中,我們稱之為 slice。不管是 Windows 的 Partition 或是 FreeBSD 的 slice,在這裡我們統稱為主要磁區。PC 架構下,BIOS 認得的主要磁區最多只有四個。
FreeBSD 和其它作業系統不同的地方是我們會先分割在主要磁區 (slice) 下再細分成多個分割區,而這個細分之後的分割區才叫做 Partition。以下面這個圖為例:
圖 6-1
我們看到第一個主要磁區是 Windows 用的掉的,它在 FreeBSD 中的代號是 ad0s1,而第二個主要磁區是 FreeBSD 所使用,其代號是 ad0s2,代號 s1、s2 指的就是主要磁區 slice 1 及 slice 2。而在 ad0s2 這個主要磁區中,我們又細分為三個分割區,分別是 ad0s2a、ad0s2b 及 ad0s2d。
分割區代號 a、b、d 等在 FreeBSD 有一些規則:
- a:代號 a 通常會分配給根目錄使用。
- b:代號 b 通常是給 swap 空間使用。
- c:代號 c 通常是代表整個主要磁區,所以不會被拿來使用。
- defgh:其它的代號都是可以被用在任何分割區上。以前代號 d 有一些特別用意,不過現在已經沒有了。
所以當您看到一個分割區代號 ad0s1a 時,就可以知道它是第一個 IDE 硬碟 (ad0) 的第一個主要磁區 (ad0s1) 的第一個分割區 (ad0s1a)。
讓我們回到硬碟分割區和目錄之間的關係。在 FreeBSD 中,硬碟分割區會被掛在目錄下使用,例如下列的 df 指令輸出結果:
# df -h Filesystem Size Used Avail Capacity Mounted on /dev/ad0s1a 1.9G 389M 1.4G 21% / devfs 1.0K 1.0K 0B 100% /dev /dev/ad0s1d 989M 54K 910M 0% /var /dev/ad0s1e 4.8G 3.8G 657M 86% /usr /dev/ad1s1d 10.9G 149M 10.6G 1% /usr/local
我們可以看到分割區 ad0s1a 是掛在根目錄 (/) 下,而 ad0s1d 掛在 /var 中。上述 df 指令輸出的範例中,/、/dev、/var、/usr 等都是磁碟分割區的掛入點 (mount points)。下圖即為分割區示意圖:
圖 6-2
除了根目錄外,每一個掛入點都可以被卸載。例如 ad1s1d 被掛在 /usr/local 中,我們可以動態卸載它。/usr/local 在掛入磁碟分割區前,它可能空的或是已經有一些檔案或目錄,但掛入後,我們看到該目錄中的東西會全部變成存在於 ad1s1d 這個硬碟中的資料。通常這些系統用的掛入點在還沒掛入磁碟前都是一些空目錄,而掛入後才會出現該目錄下的其它檔案及資料。以 /var 為例,在掛入前它是空的目錄,而掛入後,才會出現 db、mail 等目錄。
請注意,掛入點和磁碟分割區之間並沒有什麼特殊關聯。例如,如果您有二個掛入點 /volume1 及 /volume2,而有二個分割區 ad0s1d 及 ad0s1e,您可以任意將 ad0s1d 掛在 /volume1 或 /volume2。以上圖中的掛入點為例,您也可以將 ad1s1d 掛在 /mnt 下,只是 ad1s1d 這個分割區原本是掛在 /usr/local 下,已有一些 /usr/local 下的目錄結構及資料,所以還是掛在 /usr/local 下才不會有系統檔案找不到的問題。
6.2 監看檔案系統使用情形
幾乎所有 FreeBSD 上的應用都必須使用硬碟。我們必須注意系統磁碟空間足夠,並了解磁碟的使用效率。本小節中,我們將介紹一些 FreeBSD 常用的磁碟管理指令,讓我們可以更快的了解目前的系統使用狀態。
6.2.1 磁碟空間使用情形
在大部份的 UNIX 系統中都有二個指令可以了解硬碟的使用情形:df 及 du。
指令 df 可以顯示目前所有檔案系統的最大可用空間及使用情形,請看下列這個例子:
# df -h Filesystem Size Used Avail Capacity Mounted on /dev/ad0s1a 1.9G 389M 1.4G 21% / devfs 1.0K 1.0K 0B 100% /dev /dev/ad0s1d 989M 54K 910M 0% /tmp /dev/ad0s1f 4.8G 3.8G 657M 86% /usr /dev/ad0s1e 1.9G 149M 1.6G 8% /var /dev/ad0s1g 26G 890K 24G 0% /volume2 /dev/da0s1d 325G 261G 38G 87% /volume1
我們加了參數 -h 表示使用「Human-readable」的輸出,也就是在檔案系統大小使用 GB、MB 等易讀的格式。
上面的指令輸出的第一個欄位及最後一個欄位分別是檔案系統及其掛入點。我們可以看到 /dev/ad0s1a 這個分割區被掛在根目錄下。我們在上一小節提到過 ad 所代表的是 IDE 的硬碟,而 s1 表示第一個主要磁區。我另外有一個 SCSI 硬碟,它的代號是 da,它的容量很大,主要用來存放資料。devfs 是一個特別的檔案系統,該檔案系統並非真的磁碟,而是 FreeBSD 用來管理系統硬體裝置的虛擬檔案系統。
接下來的四個欄位 Size、Used、Avail、及 Capacity 分別是該分割區的容量、已使用的大小、剩下的大小、及使用的百分比。當硬碟容量已滿時,您可能會看到已使用的百分比超過 100%,因為 FreeBSD 會留一些空間給 root,讓 root 在檔案系統滿時,還是可以寫東西到該檔案系統中,以進行管理。
另外,我們還可以使用參數 -i 來查看目前檔案系統 inode 的使用情形。有的時候雖然檔案系統還有空間,但若沒有足夠的 inode 來存放檔案的資訊,一樣會不能增加新的檔案。
# df -ih Filesystem Size Used Avail Capacity iused ifree %iused Mounted on /dev/ad0s1a 1.9G 389M 1.4G 21% 20495 262127 7% / devfs 1.0K 1.0K 0B 100% 0 0 100% /dev /dev/ad0s1d 989M 62K 910M 0% 24 141286 0% /tmp /dev/ad0s1f 4.8G 3.8G 657M 86% 311439 348015 47% /usr /dev/ad0s1e 1.9G 149M 1.6G 8% 1758 280864 1% /var /dev/ad0s1g 26G 890K 24G 0% 12 3532786 0% /volume2 /dev/da0s1d 325G 261G 38G 87% 707277 43311409 2% /volume1
我們可以看到根目錄的已經用掉的 inode 數量為 20495,還有 262127 的可用 inode。
|
指令 df 只能用來查看整個檔案系統的使用情形,如果您需要知道某個目錄的使用情形,可以用指令 du。
指令 du 能以指定的目錄下的子目錄為單位,顯示每個目錄內所有檔案所占用的磁碟空間大小。例如:
# du -h /etc 104K /etc/defaults 6.0K /etc/X11 8.0K /etc/bluetooth 4.0K /etc/gnats 52K /etc/isdn 388K /etc/mail 68K /etc/mtree 2.0K /etc/ntp 38K /etc/pam.d 44K /etc/periodic/daily 6.0K /etc/periodic/monthly 42K /etc/periodic/security 16K /etc/periodic/weekly 110K /etc/periodic 6.0K /etc/ppp 318K /etc/rc.d 2.0K /etc/skel 130K /etc/ssh 10K /etc/ssl 1.7M /etc
我們目樣使用 -h 參數來顯示 human-readable 的格式。在應用時,我們可以使用 du 這個指令來查看哪個目錄佔用最多的空間。不過,du 的輸出結果通常很長,我們可以加上 -s 參數來省略指定目錄下的子目錄,而只顯示該目錄的總合即可:
# du -sh /etc 1.7M /etc
在查看目錄的使用情形時,我們可以將輸出結果導到 sort 指令進行排序,以了解哪個檔案用了最多的空間:
# du /etc | sort -nr | more 1746 /etc 388 /etc/mail 318 /etc/rc.d 130 /etc/ssh 110 /etc/periodic 104 /etc/defaults 68 /etc/mtree 52 /etc/isdn 44 /etc/periodic/daily 42 /etc/periodic/security 38 /etc/pam.d 16 /etc/periodic/weekly 10 /etc/ssl 8 /etc/bluetooth 6 /etc/ppp 6 /etc/periodic/monthly 6 /etc/X11 4 /etc/gnats 2 /etc/skel 2 /etc/ntp
sort 的參數 -nr 表示要以數字排序法進行反向排序,因為我們要對目錄大小做排序,所以不可以使用 human-readable 的大小輸出,不然目錄大小中會有 K、M 等字樣,會造成排序不正確。
6.2.2 磁碟使用效率
除了查看硬碟的空間使用情形外,我們還可以查看目前硬碟是否忙碌中,以了解硬碟的使用效率。我們可以使用 systat 這個指令:
# systat -vm 1 3 users Load 0.12 0.12 0.09 6 26 00:38 Mem:KB REAL VIRTUAL VN PAGER SWAP PAGER Tot Share Tot Share Free in out in out Act 130120 5436 385556 11716 30540 count 146 All 233584 17544 2762124 45604 pages 846 Interrupts Proc:r p d s w Csw Trp Sys Int Sof Flt 8 cow 474 total 75 1514 379 2525 690 66 375 70564 wire 100 0: clk 132932 act 1: atkb 14.0%Sys 1.6%Intr 2.3%User 0.0%Nice 82.2%Idl 18024 inact 3: sio1 | | | | | | | | | | 13024 cache 4: sio0 =======+> 17516 free 7: ppc0 daefr 128 8: rtc Namei Name-cache Dir-cache 38 prcfr 40 9: fxp0 Calls hits % hits % 228 react 31 10: fxp 1020 672 66 pdwak 11: hpt 43 zfod pdpgs 12: psm Disks ad0 da0 pass0 43 ofod intrn 13: npx KB/t 28.20 0.00 0.00 %slo-z 35664 buf 175 14: ata tps 164 0 0 70 tfree 334 dirty 15: ata MB/s 4.52 0.00 0.00 17810 desiredvnodes % busy 43 0 0 16852 numvnodes 13772 freevnodes
systat 有許多資訊,我們使用參數 -vm1 來顯示最詳細的資訊,並設定每 1 秒更新一次資訊。在上面一堆複製的資訊中,請將重點於在中間「====+>」及左下角的 Disks,中間部份的「====+>」表示目前 CPU 的使用情形,我們可以看到有 82.2% 的 Idle (閒置)。而硬碟的使用情形中,我的第一個硬碟 ad0 正在忙碌中,有 43% 的忙碌。而另一個 SCSI 硬碟 da0 則是完全閒置,也就是沒有人正在使用它。
如果您想要知硬碟本身的存取速度,可以使用 diskinfo 這個指令。diskinfo 加了 -t 參數會對硬碟做一些測試並回報結果:
# diskinfo -v -t ad0 ad0 512 # sectorsize 40020664320 # mediasize in bytes (37G) 78165360 # mediasize in sectors 77545 # Cylinders according to firmware. 16 # Heads according to firmware. 63 # Sectors according to firmware. Seek times: Full stroke: 250 iter in 5.199255 sec = 20.797 msec Half stroke: 250 iter in 4.011383 sec = 16.046 msec Quarter stroke: 500 iter in 6.797812 sec = 13.596 msec Short forward: 400 iter in 2.774055 sec = 6.935 msec Short backward: 400 iter in 3.257613 sec = 8.144 msec Seq outer: 2048 iter in 0.352483 sec = 0.172 msec Seq inner: 2048 iter in 0.369383 sec = 0.180 msec Transfer rates: outside: 102400 kbytes in 4.511970 sec = 22695 kbytes/sec middle: 102400 kbytes in 4.770641 sec = 21465 kbytes/sec inside: 102400 kbytes in 4.174557 sec = 24530 kbytes/sec
diskinfo 指令的 -r 參數會先印出一些分割區的基本資訊,包含 sector size、分割區大小、磁柱數量等。接下來的測試會花一點時間,測試結果包含了「Seek times」及「Transfer rates」。「Seek times」指的是硬碟的搜尋速度,而「Transfer rates」是資料找到後從硬碟傳到系統的速度。