Linux sysfs系统经过长时间的发展,很多用户都很了解Linux sysfs系统了,这里我发表一下个人理解,和大家讨论讨论。Linux sysfs系统下具有使用 SCSI 总线连接的主机上,与 PCI类似的是也采用四个号码作为一组来描述一个设备,其中位于最顶层的是scsi_host。以社区支持的方式开发Linux发行版Fedora Core Linux,而Red Hat公司原来Red Hat Linux的开发团队也将继续参与这一发行版本的开发工作。Red Hat公司把Fedora Project看作一个新技术的开发园地,鼓励有兴趣的自由软件开发人员参与此项项目的开发,希望这一发行版本真正成为以自由软件开发为模式的操作系统。
我们从设备类别 /class/为起点来探索:
# ls -lU /sys/class/scsi_host总计 0
lrwxrwxrwx 1 root root 0 12-13 01:59 host0 -> \
../../devices/pci0000:00/0000:00:02.5/host0/scsi_host/host0
lrwxrwxrwx 1 root root 0 12-13 01:59 host1 -> \
../../devices/pci0000:00/0000:00:02.5/host1/scsi_host/host1
注意这是 2.6.27 内核的最新变化,在 /sys/class/ 下的都改为符号链接,真实的 kobject 都存在于 /sys/devices/ 中;我们这里探索其中的 host0 这个 SCSI 控制器:
# readlink -f /sys/class/scsi_host/host0
/sys/devices/pci0000:00/0000:00:02.5/host0/scsi_host/host0
# ls -lU /sys/devices/pci0000:00/0000:00:02.5/host0/scsi_host/host0
总计 0
-rw-r--r-- 1 root root 4096 12-13 02:02 uevent
lrwxrwxrwx 1 root root 0 12-13 02:02 subsystem -> ../../../../../../class/scsi_host
lrwxrwxrwx 1 root root 0 12-13 02:02 device -> ../../../host0
-r--r--r-- 1 root root 4096 12-13 02:02 unique_id
-r--r--r-- 1 root root 4096 12-13 02:02 host_busy
-r--r--r-- 1 root root 4096 12-13 02:02 cmd_per_lun
-r--r--r-- 1 root root 4096 12-13 02:02 can_queue
-r--r--r-- 1 root root 4096 12-13 02:02 sg_tablesize
-r--r--r-- 1 root root 4096 12-13 02:02 unchecked_isa_dma
-r--r--r-- 1 root root 4096 12-13 02:02 proc_name
--w------- 1 root root 4096 12-13 02:02 scan
-rw-r--r-- 1 root root 4096 12-13 02:02 state
-rw-r--r-- 1 root root 4096 12-13 02:02 supported_mode
-rw-r--r-- 1 root root 4096 12-13 02:02 active_mode
-r--r--r-- 1 root root 4096 12-13 02:02 prot_capabilities
-r--r--r-- 1 root root 4096 12-13 02:02 prot_guard_type
drwxr-xr-x 2 root root 0 12-13 02:02 power
对这些属性文件解释如下:
有四个 SCSI 特有的可写参数: scan,state,supported_mode,active_mode;可以向其中写入不同的参数来控制此 SCSI 控制器的各种状态;
其它一些可读属性用于读取这个 SCSI 控制器的一些当前值;
其中的 scan 属性文件在调试一些 SCSI 硬件驱动时很有用,它是只写的,可以写入三个至四个以空格分开的整数,用于分别指定对应的 host, channel, id, lun 进行重新搜索。且这个 scan 属性支持以"-"作为通配符,如以下命令可以执行让整个 scsi_host 进行重新搜索,这个功能用于调试某些对热挺拔实现不完善的 SCSI 驱动程序很有用:
# echo '- - -' >/sys/devices/pci0000:00/0000:00:02.5/host0/scsi_host/host0/scan
内核模块中的 Linux sysfs系统属性文件
以一个 8139too 模块为例解释在这个 kboject 下每一个属性的用途;
# find /sys/module/8139too/ -ls
6408 0 -r--r--r-- 1 root root 4096 12月 13 02:17 \
/sys/module/8139too/version
6412 0 drwxr-xr-x 2 root root 0 12月 13 02:17 \
/sys/module/8139too/sections
6433 0 drwxr-xr-x 2 root root 0 12月 13 02:17 \
/sys/module/8139too/notes
6434 0 -r--r--r-- 1 root root 36 12月 13 02:17 \
/sys/module/8139too/notes/.note.gnu.build-id
6486 0 drwxr-xr-x 2 root root 0 12月 13 02:17 \
/sys/module/8139too/drivers
6487 0 lrwxrwxrwx 1 root root 0 12月 13 02:17 \
/sys/module/8139too/drivers/pci:8139too -> ../../../bus/pci/drivers/8139too
其中的属性文件都是只读的,用于提供信息。从 version, srcversion 上可以了解到这个模块所声明的版本号,源码版本号, refcnt 是模块引用计数, sections 属性组中有一些模块加载至内存的相应节信息, drivers/ 目录中是对所提供的驱动的链接;
因为模块是Linux sysfs系统内核驱动编程的最佳选择,而一个模块有可能提供多个Linux sysfs系统驱动程序,因而在未知一个设备在用哪一个驱动的情况下可以先从 /sys/module/ 查找相应模块的情况,再从 drivers/ 发现出真正的驱动程序。或者也可以完全反过来利用这些信息,先用 lspci/lshw 等工具找到 /sys/devices/ 下的设备节点,再从其设备的 driver 链接找到 /sys/bus/*/drivers/ 下的 device_driver, 再从 device_driver 下的 module 链接找到 /sys/module/*/,这样就可以得到已加载模块中空间是哪一个模块在给一个设备提供驱动程序。
更多 Linux sysfs系统属性文件
以上所举的例子仅仅是一些常见的 Linux sysfs系统属性用法,实际的系统中还常常有很多其它的从未见过的 Linux sysfs系统属性,因此只有举例是不够的,即使维护了一份 Linux sysfs系统属性用法参考大全也不够,未来的内核版本还会出现新的 Linux sysfs系统属性,因此还必须了解 Linux 内核代码以找到实现这些属性的代码位置,以学会在没有相应属性文档的情况从内核源代码来分析其 Linux sysfs系统属性功能。
【编辑推荐】