Skip to main content

第 3 章:磁碟與檔案系統管理

ls -li 觀察 root 家目錄內的檔案所佔用的 inode 號碼

ls -li
ls -li

total 8
53735697 -rw-------. 1 root root 1816 May 4 17:57 anaconda-ks.cfg
53745858 -rw-r--r--. 1 root root 1864 May 4 18:01 initial-setup-ks.cfg

df 列出檔案系統的整體磁碟使用

df
df [-ahikHTm] [目錄或檔名]選項與參數:
-a :列出所有的檔案系統,包括系統特有的 /proc 等檔案系統;
-k :以 KBytes 的容量顯示各檔案系統;
-m :以 MBytes 的容量顯示各檔案系統;
-h :以人們較易閱讀的 GBytes, MBytes, KBytes 等格式自行顯示;
-H :以 M=1000K 取代 M=1024K 的進位方式;
-T :連同該 partition 的 filesystem 名稱 (例如 xfs) 也列出;
-i :不用磁碟容量,而以 inode 的數量來顯示

#範例一:將系統內所有的 filesystem 列出來!

df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/centos-root 10475520 3409408 7066112 33% /
devtmpfs 627700 0 627700 0% /dev
tmpfs 637568 80 637488 1% /dev/shm
tmpfs 637568 24684 612884 4% /run
tmpfs 637568 0 637568 0% /sys/fs/cgroup
/dev/mapper/centos-home 5232640 67720 5164920 2% /home
/dev/vda2 1038336 133704 904632 13% /boot

# 在 Linux 底下如果 df 沒有加任何選項,那麼預設會將系統內所有的
# (不含特殊記憶體內的檔案系統與 swap) 都以 1 Kbytes 的容量來列出來!
# 至於那個 /dev/shm 是與記憶體有關的掛載,先不要理他!
df example
#範例二:將容量結果以易讀的容量格式顯示出來

df -h

Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 10G 3.3G 6.8G 33% /
devtmpfs 613M 0 613M 0% /dev
tmpfs 623M 80K 623M 1% /dev/shm
tmpfs 623M 25M 599M 4% /run
tmpfs 623M 0 623M 0% /sys/fs/cgroup
/dev/mapper/centos-home 5.0G 67M 5.0G 2% /home
/dev/vda2 1014M 131M 884M 13% /boot

#範例三:將系統內的所有特殊檔案格式及名稱都列出來

df -aT

Filesystem Type 1K-blocks Used Available Use% Mounted on
rootfs rootfs 10475520 3409368 7066152 33% /
proc proc 0 0 0 - /proc
sysfs sysfs 0 0 0 - /sys
devtmpfs devtmpfs 627700 0 627700 0% /dev
securityfs securityfs 0 0 0 - /sys/kernel/security
tmpfs tmpfs 637568 80 637488 1% /dev/shm
devpts devpts 0 0 0 - /dev/pts
tmpfs tmpfs 637568 24684 612884 4% /run
tmpfs tmpfs 637568 0 637568 0% /sys/fs/cgroup
.....(中間省略).....
/dev/mapper/centos-root xfs 10475520 3409368 7066152 33% /
selinuxfs selinuxfs 0 0 0 - /sys/fs/selinux
.....(中間省略).....
/dev/mapper/centos-home xfs 5232640 67720 5164920 2% /home
/dev/vda2 xfs 1038336 133704 904632 13% /boot
binfmt_misc binfmt_misc 0 0 0 - /proc/sys/fs/binfmt_misc

# 系統裡面其實還有很多特殊的檔案系統存在的。那些比較特殊的檔案系統幾乎
# 都是在記憶體當中,例如 /proc 這個掛載點。因此,這些特殊的檔案系統
# 都不會佔據磁碟空間喔! ^_^

# 範例四:將 /etc 底下的可用的磁碟容量以易讀的容量格式顯示

df -h /etc

Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 10G 3.3G 6.8G 33% /

# 這個範例比較有趣一點啦,在 df 後面加上目錄或者是檔案時, df
# 會自動的分析該目錄或檔案所在的 partition ,並將該 partition 的容量顯示出來,
# 所以,您就可以知道某個目錄底下還有多少容量可以使用了! ^_^範例五:將目前各個 partition 當中可用的 inode 數量列出

df -ih

Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/centos-root 10M 108K 9.9M 2% /
devtmpfs 154K 397 153K 1% /dev
tmpfs 156K 5 156K 1% /dev/shm
tmpfs 156K 497 156K 1% /run
tmpfs 156K 13 156K 1% /sys/fs/cgroup

# 這個範例則主要列出可用的 inode 剩餘量與總容量。分析一下與範例一的關係,
# 你可以清楚的發現到,通常 inode 的數量剩餘都比 block 還要多呢

du 評估檔案系統的磁碟使用量

du
du [-ahskm] 檔案或目錄名稱

選項與參數:
-a :列出所有的檔案與目錄容量,因為預設僅統計目錄底下的檔案量而已。
-h :以人們較易讀的容量格式 (G/M) 顯示;
-s :列出總量而已,而不列出每個各別的目錄佔用容量;
-S :不包括子目錄下的總計,與 -s 有點差別。
-k :以 KBytes 列出容量顯示;
-m :以 MBytes 列出容量顯示;範例一:列出目前目錄下的所有檔案容量

du

4 ./.cache/dconf <==每個目錄都會列出來
4 ./.cache/abrt
8 ./.cache
....(中間省略)....
0 ./test4
4 ./.ssh <==包括隱藏檔的目錄
76 . <==這個目錄(.)所佔用的總量

# 直接輸入 du 沒有加任何選項時,則 du 會分析『目前所在目錄』
# 的檔案與目錄所佔用的磁碟空間。但是,實際顯示時,僅會顯示目錄容量(不含檔案),
# 因此 . 目錄有很多檔案沒有被列出來,所以全部的目錄相加不會等於 . 的容量喔!
# 此外,輸出的數值資料為 1K 大小的容量單位。範例二:同範例一,但是將檔案的容量也列出來

du -a

4 ./.bash_logout <==有檔案的列表了
4 ./.bash_profile
4 ./.bashrc
....(中間省略)....
4 ./.ssh/known_hosts
4 ./.ssh
76 .

# 範例三:檢查根目錄底下每個目錄所佔用的容量

