2012-09-17 70 views
4

我有意攔截與文件系統相關的所有系統調用,而不是讓自己的代碼運行。例如,創建,寫入,關閉,lseek,getcwd等的調用。我的目標是創建一個像execve這樣的函數,用於捕獲從生成的程序到調用進程管理的內存文件系統中的所有文件I/O。這樣調用程序就可以檢查輸出而不會造成文件系統開銷。如何攔截對文件系統的調用

我的使用案例與沒有API或庫的大型數值模擬程序一起工作。這些程序只能通過輸入和輸出文件進行通信。如果這些文件很大,則只需執行大部分運行時即可完成I/O。在有些超級用戶權限的計算機上,可以設置一個駐留在RAM中的文件系統(例如Linux上的tmpfs),但是沒有超級用戶權限,或者以某種方式配置的計算機,這是不可能的。

據我所知,使用LD_PRELOAD將有可能調用定製代碼而不是libc中的函數。但是,這僅適用於動態鏈接的程序,並且它不回答在調用程序(我想要託管內存文件系統)和被調用程序之間如何執行IPC的問題。這種方法的問題是如何最好地執行IPC。我應該使用管道,unix域套接字還是一些共享內存?

我也看過ptrace作爲攔截系統調用的一種方法。這看起來可能有用,但我對這種方法有兩個問題。首先,我們如何防止實際的系統調用發生(而不是像我在一些例子中看到的那樣僅僅修改系統調用的參數)。其次,ptrace是否允許高性能地讀取被調用者的內存空間?

回答

2

使用LD_PRELOAD,您可以讓攔截代碼在被調用者的內存空間中運行。使用庫構造函數(__attribute__((constructor))),您可以在庫初次啓動時使您選擇的代碼運行,例如您的虛擬文件系統並初始化它。

然後,當您用預加載的庫攔截調用時,庫的函數在目標進程中運行,並可訪問構造的文件系統 - 無需IPC。

如果調用進程必須管理文件系統,則會引發與其進行通信的開銷。我建議在子進程中映射文件系統的重要部分(可能是作爲共享內存區域),而是使用子進程中的監聽器來監視父進程的文件系統更改(對文件系統操作進行適當的鎖定)。由於帶寬要求較低,您可以使用簡單的管道完成更改通知。

還檢出Plash,通過提供修改的Glibc沙漏文件系統訪問的半虛擬化系統。

+0

Plash似乎不再存在。 – Gael