Linux 中的虛擬文件系統:為什麼需要它們以及它們如何工作? 第2部分

大家好,我們正在與您分享《Linux 中的虛擬檔案系統:為什麼需要它們以及它們如何運作?》的第二部分。 你可以閱讀第一部分 這裡。 讓我們提醒您,該系列出版物的發佈時間與課程新流的推出同時進行 《Linux 管理員》,很快就開始了。

如何使用 eBPF 和 bcc 工具監控 VFS

了解核心如何操作檔案最簡單的方法 sysfs 就是在實務上看,而看ARM64最簡單的方法就是使用eBPF。 eBPF(伯克利資料包過濾器的縮寫)由運行在 ,特權使用者可以請求哪些(query)從命令列。 內核原始碼告訴讀者核心可以做什麼; 在已載入的系統上執行 eBPF 工具可以顯示核心實際在做什麼。

Linux 中的虛擬文件系統:為什麼需要它們以及它們如何工作? 第2部分

幸運的是,在工具的幫助下開始使用 eBPF 非常容易 BCC,它們可以作為一般發行版的包提供 Linux 並詳細記錄 伯納德·格雷格。 工具 bcc 是插入少量 C 程式碼的 Python 腳本,這意味著熟悉這兩種語言的任何人都可以輕鬆修改它們。 在 bcc/tools Python 腳本有 80 個,這意味著開發人員或系統管理員很可能能夠選擇適合解決問題的腳本。
要至少粗略地了解 VFS 在正在運行的系統上所做的工作,請嘗試 vfscountvfsstat。 比方說,這將顯示數十個調用 vfs_open() 「他的朋友」幾乎每秒鐘都在發生。

Linux 中的虛擬文件系統:為什麼需要它們以及它們如何工作? 第2部分

vfsstat.py 是一個帶有 C 程式碼插入的 Python 腳本,用於簡單地計算 VFS 函數呼叫的數量。

讓我們舉一個更簡單的例子,看看當我們將 USB 隨身碟插入電腦並且系統偵測到它時會發生什麼。

Linux 中的虛擬文件系統:為什麼需要它們以及它們如何工作? 第2部分

使用 eBPF 你可以看到發生了什麼 /sys當插入 USB 隨身碟時。 這裡顯示了一個簡單和複雜的範例。

在上面所示的範例中, bcc 工具 跟踪.py 運行命令時列印一條訊息 sysfs_create_files()。 我們看到 sysfs_create_files() 是使用啟動的 kworker 串流響應閃存驅動器插入的事實,但創建了什麼文件? 第二個範例展示了 eBPF 的強大功能。 這裡 trace.py 列印核心回溯(-K 選項)和建立的檔案的名稱 sysfs_create_files()。 單語句插入是 C 程式碼,其中包含執行 LLVM 的 Python 腳本提供的易於識別的格式字串 即時編譯器。 它編譯該行並在核心內的虛擬機器中執行它。 全功能簽名 sysfs_create_files () 必須在第二個命令中重現,以便格式字串可以引用參數之一。 這段 C 程式碼中的錯誤會導致 C 編譯器出現可辨識的錯誤。 例如,如果省略 -l 參數,您將看到「無法編譯 BPF 文字」。 熟悉 C 和 Python 的開發人員會找到這些工具 bcc 易於擴展和更改。

當USB驅動器插入時,核心回溯將顯示PID 7711是一個線程 kworker創建了該文件 «events» в sysfs。 因此,來自 sysfs_remove_files() 將顯示刪除磁碟機導致檔案被刪除 events,這對應於引用計數的一般概念。 同時,觀看 sysfs_create_link () 插入 USB 隨身碟時使用 eBPF 將顯示至少已建立 48 個符號連結。

那麼事件文件有什麼意義呢? 用法 範圍 用於搜索 __device_add_disk(),顯示其原因 disk_add_events (),或者 "media_change""eject_request" 可以記錄在事件文件中。 這裡內核區塊層通知用戶空間一個「磁碟」已經出現並彈出。 請注意,與試圖純粹從源頭上弄清楚事物如何運作相比,這種透過插入 USB 隨身碟的研究方法提供了多少資訊。

只讀根檔案系統支援嵌入式設備

當然,沒有人會從插座拔下插頭來關閉伺服器或電腦。 但為什麼? 這是因為實體儲存設備上安裝的檔案系統可能具有滯後寫入,並且記錄其狀態的資料結構可能與儲存寫入不同步。 發生這種情況時,系統所有者必須等到下次啟動才能啟動該實用程式。 fsck filesystem-recovery 並且,在最壞的情況下,還會遺失資料。

