sysfs 文件系統總是被掛載在 /sys 掛載點上。雖然在較早期的2.6內核系統上並沒有規定 sysfs 的標準掛載位置,可以把 sysfs 掛載在任何位置,但較近的2.6內核修正了這一規則,要求 sysfs 總是掛載在 /sys 目錄上;針對以前的 sysfs 掛載位置不固定或沒有標準被掛載,有些程序從 /proc/mounts 中解析出 sysfs 是否被掛載以及具體的掛載點,這個步驟現在已經不需要了。請參考附錄給出的 sysfs-rules.txt 文件鏈接。
sysfs 與 proc 相比有很多優點,最重要的莫過於設計上的清晰。一個 proc 虛擬文件可能有內部格式,如 /proc/scsi/scsi
,它是可讀可寫的,(其文件權限被錯誤地標記爲了 0444 !,這是內核的一個BUG),並且讀寫格式不一樣,代表不同的操作,應用程序中讀到了這個文件的內容一般還需要進行字符串解析,而在寫入時需要先用字符串 格式化按指定的格式寫入字符串進行操作;相比而言, sysfs 的設計原則是一個屬性文件只做一件事情, sysfs 屬性文件一般只有一個值,直接讀取或寫入。整個 /proc/scsi
目錄在2.6內核中已被標記爲過時(LEGACY),它的功能已經被相應的 /sys 屬性文件所完全取代。新設計的內核機制應該儘量使用 sysfs 機制,而將 proc 保留給純淨的“進程文件系統”。
清單 1. 與 /sys 文件系統的一次交互(視內核版本號和外接設備的不同,在您的系統上執行這些命令的結果可能與此有所不同)
$ ls -F /sys |
這是在 Fedora 10 的 2.6.27.5-117.fc10.i686 的內核上,可以看到在 /sys 目錄下有 block, bus, class, dev, devices, firmware, fs, kernel, module, power 這些子目錄,本文將分別介紹這些目錄存在的含義。
第二個 ls 命令展示了在一個 pci 設備目錄下的文件, "ls" 命令的 "-F" 命令爲所列出的每個文件使用後綴來顯示文件的類型,後綴 "/" 表示列出的是目錄,後綴 "@" 表示列出的是符號鏈接文件。可以看到第二個目錄下包含有普通文件 (regular file) 和符號鏈接文件 (symbolic link file) ,本文也將以這個具體的設備爲例說明其中每一個普通文件的用途。
/sys 下的目錄結構是經過精心設計的:在 /sys/devices
下是所有設備的真實對象,包括如視頻卡和以太網卡等真實的設備,也包括 ACPI 等不那麼顯而易見的真實設備、還有 tty, bonding 等純粹虛擬的設備;在其它目錄如 class, bus 等中則在分類的目錄中含有大量對 devices 中真實對象引用的符號鏈接文件; 清單1 中在 /sys 根目錄下頂層目錄的意義如下:
/sys 下的子目錄 | 所包含的內容 |
---|---|
/sys/devices | 這是內核對系統中所有設備的分層次表達模型,也是 /sys 文件系統管理設備的最重要的目錄結構,下文會對它的內部結構作進一步分析; |
/sys/dev | 這個目錄下維護一個按字符設備和塊設備的主次號碼(major:minor)鏈接到真實的設備(/sys/devices下)的符號鏈接文件,它是在內核 2.6.26 首次引入; |
/sys/bus | 這是內核設備按總線類型分層放置的目錄結構, devices 中的所有設備都是連接於某種總線之下,在這裏的每一種具體總線之下可以找到每一個具體設備的符號鏈接,它也是構成 Linux 統一設備模型的一部分; |
/sys/class | 這是按照設備功能分類的設備模型,如系統所有輸入設備都會出現在 /sys/class/input 之下,而不論它們是以何種總線連接到系統。它也是構成 Linux 統一設備模型的一部分; |
/sys/block | 這裏是系統中當前所有的塊設備所在,按照功能來說放置在 /sys/class 之下會更合適,但只是由於歷史遺留因素而一直存在於 /sys/block, 但從 2.6.22 開始就已標記爲過時,只有在打開了 CONFIG_SYSFS_DEPRECATED 配置下編譯纔會有這個目錄的存在,並且在 2.6.26 內核中已正式移到 /sys/class/block, 舊的接口 /sys/block 爲了向後兼容保留存在,但其中的內容已經變爲指向它們在 /sys/devices/ 中真實設備的符號鏈接文件; |
/sys/firmware | 這裏是系統加載固件機制的對用戶空間的接口,關於固件有專用於固件加載的一套API,在附錄 LDD3 一書中有關於內核支持固件加載機制的更詳細的介紹; |
/sys/fs | 這裏按照設計是用於描述系統中所有文件系統,包括文件系統本身和按文件系統分類存放的已掛載點,但目前只有 fuse,gfs2 等少數文件系統支持 sysfs 接口,一些傳統的虛擬文件系統(VFS)層次控制參數仍然在 sysctl (/proc/sys/fs) 接口中中; |
/sys/kernel | 這裏是內核所有可調整參數的位置,目前只有 uevent_helper, kexec_loaded, mm, 和新式的 slab 分配器等幾項較新的設計在使用它,其它內核可調整參數仍然位於 sysctl (/proc/sys/kernel) 接口中 ; |
/sys/module | 這裏有系統中所有模塊的信息,不論這些模塊是以內聯(inlined)方式編譯到內核映像文件(vmlinuz)中還是編譯爲外部模塊(ko文件),都可能會出現在 /sys/module 中:
|
/sys/power | 這裏是系統中電源選項,這個目錄下有幾個屬性文件可以用於控制整個機器的電源狀態,如可以向其中寫入控制命令讓機器關機、重啓等。 |
/sys/slab (對應 2.6.23 內核,在 2.6.24 以後移至 /sys/kernel/slab) | 從2.6.23 開始可以選擇 SLAB 內存分配器的實現,並且新的 SLUB(Unqueued Slab Allocator)被設置爲缺省值;如果編譯了此選項,在 /sys 下就會出現 /sys/slab ,裏面有每一個 kmem_cache 結構體的可調整參數。對應於舊的 SLAB 內存分配器下的 /proc/slabinfo 動態調整接口,新式的 /sys/kernel/slab/<slab_name> 接口中的各項信息和可調整項顯得更爲清晰。 |
接下來對 /sys/devices/ 下的目錄結構作進一步探討:
$ ls -F /sys/devices/ |
可以看到,在 /sys/devices/ 目錄下是按照設備的基本總線類型分類的目錄,再進入進去查看其中的 PCI 類型的設備:
清單 3. 查看 /sys/devices/pci0000:00/ 的目錄結構
$ ls -F /sys/devices/pci0000:00/ |
在 /sys/devices/pci0000:00/ 目錄下是按照 PCI 總線接入的設備號分類存放的目錄,再查看其中一個,
清單 4. 查看 /sys/devices/pci0000:00/ 的目錄結構
$ ls -F /sys/devices/pci0000:00/0000:00:01.0/ |
可以看到,其中有一個目錄 0000:01:00.0/, 其它都是屬性文件和屬性組,而如果對 0000:01:00.0/ 子目錄中進行再列表查看則會得到 清單1 的目錄結構。
繼續以上過程可以瞭解整個目錄樹的結構,這裏把它整理成 圖 1. sysfs 目錄層次圖
其中涉及到 ksets, kobjects, attrs 等很多術語,這就不得不提到 Linux 統一設備模型。