郭松,謝維波
(華僑大學計算機科學與技術(shù)學院,福建泉州362021)
L inux下Proc文件系統(tǒng)的編程剖析
郭松,謝維波
(華僑大學計算機科學與技術(shù)學院,福建泉州362021)
論述Linux下可加載內(nèi)核模塊和虛擬文件系統(tǒng)的運作原理,比較內(nèi)核程序運行在微內(nèi)核和一體化內(nèi)核兩種組織方式下的優(yōu)缺點.在此基礎(chǔ)上,提出Proc文件系統(tǒng)下的編程,包括編寫內(nèi)核模塊和Proc文件系統(tǒng)程序的一些過程,并對主要代碼進行解析說明.通過一個編程示例,給出Proc文件系統(tǒng)編程的框架,以顯示Linux虛擬文件系統(tǒng)的能力.
Proc文件系統(tǒng);Linux;內(nèi)核模塊;虛擬文件系統(tǒng)
通過對Proc文件系統(tǒng)中文件的讀寫操作,達到對驅(qū)動程序或其他內(nèi)核程序的控制,實現(xiàn)用戶態(tài)程序與核心態(tài)程序的數(shù)據(jù)通信.向Proc寫入信息,可以使用標準的文件系統(tǒng)提供的機制.文件系統(tǒng)注冊的標準機制,是每個文件系統(tǒng)都用自己的函數(shù)來處理索引節(jié)點和文件操作.通過編寫內(nèi)核模塊來實現(xiàn)用戶態(tài)到核心態(tài)通信,通過內(nèi)核模塊在Proc文件系統(tǒng)中創(chuàng)建文件夾或文件,來為用戶程序提供接口.基于此,本文介紹編寫內(nèi)核模塊和Proc文件系統(tǒng)程序的一些過程,并對主要代碼進行解析說明.
1.1 可加載內(nèi)核模塊
為了支持構(gòu)建安全操作系統(tǒng),現(xiàn)代中央處理器(CPU)一般提供至少兩種運行模式:特權(quán)模式與用戶模式.它們不僅具有不同的優(yōu)先權(quán)等級,還有各自的地址空間,即內(nèi)核空間和用戶空間.所有的現(xiàn)代CPU都具有保護系統(tǒng)軟件不受應(yīng)用程序破壞的功能,即在CPU中實現(xiàn)不同的操作模式或級別[1].
Unix系統(tǒng)使用最高級別和最低級別——內(nèi)核程序運行在特權(quán)模式,在這個級別中可以進行所有的操作;而應(yīng)用程序運行在用戶模式,處理器控制著對硬件的直接訪問,以及對內(nèi)存的非授權(quán)訪問.
根據(jù)各個管理模塊是否放在特權(quán)模式下,操作系統(tǒng)有微內(nèi)核和一體化內(nèi)核兩種組織方式[1],如圖1所示.傳統(tǒng)的Unix及大部分類Unix操作系統(tǒng)基本上都屬于一體化內(nèi)核組織方式,而M ach,Window s N T,Window 2000/XP等基本屬于微內(nèi)核組織方式(圖1).
圖1 操作系統(tǒng)內(nèi)核組織方式Fig.1 O rganization of operating system kernel
一體化內(nèi)核組織方式的優(yōu)點是效率高、安全,但其缺點是不容易擴展.若要增加一種新設(shè)備驅(qū)動或文件系統(tǒng)等功能,則必須對內(nèi)核重新編譯定制,而且占用內(nèi)存較多.微內(nèi)核組織方式的優(yōu)點是可擴展性好,占用內(nèi)存少,但缺點是效率低,也沒有一體化內(nèi)核安全[1].
在Linux中引入內(nèi)核模塊機制,主要目的是為了充分吸取兩者的優(yōu)點,克服它們的缺點.內(nèi)核模塊是Linux用來高效地利用微內(nèi)核的理論優(yōu)點而不會降低系統(tǒng)性能的一種方法.
Linux內(nèi)核模塊本質(zhì)上是存放在文件系統(tǒng)中的ELF對象文件,沒有鏈接,不能獨立運行,但可以動態(tài)加載(Insmod)到內(nèi)核并與內(nèi)核鏈接,從而成為內(nèi)核的一部分,或者從內(nèi)核解除鏈接.其基本機理是, Linux內(nèi)核本身有一張內(nèi)核符號表(Kernel Sym bol Table),包括用來描述系統(tǒng)提供哪些函數(shù)服務(wù)、系統(tǒng)全局變量及它們的地址.在Linux用一個宏EXPORT_SYMBOL(或EXPORT_SYMBOL_GPL,定義在include/linux/module.h中)導(dǎo)出需要輸出的函數(shù)及系統(tǒng)全局變量,以使內(nèi)核各個模塊能夠互相引用.同理,每個內(nèi)核目標模塊也有一張類似的符號表,其中定義了此模塊所提供的功能函數(shù)及變量,以及此模塊可能要用到的系統(tǒng)內(nèi)核,或者其他已加載模塊中的函數(shù)及變量,但此時又不知其實際地址.
為了使內(nèi)核模塊真正成為Linux系統(tǒng)內(nèi)核的一部分,必須將此內(nèi)核模塊動態(tài)裝入到內(nèi)存中,并把相應(yīng)的各種符號函數(shù)解析定位好.然后,內(nèi)核模塊提供的各種函數(shù)才能真正被使用.當模塊加載入內(nèi)核時,系統(tǒng)將新加載模塊提供的資源和符號加到內(nèi)核符號表中;而當模塊加載時,內(nèi)核用符號表來解決模塊的資源引用問題.Linux允許模塊堆棧,即一個模塊可請求其他模塊為之服務(wù).通過這種通信機制,新加載的模塊可以訪問已加載模塊提供的資源[2].
內(nèi)核中有一個變量叫做module_list,定義在include/linux/module.h中,是一個全局變量.每當用戶將一個模塊加載到內(nèi)核時,這個模塊就會被添加到由module_list形成的鏈表中.必要時,內(nèi)核就會檢索這個鏈表,找到該模塊,然后再使用其提供的函數(shù)或變量.
1.2 虛擬文件系統(tǒng)
Linux的最重要特征之一就是支持多種文件系統(tǒng),因此,它更加靈活并可以和許多其他操作系統(tǒng)共存.文件系統(tǒng)不僅包含著文件中的數(shù)據(jù),而且還有文件系統(tǒng)的結(jié)構(gòu)(屬性、操作等).每個實際文件系統(tǒng)從操作系統(tǒng)和系統(tǒng)服務(wù)中分離出來,它們之間通過一個接口層——虛擬文件系統(tǒng)(VFS)來通訊.虛擬文件系統(tǒng)所隱含的思想是,把表示很多不同種類文件系統(tǒng)的共同信息——通用文件模型放入內(nèi)核.Linux核心的其他部分及系統(tǒng)中運行程序?qū)⒖吹浇y(tǒng)一的文件系統(tǒng).
把通用文件模型看作是面向?qū)ο蟮?在這里對象是一個結(jié)構(gòu),其中既定義了數(shù)據(jù)結(jié)構(gòu),也定義了其上的操作方法.VFS依賴于數(shù)據(jù)結(jié)構(gòu)來保存其對一個文件系統(tǒng)的一般表示.通用文件模型由超結(jié)塊、索引節(jié)點、目錄項和數(shù)據(jù)塊(文件)等對象類型(結(jié)構(gòu))組成[2].在相應(yīng)的目錄下有對應(yīng)結(jié)構(gòu)的操作方法的接口結(jié)構(gòu),如struct inode_operations,struct file_operations,成員幾乎都是一些函數(shù)指針.
用戶程序通過系統(tǒng)調(diào)用訪問通用的VFS.每個支持的文件系統(tǒng)必須實現(xiàn)一組函數(shù),而這組函數(shù)完成V FS所支持的操作.V FS了解它所支持的文件系統(tǒng)和完成每個操作的函數(shù)[3].V FS管理文件系統(tǒng)相關(guān)的系統(tǒng)調(diào)用,并把它們轉(zhuǎn)化成適應(yīng)文件系統(tǒng)類型的函數(shù),如圖2所示[2].
圖2 VFS與具體文件系統(tǒng)的關(guān)系示意圖Fig.2 Relationship of VFSand concrete file system
具體的文件系統(tǒng)可以設(shè)計成可加載模塊,在系統(tǒng)需要時進行加載.掛載具體文件系統(tǒng)時,VFS讀取它的超級塊,得到具體文件系統(tǒng)的拓撲結(jié)構(gòu),并將這些信息映射到VFS超級塊結(jié)構(gòu)中.VFS在系統(tǒng)中保存著一組已安裝文件系統(tǒng)的鏈表及其VFS超塊,而每個VFS超塊包含一些信息及一個執(zhí)行特定功能的函數(shù)指針.
當進程或者shell命令訪問目錄和文件時,shell命令及應(yīng)用程序分解成系統(tǒng)調(diào)用,進入內(nèi)核空間,遍歷系統(tǒng)的VFS inode,而VFS的inode指向了具體文件系統(tǒng)的節(jié)點.通過底層塊I/O函數(shù)調(diào)用IDE接口,再通過塊驅(qū)動程序訪問塊設(shè)備,得到文件數(shù)據(jù).另外,還有一種特殊的文件系統(tǒng),如Proc或者Sysfs,它們操作內(nèi)存緩沖區(qū),在內(nèi)存緩沖區(qū)中存有相關(guān)系統(tǒng)管理信息.所有Linux文件系統(tǒng)使用一個通用buffer cache,來緩沖來自底層設(shè)備的數(shù)據(jù)以加速對包含此文件系統(tǒng)物理設(shè)備的存取[3].
此虛擬文件系統(tǒng)能夠管理在任何時刻映像到系統(tǒng)的不同文件系統(tǒng).它通過維護一個描述整個虛擬文件系統(tǒng)和實際已安裝文件系統(tǒng)的結(jié)構(gòu)來完成這個工作.VFS對文件系統(tǒng)共有的內(nèi)核上層及底層部分進行了處理.上層處理如文件路徑的查找、文件的讀寫操作、從用戶空間向下傳遞到具體文件系統(tǒng)的部分;在底層進行各種緩存的處理.
Proc文件系統(tǒng)真正顯示了Linux虛擬文件系統(tǒng)的能力,但事實上它并不存在.不管是Proc目錄,還是其子目錄和文件都不是真正的存在(不保存在硬盤或者其他磁盤中).Proc文件系統(tǒng)象一個真正的文件系統(tǒng)一樣向虛擬文件系統(tǒng)注冊.然而,當有對Proc中的文件和目錄的請求發(fā)生時,VFS系統(tǒng)將從核心中的數(shù)據(jù)中臨時構(gòu)造這些文件和目錄.Proc文件系統(tǒng)提供給用戶一個核心內(nèi)部工作的可讀窗口. Linux核心模塊都在Proc文件系統(tǒng)中創(chuàng)建入口.
2.1 內(nèi)核模塊
在Linux模塊中,只能調(diào)用那些由內(nèi)核導(dǎo)出的函數(shù),而不能像其他應(yīng)用程序那樣調(diào)用庫函數(shù).因為Linux內(nèi)核函數(shù)運行在內(nèi)核空間,沒被鏈接到C庫,所以在內(nèi)核空間無法調(diào)用C庫的函數(shù)[3].內(nèi)核函數(shù)通常定義在內(nèi)核源代碼的include目錄下,需要用的大都在include/Linux下.一個內(nèi)核模塊必須至少有兩個函數(shù),函數(shù)init_module()在該模塊加載到內(nèi)核的時候被調(diào)用,而函數(shù)cleanup_module()在模塊被卸載之前調(diào)用[3].
2.2 Proc文件系統(tǒng)程序
實現(xiàn)一個程序,它是內(nèi)核維護記錄學生名和學號的一張表格.利用Proc文件系統(tǒng)作為與內(nèi)核通信的手段,實現(xiàn)對文件的維護和操作.該程序由兩部分組成.一部分,作為內(nèi)核模塊在內(nèi)核運行,在加載模塊時,初始化表格,建立相應(yīng)的Proc文件;在卸載模塊時,清除該表格和Proc文件;在加載后,則通過Proc文件系統(tǒng)接受用戶請求,實現(xiàn)對表格的維護操作.另一部分,實現(xiàn)為一個用戶態(tài)程序,它從命令行讀取用戶的命令,解析用戶命令;通過Proc文件系統(tǒng)將命令傳遞到內(nèi)核模塊,也可通過Proc文件系統(tǒng)從內(nèi)核模塊讀取信息[4].
2.2.1 解決方案 設(shè)計一個用戶態(tài)程序和一個核心態(tài)程序.用戶態(tài)程序包括添加記錄、刪除記錄、查看信息;核心態(tài)程序包括實現(xiàn)內(nèi)存的初始化、管理、卸載等功能.具體的通信過程:用戶態(tài)程序?qū)roc文件系統(tǒng)進行讀和寫的操作.當寫文件時,內(nèi)核獲得用戶寫入的內(nèi)容,對寫入的內(nèi)容進行處理和管理;當用戶讀文件時,內(nèi)核首先把內(nèi)存中保存的內(nèi)容寫到Proc文件中,用戶再讀些文件,得到想要讀的內(nèi)容[4].
2.2.2 主要代碼解析
利用Linux強大易用的可加載內(nèi)核模塊機制,可以靈活地擴充Linux內(nèi)核,廣泛利用在Linux設(shè)備驅(qū)動和netfilter等方面的開發(fā)中.因此,在提高系統(tǒng)的安全性的同時,也可以被攻擊者利用而非法入侵系統(tǒng).它猶如一把雙刃劍,在提供強大的靈活性同時有存在著極大的安全隱患,需要用戶謹慎使用.
[1] 熊海泉.Linux模塊實現(xiàn)機制剖析[J].科技廣場,2006(2):7-8.
[2] 吳偉國,李張,任廣臣.Linux內(nèi)核分析及高級編程[M].北京:電子工業(yè)出版社,2008:187.
[3] 毛德操,胡希明.Linux內(nèi)核源代碼情景分析[M].杭州:浙江大學出版社,2001:415-430.
[4] 羅宇,褚瑞.操作系統(tǒng)課程設(shè)計[M].北京:機械工業(yè)出版社,2005:106-120.
[5] CHERAM I.Linux內(nèi)核模塊編程——將/Proc作為輸入[EB/OL].[2006-12-16].http://www.egunao.com/os/ linux/18220.htm l.
Analysis in Depth on L inux Proc File System Programm ing
GUO Song,X IEWei-bo
(College of Computer Science&Technology,Huaqiao University,Quanzhou 362021,China)
The operation p rincip le of Linux loadable kernelmodule and virtual file system was discussed,and the advantages and disadvantages of the kernel p rogram running in micro kernel and integrated kernelwere compared.Base on this foundation,the Proc file system p rogramming is p roposed.W hich include the p rogramming p rocedure of kernel module and Proc file system,and to themain code was analyzed.Through a p rogramming demonstration,the framewo rk of Proc file system p rogramming is given to demonstrate the ability of Linux virtual file system.
Proc file system;Linux;kernelmodule;virtual file system
TP 311.1
A
(責任編輯:黃仲一 英文審校:吳逢鐵)
1000-5013(2010)05-0515-06
2009-10-23
謝維波((1964-),男,教授,主要從事信號處理與模式識別的研究.E-mail:xw blxf@hqu.edu.cn.
福建省廈門市科技計劃項目(3502Z20083047)