1. 什麼是sysfs
sysfs是Linux 內核中設計較新的一種虛擬的基於內存的文件系統,它的作用與 proc 有些類似,但除了與 proc 相同的具有查看和設定內核參數功能之外,還有爲 Linux 統一設備模型作爲管理之用。相比於 proc 文件系統,使用 sysfs 導出內核數據的方式更爲統一,並且組織的方式更好,它的設計從 proc 中吸取了很多教訓。
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 保留給純淨的“進程文件系統”。
/sys 下的目錄結構是經過精心設計的:在 /sys/devices 下是所有設備的真實對象,包括如視頻卡和以太網卡等真實的設備,也包括 ACPI 等不那麼顯而易見的真實設備、還有 tty, bonding 等純粹虛擬的設備;在其它目錄如 class, bus 等中則在分類的目錄中含有大量對 devices 中真實對象引用的符號鏈接文件;在 /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> 接口中的各項信息和可調整項顯得更爲清晰。 |
[root@local~]# ls -F /sys/devices/ isa/ LNXSYSTM:00/ pci0000:00/ platform/ pnp0/ pnp1/ system/ virtual/ |
2.可以看到,在 /sys/devices/ 目錄下是按照設備的基本總線類型分類的目錄,再進入進去查看其中的 PCI 類型的設備,查看 /sys/devices/pci0000:00/ 的目錄結構
$ ls -F /sys/devices/pci0000:00/ 0000:00:00.0/ 0000:00:02.5/ 0000:00:03.1/ 0000:00:0e.0/ power/ 0000:00:01.0/ 0000:00:02.7/ 0000:00:03.2/ firmware_node@ uevent 0000:00:02.0/ 0000:00:03.0/ 0000:00:03.3/ pci_bus/ |
3.在 /sys/devices/pci0000:00/ 目錄下是按照 PCI 總線接入的設備號分類存放的目錄,再查看其中一個,查看/sys/devices/pci0000:00/ 的目錄結構
$ ls -F /sys/devices/pci0000:00/0000:00:01.0/ 0000:01:00.0/ device local_cpus power/ subsystem_vendor broken_parity_status enable modalias resource uevent class irq msi_bus subsystem@ vendor config local_cpulist pci_bus/ subsystem_device |
可以看到,其中有一個目錄 0000:01:00.0/, 其它都是屬性文件和屬性組,
其中涉及到 ksets, kobjects, attrs 等很多術語,這就需要熟悉 Linux 統一設備模型,參見《Linux設備驅動程序》。
sysfs目錄層次圖所表達的/sys目錄結構就是非常清晰明瞭:
1.在/sys根目錄之下的都是 kset,它們組織了 /sys 的頂層目錄視圖;
2.在部分kset 下有二級或更深層次的 kset;
3.每個kset 目錄下再包含着一個或多個 kobject,這表示一個集合所包含的 kobject 結構體;
4.在 kobject 下有屬性(attrs)文件和屬性組(attr_group),屬性組就是組織屬性的一個目錄,它們一起向用戶層提供了表示和操作這個 kobject 的屬性特徵的接口;
5.在 kobject 下還有一些符號鏈接文件,指向其它的 kobject,這些符號鏈接文件用於組織上面所說的 device, driver, bus_type, class, module 之間的關係;
6.不同類型如設備類型的、設備驅動類型的 kobject 都有不同的屬性,不同驅動程序支持的 sysfs 接口也有不同的屬性文件;而相同類型的設備上有很多相同的屬性文件。
4. 參考資料
網址:http://www.ibm.com/developerworks/cn/linux/l-cn-sysfs/index.html
鏈接:使用/sys文件系統訪問Linux 內核 -sysfs 虛擬文件系統提供了一種比 proc 更爲理想的訪問內核數據的途徑