2014-02-07 39 views
0

我正在爲Linux編寫一個C程序,用於讀取和寫入NFS服務器上的文件。這份份額很難實現;嘗試訪問它將無限期地阻止,直到它們工作。無限期地讓我的程序塊不好,即使文件不可用,它仍然能夠做有用的工作。重新安裝共享軟件不是一種選擇。將硬盤掛載的NFS卷視爲軟件

有兩個進程,其中一個工作並且不會阻塞,另一個處理文件IO並可能阻塞的進程是一個選項,但會構成重大更改。我想避免這種情況。真的,我想說,「我知道你很難安裝,所以天真的程序可以假裝你是一個高度可靠的本地磁盤。但我知道更好,我準備應付任何訪問失敗,類似於行爲如果你是軟裝的。「因此:

在C中,如何訪問硬安裝的NFS共享上的文件,如果服務器不可用而不是無限制地阻塞,則會出錯?

我可以根據需要運行,但不希望。使用root重新安裝共享是正確的。我可以依靠新的功能,但進一步的支持會變得更好。

我的研究表明答案是這是不可能的,但也許我錯過了一些東西。

+1

爲什麼不設置超時信號來在合適的超時後中斷阻塞呼叫。每當你進行一個阻塞調用('open()','fopen()','readdir()','chdir()','stat()'等)時,啓動定時器,如果調用返回'errno == EINTR',並且你的超時信號處理程序設置了一個標誌,你可以知道這個通話在分配的時間內沒有進行,並且把它當作是錯誤的。超時信號處理的額外開銷非常值得;這在像Apache這樣的服務器軟件中很常見。使超時用戶可配置,並設置。 –

+0

這是一個潛在的解決方法。這是可靠的嗎?我相信一個不可用的NFS掛載可能會使進程進入不可中斷的睡眠狀態,而信號本身會阻塞該睡眠。 –

+0

啊。在2.6.25內核之前,'nointr'掛載選項確實可靠,但在後續的內核上它會被忽略。 'SIGKILL'是唯一可行的。因此,您需要使用子進程來訪問掛載,並通過Unix域套接字輔助消息返回描述符(文件或目錄)。如果操作時間過長,原始進程會使用超時「殺死」孩子。使用長壽命的小孩子爲每個操作分配一個子孩子應該將開銷降低到可接受的水平。也許在每次訪問之前解析'/ proc/mounts'只能解決NFS的問題。 –

回答

3

你沒有錯過任何東西,你永遠不會收到服務器不可用的錯誤,因爲內核永遠不會在硬掛載的nfs掛載點上傳遞它們。

由於硬選項是安裝點的屬性,因此您不能選擇應用程序,因爲內核沒有設置爲以這種方式運行。

但是,您確實提到可以以root身份運行該應用程序。爲什麼不在其他地方安裝文件系統軟,然後獲得您的預期行爲?

+0

在其他地方進行軟安裝絕對是某些環境的有效選擇!可悲的是,我不能假定系統管理員將會出現新的坐騎。目標是最大限度地發揮最小的驚喜。 根據我的約束,不可能是有效的答案。公認。 –