du -sm /*

0 /bin
99 /boot
....(中間省略)....
du: cannot access ‘/proc/17772/task/17772/fd/4’: No such file or directory
du: cannot access ‘/proc/17772/fdinfo/4’: No such file or directory
0 /proc <==不會佔用硬碟空間!
1 /root
25 /run
....(中間省略)....
3126 /usr <==系統初期最大就是他了啦!
117 /var

# 這是個很常被使用的功能~利用萬用字元 * 來代表每個目錄,如果想要檢查某個目錄下,
# 哪個次目錄佔用最大的容量,可以用這個方法找出來。值得注意的是,如果剛剛安裝好 Linux 時,
# 那麼整個系統容量最大的應該是 /usr 。而 /proc 雖然有列出容量,但是那個容量是在記憶體中,
# 不佔磁碟空間。至於 /proc 裡頭會列出一堆『No such file or directory』 的錯誤,
# 別擔心!因為是記憶體內的程序,程序執行結束就會消失,因此會有些目錄找不到,是正確的!
  • 每個檔案都會佔用一個 inode ,檔案內容由 inode 的記錄來指向;
  • 想要讀取該檔案,必須要經過目錄記錄的檔名來指向到正確的 inode 號碼才能讀取。
Hard Link
ll -i /etc/crontab34474855

-rw-r--r--. 1 root root 451 Jun 10 2014 /etc/crontab

ln /etc/crontab . <==建立實體連結的指令

ll -i /etc/crontab crontab34474855

-rw-r--r--. 2 root root 451 Jun 10 2014 crontab
34474855 -rw-r--r--. 2 root root 451 Jun 10 2014 /etc/crontab

在建立一個獨立的檔案,而這個檔案會讓資料的讀取指向他 link 的那個檔案的檔名!由於只是利用檔案來做為指向的動作, 所以,當來源檔被刪除之後,symbolic link 的檔案會『開不了』, 會一直說『無法開啟某檔案!』。實際上就是找不到原始『檔名』而已

Symbolic Link
ln -s /etc/crontab crontab2
ll -i /etc/crontab /root/crontab234474855

-rw-r--r--. 2 root root 451 Jun 10 2014 /etc/crontab
53745909 lrwxrwxrwx. 1 root root 12 Jun 23 22:31 /root/crontab2 -> /etc/crontab
Symbolic Link example
ln [-sf] 來源檔 目標檔

選項與參數:
-s :如果不加任何參數就進行連結,那就是hard link,至於 -s 就是symbolic link
-f :如果 目標檔 存在時,就主動的將目標檔直接移除後再建立!範例一:將 /etc/passwd 複製到 /tmp 底下,並且觀察 inode 與 block

cd /tmp
cp -a /etc/passwd .
du -sb ; df -i .6602 . <==先注意一下這裡的容量是多少!
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/centos-root 10485760 109748 10376012 2% /

# 利用 du 與 df 來檢查一下目前的參數~那個 du -sb 是計算整個 /tmp 底下有多少 bytes 的容量啦!

# 範例二:將 /tmp/passwd 製作 hard link 成為 passwd-hd 檔案,並觀察檔案與容量

ln passwd passwd-hd
du -sb ; df -i .6602 .
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/centos-root 10485760 109748 10376012 2% /

# 仔細看,即使多了一個檔案在 /tmp 底下,整個 inode 與 block 的容量並沒有改變!

ls -il passwd*2668897

-rw-r--r--. 2 root root 2092 Jun 17 00:20 passwd
2668897 -rw-r--r--. 2 root root 2092 Jun 17 00:20 passwd-hd

# 原來是指向同一個 inode 啊!這是個重點啊!另外,那個第二欄的連結數也會增加!範例三:將 /tmp/passwd 建立一個符號連結

ln -s passwd passwd-so
ls -li passwd*

2668897 -rw-r--r--. 2 root root 2092 Jun 17 00:20 passwd
2668897 -rw-r--r--. 2 root root 2092 Jun 17 00:20 passwd-hd
2668898 lrwxrwxrwx. 1 root root 6 Jun 23 22:40 passwd-so -> passwd

# passwd-so 指向的 inode number 不同了!這是一個新的檔案~這個檔案的內容是指向
# passwd 的。passwd-so 的大小是 6bytes ,因為 『passwd』 這個單字共有六個字元之故

du -sb ; df -i .6608 .
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/mapper/centos-root 10485760 109749 10376011 2% /

#整個容量與 inode 使用數都改變囉~確實如此啊!範例四:刪除原始檔案 passwd ,其他兩個檔案是否能夠開啟?

rm passwd
cat passwd-hd.....(正常顯示完畢!)
cat passwd-so
cat: passwd-so: No such file or directory
ll passwd*

-rw-r--r--. 1 root root 2092 Jun 17 00:20 passwd-hd
lrwxrwxrwx. 1 root root 6 Jun 23 22:40 passwd-so -> passwd

# 怕了吧!符號連結果然無法開啟!另外,如果符號連結的目標檔案不存在,
# 其實檔名的部分就會有特殊的顏色顯示喔!

lsblk 列出系統上的所有磁碟列表

lsblk
lsblk [-dfimpt] [device]

選項與參數:
-d :僅列出磁碟本身,並不會列出該磁碟的分割資料
-f :同時列出該磁碟內的檔案系統名稱
-i :使用 ASCII 的線段輸出,不要使用複雜的編碼 (再某些環境下很有用)
-m :同時輸出該裝置在 /dev 底下的權限資料 (rwx 的資料)
-p :列出該裝置的完整檔名!而不是僅列出最後的名字而已。
-t :列出該磁碟裝置的詳細資料,包括磁碟佇列機制、預讀寫的資料量大小等範例一:列出本系統下的所有磁碟與磁碟內的分割資訊

lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom
vda 252:0 0 40G 0 disk # 一整顆磁碟
|-vda1 252:1 0 2M 0 part
|-vda2 252:2 0 1G 0 part /boot
`-vda3 252:3 0 30G 0 part
|-centos-root 253:0 0 10G 0 lvm / # 在 vda3 內的其他檔案系統
|-centos-swap 253:1 0 1G 0 lvm [SWAP]
`-centos-home 253:2 0 5G 0 lvm /home

blkid 列出裝置的 UUID 等參數

直接使用 blkid 來找出裝置的 UUID 喔!UUID 是全域單一識別碼 (universally unique identifier),Linux 會將系統內所有的裝置都給予一個獨一無二的識別碼, 這個識別碼就可以拿來作為掛載或者是使用這個裝置/檔案系統之用。

blkid
blkid

/dev/vda2: UUID="94ac5f77-cb8a-495e-a65b-2ef7442b837c" TYPE="xfs"
/dev/vda3: UUID="WStYq1-P93d-oShM-JNe3-KeDl-bBf6-RSmfae" TYPE="LVM2_member"
/dev/sda1: UUID="35BC-6D6B" TYPE="vfat"
/dev/mapper/centos-root: UUID="299bdc5b-de6d-486a-a0d2-375402aaab27" TYPE="xfs"
/dev/mapper/centos-swap: UUID="905dc471-6c10-4108-b376-a802edbd862d" TYPE="swap"
/dev/mapper/centos-home: UUID="29979bf1-4a28-48e0-be4a-66329bf727d9" TYPE="xfs"

parted 列出磁碟的分割表類型與分割資訊

雖然我們已經知道了系統上面的所有裝置,並且透過 blkid 也知道了所有的檔案系統!不過,還是不清楚磁碟的分割類型。 這時我們可以透過簡單的 parted 來輸出喔!

parted
parted device_name print

# 範例一:列出 /dev/vda 磁碟的相關資料

parted /dev/vda print

Model: Virtio Block Device (virtblk) # 磁碟的模組名稱(廠商)
Disk /dev/vda: 42.9GB # 磁碟的總容量
Sector size (logical/physical): 512B/512B # 磁碟的每個邏輯/物理磁區容量
Partition Table: gpt # 分割表的格式 (MBR/GPT)
Disk Flags: pmbr_boot

Number Start End Size File system Name Flags # 底下才是分割資料
1 1049kB 3146kB 2097kB bios_grub
2 3146kB 1077MB 1074MB xfs
3 1077MB 33.3GB 32.2GB lvm

gdisk

gdisk
gdisk 裝置名稱

#範例:由前一小節的 lsblk 輸出,我們知道系統有個 /dev/vda,請觀察該磁碟的分割與相關資料

gdisk /dev/vda <==仔細看,不要加上數字喔!

GPT fdisk (gdisk) version 0.8.6

Partition table scan:
MBR: protective
BSD: not present
APM: not present
GPT: present

Found valid GPT with protective MBR; using GPT. <==找到了 GPT 的分割表!

Command (? for help): <==這裡可以讓你輸入指令動作,可以按問號 (?) 來查看可用指令
Command (? for help):?
b back up GPT data to a file
c change a partition's name
d delete a partition # 刪除一個分割
i show detailed information on a partition
l list known partition types
n add a new partition # 增加一個分割
o create a new empty GUID partition table (GPT)
p print the partition table # 印出分割表 (常用)
q quit without saving changes # 不儲存分割就直接離開 gdisk
r recovery and transformation options (experts only)
s sort partitions
t change a partition's type code
v verify disk
w write table to disk and exit # 儲存分割操作後離開 gdisk
x extra functionality (experts only)
? print this menu
Command (? for help):

gdisk example
Command (? for help):p  <== 這裡可以輸出目前磁碟的狀態
Disk /dev/vda: 83886080 sectors, 40.0 GiB # 磁碟檔名/磁區數與總容量
Logical sector size: 512 bytes # 單一磁區大小為 512 bytes
Disk identifier (GUID): A4C3C813-62AF-4BFE-BAC9-112EBD87A483 # 磁碟的 GPT 識別碼
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 83886046
Partitions will be aligned on 2048-sector boundaries
Total free space is 18862013 sectors (9.0 GiB)

Number Start (sector) End (sector) Size Code Name # 底下為完整的分割資訊了!
1 2048 6143 2.0 MiB EF02 # 第一個分割槽資料
2 6144 2103295 1024.0 MiB 0700
3 2103296 65026047 30.0 GiB 8E00
# 分割編號 開始磁區號碼 結束磁區號碼 容量大小
Command (? for help):q# 想要不儲存離開嗎?按下 q 就對了!不要隨便按 w 啊!

用 gdisk 新增分割槽

假設我需要有如下的分割需求:

  • 1GB 的 xfs 檔案系統 (Linux)
  • 1GB 的 vfat 檔案系統 (Windows)
  • 0.5GB 的 swap (Linux swap)
gdisk 分割
gdisk /dev/vda
Command (? for help):p
Number Start (sector) End (sector) Size Code Name
1 2048 6143 2.0 MiB EF02
2 6144 2103295 1024.0 MiB 0700
3 2103296 65026047 30.0 GiB 8E00
# 找出最後一個 sector 的號碼是很重要的!

Command (? for help):? # 查一下增加分割的指令為何
Command (? for help):n # 就是這個!所以開始新增的行為!
Partition number (4-128, default 4):4 # 預設就是 4 號,所以也能 enter 即可!
First sector (34-83886046, default = 65026048) or {+-}size{KMGTP}:65026048 # 也能 enter
Last sector (65026048-83886046, default = 83886046) or {+-}size{KMGTP}:+1G # 決不要 enter
# 這個地方可有趣了!我們不需要自己去計算磁區號碼,透過 +容量 的這個方式,
# 就可以讓 gdisk 主動去幫你算出最接近你需要的容量的磁區號碼喔!

Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): # 使用預設值即可~直接 enter 下去!
# 這裡在讓你選擇未來這個分割槽預計使用的檔案系統!預設都是 Linux 檔案系統的 8300 囉!

Command (? for help):p
Number Start (sector) End (sector) Size Code Name
1 2048 6143 2.0 MiB EF02
2 6144 2103295 1024.0 MiB 0700
3 2103296 65026047 30.0 GiB 8E00
4 65026048 67123199 1024.0 MiB 8300 Linux filesystem

重點在『 Last sector 』那一行,那行絕對不要使用預設值!因為預設值會將所有的容量用光!因此它預設選擇最大的磁區號碼! 因為我們僅要 1GB 而已,所以你得要加上 +1G 這樣即可!不需要計算 sector 的數量,gdisk 會根據你填寫的數值, 直接計算出最接近該容量的磁區數!每次新增完畢後,請立即『 p 』查看一下結果喔!請繼續處理後續的兩個分割槽! 最終出現的畫面會有點像底下這樣才對!

gdisk command
Command (? for help):p
Number Start (sector) End (sector) Size Code Name
1 2048 6143 2.0 MiB EF02
2 6144 2103295 1024.0 MiB 0700
3 2103296 65026047 30.0 GiB 8E00
4 65026048 67123199 1024.0 MiB 8300 Linux filesystem
5 67123200 69220351 1024.0 MiB 0700 Microsoft basic data
6 69220352 70244351 500.0 MiB 8200 Linux swap

基本上,幾乎都用預設值,然後透過 +1G, +500M 來建置所需要的另外兩個分割槽!比較有趣的是檔案系統的 ID 啦!一般來說, Linux 大概都是 8200/8300/8e00 等三種格式, Windows 幾乎都用 0700 這樣,如果忘記這些數字,可以在 gdisk 內按下:『 L 』來顯示喔! 如果一切的分割狀態都正常的話,那麼就直接寫入磁碟分割表吧!

gdisk Partition
Command (? for help):w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N):y
OK; writing new GUID partition table (GPT) to /dev/vda.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot.
The operation has completed successfully.
# gdisk 會先警告你可能的問題,我們確定分割是對的,這時才按下 y !不過怎麼還有警告?
# 這是因為這顆磁碟目前正在使用當中,因此系統無法立即載入新的分割表~

cat /proc/partitions
major minor #blocks name

252 0 41943040 vda
252 1 2048 vda1
252 2 1048576 vda2
252 3 31461376 vda3
253 0 10485760 dm-0
253 1 1048576 dm-1
253 2 5242880 dm-2
# 你可以發現,並沒有 vda4, vda5, vda6 喔!因為核心還沒有更新!

因為 Linux 此時還在使用這顆磁碟,為了擔心系統出問題,所以分割表並沒有被更新喔!這個時候我們有兩個方式可以來處理! 其中一個是重新開機,不過很討厭!另外一個則是透過 partprobe 這個指令來處理即可!

partprobe 更新 Linux 核心的分割表資訊

partprobe
partprobe [-s]  # 你可以不要加 -s !那麼螢幕不會出現訊息!
partprobe -s # 不過還是建議加上 -s 比較清晰!
/dev/vda: gpt partitions 1 2 3 4 5 6

lsblk /dev/vda # 實際的磁碟分割狀態
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 252:0 0 40G 0 disk
|-vda1 252:1 0 2M 0 part
|-vda2 252:2 0 1G 0 part /boot
|-vda3 252:3 0 30G 0 part
| |-centos-root 253:0 0 10G 0 lvm /
| |-centos-swap 253:1 0 1G 0 lvm [SWAP]
| `-centos-home 253:2 0 5G 0 lvm /home
|-vda4 252:4 0 1G 0 part
|-vda5 252:5 0 1G 0 part
`-vda6 252:6 0 500M 0 part

cat /proc/partitions # 核心的分割紀錄
major minor #blocks name

252 0 41943040 vda
252 1 2048 vda1
252 2 1048576 vda2
252 3 31461376 vda3
252 4 1048576 vda4
252 5 1048576 vda5
252 6 512000 vda6
# 現在核心也正確的抓到了分割參數了!

用 gdisk 刪除一個分割槽

gdisk delete
gdisk /dev/vda
Command (? for help):p

Number Start (sector) End (sector) Size Code Name
1 2048 6143 2.0 MiB EF02
2 6144 2103295 1024.0 MiB 0700
3 2103296 65026047 30.0 GiB 8E00
4 65026048 67123199 1024.0 MiB 8300 Linux filesystem
5 67123200 69220351 1024.0 MiB 0700 Microsoft basic data
6 69220352 70244351 500.0 MiB 8200 Linux swap

Command (? for help):d
Partition number (1-6):6

Command (? for help):p# 你會發現 /dev/vda6 不見了!非常棒!沒問題就寫入吧!

Command (? for help):w# 同樣會有一堆訊息!

lsblk# 你會發現!怪了!怎麼還是有 /dev/vda6 呢?沒辦法!還沒有更新核心的分割表啊!所以當然有錯!

partprobe -s
lsblk# 這個時候,那個 /dev/vda6 才真的消失不見了!了解吧!

fdisk

fdisk 跟 gdisk 使用的方式幾乎一樣!只是一個使用 ? 作為指令提示資料,一個使用 m 作為提示這樣而已。 此外,fdisk 有時會使用磁柱 (cylinder) 作為分割的最小單位,與 gdisk 預設使用 sector 不太一樣!

fdisk
fdisk /dev/sda
Command (m for help):m <== 輸入 m 後,就會看到底下這些指令介紹
Command action
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition <==刪除一個partition
l list known partition types
m print this menu
n add a new partition <==新增一個partition
o create a new empty DOS partition table
p print the partition table <==在螢幕上顯示分割表
q quit without saving changes <==不儲存離開fdisk程式
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit <==將剛剛的動作寫入分割表
x extra functionality (experts only)

磁碟格式化:建置檔案系統

XFS 檔案系統 mkfs.xfs

XFS
mkfs.xfs [-b bsize] [-d parms] [-i parms] [-l parms] [-L label] [-f] \\
[-r parms] 裝置名稱選項與參數:
關於單位:底下只要談到『數值』時,沒有加單位則為 bytes 值,可以用 k,m,g,t,p (小寫)等來解釋
比較特殊的是 s 這個單位,它指的是 sector 的『個數』喔!
-b :後面接的是 block 容量,可由 512 到 64k,不過最大容量限制為 Linux 的 4k 喔!
-d :後面接的是重要的 data section 的相關參數值,主要的值有:
agcount=數值 :設定需要幾個儲存群組的意思(AG),通常與 CPU 有關
agsize=數值 :每個 AG 設定為多少容量的意思,通常 agcount/agsize 只選一個設定即可
file :指的是『格式化的裝置是個檔案而不是個裝置』的意思!(例如虛擬磁碟)
size=數值 :data section 的容量,亦即你可以不將全部的裝置容量用完的意思
su=數值 :當有 RAID 時,那個 stripe 數值的意思,與底下的 sw 搭配使用
sw=數值 :當有 RAID 時,用於儲存資料的磁碟數量(須扣除備份碟與備用碟)
sunit=數值 :與 su 相當,不過單位使用的是『幾個 sector(512bytes大小)』的意思
swidth=數值 :就是 su*sw 的數值,但是以『幾個 sector(512bytes大小)』來設定
-f :如果裝置內已經有檔案系統,則需要使用這個 -f 來強制格式化才行!
-i :與 inode 有較相關的設定,主要的設定值有:
size=數值 :最小是 256bytes 最大是 2k,一般保留 256 就足夠使用了!
internal=[0|1]:log 裝置是否為內建?預設為 1 內建,如果要用外部裝置,使用底下設定
logdev=device :log 裝置為後面接的那個裝置上頭的意思,需設定 internal=0 才可!
size=數值 :指定這塊登錄區的容量,通常最小得要有 512 個 block,大約 2M 以上才行!
-L :後面接這個檔案系統的標頭名稱 Label name 的意思!
-r :指定 realtime section 的相關設定值,常見的有:
extsize=數值 :就是那個重要的 extent 數值,一般不須設定,但有 RAID 時,
最好設定與 swidth 的數值相同較佳!最小為 4K 最大為 1G 。範例:將前一小節分割出來的 /dev/vda4 格式化為 xfs 檔案系統
mkfs.xfs /dev/vda4
meta-data=/dev/vda4 isize=256 agcount=4, agsize=65536 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0 finobt=0
data = bsize=4096 blocks=262144, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=0
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
# 很快格是化完畢!都用預設值!較重要的是 inode 與 block 的數值

blkid /dev/vda4
/dev/vda4: UUID="39293f4f-627b-4dfd-a015-08340537709c" TYPE="xfs"
# 確定建置好 xfs 檔案系統了!

XFS example
範例:找出你系統的 CPU 數,並據以設定你的 agcount 數值
grep 'processor' /proc/cpuinfo
processor : 0
processor : 1
# 所以就是有兩顆 CPU 的意思,那就來設定設定我們的 xfs 檔案系統格式化參數吧!!

mkfs.xfs -f -d agcount=2 /dev/vda4
meta-data=/dev/vda4 isize=256 agcount=2, agsize=131072 blks
= sectsz=512 attr=2, projid32bit=1
= crc=0 finobt=0
.....(底下省略).....
# 可以跟前一個範例對照看看,可以發現 agcount 變成 2 了喔!
# 此外,因為已經格式化過一次,因此 mkfs.xfs 可能會出現不給你格式化的警告!因此需要使用 -f

XFS example
mkfs.xfs -f -d agcount=2,sunit=512,swidth=3584 -r extsize=1792k /dev/vda4

EXT4 檔案系統 mkfs.ext4

EXT4
mkfs.ext4 [-b size] [-L label] 裝置名稱選項與參數:
-b :設定 block 的大小,有 1K, 2K, 4K 的容量,
-L :後面接這個裝置的標頭名稱。範例:將 /dev/vda5 格式化為 ext4 檔案系統
mkfs.ext4 /dev/vda5
mke2fs 1.42.9 (28-Dec-2013)
Filesystem label= # 顯示 Label name
OS type: Linux
Block size=4096 (log=2) # 每一個 block 的大小
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks # 跟 RAID 相關性較高
65536 inodes, 262144 blocks # 總計 inode/block 的數量
13107 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=268435456
8 block groups # 共有 8 個 block groups 喔!
32768 blocks per group, 32768 fragments per group
8192 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376

Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done

dumpe2fs -h /dev/vda5
dumpe2fs 1.42.9 (28-Dec-2013)
Filesystem volume name: <none>
Last mounted on: <not available>
Filesystem UUID: 3fd5cc6f-a47d-46c0-98c0-d43b072e0e12
....(中間省略)....
Inode count: 65536
Block count: 262144
Block size: 4096
Blocks per group: 32768
Inode size: 256
Journal size: 32M

其他檔案系統 mkfs

mkfs 其實是個綜合指令而已,當我們使用 mkfs -t xfs 時,它就會跑去找 mkfs.xfs 相關的參數給我們使用! 如果想要知道系統還支援哪種檔案系統的格式化功能,直接按 [tabl] 就很清楚了!

file system
mkfs[tab][tab]
mkfs mkfs.btrfs mkfs.cramfs mkfs.ext2 mkfs.ext3 mkfs.ext4
mkfs.fat mkfs.minix mkfs.msdos mkfs.vfat mkfs.xfs

所以系統還有支援 ext2/ext3/vfat 等等多種常用的檔案系統喔!那如果要將剛剛的 /dev/vda5 重新格式化為 VFAT 檔案系統呢?

vfat
mkfs -t vfat /dev/vda5
blkid /dev/vda5
/dev/vda5: UUID="7130-6012" TYPE="vfat" PARTLABEL="Microsoft basic data"

mkfs.ext4 /dev/vda5
blkid /dev/vda4 /dev/vda5
/dev/vda4: UUID="e0a6af55-26e7-4cb7-a515-826a8bd29e90" TYPE="xfs"
/dev/vda5: UUID="899b755b-1da4-4d1d-9b1c-f762adb798e1" TYPE="ext4"

檔案系統檢驗

xfs_repair 處理 XFS 檔案系統

當有 xfs 檔案系統錯亂才需要使用這個指令!所以,這個指令最好是不要用到啦!但有問題發生時,這個指令卻又很重要...

xfs_repair
xfs_repair [-fnd] 裝置名稱

選項與參數:
-f :後面的裝置其實是個檔案而不是實體裝置
-n :單純檢查並不修改檔案系統的任何資料 (檢查而已)
-d :通常用在單人維護模式底下,針對根目錄 (/) 進行檢查與修復的動作!很危險!不要隨便使用範例:檢查一下剛剛建立的 /dev/vda4 檔案系統
xfs_repair /dev/vda4
Phase 1 - find and verify superblock...
Phase 2 - using internal log
Phase 3 - for each AG...
Phase 4 - check for duplicate blocks...
Phase 5 - rebuild AG headers and trees...
Phase 6 - check inode connectivity...
Phase 7 - verify and correct link counts...
done
# 共有 7 個重要的檢查流程!詳細的流程介紹可以 man xfs_repair 即可!範例:檢查一下系統原本就有的 /dev/centos/home 檔案系統
xfs_repair /dev/centos/home
xfs_repair: /dev/centos/home contains a mounted filesystem
xfs_repair: /dev/centos/home contains a mounted and writable filesystem

fatal error -- couldn't initialize XFS library

xfs_repair 可以檢查/修復檔案系統,不過,因為修復檔案系統是個很龐大的任務!因此,修復時該檔案系統不能被掛載! 所以,檢查與修復 /dev/vda4 沒啥問題,但是修復 /dev/centos/home 這個已經掛載的檔案系統時,嘿嘿!就出現上述的問題了! 沒關係,若可以卸載,卸載後再處理即可。

Linux 系統有個裝置無法被卸載,那就是根目錄啊!如果你的根目錄有問題怎辦?這時得要進入單人維護或救援模式,然後透過 -d 這個選項來處理! 加入 -d 這個選項後,系統會強制檢驗該裝置,檢驗完畢後就會自動重新開機囉!

fsck.ext4 處理 EXT4 檔案系統

fsck 是個綜合指令,如果是針對 ext4 的話,建議直接使用 fsck.ext4 來檢測比較妥當!那 fsck.ext4 的選項有底下幾個常見的項目:

fsck.ext4
fsck.ext4 [-pf] [-b superblock] 裝置名稱

選項與參數:
-p :當檔案系統在修復時,若有需要回覆 y 的動作時,自動回覆 y 來繼續進行修復動作。
-f :強制檢查!一般來說,如果 fsck 沒有發現任何 unclean 的旗標,不會主動進入
細部檢查的,如果您想要強制 fsck 進入細部檢查,就得加上 -f 旗標囉!
-D :針對檔案系統下的目錄進行最佳化配置。
-b :後面接 superblock 的位置!一般來說這個選項用不到。但是如果你的 superblock 因故損毀時,
透過這個參數即可利用檔案系統內備份的 superblock 來嘗試救援。一般來說,superblock 備份在:
1K block 放在 8193, 2K block 放在 16384, 4K block 放在 32768範例:找出剛剛建置的 /dev/vda5 的另一塊 superblock,並據以檢測系統
dumpe2fs -h /dev/vda5 | grep 'Blocks per group'
Blocks per group: 32768
# 看起來每個 block 群組會有 32768 個 block,因此第二個 superblock 應該就在 32768 上!
# 因為 block 號碼為 0 號開始編的!

fsck.ext4 -b 32768 /dev/vda5
e2fsck 1.42.9 (28-Dec-2013)
/dev/vda5 was not cleanly unmounted, check forced.
Pass 1: Checking inodes, blocks, and sizes
Deleted inode 1577 has zero dtime. Fix<y>?yes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information

/dev/vda5: * FILE SYSTEM WAS MODIFIED * # 檔案系統被改過,所以這裡會有警告!
/dev/vda5: 11/65536 files (0.0% non-contiguous), 12955/262144 blocks
# 當檔案系統出問題,它就會要你選擇是否修復~如果修復如上所示,按下 y 即可!
# 最終系統會告訴你,檔案系統已經被更改過,要注意該項目的意思!範例:已預設設定強制檢查一次 /dev/vda5
fsck.ext4 /dev/vda5
e2fsck 1.42.9 (28-Dec-2013)
/dev/vda5: clean, 11/65536 files, 12955/262144 blocks
# 檔案系統狀態正常,它並不會進入強制檢查!會告訴你檔案系統沒問題 (clean)

fsck.ext4 -f /dev/vda5
e2fsck 1.42.9 (28-Dec-2013)
Pass 1: Checking inodes, blocks, and sizes
....(底下省略)....

檔案系統掛載與卸載

掛載點是目錄, 而這個目錄是進入磁碟分割槽的入口。不過要進行掛載前,先確定幾件事

  • 單一檔案系統不應該被重複掛載在不同的掛載點(目錄)中;
  • 單一目錄不應該重複掛載多個檔案系統;
  • 要作為掛載點的目錄,理論上應該都是空目錄才是。
mount
mount -a

mount [-l]
mount [-t 檔案系統] LABEL='' 掛載點
mount [-t 檔案系統] UUID='' 掛載點
mount [-t 檔案系統] 裝置檔名 掛載點選項與參數:
-a :依照設定檔/etc/fstab 的資料將所有未掛載的磁碟都掛載上來
-l :單純的輸入 mount 會顯示目前掛載的資訊。加上 -l 可增列 Label 名稱!
-t :可以加上檔案系統種類來指定欲掛載的類型。常見的 Linux 支援類型有:xfs, ext3, ext4,
reiserfs, vfat, iso9660(光碟格式), nfs, cifs, smbfs (後三種為網路檔案系統類型)
-n :在預設的情況下,系統會將實際掛載的情況即時寫入 /etc/mtab 中,以利其他程式的運作。
但在某些情況下(例如單人維護模式)為了避免問題會刻意不寫入。此時就得要使用 -n 選項。
-o :後面可以接一些掛載時額外加上的參數!比方說帳號、密碼、讀寫權限等:
async, sync: 此檔案系統是否使用同步寫入 (sync) 或非同步 (async) 的
記憶體機制,請參考檔案系統運作方式。預設為 async。
atime,noatime: 是否修訂檔案的讀取時間(atime)。為了效能,某些時刻可使用 noatime
ro, rw: 掛載檔案系統成為唯讀(ro) 或可讀寫(rw)
auto, noauto: 允許此 filesystem 被以 mount -a 自動掛載(auto)
dev, nodev: 是否允許此 filesystem 上,可建立裝置檔案? dev 為可允許
suid, nosuid: 是否允許此 filesystem 含有 suid/sgid 的檔案格式?
exec, noexec: 是否允許此 filesystem 上擁有可執行 binary 檔案?
user, nouser: 是否允許此 filesystem 讓任何使用者執行 mount ?一般來說,
mount 僅有 root 可以進行,但下達 user 參數,則可讓
一般 user 也能夠對此 partition 進行 mount 。
defaults: 預設值為:rw, suid, dev, exec, auto, nouser, and async
remount: 重新掛載,這在系統出錯,或重新更新參數時,很有用!

系統有沒有指定哪些類型的 filesystem 才需要進行上述的掛載測試呢? 主要是參考底下這兩個檔案:

  • /etc/filesystems:系統指定的測試掛載檔案系統類型的優先順序;
  • /proc/filesystems:Linux系統已經載入的檔案系統類型。

那我怎麼知道我的 Linux 有沒有相關檔案系統類型的驅動程式呢?我們 Linux 支援的檔案系統之驅動程式都寫在如下的目錄中:

  • /lib/modules/$(uname -r)/kernel/fs/

例如 ext4 的驅動程式就寫在『/lib/modules/$(uname -r)/kernel/fs/ext4/』這個目錄下啦!

掛載 xfs/ext4/vfat 等檔案系統

mount
範例:找出 /dev/vda4 的 UUID 後,用該 UUID 來掛載檔案系統到 /data/xfs 內
blkid /dev/vda4
/dev/vda4: UUID="e0a6af55-26e7-4cb7-a515-826a8bd29e90" TYPE="xfs"

mount UUID="e0a6af55-26e7-4cb7-a515-826a8bd29e90" /data/xfs
mount: mount point /data/xfs does not exist # 非正規目錄!所以手動建立它!

mkdir -p /data/xfs
mount UUID="e0a6af55-26e7-4cb7-a515-826a8bd29e90" /data/xfs
df /data/xfs
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda4 1038336 32864 1005472 4% /data/xfs
# 順利掛載,且容量約為 1G 左右沒問題!範例:使用相同的方式,將 /dev/vda5 掛載於 /data/ext4
blkid /dev/vda5
/dev/vda5: UUID="899b755b-1da4-4d1d-9b1c-f762adb798e1" TYPE="ext4"

mkdir /data/ext4
mount UUID="899b755b-1da4-4d1d-9b1c-f762adb798e1" /data/ext4
df /data/ext4
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda5 999320 2564 927944 1% /data/ext4

重新掛載根目錄與掛載不特定目錄

整個目錄樹最重要的地方就是根目錄了,所以根目錄根本就不能夠被卸載的!問題是,如果你的掛載參數要改變, 或者是根目錄出現『唯讀』狀態時,如何重新掛載呢?最可能的處理方式就是重新開機 (reboot)!

mount
範例:將 / 重新掛載,並加入參數為 rw 與 auto
mount -o remount,rw,auto /

重點是那個『 -o remount,xx 』的選項與參數!請注意,要重新掛載 (remount) 時, 這是個非常重要的機制!尤其是當你進入單人維護模式時,你的根目錄常會被系統掛載為唯讀,這個時候這個指令就太重要了!

另外,我們也可以利用 mount 來將某個目錄掛載到另外一個目錄去喔!這並不是掛載檔案系統,而是額外掛載某個目錄的方法! 雖然底下的方法也可以使用 symbolic link 來連結,不過在某些不支援符號連結的程式運作中,還是得要透過這樣的方法才行。

mount
範例:將 /var 這個目錄暫時掛載到 /data/var 底下:

mkdir /data/var
mount --bind /var /data/var
ls -lid /var /data/var
16777346 drwxr-xr-x. 22 root root 4096 Jun 15 23:43 /data/var
16777346 drwxr-xr-x. 22 root root 4096 Jun 15 23:43 /var
# 內容完全一模一樣啊!因為掛載目錄的緣故!

mount | grep var
/dev/mapper/centos-root on /data/var type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

看起來,其實兩者連結到同一個 inode!透過這個 mount --bind 的功能, 您可以將某個目錄掛載到其他目錄去喔!而並不是整塊 filesystem 的啦!所以從此進入 /data/var 就是進入 /var 的意思喔!

umount 將裝置檔案卸載

unmount
umount [-fn] 裝置檔名或掛載點

選項與參數:
-f :強制卸載!可用在類似網路檔案系統 (NFS) 無法讀取到的情況下;
-l :立刻卸載檔案系統,比 -f 還強!
-n :不更新 /etc/mtab 情況下卸載。
unmount
範例:將本章之前自行掛載的檔案系統全部卸載:
mount.....(前面省略)...../dev/vda4 on /data/xfs type xfs (rw,relatime,seclabel,attr2,inode64,logbsize=256k,sunit=512,..)
/dev/vda5 on /data/ext4 type ext4 (rw,relatime,seclabel,data=ordered)
/dev/sr0 on /data/cdrom type iso9660 (ro,relatime)
/dev/sda1 on /data/usb type vfat (rw,relatime,fmask=0022,dmask=0022,codepage=950,iocharset=...)
/dev/mapper/centos-root on /data/var type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
# 先找一下已經掛載的檔案系統,如上所示,特殊字體即為剛剛掛載的裝置囉!
# 基本上,卸載後面接裝置或掛載點都可以!不過最後一個 centos-root 由於有其他掛載,
# 因此,該項目一定要使用掛載點來卸載才行!

umount /dev/vda4 <==用裝置檔名來卸載
umount /data/ext4 <==用掛載點來卸載
umount /data/cdrom <==因為掛載點比較好記憶!
umount /data/usb
umount /data/var <==一定要用掛載點!因為裝置有被其他方式掛載

磁碟/檔案系統參數修訂

某些時刻,你可能會希望修改一下目前檔案系統的一些相關資訊,舉例來說,你可能要修改 Label name , 或者是 journal 的參數,或者是其他磁碟/檔案系統運作時的相關參數 (例如 DMA 啟動與否~)。 這個時候,就得需要底下這些相關的指令功能囉~

mknod

還記得我們說過,在 Linux 底下所有的裝置都以檔案來代表吧!但是那個檔案如何代表該裝置呢? 很簡單!就是透過檔案的 major 與 minor 數值來替代的~所以,那個 major 與 minor 數值是有特殊意義的,不是隨意設定的喔!我們在 lsblk 指令的用法裡面也談過這兩個數值呢!

mknod
ll /dev/vda*
brw-rw----. 1 root disk 252, 0 Jun 24 02:30 /dev/vda
brw-rw----. 1 root disk 252, 1 Jun 24 02:30 /dev/vda1
brw-rw----. 1 root disk 252, 2 Jun 15 23:43 /dev/vda2
brw-rw----. 1 root disk 252, 3 Jun 15 23:43 /dev/vda3
brw-rw----. 1 root disk 252, 4 Jun 24 20:00 /dev/vda4
brw-rw----. 1 root disk 252, 5 Jun 24 21:15 /dev/vda5

上表當中 252 為主要裝置代碼 (Major) 而 0~5 則為次要裝置代碼 (Minor)。 我們的 Linux 核心認識的裝置資料就是透過這兩個數值來決定的!舉例來說,常見的磁碟檔名 /dev/sda 與 /dev/loop0 裝置代碼如下所示:

磁碟檔名MajorMinor
/dev/sda80-15
/dev/sdb816-31
/dev/loop070
/dev/loop171
mknod
mknod 裝置檔名 [bcp] [Major] [Minor]

選項與參數:
裝置種類:
b :設定裝置名稱成為一個周邊儲存設備檔案,例如磁碟等;
c :設定裝置名稱成為一個周邊輸入設備檔案,例如滑鼠/鍵盤等;
p :設定裝置名稱成為一個 FIFO 檔案;
Major :主要裝置代碼;
Minor :次要裝置代碼;範例:由上述的介紹我們知道 /dev/vda10 裝置代碼 252, 10,請建立並查閱此裝置
mknod /dev/vda10 b 252 10
ll /dev/vda10brw-r--r--. 1 root root 252, 10 Jun 24 23:40 /dev/vda10
# 上面那個 252 與 10 是有意義的,不要隨意設定啊!範例:建立一個 FIFO 檔案,檔名為 /tmp/testpipe
mknod /tmp/testpipe p
ll /tmp/testpipeprw-r--r--. 1 root root 0 Jun 24 23:44 /tmp/testpipe
# 注意啊!這個檔案可不是一般檔案,不可以隨便就放在這裡!
# 測試完畢之後請刪除這個檔案吧!看一下這個檔案的類型!是 p 喔!^_^

rm /dev/vda10 /tmp/testpipe
rm: remove block special file '/dev/vda10' ?y
rm: remove fifo '/tmp/testpipe' ?y

xfs_admin 修改 XFS 檔案系統的 UUID 與 Label name

如果你當初格式化的時候忘記加上標頭名稱,後來想要再次加入時,不需要重複格式化!直接使用這個 xfs_admin 即可。 這個指令直接拿來處理 LABEL name 以及 UUID 即可囉!

xfs_admin
xfs_admin [-lu] [-L label] [-U uuid] 裝置檔名選項與參數:
-l :列出這個裝置的 label name
-u :列出這個裝置的 UUID
-L :設定這個裝置的 Label name
-U :設定這個裝置的 UUID 喔!範例:設定 /dev/vda4 的 label name 為 vbird_xfs,並測試掛載

xfs_admin -L vbird_xfs /dev/vda4
writing all SBs
new label = "vbird_xfs" # 產生新的 LABEL 名稱囉!
xfs_admin -l /dev/vda4
label = "vbird_xfs"
mount LABEL=vbird_xfs /data/xfs/範例:利用 uuidgen 產生新 UUID 來設定 /dev/vda4,並測試掛載
umount /dev/vda4 # 使用前,請先卸載!
uuidgen
e0fa7252-b374-4a06-987a-3cb14f415488 # 很有趣的指令!可以產生新的 UUID 喔!
xfs_admin -u /dev/vda4
UUID = e0a6af55-26e7-4cb7-a515-826a8bd29e90
xfs_admin -U e0fa7252-b374-4a06-987a-3cb14f415488 /dev/vda4
Clearing log and setting UUID
writing all SBs
new UUID = e0fa7252-b374-4a06-987a-3cb14f415488
mount UUID=e0fa7252-b374-4a06-987a-3cb14f415488 /data/xfs

tune2fs 修改 ext4 的 label name 與 UUID

tune2fs
tune2fs [-l] [-L Label] [-U uuid] 裝置檔名

選項與參數:
-l :類似 dumpe2fs -h 的功能~將 superblock 內的資料讀出來~
-L :修改 LABEL name
-U :修改 UUID 囉!範例:列出 /dev/vda5 的 label name 之後,將它改成 vbird_ext4
dumpe2fs -h /dev/vda5 | grep name
dumpe2fs 1.42.9 (28-Dec-2013)
Filesystem volume name: <none> # 果然是沒有設定的!

tune2fs -L vbird_ext4 /dev/vda5
dumpe2fs -h /dev/vda5 | grep name
Filesystem volume name: vbird_ext4
mount LABEL=vbird_ext4 /data/ext4

開機掛載 /etc/fstab 及 /etc/mtab

直接到 /etc/fstab 設定

  • 根目錄 / 是必須掛載的﹐而且一定要先於其它 mount point 被掛載進來。
  • 其它 mount point 必須為已建立的目錄﹐可任意指定﹐但一定要遵守必須的系統目錄架構原則 (FHS)
  • 所有 mount point 在同一時間之內﹐只能掛載一次。
  • 所有 partition 在同一時間之內﹐只能掛載一次。
  • 如若進行卸載﹐您必須先將工作目錄移到 mount point(及其子目錄) 之外。
/etc/fstab 及 /etc/mtab
cat /etc/fstab# Device                              Mount point  filesystem parameters    dump fsck
/dev/mapper/centos-root / xfs defaults 0 0
UUID=94ac5f77-cb8a-495e-a65b-2ef7442b837c /boot xfs defaults 0 0
/dev/mapper/centos-home /home xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
[裝置/UUID等]  [掛載點]  [檔案系統]  [檔案系統參數]  [dump]  [fsck]

第一欄:磁碟裝置檔名 /UUID/LABEL name:

  • 這個欄位可以填寫的資料主要有三個項目:
    • 檔案系統或磁碟的裝置檔名,如 /dev/vda2 等
    • 檔案系統的 UUID 名稱,如 UUID=xxx
    • 檔案系統的 LABEL 名稱,例如 LABEL=xxx

第二欄:掛載點 (mount point)

  • 就是掛載點,一定是目錄

第三欄:磁碟分割槽的檔案系統

  • 在手動掛載時可以讓系統自動測試掛載,但在這個檔案當中我們必須要手動寫入檔案系統才行! 包括 xfs, ext4, vfat, reiserfs, nfs 等

第四欄:檔案系統參數

參數參數概念內容意義
async/sync非同步 / 同步設定磁碟是否以非同步方式運作!預設為 async(效能較佳)
auto/noauto自動 / 非自動當下達 mount -a 時,此檔案系統是否會被主動測試掛載。預設為 auto。
rw/ro可讀寫 / 唯讀讓該分割槽以可讀寫或者是唯讀的型態掛載上來,如果你想要分享的資料是不給使用者隨意變更的, 這裡也能夠設定為唯讀。則不論在此檔案系統的檔案是否設定 w 權限,都無法寫入喔!
exec/noexec可執行 / 不可執行限制在此檔案系統內是否可以進行『執行』的工作?如果是純粹用來儲存資料的目錄, 那麼可以設定為 noexec 會比較安全。不過,這個參數也不能隨便使用,因為你不知道該目錄下是否預設會有執行檔。舉例來說,如果你將 noexec 設定在 /var ,當某些軟體將一些執行檔放置於 /var 下時,那就會產生很大的問題喔! 因此,建議這個 noexec 最多僅設定於你自訂或分享的一般資料目錄。
user/nouser允許 / 不允許使用者掛載是否允許使用者使用 mount 指令來掛載呢?一般而言,我們當然不希望一般身份的 user 能使用 mount 囉,因為太不安全了,因此這裡應該要設定為 nouser 囉!
suid/nosuid具有 / 不具有 suid 權限該檔案系統是否允許 SUID 的存在?如果不是執行檔放置目錄,也可以設定為 nosuid 來取消這個功能!
defaults-同時具有 rw, suid, dev, exec, auto, nouser, async 等參數。 基本上,預設情況使用 defaults 設定即可!

第五欄:能否被 dump 備份指令作用

  • dump 是一個用來做為備份的指令,不過現在有太多的備份方案了,所以這個項目可以不要理會啦!直接輸入 0 就好了!

第六欄:是否以 fsck 檢驗磁區

  • 早期開機的流程中,會有一段時間去檢驗本機的檔案系統,看看檔案系統是否完整 (clean)。 不過這個方式使用的主要是透過 fsck 去做的,我們現在用的 xfs 檔案系統就沒有辦法適用,因為 xfs 會自己進行檢驗,不需要額外進行這個動作!所以直接填 0 就好了。

再來看看 /dev/vda4 是否已經掛載,如果掛載了,請務必卸載再說!

df
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/vda4 1038336 32864 1005472 4% /data/xfs

竟然不知道何時被掛載了?趕緊給他卸載先!因為,如果要被掛載的檔案系統已經被掛載了(無論掛載在哪個目錄),那測試就不會進行喔!

umount /dev/vda4

最後測試一下剛剛我們寫入 /etc/fstab 的語法有沒有錯誤!這點很重要!因為這個檔案如果寫錯了, 則你的 Linux 很可能將無法順利開機完成!所以請務必要測試測試喔!

mount -a  df /data/xfs

最終有看到 /dev/vda4 被掛載起來的資訊才是成功的掛載了!而且以後每次開機都會順利的將此檔案系統掛載起來的! 現在,你可以下達 reboot 重新開機,然後看一下預設有沒有多一個 /dev/vda4 呢?

/etc/fstab 是開機時的設定檔,不過,實際 filesystem 的掛載是記錄到 /etc/mtab 與 /proc/mounts 這兩個檔案當中的。每次我們在更動 filesystem 的掛載時,也會同時更動這兩個檔案喔!但是,萬一發生你在 /etc/fstab 輸入的資料錯誤,導致無法順利開機成功,而進入單人維護模式當中,那時候的 / 可是 read only 的狀態,當然你就無法修改 /etc/fstab ,也無法更新 /etc/mtab 囉~那怎麼辦?沒關係,可以利用底下這一招:

mount -n -o remount,rw /

記憶體置換空間 swap 之建置

  • 設定一個 swap partition
  • 建立一個虛擬記憶體的檔案

使用實體分割槽建置 swap

建立 swap 分割槽的方式也是非常的簡單的!透過底下幾個步驟就搞定囉:

  1. 分割:先使用 gdisk 在你的磁碟中分割出一個分割槽給系統作為 swap 。由於 Linux 的 gdisk 預設會將分割槽的 ID 設定為 Linux 的檔案系統,所以你可能還得要設定一下 system ID 就是了。
  2. 格式化:利用建立 swap 格式的『mkswap 裝置檔名』就能夠格式化該分割槽成為 swap 格式囉
  3. 使用:最後將該 swap 裝置啟動,方法為:『swapon 裝置檔名』。
  4. 觀察:最終透過 free 與 swapon -s 這個指令來觀察一下記憶體的用量吧!
swap
gdisk /dev/vda
Command (? for help):n
Partition number (6-128, default 6):
First sector (34-83886046, default = 69220352) or {+-}size{KMGTP}:
Last sector (69220352-83886046, default = 83886046) or {+-}size{KMGTP}:+512M
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):8200
Changed type of partition to 'Linux swap'

Command (? for help):p
Number Start (sector) End (sector) Size Code Name
6 69220352 70268927 512.0 MiB 8200 Linux swap # 重點就是產生這東西!

Command (? for help):w

Do you want to proceed? (Y/N):y

partprobe
lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
vda 252:0 0 40G 0 disk
.....(中間省略).....
`-vda6 252:6 0 512M 0 part # 確定這裡是存在的才行!

開始建置 swap 格式
mkswap /dev/vda6
Setting up swapspace version 1, size = 524284 KiB
no label, UUID=6b17e4ab-9bf9-43d6-88a0-73ab47855f9d
blkid /dev/vda6
/dev/vda6: UUID="6b17e4ab-9bf9-43d6-88a0-73ab47855f9d" TYPE="swap"
# 確定格式化成功!且使用 blkid 確實可以抓到這個裝置了喔!

觀察與載入 swap
free
total used free shared buff/cache available
Mem: 1275140 227244 330124 7804 717772 875536 # 實體記憶體
Swap: 1048572 101340 947232 # swap 相關
# 我有 1275140K 的實體記憶體,使用 227244K 剩餘 330124K ,使用掉的記憶體有
# 717772K 用在緩衝/快取的用途中。至於 swap 已經有 1048572K 囉!這樣會看了吧?!

swapon /dev/vda6
free
total used free shared buff/cache available
Mem: 1275140 227940 329256 7804 717944 874752
Swap: 1572856 101260 1471596 <==有看到增加了沒?

swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 1048572 101260 -1
/dev/vda6 partition 524284 0 -2
# 上面列出目前使用的 swap 裝置有哪些的意思!

nano /etc/fstab
UUID="6b17e4ab-9bf9-43d6-88a0-73ab47855f9d" swap swap defaults 0 0
# 當然要寫入設定檔,只不過不是檔案系統,所以沒有掛載點!第二個欄位寫入 swap 即可。

使用檔案建置 swap

如果是在實體分割槽無法支援的環境下,此時前一小節提到的 loop 裝置建置方法就派的上用場啦! 與實體分割槽不一樣的,這個方法只是利用 dd 去建置一個大檔案而已。多說無益,我們就再透過檔案建置的方法建立一個 128 MB 的記憶體置換空間吧!

  • 使用 dd 這個指令來新增一個 128MB 的檔案在 /tmp 底下:
dd
dd if=/dev/zero of=/tmp/swap bs=1M count=128
128+0 records in
128+0 records out
134217728 bytes (134 MB) copied, 1.7066 seconds, 78.6 MB/s

ll -h /tmp/swap
-rw-r--r--. 1 root root 128M Jun 26 17:47 /tmp/swap
  • 使用 mkswap 將 `/tmp/swap`` 這個檔案格式化為 swap 的檔案格式:
mkswap
mkswap /tmp/swap
Setting up swapspace version 1, size = 131068 KiB
no label, UUID=4746c8ce-3f73-4f83-b883-33b12fa7337c
# 這個指令下達時請『特別小心』,因為下錯字元控制,將可能使您的檔案系統掛掉!
  • 使用 swapon 來將 /tmp/swap 啟動囉!
swapon
swapon /tmp/swap
swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 1048572 100380 -1
/dev/vda6 partition 524284 0 -2
/tmp/swap file 131068 0 -3
  • 使用 swapoff 關掉 swap file,並設定自動啟用
swapoff
nano /etc/fstab/tmp/swap  swap  swap  defaults  0  0
# 為何這裡不要使用 UUID 呢?這是因為系統僅會查詢區塊裝置 (block device) 不會查詢檔案!
# 所以,這裡千萬不要使用 UUID,不然系統會查不到喔!

swapoff /tmp/swap /dev/vda6
swapon -s
Filename Type Size Used Priority
/dev/dm-1 partition 1048572 100380 -1
# 確定已經回復到原本的狀態了!然後準備來測試!!

swapon -a
swapon -s

# 最終你又會看正確的三個 swap 出現囉!這也才確定你的 /etc/fstab 設定無誤!

檔案系統的特殊觀察與操作

磁碟空間之浪費問題

在 EXT2 介紹中談到了一個 block 只能放置一個檔案, 因此太多小檔案將會浪費非常多的磁碟容量。但你有沒有注意到,整個檔案系統中包括 superblock, inode table 與其他中介資料等其實都會浪費磁碟容量喔!所以當我們在 /dev/vda4, /dev/vda5 建立起 xfs/ext4 檔案系統時, 一掛載就立刻有很多容量被用掉了!

另外,不知道你有沒有發現到,當你使用 ls -l 去查詢某個目錄下的資料時,第一行都會出現一個『total』的字樣! 那是啥東西?其實那就是該目錄下的所有資料所耗用的實際 block 數量 * block 大小的值。 我們可以透過 ll -s 來觀察看看上述的意義:

ll -sh
ll -sh
total 12K
4.0K -rw-------. 1 root root 1.8K May 4 17:57 anaconda-ks.cfg
4.0K -rw-r--r--. 2 root root 451 Jun 10 2014 crontab
0 lrwxrwxrwx. 1 root root 12 Jun 23 22:31 crontab2 -> /etc/crontab
4.0K -rw-r--r--. 1 root root 1.9K May 4 18:01 initial-setup-ks.cfg
0 -rw-r--r--. 1 root root 0 Jun 16 01:11 test1
0 drwxr-xr-x. 2 root root 6 Jun 16 01:11 test2
0 -rw-rw-r--. 1 root root 0 Jun 16 01:12 test3
0 drwxrwxr-x. 2 root root 6 Jun 16 01:12 test4