歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Unix知識 >> Unix基礎知識

解決分區卸載問題

所有計算機操作系統都在引導時檢查它們掛載的文件系統是否是一致的,也就是說,確認它們的內部數據結構和映射到的相關存儲沒有錯誤。UNIX、Linux® 和其他類 UNIX 操作系統采用一種聰明的方法檢查文件系統的一致性(通常使用 fast 命令)。當這些系統掛載文件系統時,它們在文件系統頭中設置一個值,把文件系統標為 DIRTY,這意味著它正在使用,在向它寫入更新時可能暫時處於不一致的狀態。在系統關閉期間卸載文件系統時,把它們標為 CLEAN。在重新引導系統時,只需要檢查仍然標為 DIRTY 的文件系統的一致性。

在系統關閉過程中,會自動地卸載文件系統,這通常在終止所有非系統進程之後進行。但是,卸載文件系統仍然可能失敗並顯示以下消息:

$ sudo umount /mnt/NAS
umount: /mnt/NAS: device is busy

在這裡,busy 意味著一個進程正在寫這個文件系統或者進程是從它運行的。在這兩種情況下,都無法卸載文件系統,這是計算機系統的基本規則之一。如果不采用這個規則,可以在進程正在寫文件系統包含的文件時卸載文件系統,就會讓文件處於不一致的狀態,而文件系統本身標為 CLEAN

umount 命令的標准 Linux 版本包含一個延遲卸載選項 -l,它有助於卸載正在使用的文件系統。這個命令需要 Linux 內核 2.4.11 或更高版本,目前這通常沒問題。執行 umount -l /name/of/file system 可以讓指定的文件系統與系統的目錄層次結構脫離,讓新進程不能使用這個文件系統,然後當正在訪問它的所有進程都終止時卸載它。這很方便,但是當需要馬上卸載文件系統時它並不合適。

如果需要馬上卸載文件系統,而文件系統報告忙碌,還有其他辦法。如果您是系統的惟一用戶,那麼只需終止阻止文件系統卸載的進程。這需要查看所有窗口,尋找並終止正在寫這個分區或使用它作為當前工作目錄的暫停的進程或後台進程。但是,在有許多本地用戶和遠程用戶的多用戶系統上,這種方法是不實際的。幸運的是,開放源碼社區提供了一些命令,可以輕松地識別並終止這些進程。

lsof 尋找打開的文件

lsof (list open files) 命令列出特定的文件系統、目錄或設備上所有打開的文件以及與它們相關聯的進程。在大多數 UNIX 和類 UNIX 系統上都可以使用 lsof 命令,包括 IBM® AIX®、Berkeley Software Distribution (BSD®)、Hewlett Packard UNIX (HP-UX®)、Linux 和 Solaris®。關於獲取適合自己系統的 lsof 的信息請參見 參考資料。

在默認情況下,lsof 命令列出當前打開的所有文件、共享庫和目錄,並提供盡可能多的相關信息。即使在負載很輕的系統上,這個命令的輸出也非常長,因此通常通過命令行參數指定一個目錄名,或者使用管道篩選它的輸出。例如,假設希望卸載掛載在 /opt2 目錄上的文件系統。為了查看與 /opt2 目錄相關聯的所有進程,應該執行 清單 1 所示的命令。


清單 1. 與一個掛載的文件系統相關聯的進程
				
$ lsof /opt2
COMMAND   PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
bash    23334  wvh  cwd    DIR   8,17     4096    2 /opt2
more    23402  wvh  cwd    DIR   8,17     4096    2 /opt2
more    23402  wvh    3r   REG   8,17    10095  264 /opt2/resume.txt

需要終止所有這些進程,然後才能卸載 /opt2 分區。因為這個列表中的進程都不能寫任何文件,所以可以使用 kill 命令並指定第二列中列出的進程 ID (PID) 以終止它們,然後就可以順利地卸載分區。注意,PID 23402 與最後兩行相關聯 — 第一行表示 more 命令以 /opt2 作為當前工作目錄 (cwd),第二行表示 more 命令打開了 /opt2/resume.txt 文件。

但是,假設 lsof 命令的輸出像 清單 2 這樣。

但是,fuser 命令的默認輸出不便於最終用戶使用,即使按 Linux 標准來看也是如此。fuser 命令提供一個 -v 選項,它在 fuser 命令的輸出中增加一些與標准 ps 命令相似的輸出,見 清單 7。


清單 7. 掛載的 NFS 文件系統上的用戶進程
				
$ fuser -v /mnt/yellowmachine
                     USER        PID ACCESS COMMAND
/mnt/yellowmachine:  wvh       23334 ..c.. bash
                     wvh       23697 ..c.. emacs

這更方便,因為它至少指出了進程是什麼程序。在通過 fuser 命令獲得 PID 信息之後,可以在終止進程之前結合使用標准的 psegrep 命令了解盡可能詳細的相關信息,見 清單 8。


清單 8. 在系統上搜索特定的進程
				
# ps alxww |egrep '23334|23697'
4 1000 23334 23332 20 0 18148  2076 wait   Ss pts/13  0:00 -bash
0 1000 23697 23334 20 0 75964 12352 poll_s S+ pts/13  0:00 emacs -nw file2.txt
0    0 23703 23665 20 0  6060   632 -      R+ pts/16  0:00 egrep
23334|23697

然後,可以使用標准的 kill 命令手工終止指定的進程,或者像下一節中解釋的,使用 fuser 命令的一些高級功能自動地終止它們。

fuser 終止進程

在通過參數指定掛載點時,fuser 命令的 -k 選項會自動地終止找到的進程。當然,必須作為根用戶執行 fuser 命令,才能終止屬於其他用戶的進程,見 清單 9。
清單 9. 終止與掛載的 NFS 文件系統相關聯的進程

				
# fuser -k /mnt/yellowmachine
/mnt/yellowmachine:  23334c 23697c
Could not kill process 23697: No such process

在這裡,第二個進程 (emacs) 是第一個進程 (bash shell) 的子進程,因此在 fuser 命令殺死第一個進程時它就會終止。

如果希望指定底層物理設備名,而不是它包含的文件系統的掛載點,那麼還必須指定 -m 選項,見 清單 10。
清單 10. 掛載點和設備的進程列表

				
# fuser -v /opt2
                     USER        PID ACCESS COMMAND
/opt2:               wvh       23712 ..c.. bash
                     wvh       23753 ..c.. emacs
# fuser -v /dev/sdb1
# fuser -vm /dev/sdb1
                     USER        PID ACCESS COMMAND
/dev/sdb1:           wvh       23712 ..c.. bash
                     wvh       23753 ..c.. emacs

第一個命令返回的輸出符合預期,因為它引用文件系統的掛載點。第二個命令表明,不能使用標准的 fuser 選項直接查詢底層設備。第三個命令說明,-m 選項允許直接指定設備。可以在第一個和第三個命令中添加 -k 選項,從而終止與 /dev/sdb1 設備上的文件系統相關聯的進程。

結束語

有時候,為了應對一些緊急情況或者刪除掛載的 CD-ROM 或 DVD 等設備,Linux 或 UNIX 系統管理員需要卸載分區。在由於設備忙系統不允許刪除它的情況下,檢查系統上的所有進程是一個很煩人、很緩慢的過程。lsoffuser 命令有助於識別阻止文件系統卸載的進程。如果情況非常緊急,fuser 命令甚至可以替您終止它們。

 

Copyright © Linux教程網 All Rights Reserved