周家勁,謝俊峰,胡曉勤,謝卓偉
(1.四川大學網絡空間安全學院,成都 610200;2.成都云祺科技有限公司,成都 610041)
傳統(tǒng)的文件系統(tǒng)如NTFS、Ext4實現在內核態(tài),以物理磁盤作為存儲介質;在內核開發(fā)新的文件系統(tǒng)技術門檻較高,設計較為困難。FUSE(file system in userspace)提供一種面向類Unix操作系統(tǒng)的軟件接口,內核組件與VFS(virtual file system)交互,使得用戶無需編輯內核代碼即可創(chuàng)建自己的文件系統(tǒng),在類Unix操作系統(tǒng)端已有成熟的應用,比較知名的有GlusterFS(gluster file system)、ZFS(zettabyte file system)、SSHFS等,其他一些出于研究目的搭建的文件系統(tǒng)也使用了FUSE。由于Windows平臺的非開源環(huán)境,開發(fā)文件系統(tǒng)的難度更高,用戶空間文件系統(tǒng)的發(fā)展緩慢,FUSE底層設計面向VFS接口,Windows平臺下無法使用FUSE開發(fā)易于維護的用戶空間文件系統(tǒng)。
Dokan與WinFsp兩個開源項目搭建類似FUSE的框架,可以無需編寫設備驅動程序在Windows上創(chuàng)建除FAT或NTFS以外的新文件系統(tǒng)。NFS-win、sshfs-win基 于WinFsp,winSshFs基于Dokan,SftpDrive可利用ssh或nfs將遠端文件系統(tǒng)掛載到本地網絡驅動器,像訪問本地文件一樣訪問遠端文件系統(tǒng)。
本文提供了一種開發(fā)文件系統(tǒng)且不需要掛載新卷的詳細設計方案,在此基礎上設計并實現了一個基于文件過濾驅動的跨平臺網絡文件系統(tǒng)-CPNFS(cross-platform network file system)。CPNFS無需新建卷分配盤符,在原有卷子目錄下即可虛擬一個文件系統(tǒng)。如圖1所示,通過文件過濾驅動,監(jiān)視、攔截I/O管理器下發(fā)的I/O請求包IRP(I/Orequest packet)。請求包沿設備棧向下傳遞,發(fā)送到卷設備的文件請求先經過文件過濾驅動。用戶層遵循客戶端/服務器架構,采用TCP協(xié)議進行通信。服務端可以是任意平臺,客戶端用戶層使用內核提供的接口獲取請求發(fā)送到服務端處理,實現文件請求的重定向。對比測試了CPNFS與其他遠端共享文件系統(tǒng)在讀寫上的效率以及系統(tǒng)的兼容性,實驗結果表明,CPNFS在性能與兼容性上均有優(yōu)秀的表現。
圖1 分層驅動
如圖2所示,CPNFS采用客戶端/服務器端架構,客戶端由用戶層客戶端進程CPNFS-user與內核層過濾驅動CPNFS-kernel組成。
圖2 CPNFS系統(tǒng)框架
內核層CPNFS-kernel主體為文件系統(tǒng)過濾驅動,由過濾模塊、控制模塊與隊列管理模塊組成。過濾模塊綁定文件系統(tǒng)卷,監(jiān)視攔截用戶層始發(fā)進程通過環(huán)境子系統(tǒng)下發(fā)的文件請求,將需要處理的I/O請求傳遞到隊列管理模塊。隊列管理模塊負責請求的出入隊以及超時處理,I/O隊列類型分為待處理隊列、處理隊列兩種。控制模塊通過IRP_MJ_DEVICE_CONTROL例程暴露給用戶層接口,用戶層利用此接口訪問內核數據。
客戶端用戶層進程分為通信模塊client、請求處理模塊、過濾管理模塊以及統(tǒng)一接口層。通信模塊與服務端建立連接,發(fā)送請求報文到服務端,從服務端接收完成報文,完成報文傳遞給請求處理模塊。請求處理模塊對請求進行預處理,需要傳遞到遠端處理的請求轉換成請求報文傳遞給通信模塊,接收完成結果后利用統(tǒng)一接口層將數據傳遞到內核。過濾管理模塊維護過濾路徑表,將過濾路徑與遠端文件系統(tǒng)一一對應。
服務端由通信模塊server、文件管理模塊以及響應模塊reactor組成。通信模塊維護客戶端的連接,為每一個連接的客戶端建立子進程收發(fā)報文,并將請求報文傳遞給響應模塊。響應模塊接收請求報文,使用用戶層API對VFS層發(fā)起IO操作,將完成結果轉化為完成報文傳遞給通信模塊。文件管理模塊建立客戶端文件對象與本地文件描述符的映射,并保存文件的客戶端獨有屬性。
表1 請求處理統(tǒng)一接口
用戶層進程打開文件獲得句柄,通過句柄對文件或文件夾進行操作,內核層則會創(chuàng)建文件對象,文件對象包含名稱、安全描述符、偏移位置和引用計數等信息,句柄與文件對象一一對應,通過文件對象指針可以控制訪問一個文件的打開實例。文件對象由內核組件對象管理器創(chuàng)建,從內核空間分配內存地址,因不同進程共享內核空間,指向文件對象的指針在不同進程上下文中可唯一指定一個文件對象。因此,重定向進程管理文件對象時,以文件對象指針數值作為鍵建立哈希表。
CPNFS采用了如圖3所示的數據結構來管理文件對象,客戶端建立以文件對象指針為鍵的文件哈希表,緩存文件的屬性信息如文件名、安全描述符以及目錄的打開狀態(tài)。服務端對每一個客戶端建立以文件對象指針為鍵的文件映射哈希表,完成客戶端文件對象與服務端文件描述符的映射,同時儲存文件名、文件屬性stat、inode等信息,Linux下inode可以唯一標識一個文件。同時建立以inode為鍵的屬性哈希表,緩存客戶端設置的一些NTFS獨有屬性file_attri,所有進程共享同一個屬性哈希表,此表駐留在服務端。
圖3 文件對象存儲方式
CPNFS請求處理流程如圖4所示,客戶端進程與服務器端建立連接,設置過濾目錄與服務器端目錄建立映射,完成后客戶端進程進入休眠。新的文件請求到達過濾驅動時,截獲需要重定向處理的IRP,將該IRP掛起并插入待處理隊列,返回PENDING狀態(tài)表示請求后續(xù)異步完成。新請求入隊時客戶端進程喚醒,通過CTL_GET_REQUEST接口從內核隊列獲取請求內容,然后發(fā)送請求報文到服務端,服務端處理完成后發(fā)送完成報文到客戶端,客戶端通過CTL_RESPONSE_COMPLETION通知內核請求已完成并以內存映射的方式將數據傳遞到內核。
圖4 一次IO處理流程
(1)打開操作。當用戶進程使用fopen、CreateFile等系統(tǒng)調用打開文件時,客戶端進程發(fā)送文件名以及打開標記到服務端。服務端打開文件,建立本地文件對象與服務端文件描述符的映射,并建立文件打開列表保存已打開的文件,返回到客戶端時內核完成請求,IO管理器返回句柄。
(2)讀操作。當用戶進程使用fread、Read-File等系統(tǒng)調用通過文件句柄讀取文件時,客戶端進程發(fā)送文件對象鍵值、偏移量以及讀取長度到服務端,服務端通過查找文件打開列表獲得文件描述符,使用服務端系統(tǒng)調用如pread讀取文件,獲得數據后返回到客戶端。
(3)寫操作。當用戶進程使用fwrite、Write-File等系統(tǒng)調用通過文件句柄寫文件時,客戶端進程請求參數以及數據報文到服務端,服務端使用服務端系統(tǒng)調用如pwrite將數據寫入文件。
(4)查詢文件屬性。當用戶進程使用Get-FileInformationByHandle等系統(tǒng)調用查詢文件屬性時,客戶端進程轉換請求為符合服務端的請求類型,將請求發(fā)送到服務端,服務端查詢文件屬性后返回到客戶端,客戶端轉換屬性結構返回到內核。
(5)目錄遍歷。當資源管理器獲取目錄下的子目錄或文件時,客戶端進程發(fā)送目錄遍歷請求到服務端,服務端遍歷目錄返回到客戶端,客戶端轉換格式將目錄內容返回到內核。
According to above all, we can draw the calculated value of X axial force of support plates as follows:
(6)關閉操作。當用戶進程調用fclose、CloseHandle等系統(tǒng)調用關閉句柄時,IO管理器會檢查對象的引用計數是否為0,引用計數為0時表明沒有用戶進程或內核組件訪問該文件??蛻舳诉M程發(fā)送文件對象鍵值到服務端,服務端關閉文件并刪除文件映射表中對應項。
所有的實驗在Vmware ESXI管理的虛擬化環(huán)境下所開啟的兩臺虛擬機上運行,其中一臺作為CPNFS的服務器,另外一臺作為CPNFS的客戶端。服務器端系統(tǒng)為CentOS 7,內核版本為Linux 3.10.0,預留2GB內存;客戶端版本為Windows server 2012,內部版本為6.2.9200,預留8 GB內存。使用iperf3測試客戶端到服務端的上行帶寬約150MB/s,下行帶寬約100MB/s。表2為測試環(huán)境的具體參數。
表2 實驗環(huán)境配置
本節(jié)使用標準測試工具FIO(Flexible I/Otester)測 試CPNFS、WinFsp+NFS-win、WinFsp+SshFs-win、Dokan+WinSshFs與SftpDriver在8 KB隨機讀寫吞吐、8 KB混合隨機讀寫吞吐以及4 MB順序讀寫吞吐性能。
2.2.1 隨機訪問性能
測量了CPNFS與其他幾種網絡文件系統(tǒng)的8KB隨機讀寫以及讀占70%、寫占30%的混合隨機讀寫兩個項目。從結果上看,CPNFS的隨機讀性能與WinFsp+sshfs-win接近,相對于WinFsp+NFS-win約提升40%,接近Dokan+winSshFs的2倍,是SftpDriver的2.5倍以上。CPNFS的隨機寫性能接近Dokan+winSshFs,是WinFsp+NFS-win的7倍以上,WinFsp+sshfs-win的4倍以上,SftpDriver的1.5倍以上,見圖5。
圖5 CPNFS與其他關于8 KB隨機讀寫的性能比較
從8 KB上讀占70%、寫占30%的混合隨機讀寫的結果上可以看到CPNFS的讀寫同時進行場景的性能均比其他四個優(yōu)秀,分別約提升180%、100%、70%、30%,見圖6。
圖6 CPNFS與其他關于8KB混合隨機讀寫的性能比較
2.2.2 順序訪問性能
在4 MB的順序讀上,CPNFS與WinFsp+NFS-win的性能接近,遠遠超過WinFsp+sshfswin與SftpDriver,是WinFsp+sshfs-win的3倍以上、SftpDriver的35倍以上,其中Dokan+win SshFs不支持大文件的順序讀。在4 MB的順序寫上,CPNFS的性能相對于WinFsp+NFS-win約提升了50%,與其他三者相比分別提升了500%、850%、1660%,見圖7。
圖7 CPNFS與其他關于4 MB順序訪問的吞吐性能比較
表3總結了CPNFS與WinFsp+NFS-win在幾個測試場景的性能對比,可以發(fā)現,除順序讀以外,其他場景下CPNFS的性能都比較優(yōu)秀。
表3 CPNFS與WinFsp+NFS-win綜合比較
本文提出了一種基于文件過濾驅動的文件系統(tǒng)設計方法,實現無需掛載盤符的用戶文件系統(tǒng)開發(fā)。該設計在內核層截獲所有文件IO,保存需要處理的IO并提供統(tǒng)一接口供用戶層實現,可在原來文件系統(tǒng)卷目錄下虛擬文件系統(tǒng)。基于該設計,在Windows下設計并實現了一個跨平臺的網絡文件系統(tǒng)-CPNFS,無需新建新卷即可如訪問本地文件系統(tǒng)一樣訪問遠端文件系統(tǒng)。實驗測試結果表明,CPNFS在隨機讀寫與順序寫上,相較于其他共享文件系統(tǒng)方法都具有十分明顯的優(yōu)勢。