linux umount 提示"device is busy" 終極解決
為了乾淨地關閉或熱交換 UNIX 或類 UNIX 系統上的儲存硬體,必須能夠解除安裝使用此裝置上的儲存的所有檔案系統。但是,如果正在使用檔案系統中的檔案或目錄,就無法解除安裝它。lsof 和 fuser 命令可以幫助您識別並終止那些正在使用儲存裝置上的檔案或從儲存裝置執行的程序。使用這些命令有助於尋找那些阻止儲存裝置解除安裝的程序,減少麻煩,讓您能夠繼續處理更重要的系統管理任務。
所有計算機作業系統都在引導時檢查它們掛載的檔案系統是否是一致的,也就是說,確認它們的內部資料結構和對映到的相關儲存沒有錯誤。UNIX、Linux 和其他類 UNIX 作業系統採用一種聰明的方法檢查檔案系統的一致性(通常使用 fast 命令)。當這些系統掛載檔案系統時,它們在檔案系統頭中設定一個值,把檔案系統標為 DIRTY,這意味著它正在使用,在向它寫入更新時可能暫時處於不一致的狀態。在系統關閉期間解除安裝檔案系統時,把它們標為 CLEAN。在重新引導系統時,只需要檢查仍然標為 DIRTY 的檔案系統的一致性。
在系統關閉過程中,會自動地解除安裝檔案系統,這通常在終止所有非系統程序之後進行。但是,解除安裝檔案系統仍然可能失敗並顯示以下訊息:
在這裡,busy 意味著一個程序正在寫這個檔案系統或者程序是從它執行的。在這兩種情況下,都無法解除安裝檔案系統,這是計算機系統的基本規則之一。如果不採用這個規則,可以 在程序正在寫檔案系統包含的檔案時解除安裝檔案系統,就會讓檔案處於不一致的狀態,而檔案系統本身標為 CLEAN。
umount 命令的標準 Linux 版本包含一個延遲解除安裝選項 -l,它有助於解除安裝正在使用的檔案系統。這個命令需要 Linux 核心 2.4.11 或更高版本,目前這通常沒問題。執行 umount -l /name/of/
如果需要馬上解除安裝檔案系統,而檔案系統報告忙碌,還有其他辦法。如果您是系統的惟一使用者,那麼只需終止阻止檔案系統解除安裝的程序。這需要檢視所有視窗,尋找 並終止正在寫這個分割槽或使用它作為當前工作目錄的暫停的程序或後臺程序。但是,在有許多本地使用者和遠端使用者的多使用者系統上,這種方法是不實際的。幸運的 是,開放原始碼社群提供了一些命令,可以輕鬆地識別並終止這些程序。
用 lsof 尋找開啟的檔案
lsof (list open files) 命令列出特定的檔案系統、目錄或裝置上所有開啟的檔案以及與它們相關聯的程序。在大多數 UNIX 和類 UNIX 系統上都可以使用 lsof 命令。
在預設情況下,lsof 命令列出當前開啟的所有檔案、共享庫和目錄,並提供儘可能多的相關資訊。即使在負載很輕的系統上,這個命令的輸出也非常長,因此通常通過命令列引數指定一 個目錄名,或者使用管道篩選它的輸出。例如,假設希望解除安裝掛載在 /opt2目錄上的檔案系統。為了檢視與 /opt2 目錄相關聯的所有程序,應該執行下面所示的命令。
需要終止所有這些程序,然後才能解除安裝 /opt2 分割槽。因為這個列表中的程序都不能寫任何檔案,所以可以使用 kill 命令並指定第二列中列出的程序 ID (PID) 以終止它們,然後就可以順利地解除安裝分割槽。注意,PID 23402 與最後兩行相關聯 — 第一行表示 more 命令以 /opt2 作為當前工作目錄 (cwd),第二行表示 more 命令打開了 /opt2/resume.txt 檔案。
但是,假設 lsof 命令的輸出像下面這樣。
前三個與 /opt2 目錄相關聯的命令與前面一樣,但是後兩個命令是由另一個使用者執行的。其中的 emacs 命令用於編輯檔案,所以可以讓 USER 列中列出的使用者儲存檔案並退出,然後終止這個程序。
lsof 命令還有許多選項,可以幫助您識別不同型別的檔案系統上開啟的檔案和目錄、打開了網路套接字的程序、正在使用特定的庫的程序等等。lsof 命令的缺點是,必須聯絡使用者並要求他們終止某些程序,或者自己手工終止它們。fuser 命令更復雜,但是更強大,在作為根使用者執行時可以替您執行許多程序終止工作。
用 fuser 尋找使用者程序
fuser (find user processes) 命令也是一個開放原始碼應用程式,可以幫助您識別阻止檔案系統解除安裝的程序。fuser 命令尋找與作為命令列引數指定的檔案、目錄或檔案系統相關聯的程序。本文主要關注對檔案系統掛載點使用 fuser。關於 fuser 命令的更多資訊,請參見它的線上參考資訊。fuser 命令要求系統支援 /proc 檔案系統。因此,在所有 Linux 發行版和 FreeBSD 系統上都可以使用它。關於獲得 fuser 命令的原始碼的方法請參見 參考資料。
與 lsof 命令一樣,作為命令列引數提供檔案系統掛載點名稱是使用 fuser 命令識別阻止檔案系統解除安裝的程序的最簡單方法:
fuser 命令的輸出指出正在使用指定掛載點的程序的 PID。每個 PID 後面有一個字母,它表示與 PID 相關聯的程序以什麼方式使用指定的掛載點。最常見的字母是前面示例所示的 c,這表示指定的程序使用此檔案系統上的一個目錄作為當前工作目錄。
但是,fuser 命令的預設輸出不便於終端使用者使用,即使按 Linux 標準來看也是如此。fuser 命令提供一個 -v 選項,它在 fuser 命令的輸出中增加一些與標準 ps 命令相似的輸出,如下面所示。
這更方便,因為它至少指出了程序是什麼程式。在通過 fuser 命令獲得 PID 資訊之後,可以在終止程序之前結合使用標準的 ps 和 egrep 命令瞭解儘可能詳細的相關資訊,如下面所示
然後,可以使用標準的 kill 命令手工終止指定的程序,或者像下一節中解釋的,使用 fuser 命令的一些高階功能自動地終止它們。
用 fuser 終止程序
在通過引數指定掛載點時,fuser 命令的 -k 選項會自動地終止找到的程序。當然,必須作為根使用者執行 fuser 命令,才能終止屬於其他使用者的程序,如下面所示
在這裡,第二個程序 (emacs) 是第一個程序 (bash shell) 的子程序,因此在 fuser 命令殺死第一個程序時它就會終止。
如果希望指定底層物理裝置名,而不是它包含的檔案系統的掛載點,那麼還必須指定 -m 選項,如下面所示
第一個命令返回的輸出符合預期,因為它引用檔案系統的掛載點。第二個命令表明,不能使用標準的 fuser 選項直接查詢底層裝置。第三個命令說明,-m 選項允許直接指定裝置。可以在第一個和第三個命令中新增 -k 選項,從而終止與 /dev/sdb1 裝置上的檔案系統相關聯的程序。
有時候,為了應對一些緊急情況或者刪除掛載的 CD-ROM 或 DVD 等裝置,Linux 或 UNIX 系統管理員需要解除安裝分割槽。在由於裝置忙系統不允許刪除它的情況下,檢查系統上的所有程序是一個很煩人、很緩慢的過程。lsof 和 fuser 命令有助於識別阻止檔案系統解除安裝的程序。如果情況非常緊急,fuser 命令甚至可以替您終止它們。