然而,我們都知道許多物聯網設備,以及路由器、恆溫器和汽車,現在都運行 Linux。 其中許多設備幾乎沒有用戶介面,並且無法「徹底」關閉它們。 想像一下,當控制單元的電源關閉時,啟動電池沒電的汽車 Linux 不斷地上下跳躍。 系統啟動沒有很長的時間怎麼辦? fsck引擎什麼時候最終開始運轉? 答案很簡單。 嵌入式設備依賴根檔案系統 僅用於閱讀 (縮寫 ro-rootfs (只讀根檔案系統))。

ro-rootfs 提供了許多不如真實性那麼明顯的好處。 優點之一是惡意軟體無法寫入 /usr/lib,如果沒有 Linux 進程可以在那裡寫入。 另一個原因是,很大程度上不可變的文件系統對於遠端設備的現場支援至關重要,因為支援人員依賴名義上與現場系統相同的本地系統。 也許最重要(但也是最陰險)的好處是 ro-rootfs 迫使開發人員在系統設計階段決定哪些系統物件是不可變的。 使用 ro-rootfs 可能會很尷尬和痛苦,因為 const 變數通常出現在程式語言中,但它們的好處很容易證明額外的開銷是合理的。

創建 rootfs 只讀需要嵌入式開發人員付出一些額外的努力,這就是 VFS 發揮作用的地方。 Linux 要求檔位於 /var 是可寫入的,此外,許多運行嵌入式系統的流行應用程式將嘗試建立配置 dot-files в $HOME。 主目錄中設定檔的一種解決方案通常是預先產生並將它們建置到 rootfs。 為 /var 一種可能的方法是將其安裝在單獨的可寫入分割區上,同時 / 以唯讀方式安裝。 另一種流行的替代方法是使用綁定或覆蓋安裝。

可連接且可堆疊的安裝座及其在容器中的使用

命令執行 man mount 是了解可綁定和可覆蓋安裝的最佳方式,它使開發人員和系統管理員能夠在一個路徑中建立檔案系統,然後將其公開給另一個路徑中的應用程式。 對於嵌入式系統,這意味著能夠將檔案儲存在 /var 在唯讀閃存驅動器上,但來自覆蓋或可連結的安裝路徑 tmpfs в /var 加載時,它將允許應用程式在那裡寫筆記(亂寫亂畫)。 下次打開更改時 /var 會迷路。 覆蓋安裝在之間創建聯合 tmpfs 和底層檔案系統,並允許您對現有文件進行表面上的更改 ro-tootf 而可綁定的安裝座可以使新的安裝座變空 tmpfs 資料夾可見可寫 ro-rootfs 方法。 儘管 overlayfs 這是正確的(proper) 檔案系統類型,可綁定掛載實現於 VFS命名空間.

根據對覆蓋層和可連接安裝座的描述,沒有人對此感到驚訝 Linux容器 它們被積極使用。 讓我們看看當我們使用時會發生什麼 systemd-nspawn 使用該工具運行容器 mountsnoopbcc.

通話 system-nspawn 運行時啟動容器 mountsnoop.py.

讓我們來看看發生了什麼:

Запуск mountsnoop 當容器正在「啟動」時,表示容器的運行時高度依賴正在連結的掛載(僅顯示長輸出的開頭)。

這裡 systemd-nspawn 提供選定的文件 procfs и sysfs 主機到容器作為其路徑 rootfs。 除了 MS_BIND 設定綁定掛載的標誌,掛載上的其他一些標誌定義主機和容器名稱空間變更之間的關係。 例如,連結安裝可以跳過對 /proc и /sys 放入容器中,或根據呼叫隱藏它們。

結論

了解 Linux 的內部工作原理似乎是一項不可能的任務,因為核心本身包含大量程式碼,不考慮 Linux 用戶空間應用程式和 C 庫中的系統呼叫接口,例如 glibc。 取得進展的一種方法是閱讀一個內核子系統的源代碼,重點是理解系統調用和用戶空間標頭,以及主要的內部內核接口,例如表 file_operations。 文件操作提供了「一切都是文件」的原則,使管理起來特別愉快。 頂層目錄中的C內核來源文件 fs/ 提出了虛擬檔案系統的實現,它是一個包裝層,在流行的檔案系統和儲存設備之間提供廣泛且相對簡單的兼容性。 透過 Linux 命名空間進行連結和覆蓋安裝是 VFS 的魔力,它使創建唯讀容器和根檔案系統成為可能。 結合源碼考察,eBPF核心工具及其接口 bcc
讓岩心探勘變得比以往更容易。

朋友們,請留言,這篇文章對您有用嗎? 也許您有什麼意見或評論? 歡迎對 Linux 管理員課程有興趣的人參加 開放日,將於 18 月 XNUMX 日舉行。

第一部分。

來源: www.habr.com

添加評論