--- title: '分區、檔案系統 FS、邏輯卷' disqus: kyleAlien --- 分區、檔案系統 FS、邏輯卷 === ## Overview of Content 如有引用該文章請標明 :smile_cat: Linux 對於儲存設備要使用哪一種 **檔案系統** 有許多個選擇,**不同的檔案系統會有不同的特性** :::success * 如果喜歡讀更好看一點的網頁版本,可以到我新做的網站 [**DevTech Ascendancy Hub**](https://devtechascendancy.com/) 本篇文章對應的是 [**深入探索 Linux 文件系統與硬體管理 | 分區、檔案系統、邏輯卷 | inode**](https://devtechascendancy.com/partition_file-system_volume/) ::: [TOC] ## Linux 文件系統:虛擬目錄 Linux 硬碟路徑 **不採用** **驅動器符號** (`C:`, `D:` 槽...)而是採用 **虛擬目錄(`virtual directory`)**,虛擬目錄目錄的根 (root) 只有一個,透過這個根進入後才可以訪問其他檔案 :::info Linux 目錄路徑使用「正斜線, `/`」,Window 則是使用「反斜線, `\`」 ::: ### root 驅動器 * Linux 虛擬目錄會協調各個物理儲存設備(你可能有 10 個硬碟),而預設「第一個硬碟」就是 root 驅動器;root 驅動器包含了 **虛擬目錄的核心** ```shell= ## 切換到 root 目錄 cd / ``` * 在 root 目錄下,會創建一些特別的目錄,這些目錄稱為 **掛載點 (`mount point`)**;掛載點是虛擬目錄用於分配額外儲存設備的目錄,虛擬目錄會將這些文件或目錄出現在掛載點中 > 但這些被掛載的文件其實是在各自的硬碟中 (也就是目錄本身不代表真實資料在硬碟中的位置) > ![](https://i.imgur.com/Q991zGX.png) ### Linux 根目錄結構 * Linux 文件系統結構承襲 Unix 目錄結構,以下是幾個 root 目錄中常見的目錄及內容;這些目錄是基於 [**Filesystem Hierarchy Standard**](https://www.pathname.com/fhs/) 規範 | 目錄 | 描述 | 補充 | | - | - | - | | / | 虛擬根目錄 | - | | /bin | 二進制文件 | 存放用戶可使用的 GUN 工具 | | /boot | 啟動目錄 | 存放啟動相關文件 | | /dev | 設備目錄 | 創建設備節點 | | /etc | 系統配置文件 | 系統配置文件 `/etc/group`, `/etc/passwd`... 等等 | | /home | 主目錄 | 用戶目錄 | | /lib | 庫目錄 | 存放系統、應用所需的庫;`/lib` 目錄下一般只有共享函式庫,而 `/usr/lib` 目錄中則有靜態、動態函式庫 | | /media | 媒體目錄 | 可移動媒體設備常用掛載點(CD) | | /mnt | 掛載目錄 | 可移動設備的常用掛載點(USB) | | /opt | 可選目錄 | 存放第三方軟體、數據 | | /proc | 進程目錄 | 存放現有硬體、進程相關訊息 | | /root | root 用戶專用的主目錄 | - | | /sbin | 二進制文件 | **管理員級** GUN 工具 | | /run | 運行時目錄 | 存在軟體在運行時的文件 | | /srv | 服務目錄 | 存放本地服務的的文件 | | /sys | 系統目錄 | 存放系統硬碟資訊 | | /tmp | 臨時目錄 | 在目錄中創建、刪除臨時工作文件(重起時就會被清空) | | /usr | 二進制文件 | 用戶級 GUN 工具和數據文件 | | /var | 可變目錄 | 存放常變化的文件(log 日誌...等等) | >![](https://i.imgur.com/Arghd0J.png) * **`usr` 目錄**:用來存放 **使用者空間** 中的程序、資料,有許多重複根目錄的資料夾如下圖所示 > ![](https://hackmd.io/_uploads/Hyx2pKdL2.png) :::success * **Linux 核心位置** Linux 核心位置通常在 `/vmlinux` or `/boot/vmlinuz` 資料夾中;當系統啟動時引導裝載程式就會將引導程式加載到記憶體中 > 加載到記憶體中後,就不再需要讀取引導程式了 之後… 系統會根據需要載入、移除許多模組(這些 **模組稱為`loadable kernel modules`,這些模組通常在 `lib/modules` 目錄下**) ::: ### 相對、絕對路徑概念 * Unix 的目錄結構是從 `/`(正斜線)開始,也就是上面說的 root 目錄;接著目錄之間都使用 `/`(正斜線)分隔 :::info Window 系統則是使用 `\`(反斜線) ::: * 而路徑差異有分兩種 * **絕對路徑**:以 `/`(正斜線)開頭的路徑 * **相對路徑**:以 `.` or `..` 符號開頭的路徑;其中 **`.` 符號代表了當前的目錄** **`..` 符號則代表了上一層目錄!** ## 認識「分區」 **分區是軟體對整個硬碟(硬體)的劃分手段,而「系統認的是分區」而不是硬碟**,而分區是一種抽象出來的機制跟概念 > eg. 軟體將一塊硬碟區分為:`/dev/sda1`、`/dev/sdb3`、`/dev/sdc5` 三個分區,系統就會認為該裝置有三個硬碟(但實質上就只有一個硬碟) :::info * **為何需要分區**? 緣由有一些舊系統只能透過硬體上的 **固有區塊(`Boot Partition`)進行啟動**,所以管理員會預留這個區塊給啟動區 > 有可能這個硬碟的啟動區塊為 `0x00000000` ~ `0x000000FFFF`,那這個區塊就不可以讓使用者使用 為了避免特地買一塊小硬碟來作為啟動,所以規劃一塊硬碟中分區,來達成節省的目的 ::: * 大多數作業系統(Mac, Linux, Window...)都會對硬體進行分區切割,它分配的概念、常見關鍵自如下表 | 分配項目 | 說明 | | -------- | -------- | | 分區表 | 指向該硬碟有多少個分區,以及分區的地址 | | 分區 | 整塊分區,其中包含檔案系統、資料 | | 檔案系統 (F.S)| 協助上層訪問分區中的檔案資料 | 下圖為 Linux 對於一塊硬碟分區的概念圖: > ![](https://hackmd.io/_uploads/r1BgbJiDh.png) ### 使用者空間 & 核心空間:訪問檔案的差異 * 接著我們的應用一般來說存在 **使用者空間**(稱為使用者空間應用),而這個應用又是如何訪問到指定分區的檔案呢?請看下圖對應說明 從圖中我們可以看到核心空間的幾點要點 1. **使用者應用並不會直接呼叫到檔案系統**(`FS`),而是 **透過系統呼叫(`System Call`)來訪問檔案系統** > 系統呼叫就是使用者空件與核心空間的通訊方式 2. 檔案系統的角色是 **非必須角色**,系統仍可以繞過檔案系統來訪問分區設備 3. 設備介面、分區對照表會在訪問子設備(像是 SCSI),而子設備(驅動)才是真正訪問硬體設備的地方(有興趣可以先看看 [**硬體 - 設備管理**](https://devtechascendancy.com/unix-linux-dev_udevd_scsi/) 再往下閱讀) > ![](https://hackmd.io/_uploads/Skx7dJjw2.png) ### Linux 設備分區:操作分區表 * **分區表(用來紀錄硬碟的分區位置)有很多種,大略可以分為兩種** * **`Master Boot Record`**:傳統典型,主開機紀錄簡稱 `MBR` * **`Globally Unique Identifier Partition Table`**:逐漸普及,GUID 分區表簡稱 `GPT` ```mermaid graph LR 分區表 --> MBR 分區表 --> GPT ``` * 而如果使用者要操作分區表,在 Linux 有一些命令工具可以操控(創建、修改、移除、查看... 等等行為)分區,如下表 | 命令 | 功能概述 | | -------- | -------- | | `parted` | 文字命令工具,支援 `MBR`, `GPT` | | `gparted` | `parted` 命令的 GUI 版本 | | `fdisk` | Linux 傳統文字分區工具(**不支援 GPT**) | | `gdisk` | `fdisk` 另一個版本,該版本支援 GPT | ### 查看分區表:parted 命令 * **查看電腦當前的分區**:透過 `parted` 指令可以查看當前電腦裝置的所有分區 ```shell= sudo parted -l ``` > ![](https://hackmd.io/_uploads/ryiSakiwn.png) 從上圖我們可以觀察到幾件事,目前電腦裝置有 3 個分區(注意 `Module` 標註),它們使用的分區表就不同,如下表 | Module 標註 | 分區表類型(`partition`) | | - | - | | `Mass Storage device` | msdos(MBR 表) | | `Linux device-mapper` | loop | | `SD EE 4S5` | msdos(MBR 表) | > loop 設備允許將檔案當作區塊設備使用,從而將檔案系統對應到一個虛擬的區塊設備上 其中我們可以看到 `SD EE 4S5` 有兩個分區(兩個都是主分區) :::warning * **MBR 最多只能有 4 個主分區**,如果需要更多分區可以用擴充分區、邏輯分區來拓展 ::: > ![](https://hackmd.io/_uploads/rJA-lgow3.png) :::info * 另外我們可以使用 `dmesg` 命令來讀取 Linux 核心在初始化讀取 MBR 表時的除錯訊息 ```shell= dmesg | gawk '/sd+/{print $0}' ``` > ![](https://hackmd.io/_uploads/r1_B-giDh.png) ::: ### 更改分區表:操作 parted 命令 :::warning * 更改分區表的指令 `parted`、`fdisk` 差異? `parted` 會在你執行命令的同時「立刻」去增刪改,而 `fdisk` 則會在一系列的問答結束後才對分區做增刪改 ::: * **更改分區表時,需要注意以下兩點** 1. 更改前的資料 **備份**: 更改分區表,相對的分區表以下的管理區域(各個分區)都會被刪除,而刪除分區後資料就很難恢復,做好事先做備份 > 因為刪除分區時,同時也刪除了檔案系統(FS),而檔案由系統管理,所以很難將資料復原 2. **確保要操作硬碟沒有在被使用**: 因為大部分的 Linux 系統會自動掛載被刪除的檔案系統 * **在這裡我們使用 `parted` 命令分區**(如果要看 `fdisk` 請看另外小節) **`parted` 命令指定分區硬碟設定**: 運行以下命令來啟動 `parted` 命令並指定 `/dev` 目錄下,要分區的硬碟設備(例如 `/dev/sda`) ```shell= sudo parted /dev/sda ``` 在這個命令之後就會 進入 parted 交互式命令行(開始選擇一些選項,並使用一些內部的子資訊,像是 `mklabel`、`mkpart`、`print`、`quit`… 等等) * **`mklabel` 命令指定分區表類型**: `mklabel` 是 `parted` 中的一個子命令,用於指定一個新的分區表類型,**選擇適當的分區表類型(如 `msdos` 或 `gpt`)**,以下我們將 `/dev/sda` 硬碟做 GPT 分區 ```shell= mklabel gpt ``` * **`mkpart` 命令創建一個新分區**: 透過 `mkpart` 命令可以指定分區、並也可以指定文件系統類型、開始以及結束位置;以下創建 `/dev/sda` 的主要「分區」 ```shell= # mkpart primary <文件系统类型> <起始位置> <结束位置> # 檔案系統像是 ext4, fat32... 等等 # 起始、結束位置則以 MB, GB 為單位 mkpart primary ``` * **`print` 命令可以顯示對於硬碟的分區資訊**: 打印當前磁碟的分區訊息 ```shell= print ``` * **`quit` 命令退出操作**: ```shell= quit ``` ## 分區與硬體 ### 分區 & 傳統磁碟的構造:LBA 概念 * **傳統磁碟硬體概念圖如下** 透過概念圖可以得知,資料的讀取是透過 **讀寫頭**,如果是大容量磁碟就會有多個磁碟片、讀寫頭(每個磁碟片會有 `1~2` 個讀寫頭) > ![](https://hackmd.io/_uploads/Bko0Rgjvh.png) :::warning * 有人把傳統硬碟構造稱之為「**CHS 構造**」 `C` 柱面 `Cylinder`、`H` 讀寫頭 `Head`、`S` 扇區 `sector` * 讀取 CHS 數量? 對於 **現代硬碟來講,透過 ++指令獲取的 柱面數++ 並不準確**(無法適應現代的大容量硬碟,也無法處理外道柱面到內道柱面的儲存容量大小差異) ::: * **那分區、磁碟到底有什麼關係**? 傳統磁碟透過 ++磁碟片的旋轉++ & ++柱面++ 的讀取,來達到讀取資料;**如果分區沒有精確至於柱面,那讀取資料的速度就會不佳**;如下圖 > 下圖,對於同一份資料,但是分散在不同的住面分區,會導致讀寫頭要不斷移動才能讀取到所需的資料… 效能自然不佳 > > ![](https://hackmd.io/_uploads/Hy1mEZiDn.png) * 大部分硬碟支援 **邏輯區塊定址 LBA (`Logical Block Addressing`),透過區塊編號來定址**(也就是不會直接指向真正地址),而透過 LBA 可以確保分區位置在效率較佳的區塊 :::success * MBR 分區表包含 CHS 資訊和對應的 LBA 資訊 ```mermaid graph LR subgraph MBR 分區表 c(CHS 資訊) l(LBA 資訊) end ``` ::: ### 分區 & 固態硬碟 * 固態硬碟 SSD (`Solid State Disk`, SSD),**不需要旋轉磁盤**,它甚至沒有任何需動作的元件,也由於不需要像是傳統硬碟一樣移動讀寫頭,所以 **隨機存取也不會有問題** > 也就是說「不會因為分區位置不佳導致效率低」,分區位置變得不是很重要 * 雖然效能好,但仍有一些問題因素會影響到 SSD 效能:像是 **分區設定** 由於 SSD 每次讀取資料時都是讀取一塊資料(像是 `4096 Byte` 的資料),所以如果純取資料時,沒有精確地按照區塊存取,那同一份資料就可能分散到不同區塊(也就是塊狀讀取效能的問題),如下圖 > ![](https://hackmd.io/_uploads/SyEB6mTPn.png) ## 認識檔案系統 FS > 有時 檔案系統 也會被稱為 文件系統 :::success * **什麼是檔案系統**? 檔案系統通常是 **核心 & 使用者空間 聯繫的一環**,使用者程序可以透過系統呼叫來操作檔案系統,取得對應資訊(像是 `cd`, `ls` 等命令都是在檔案系統的基礎上操作) > ![](https://i.imgur.com/EpMyqi3.png) **檔案系統是一個 ++資料函式庫++**,它會透過映射區塊設備(`/dev` 目錄下的設備)為使用者提供我們共容易了解的樹狀檔案目錄結構(又稱為 **虛擬目錄**) :::info * 以往的檔案系統 **以往都是在核心負責實現檔案系統**,但有 [**Plan 9 計畫**](https://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs) 後,間接將檔案系統推向了在使用者空間也可以實現 > Plan 9 的 9P: 所有希望 **將服務作為文件** 提供給其他程序的程序都 **使用統一的協議** > > ![](https://hackmd.io/_uploads/H1ypWN6v2.png) ::: ::: 檔案系統決定了系統會如何去處理這個硬體的資訊(0 and 1 的讀取方式),**每種檔案系統都會「在 Linux 的虛擬目錄上建立一個虛擬目錄」** 而檔案系統又有很多類型,接下來小節會介紹幾個常見的檔案系統 ### VFS 虛擬檔案系統:界面協定 * 抽象虛擬文件檔案檔案系統 VFS(`Virtual File System`)負責定義檔案系統的實現介面,它使用的 Linux 可以依照介面協議支持許多不同類型的檔案系統 :::warning * **VFS 是內核中使用的所有文件系統的統一界面** > 也是由於該界面的存在,讓檔案系統自由發展;像是 Mac OS X 中使用的 `HFS+` 就是實現了 VFS 功能界面 * **`Plan 9` 的協議就是 `VFS` 嗎**? `Plan 9` 的 `9P` 協議(9P Protocol)是一種用於 **訪問 ++遠程++ 文件系統的協議,它並不是特定於虛擬文件系統(Virtual File System,VFS)的協議** > 9P 協議在 Plan 9 操作系統中使用,它定義了一套客戶端和服務器之間進行文件系統操作的消息傳遞格式和規則; > > 通過 9P 協議,**客戶端程序可以通過網絡與遠程的 9P 服務器通信,並像操作本地文件系統一樣進行文件訪問和操作** ::: ### 檔案系統:基礎型 * 基礎的檔案系統有如下表 | 基礎檔案系統 | 說明 | 補充 | | - | - | - | | `ext` (extended filesystem) | 提供基本的類 Unix 檔案系統 | 虛擬目錄操作物理設備,物理設備按照 **++固定長++ 的塊 (Block)** 儲存存數據 | | `ext2` | 改善 `ext` 的 2G 大小限制,拓展為 32TB,追蹤更多的資訊,減少碎片化 | 按照 **組** 來存儲文件數據 | 1. **`ext` 檔案系統**:採用 **索引節點** 的系統來存放虛擬目錄中所儲存的訊息 ext 檔案系統則會追蹤每個文件的額外數據(e.g: 文件名、文件大小、屬主、屬群、訪問權限、指向文件硬體位置的指針) :::info * **索引節點** ? 索引點系統在每個物理設備中創建單獨的表(**索引節點**)來儲存文件的訊息;而虛擬目錄每個文件在 索引節點 中都有對應的條目(item) ```java= // 概念 Map<VM 位置, Phy 位置> ``` > ![](https://i.imgur.com/7AgT4Ag.png) * `ext` 檔案系統追蹤的就是 索引節點,也就是 物理硬盤上的索引節點(**inode 結構**)… 索引點 (inode) 由系統分配,並且是當前裝置的 **唯一值** > `ext` 通過 inode 數字快速訪問文件的元數據和實際數據 ::: 2. **`ext2` 檔案系統**:強化 ext 檔案系統,^1.^ 擴大儲存限制,^2.^ 使用組來管理 (Block group) 減少碎片化 ext2 預設的 Block 大小為 4KB,如果要調整 Block group 大小就要重新建構檔案系統 > ext2 概念圖如下 > > ![](https://i.imgur.com/iXqy9JW.png) :::danger * **`ext2` 的致命問題**! 檔案系統每次儲存或更新數據時都 **需要更新 `inode 節點表`**,但偏偏這個操作並非一次性的完成 > 可能數據已經寫入 索引節點 (inode) 但是尚未更新節點表就斷線,下次再讀取時就找不到 `inode` 對應的文件 ::: ### 檔案系統:日誌型 * 日誌型檔案系統,優化了 `ext2` 的致命問題,**文件數據不再直接寫入儲存設備(inode)再更新節點表**,而是 **改為 ==寫入 ++臨時文件++== (也就是日誌 journal)** > 在數據成功寫入裝置後,才會刪除日誌 而日誌類型的不同也會有不同的特性,以下列出三種 | 日誌類型 | 說明 | 補充 | | - | - | - | | **數據模式** | inode & 數據 都會被寫入 | 低風險、性能差 | | **有序模式** | inode 被寫入日誌,在之後數據寫入成功後,才會刪除日誌 | 取得平衡 | | **回寫模式** | inode 被寫入日誌,但不管數據何時會被寫入 | 較高機率丟失、性能高 | > ![](https://i.imgur.com/dpuNxUU.png) * FileSystem 日誌型有很多不同的實作,使用的日誌類型也不同,請參考下表 | 檔案系統名 | 日誌類型 | 特色說明 | 補充 | | - | - | - | - | | `ext3` | 有序模式 | 添加日誌系統優化 ext2 | 無法恢復誤刪,不支持加密,無內建壓縮 | | `ext4` | 有序模式 | 支持壓縮、加密 | 支持 **區段(extent)特性**,減省空間 | | `Reiser` | 回寫模式 | ^1.^ 可動態調整 FS 大小、^2.^ 尾部壓縮(可容納更多數據) | 尾部壓縮是透過把多餘的數據,放置到另一個文件的可用空間 | | `JFS` | 有序模式 | IBM 開發 | - | | `XFS` | 回寫模式 | 可動態調整 FS 大小 | 但是只能擴大,**不能縮小** | :::info * `ext4` 特性 1. **區段(extent)特性**:只儲存 block group 的頭節點位置,省略其他節點的儲存空間,所以可以節省空間 2. **預分配**:ext4 檔案系統可以為文件分配所有需要用到的塊,而不僅僅是那些現在已經 用到的塊 ::: ### 寫入時複製:COW FileSystem * **寫入時複製 ([Copy-on-write](https://hackmd.io/ptxTEwCzQBuxv61dGL_lvA#%E5%AF%AB%E5%85%A5%E6%99%82%E8%A4%87%E8%A3%BD-Copy-on-write---%E9%AB%98%E6%95%88%E8%A1%8C%E7%A8%8B%E5%BB%BA%E7%AB%8B)) 是 虛擬記憶體 的一種應用**,這個技術利用了快照,兼顧了安全性、性能 使用者修改的數據是另外的副本(記憶體中),不會立刻寫入文件,只會在合適的時機才寫入文件中 * 以下提及兩個常見的 COW FileSystem | 檔案系統名 | 說明 | 補充 | | - | - | - | | ZFS | Sun 公司開發,與 Resier4, Btrfs, ext4 勢均力敵 | GPL 尚未許可 | | Btrf | Oracle 公司開發,在 Resier4 特性的基礎上優化了可靠性 | 又稱為 B 樹文件 | ### 其他檔案系統 * 除了上述幾個檔案系統,這裡會在提及可個常見的檔案系統,它們個別支援了不同的平台、裝置 1. **平台相關的檔案系統** | 檔案系統名 | 說明 | | - | - | | `FAT` | `FAT` 檔案系統,該系帖有 `msdos` 最基本的單字 MS-DOS 系統、`vfat` 支援 Linux、`umdos`;這些都是微軟的檔案系統 | | `HFS+` | `hfsplus` 是頻果 Macintosh 電腦的檔案系統標準 | 2. **裝置相關的檔案系統** | 檔案系統名 | 說明 | | - | - | | `ISO 9660` | 它是 `CD-ROM` 的標準,大部分 `CD-ROM` 都是使用該標準的某個版本 | ### 透過 UUID 找到檔案系統:分區、PARTUUID * 由於設備名是透過核心檔案系統(`devtmpfs`)通知 `udevd` 服務,該服務會在使用者空間的 「`/dev` 目錄」下建構對應的設備名 :::info * **`/dev` 目錄可能會因為讀取順序,導致對應的硬碟會有所改變** 可能第一次開機時讀取硬碟 A,發現後設定名為 `/dev/sda`,下次開機後它(同塊硬碟)比較晚被發先,所以這次命名為 `/dev/sdc` ::: * **分區與 `PARTUUID` 的概念**: **當格式化分區並為其指定檔案系統時,唯一識別碼(`PARTUUID`)會隨著檔案系統一起寫入分割區的超級區塊中**;PARTUUID 的主要目的是提供一種獨特的標識方式,以便在系統重新啟動或重新連接硬碟時可以確定特定分割區的識別 > `PARTUUID` 是在分區時的過程中完成的,而不是在偵測硬碟時才創建的 :::danger * 只要分區不發生更改,`PARTUUID` 就不會變化,即使插入不同的電腦中也是如此 * 另外,`PARTUUID` 是確保每個分區都有一個唯一的識別碼,不受檔案系統或存儲介面的影響 **這意味著即使更改檔案系統或移動硬碟到不同的系統,分區的 `PARTUUID` 仍然保持不變**,因此可以確保每個分區都具有唯一的識別碼 > 這有助於系統識別特定的分區,而不受檔案系統的變化或硬體更換的影響 ::: * **檔案系統與 UUID** **Linux 也有提供我們 `blkid` 命令,來取得分區的 `PARTUUID` 以及檔案系統的 `UUID`**,同時也可以取得 `/dev` 路徑以及該分區的檔案系統資訊 > `blkid` 的輸出格式為:`<Dev Path>: <UUID> <FileSystem>` 使用檔案系統的唯一 `UUID`,就可以找到 **唯一的檔案系統標示**;這個 UUID 標示會在檔案系統建立時產生;命令查詢範例如下 ```shell= blkid ``` > ![](https://hackmd.io/_uploads/H1Z-ucTP3.png) :::success * **Linux 原生設備都有 UUID**,但是 FAT 設備並沒有(FAT 設備使用 FAT 序列號) * **在系統啟動時,掛載設備偏好使用 UUID 來掛載** 並且檔案系統 UUID 是可以修改的!不能修改的 PARTUUID ::: :::info * **在 `mount` 掛載時,就可以使用 UUID 替代 `/dev`** ```shell= mount UUID=<UUID> <掛載點> ``` ::: ### 檔案系統表:`/etc/fstab` * Linux 系統在 `/etc/fstab` 文件中,永久保存了檔案系統、選項列表相關資訊,可以 **透過這個表得知當前裝置使用了哪些檔案系統**,以及對應的 UUID 資訊 ```shell= cat /etc/fstab ``` 由前到後,總共有 6 個欄位,我們按照順序說明 | 欄位 index | 範例數值 | 說明 | 補充 | | - | - | - | - | | 1 | `proc` | 設備、UUID (可與 `blkid` 對應) | 最新版本大多使用 UUID | | 2 | `/proc` | 掛載點 | - | | 3 | `proc` | 檔案系統類型 (Type) | - | | 4 | `default` | 長選項(等等說明) | 可設定多個,每個之間使用逗號 `,` 區分 | | 5 | `0` | 系統 dump 時,使用的備份資訊 | 請一直保持 0 | | 6 | `0` | 檔案系統完整性 **測試順序** | **0 禁止檢查**;root 檔案系統是 1,其餘則是 2 | > ![](https://hackmd.io/_uploads/r13MUi6wn.png) * 其中第 4 個長選項(只在 `/etc/fstabs` 中適用),其中有幾個常見的如下表 | 第 4 個長選項 | 說明 | 補充 | | - | - | - | | `defaults` | 可讀、寫、啟動設備檔案、執行、setuid 模式 | mount 的預設值 | | `errors` | 當掛載出現問題時的行為,會出現像是 `errors=continue`(回傳錯誤碼,但繼續執行), `errors=remount-ro`(重掛載並切換到唯讀), `errors=panic`(核心掛載發生問題時停止) | ext2 相關參數 | | `noauto` | 防止系統啟動時掛載行動設備(`USB`, `CD-ROM`... 等等) | 讓 `mount -a` 失效 | | `user` | 讓本沒有權限的使用者,對某一行設備執行 mount 命令 | `CD-ROM` 常用 | :::success * **`/etc/fstab` 的替代品** 除了傳統的 `/etc/fstab` 文件可以查看當前系統正在使用的檔案系統、掛載點之外,還有以下兩種方式可以查看 1. **`/etc/fstab.d` 目錄**:該目錄下會有 **各個檔案系統的設定檔案** 2. **`systemmd` 單元**:**`systemmd` 單元設定通常基於 `/etc/fstab` 文件** ::: ### 特殊用途的檔案系統 * **檔案系統不僅僅是管理硬體元件**,也會**管理系統資訊** * 大多數的 Unix 系統中,都會有一些 **作為系統介面使用的檔案系統**;檔案系統就可以用來表示這些系統資訊 > eg. PID, 核心管理… **==讓檔案作為 I/O 介面==** Linux 中特殊用途的檔案系統如下表 | 特殊用途檔案系統 | 掛載點 | 功能簡介 | | - | - | - | | `proc` 檔案系統 | `/proc` | 該目錄中的子目錄以 **PID 命名**,進入子目錄後就有程序(進程)所有的狀態; (`/proc/self` 表示目前程序,`/proc/cpuinfo` 則是硬體相關訊息) | | `sysfs` 檔案系統 | `/sys` | 顯示 `udevd` 發送的硬體相關資訊 | | `tmpfs` 檔案系統 | `/run` 或其他位置 | 透過 `tmpfs` 可以創建記憶體 Swap 空間 | ```shell= echo $$ ls -laF /proc/11070/ | head -n 20 ``` > ![reference link](https://hackmd.io/_uploads/SyVOLlJ_2.png) ## 操作檔案系統 GNU 有提供我們幾個有用的工具來直接操作檔案系統,操作硬體的檔案系統有一定的步驟 1. 創建分區 2. 創建檔案系統(檢查、修復) 3. 掛載 ### 創建分區:使用 fdisk 命令 > **創建分區**:這個分區是要留給檔案系統用的 > > ![](https://i.imgur.com/8R5iaS8.png) * `fdisk` 命令:這個命令是 **交互式命令**,可以透過問答的方式達成創建分區,以下分為幾個步驟 1. 找到目標硬碟(你要在哪個硬碟下創建分區) ```shell= ls -l /dev | grep sd ## 也可以使用 lsblk 查看電腦中的裝置 lsblk ``` > ![](https://i.imgur.com/8GPesti.png) :::info * **找到目標硬碟**: 硬碟會顯示在 `/dev` 資料夾下,老式 IDE 驅動器會以 `hd<X>` 開頭;新的 `STAT 驅動器` 和 `SCSI 驅動器` 會以 `sd<X>` 開頭命名 > `X` 代表的是讀取到的是硬碟先後順序,會按照順序給予 `X` 值 ::: 2. **`fdisk` (manipulate disk partition table) 命令**:該命令必須要管理員才能使用 * 指定硬碟並下達命令後,可以看到互動式操作 ```shell= sudo fdisk /dev/sda ``` > ![](https://i.imgur.com/kLalmYU.png) 其互動命令(字元),對照功能如下 | 命令 | 說明 | | - | - | | a | 設定活動分區標誌 | | b | 編輯 BSD Uniex 系統用的硬碟標籤 | | c | 設置 DOS 兼容標誌 | | d | 刪除分區 | | l | 顯示可用分區 | | m | 顯示命令選項 | | n(常用) | **添加一個新分區** | | o | 創建 DOS 分區表 | | p(常用) | **顯示當前分區表** | | q(常用) | **退出並不保存改變** | | s | 為 Sun Unix 系統創建一個新硬碟標籤 | | t | 修改分區系統 ID (分區類型) | | u | 改變使用的存儲單位 | | v | 驗證分區表 | | w(常用) | **將分區表寫入硬碟** | | x | 高級功能 | > 如入 `p` 就可以查看當前硬碟的分區表 > > 下圖出現已分配 `/dev/sda1` 分區表(FAT32 Window 分區表),這時就可以使用 `d` 命令來刪除已有分區 > > ![](https://i.imgur.com/7Lwm1Iy.png) * **創建新分區、寫入**:使用 `n` 選項來創建磁碟分區,並選擇要主分區 (primary) 或擴展分區(extended) | 分區類型 | 說明 | | - | - | | 主分區 (`primary`) | 可以被檔案系統直接格式化 | | 擴展分區(`extended`) | 只能容納 **邏輯分區**(邏輯分區內還可以再創建 primary),每個硬體設備上只能有 4 個分區 | > ![](https://i.imgur.com/YCq5u1L.png) ```shell= ## 新建分區 n ## 創建主分區 ... 忽略大小設置使用 default setting p ## 查看分區 (記憶體內) p ## 將分區資訊寫入硬碟 w ``` > ![](https://i.imgur.com/UFNwyMA.png) > 可以看到創建出新的分區 ID 為 `Linux`,代表的是 Linux 檔案系統 > > ![](https://i.imgur.com/yF0l4BQ.png) ### 創建檔案系統:`mkfs` 命令 * 在上面我們使用 `fdisk` 命令分區結束後,就有一個空間給檔案系統使用,所以接著就是創建檔案系統;**每種檔案系統都有自己的命令行工具可以格式化分區** | 分區命令工具 | 創建的 檔案系統 | | - | - | | `mkfs` | 使用 `-t` 來指定檔案系統,可以創建多種類型檔案系統 | | `mkefs` | ext2 | | `mkefs2` | ext2 | | `mkfs.ext3` | ext3 | | `mkfs.ext4` | ext4 | | `mkreiserfs` | ReiserFS | | `jfs_mkfs` | JFS | | `mkfs.xfs` | XFS | | `mkfs.zfs` | ZFS | | `mkfs.btrfs` | Btrfs | > ![](https://hackmd.io/_uploads/SJ3qfSaP2.png) :::info * 並不是所有工具都有默認安裝,可以使用 `type` 查詢 ```shell= type mkfs.ext4 type mkfs.btrfs ``` > ![](https://i.imgur.com/HTa4P0D.png) * 可以透過查看 `mkfs.*` 檔案,知道其實該指令真正的執行者 ```shell= ls -laF /sbin/mkfs.* ``` > 可以看到 大部分檔案系統操作都導向 `mke2fs` > > ![](https://hackmd.io/_uploads/SyRAEBTD2.png) ::: ```shell= ## 查看分區 lsblk ## 對指定分區創建檔案系統(以下創建 ext4 檔案系統) sudo mkfs.ext4 /dev/sda1 ``` > 這個過程比較耗時,需等待一下 (**在這個過程中該 Shell 先不要操作其他命令,避免失敗**) > > ![](https://i.imgur.com/YHmxT1M.png) :::danger * 如果在已有檔案系統上建立另一個檔案系統,那會讓舊有資料遺失 ::: ### 掛載到虛擬目錄:mount 命令 * 上面工作都準備完後,就可以把 **檔案系統掛載到虛擬目錄中**;掛載的位置並沒有限制,只要不要掛載到根目錄 (`/`) 之下即可 ```shell= # 如果你不記得檔案系統類型可以用這個命令查詢 blkid /dev/sda1 sudo mkdir /mnt/my_partition/ # -t 指定分區類型為 ext4 # 將 /dev/sda1 掛載到 /mnt/my_partition/ 目錄中 sudo mount -t ext4 /dev/sda1 /mnt/my_partition/ # 查看掛載好的硬碟 ls -laF /mnt/my_partition ``` > ![](https://i.imgur.com/wFAR1VO.png) 掛載完成後,我們就可以透過 `/mnt/my_partition/` 目錄來訪問 `/dev/sda1` 硬碟,並做讀取或是寫入操作 :::warning 如果掛載失敗可以修復後再測掛載(下個章節) ::: * **以下有幾個檔案系統掛載(`amount`)時常用的選項** 1. **`amount` 短選項** | 短選項 | 功能 | 補充 | | - | - | - | | `-r` | 以為讀模式掛載檔案系統 | 可用在保護、系統啟動 | | **`-n`** | 確保 `mount` 命令「**不會更新**」系統執行時的掛載資料函式庫 `/etc/mtab` | 在單使用者修復系統問題時可用 | | `-t` | 指定檔案系統類型 | - | 2. **`amount` 長選項**:`mount` 長選項必須寫在 `-o` 之後,每個選項之間使用逗號 `,` 區分 | 長選項 | 功能 | | - | - | | -o `ro` | 唯讀 | | -o `rw` | 可寫可讀 | | -o `suid`, `nosuid` | 允許、禁止 `setuid` | | -o `exec`, `noexec` | 允許、禁止檔案系統中執行程式 | | -o `remount` | 重新掛載 | | -o `conv=rult` | FAT 檔案系統使用,而其中的 `rule` 有三種,^1.^ `binary` 不轉換直接使用、^2.^ `text` 只轉換文字檔、^3.^ `auto` 根據副檔名自動轉換 | > `conv=rult` 需小心使用,否則可能造成損壞 ### 檔案系統的檢查 & 修復:fsck 命令 * 每個檔案系統都有相對應得修復工具,使用起來命令很多不易掌握;這裡可以使用一個通用命令 `fsck` 去統一修復 > 命令使用的格式:fsck options filepath | fsck options | | | - | - | | `-y` | 預設同意所有 fsck 的提示 | | `-N` | 檢查檔案系統,並 **不做任何修改** | | `-P` | 修復常見錯誤 | ```shell= # 懶人用法 sudo fsck -y /dev/sda1 ``` :::info * **還有另外一個 `testdisk` 工具可以使用** ```shell= sudo apt install testdisk sudo testdisk /dev/sda ``` ::: :::warning * **已掛載硬碟不可使用 `fsck`** 因為核心在執行檢查時可能輝更新磁碟資料,導致資料不配對,進而導致系統崩潰、檔案損壞... 等等問題 ::: ## 交換空間 並非所有磁碟分區都包含檔案系統,硬碟有另一個功能,**它可以提供空間讓 Linux 做為虛擬記憶體,在系統記憶體不足時,由核心調用它作為記憶體,這種行為稱為 Swap** 使用 `free` 命令就可以看到當前記憶體、交換空間的大小 & 使用狀況 ```shell= free ``` > 當前裝置交換空間(`Swap`)為 `102 MB` > > ![](https://hackmd.io/_uploads/B1Equfg_h.png) :::success * 合適的 Swap 空間大小? 以前 Unix 會建議交換空間為記憶體的大小兩倍以上,但之後記憶體容量變大,不再是問題後,這就並非一個必要的建議 > 但這個規則 **對於使用者空間仍適用** ::: ### 磁碟作為交換空間 * 可以將磁碟作為交換空間 1. 確保分區為空,無檔案系統 2. **製作交換區**:執行 `mkswap <dev>` 命令來創建交換區塊 ```shell= # `-f` 強制 sudo mkswap -f /dev/sdb ``` > ![](https://hackmd.io/_uploads/SJdGiGxun.png) 3. **提交交換區**:執行 `swapon <dev>` 命令來將創建好的交換區提交給核心 ```shell= sudo swapon /dev/sdb # 查看交換分區,就會變大 free ``` > ![](https://hackmd.io/_uploads/SyROozxO3.png) * 使用 `swapoff` 命令來卸載磁碟的交換分區 ```shell= sudo swapoff /dev/sdb # 查看交換分區,就會變為原本大小 free ``` > ![](https://hackmd.io/_uploads/rJAu2zgu2.png) ### 檔案作為交換空間 * 我們也可將檔案作為交換空間; 1. 透過 `dd` 命令從 `/dev/zero` 空間複製,創建一個檔案 ```shell= dd if=/dev/zero of=my_swap_file bs=1024 count=60 ``` :::warning * Swap 要求最小空間為 40KB ::: 2. **製作交換區**:執行 `mkswap <file>` 命令來創建交換區塊 ```shell= sudo mkswap ./my_swap_file ``` > ![](https://hackmd.io/_uploads/SyuKpfguh.png) 3. **提交交換區**:執行 `swapon <file>` 命令來將創建好的交換區提交給核心 ```shell= sudo swapon ./my_swap_file # 查看交換分區,就會變大 free ``` > ![](https://hackmd.io/_uploads/B1FwCfx_h.png) * 使用 `swapoff` 命令來卸載磁碟的交換分區 ```shell= sudo swapoff ./my_swap_file # 查看交換分區,就會變為原本大小 free ``` > ![](https://hackmd.io/_uploads/BkbJyXg_3.png) ## 傳統檔案系統 Inode 傳統的 Unix 檔案系統有兩個基礎元件 1. **儲存資料區塊池**(Pool) 2. **管理資料池的函式庫系統(該資料函式庫是 INode 資料結構的核心)** :::warning 並非所有檔案系統都是使用 inode 資料結構 ::: ### 認識 Inode 功能 * `inode` 是一組 **資料結構**,用來描述檔案的資料,包括檔案 **類型、權限、所屬的資料池**;每個 `inode` 都會存在 **`inode 表` 中** (以數字來表示) > ![](https://hackmd.io/_uploads/HJgj8mldn.png) * **我們最常見的檔案、目錄也都是透過 inode 來實現的**,範例如下:以下我們創建兩個資料夾、4 個檔案,並透過 ln 命令產生硬連結來觀察 inode ```shell= mkdir dir_1 mkdir dir_2 echo a >dir_1/file_1 echo b >dir_1/file_2 echo c >dir_1/file_3 echo d >dir_2/file_4 ln dir_1/file_3 dir_2/file_5 tree . ``` > ![](https://hackmd.io/_uploads/H1Mhvmeu2.png) 其中,**檔案名、目錄都是透過 `inode` 來實現**(目錄 `inode` 的資料池中包含一個檔案名列表 & 指向對應的檔案 `inode`);概念如下圖所示 > ![](https://hackmd.io/_uploads/B1bkimedn.png) * **解釋(對於 `ext/2/3/4` 檔案系統來說)** 1. 編號 `111` 的 inode 就是 `root inode`,其容如下(代表該目錄下儲存的 inode) | `inode 檔案名` | `inode` 編號 | | - | - | `.` | `111` | | `dir_1` | `200` | | `dir_2` | `867` | 2. `root inode` 之中的 `dir_1`,其容如下(代表該目錄下儲存的 inode) | `inode 檔案名` | `inode` 編號 | | - | - | `.` | `200` | | `..` | `111` | | `file_1` | `201` | | `file_2` | `202` | | `file_3` | `203` | 3. `root inode` 之中的 `dir_2`,其容如下(代表該目錄下儲存的 inode) | `inode 檔案名` | `inode` 編號 | | - | - | `.` | `867` | | `..` | `111` | | `file_4` | `203` | | `file_5` | `204` | ### Inode 細節 我們繼續接續上個小節的說明,來看看 Inode 細節 > ![](https://hackmd.io/_uploads/B1bkimedn.png) * 我們可以使用以下指令查看檔案 inode 的資訊 1. 透過 `ls -i` 來查看檔案的 inode 編號(編號在開頭) ```shell= # 載是 inode 數量 ls -i ``` 2. 查看檔案 **硬連結** 數量;由於 **創建「硬連結」會指向同一個 inode 編號**,所以只要有一個硬連結,檔案的 inode 就會 +1,反知則減一! ```shell= ls -l ``` :::info * 這也就是謂何有人把刪除檔案稱為 **刪除連結** * 而當硬連結的數量為 0 後,核心就會在合適的時機刪除所有該 inode 中儲存的資料 ::: * **目錄的 inode 數量基本最少就是 2** 1. **一般目錄**:**它包含目錄中的 ^1.^ 上層目錄(`..` 符號)、^2.^ 自身的目錄參照(`.` 符號)** > ![](https://hackmd.io/_uploads/HkMgua-u3.png) 2. **root 目錄**:**檔案系統的超級區塊**(這樣檔案系統才找的到 root 目錄) 加上 **底下的目錄數量** > ![](https://hackmd.io/_uploads/rkJ5upbun.png) :::success * `inode` 其他知識點 * **`fsck` 的修復**: 它會遍歷指定區塊的 `inode` 表、目錄結構,來產生連結數目、區塊分配資訊;當發現資料不批配的狀況,`fsck` 會修復連結數錯誤、inode 行其他路徑 > 大部分 `fsck` 會將新建立的檔案放到 `lost+found` 目錄之下 * 透過 **區塊位元圖(`block bitmap`)** 來管理、區分區塊資訊;0 代表區域可用,1 代表該空間已經被佔用 ::: ## 邏輯卷管理 > 為已有的檔案系統添加額外空間是不容易的事情 Linux 邏輯卷管理器(`logical volume manager`, LVM)可以讓我們 **無需重建整理整個檔案系統就做到擴展、管理硬碟空間** ### 邏輯卷管理概念 * **邏輯卷管理的概念如下**: 1. **物理分區 (`physical volume`, PV)**:將硬碟抽象化,讓每個硬碟映射到物理分區 > ![](https://i.imgur.com/a9gxk92.png) 2. **卷組(`volume group`, VG)**:多個 PV 可以匯聚成一個 **卷組**,**邏輯卷管理系統會將這個 VG 視為一個硬碟** > 但其實 VG 是由多個硬碟組成 > ![](https://i.imgur.com/FzNta4l.png) 3. 最後一層就是 **邏輯卷(`logical volume`, LV)**:邏輯卷可以提供分區環境給檔案系統使用 **Linux 系統將邏輯捲「視為物理分區」**,最後我們就可以在這個邏輯卷寫入需要的檔案系統使用 > ![](https://i.imgur.com/Pp09krE.png) :::info 如果之後有新增硬碟,只要將硬碟加入 VG 卷組,就可以拓展空間 ::: ### Linux 邏輯卷管理 * 這裡主要介紹 LVM2(可用於 Linux 內核 2.6 版本);LVM2 除了標準的管理 Volume group 之外,還有另外一些特色… 特色如下 1. **快照 snapshot**:Linux 允許你 **在邏輯卷運作的狀況下進行複製,將其複製到另外一個設備**;概念是創建一個副本(快照),然後 LV 讀取副本資料 :::warning LVM1 只能創建唯獨讀取的副本;LVM2 可以創建可讀寫的副本(可能失敗,需要恢復修改過的數據) ::: > 概念圖 > > ![](https://i.imgur.com/jpiBwN6.png) 2. **條帶化 striping**:可以跨多個物理硬碟創建邏輯卷(LV),**將數據分配到各個不同硬碟上** :::success * 條帶化的優點是可以加強存儲效能,但缺點很明顯的就是如果有硬碟壞掉,那就會遺失數據(因為同一段數據保存到不同硬碟,只要有一個硬碟故障,就會導致數據遺失) * 如果使用 RAID 技術進行條帶化,還可以實現故障容忍性,即當某個硬碟出現故障時,仍然可以保護數據的完整性 ::: 3. **鏡像 mirror**:可以隨時創建邏輯卷副本,這個副本就可以稱為鏡像;當使用者對邏輯卷寫入時,就需要同時對鏡像進行寫入(2 次寫入);這會影響寫入的速度,但卻也同時加強了讀取效能 > LVM 邏輯卷也容易受到斷電,硬碟故障的影響,一但檔案系統損壞就可能無法再恢復,而鏡像就是其中一個解決方案 > ![](https://i.imgur.com/ejo1aX4.png) ### 使用 Linux LVM 範例 * 按照我們對邏輯卷的了解,區分三個步驟;以下是 Linux LVM 的 CLI 操作 1. **定義物理卷 (PV)**:請先確定你的「**硬碟分區類型**」,再確認正確後就可以創建物理卷 | 使用命令 | 功能 | | - | - | | `fdisk </dev/...>` | 確認(p), 修改分區類型(t) | | `pvcreate </dev/...>` | 創建物理卷 | | `pvdisplay </dev/...>` | 查看硬體分區下的物理卷 | * **`fdisk` 命令,修改硬體空間的分區類型**: ```shell= sudo fdisk /dev/sda ## 查看分區類型,當前分區類型為 83 p ## 修改分區類型 t ## 輸入 L 可以查看所有分區類型,8e 代表 Linux LVM 8e ## 退出 q ``` > 原來類型是 83 > ![](https://i.imgur.com/AKvthVF.png) > > 修改過後是 8e > ![](https://i.imgur.com/D8YO1DG.png) * **`pvcreate` 命令,創建物理卷**: ```shell= ## 如果已經有安裝 LVM2 就可以忽略這個步驟 sudo apt install lvm2 ## 卸載已掛載的硬碟,否則不能操錯分區空間 sudo umount /mnt/my_partition ``` ```shell= ## 指定分區創建物理卷 sudo pvcreate /dev/sda1 sudo display /dev/sda1 ``` > ![](https://i.imgur.com/oJkEpj9.png) 2. **創建卷組 (VG)**:從創建好的物理卷中創建一個、多個卷組 > 也可以從將物理卷加入到卷組 | 使用命令 | 功能 | | - | - | | `vgcreate <卷組名> </dev/...>` | 創建卷組 | | `vgdisplay [卷組名]` | 查看卷組細節 | ```shell= ## 創建卷組 sudo vgcreate Vol_Test /dev/sda1 ## 查看卷組細節 sudo vgdisplay ``` > ![](https://i.imgur.com/TQraI55.png) :::info **至此 ++LVM++ 會將 VG 視為一個物理硬碟** ::: 3. **創建邏輯卷 (LV)**: | 使用命令 | 功能 | | - | - | | `lvcreate <options> <邏輯卷名> <卷組>` | 創建邏輯卷 | | `lvdisplay [卷組名]` | 查看邏輯卷細節 | ```shell= ## 按照比例分配給新邏輯卷的邏輯區段 ## 以下 `-l 100%FREE` 指定 100% 的邏輯卷可用空間 sudo lvcreate -l 100%FREE -n LV_Test Vol_Test sudo lvdisplay ``` > ![](https://i.imgur.com/FSixrNY.png) :::info **至此 ++系統++ 會將 LV 視為一個物理硬碟** ::: * **接下來的步驟就如同一般操作硬碟一樣(分區類型已定義),^1.^ 指定分區的檔案系統(`mkfs...`)、^2.^ 掛載檔案系統(`mount`)** ```shell= ## 先查看硬碟的分區分配狀況 lsblk ``` > ![](https://i.imgur.com/2N9p3UJ.png) ```shell= ## 指定 LV_Test 檔案系統為 ext4 ## 最終路徑是 /卷組/邏輯卷 sudo mkfs.ext4 /dev/Vol_Test/LV_Test ``` > ![](https://i.imgur.com/dujPJqu.png) ```shell= ## 掛載硬碟 sudo mount /dev/Vol_Test/LV_Test /mnt/my_partition/ ls -la /mnt/my_partition/ ``` > ![](https://i.imgur.com/1GjFetj.png) ### LVM 動態修改 * Linux LVM 的優點在於可以動態修改檔案系統,以下列出一些工具可以幫助修改已有邏輯卷 (LV) | 命令 | 功能 | | - | - | | vgchange | 激活&禁用卷組 | | vgremove | 刪除卷組 | | vgextend | 將物理卷(PV)加入 卷組(VG) | | vgreduce | 從卷組(VG)中刪除(PV) | | lvextend | 增加邏輯卷(LV) | | lvextend | 縮小邏輯卷(LV) | :::warning * 手動調整邏輯卷大小時,邏輯卷中的文件需要手動修整來處理邏輯卷大小上的改變 ::: ## Appendix & FAQ :::info ::: ###### tags: `Linux Shell`