Linux的sys文件系统揭秘

之前一篇proc文件系统揭秘介绍了Linux的一个特殊的文件系统proc。接下来们介绍另一个重要的文件系统sys

与procfs类似,sysfs也是一个存在于内存中的“伪”文件系统。sys文件系统提供了另一个从用户空间通往内核空间的入口,Linux系统启动时把它挂载到/sys目录,通过访问这个目录下面的文件,可以获得各种的系统内核信息,例如设备、内核模块、文件系统等等。

作为与内核交互的接口,相对于proc,sys出现的更晚,在设计上也更为清晰。proc中的文件并没有一个统一的格式;而sys中的文件都遵循一个one-value-per-file的原则——每个文件代表一个属性/参数,文件内容也只有一个值。因此可以直接读取或写入,无需像在proc中对不同格式的文件做解析。

查看/sys目录,可以看到里面有一系列子目录:

# ls /sys
block  bus  class  dev  devices  firmware  fs  hypervisor  kernel  module  power
  • /sys/block

这个子目录在2.6.26 内核中被 /sys/class/block取代, 旧的接口 /sys/block为了向后兼容仍然保留,二者的内容完全一样,包括所有块设备(通常是硬盘)的符号链接(symbolic link)。链接指向的是/sys/devices中对应的目录。 在下面的例子中,系统一共有12块硬盘

# ls -lt /sys/block  
lrwxrwxrwx 1 root root 0 Oct  8 13:28 sdl -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/host10/port-10:0/expander-10:0/port-10:0:11/end_device-10:0:11/target10:0:11/10:0:11:0/block/sdl
lrwxrwxrwx 1 root root 0 Oct  8 13:28 sdk -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/host10/port-10:0/expander-10:0/port-10:0:10/end_device-10:0:10/target10:0:10/10:0:10:0/block/sdk
lrwxrwxrwx 1 root root 0 Oct  8 13:28 sdj -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/host10/port-10:0/expander-10:0/port-10:0:9/end_device-10:0:9/target10:0:9/10:0:9:0/block/sdj
lrwxrwxrwx 1 root root 0 Oct  8 13:28 sdi -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/host10/port-10:0/expander-10:0/port-10:0:8/end_device-10:0:8/target10:0:8/10:0:8:0/block/sdi
lrwxrwxrwx 1 root root 0 Oct  8 13:28 sdh -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/host10/port-10:0/expander-10:0/port-10:0:7/end_device-10:0:7/target10:0:7/10:0:7:0/block/sdh
lrwxrwxrwx 1 root root 0 Oct  8 13:28 sdg -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/host10/port-10:0/expander-10:0/port-10:0:6/end_device-10:0:6/target10:0:6/10:0:6:0/block/sdg
lrwxrwxrwx 1 root root 0 Oct  8 13:28 sdf -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/host10/port-10:0/expander-10:0/port-10:0:5/end_device-10:0:5/target10:0:5/10:0:5:0/block/sdf
lrwxrwxrwx 1 root root 0 Oct  8 13:28 sde -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/host10/port-10:0/expander-10:0/port-10:0:4/end_device-10:0:4/target10:0:4/10:0:4:0/block/sde
lrwxrwxrwx 1 root root 0 Oct  8 13:28 sdd -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/host10/port-10:0/expander-10:0/port-10:0:3/end_device-10:0:3/target10:0:3/10:0:3:0/block/sdd
lrwxrwxrwx 1 root root 0 Oct  8 13:28 sdc -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/host10/port-10:0/expander-10:0/port-10:0:2/end_device-10:0:2/target10:0:2/10:0:2:0/block/sdc
lrwxrwxrwx 1 root root 0 Oct  8 13:28 sdb -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/host10/port-10:0/expander-10:0/port-10:0:1/end_device-10:0:1/target10:0:1/10:0:1:0/block/sdb
lrwxrwxrwx 1 root root 0 Oct  8 13:28 sda -> ../devices/pci0000:00/0000:00:01.0/0000:01:00.0/host10/port-10:0/expander-10:0/port-10:0:0/end_device-10:0:0/target10:0:0/10:0:0:0/block/sda
  • /sys/bus

现代计算机都是总线结构,系统中的所有设备都是连接到某种类型的总线之上(例如:pci总线、usb总线)。每种类型的总线在/sys/bus下有一个对应的子目录:

# ls /sys/bus
acpi         clocksource  cpu   event_source  i2c  ishtp         mc0  mdio_bus  node   pci          platform  scsi   spi          usb         workqueue
clockevents  container    edac  hid           iio  machinecheck  mc1  memory    nvmem  pci_express  pnp       serio  thunderbolt  usb-serial  xen

连接到这类总线上的设备(指向/sys/devices设备目录的符号链接)会被放到相应的子目录下,例如:

# ls -l /sys/bus/cpu/devices
lrwxrwxrwx 1 root root 0 1月  19 20:16 cpu0 -> ../../../devices/system/cpu/cpu0
lrwxrwxrwx 1 root root 0 1月  19 20:16 cpu1 -> ../../../devices/system/cpu/cpu1
lrwxrwxrwx 1 root root 0 1月  19 20:16 cpu10 -> ../../../devices/system/cpu/cpu10
lrwxrwxrwx 1 root root 0 1月  19 20:16 cpu11 -> ../../../devices/system/cpu/cpu11
lrwxrwxrwx 1 root root 0 1月  19 20:16 cpu12 -> ../../../devices/system/cpu/cpu12
...
  • /sys/class

设备按照类型(比如块设备(block)、输入设备(input)、网络设备(net))组织在这个目录中,每个设备放到它的类型对应的子目录里。比如系统中的所有网络设备都可以在/sys/class/net目录下找到:

# ls -lt /sys/class/net
总用量 0
lrwxrwxrwx 1 root root    0 1月  19 21:09 bond0 -> ../../devices/virtual/net/bond0
lrwxrwxrwx 1 root root    0 1月  19 21:09 bond1 -> ../../devices/virtual/net/bond1
lrwxrwxrwx 1 root root    0 1月  19 21:09 br-8fbf2714cffe -> ../../devices/virtual/net/br-8fbf2714cffe
lrwxrwxrwx 1 root root    0 1月  19 21:09 cbr0 -> ../../devices/virtual/net/cbr0
lrwxrwxrwx 1 root root    0 1月  19 21:09 docker0 -> ../../devices/virtual/net/docker0
lrwxrwxrwx 1 root root    0 1月  19 21:09 eth0 -> ../../devices/pci0000:00/0000:00:02.2/0000:04:00.0/net/eth0
lrwxrwxrwx 1 root root    0 1月  19 21:09 eth1 -> ../../devices/pci0000:00/0000:00:02.2/0000:04:00.1/net/eth1
lrwxrwxrwx 1 root root    0 1月  19 21:09 lo -> ../../devices/virtual/net/lo
lrwxrwxrwx 1 root root    0 1月  19 21:09 tunl0 -> ../../devices/virtual/net/tunl0
lrwxrwxrwx 1 root root    0 1月  19 21:09 veth11e15386 -> ../../devices/virtual/net/veth11e15386
lrwxrwxrwx 1 root root    0 1月  19 21:09 veth148b56dc -> ../../devices/virtual/net/veth148b56dc
lrwxrwxrwx 1 root root    0 1月  19 21:09 veth28dcb2de -> ../../devices/virtual/net/veth28dcb2de
lrwxrwxrwx 1 root root    0 1月  19 21:09 veth38482784 -> ../../devices/virtual/net/veth38482784
lrwxrwxrwx 1 root root    0 1月  19 21:09 veth3b2564d6 -> ../../devices/virtual/net/veth3b2564d6
lrwxrwxrwx 1 root root    0 1月  19 21:09 veth47ee5ddd -> ../../devices/virtual/net/veth47ee5ddd
lrwxrwxrwx 1 root root    0 1月  19 21:09 veth596a1468 -> ../../devices/virtual/net/veth596a1468
lrwxrwxrwx 1 root root    0 1月  19 21:09 veth5972cf8d -> ../../devices/virtual/net/veth5972cf8d
lrwxrwxrwx 1 root root    0 1月  19 21:09 veth838421ee -> ../../devices/virtual/net/veth838421ee
lrwxrwxrwx 1 root root    0 1月  19 21:09 vethc13682b -> ../../devices/virtual/net/vethc13682b
lrwxrwxrwx 1 root root    0 1月  19 21:09 vethfee9950 -> ../../devices/virtual/net/vethfee9950
-rw-r--r-- 1 root root 4096 12月  7 13:36 bonding_masters

上面既有物理网络接口eth0和eth1,又有各种虚拟的网路设备(bridge、veth pair)。每个设备都是一个符号链接,指向/sys/devices中的设备对应的目录。

  • /sys/dev

包含两个子目录blockchar,分别代表系统中的块设备(例如:磁盘)和字节设备(例如:usb、tty)。在这两个子目录中,是指向/sys/devices中的设备目录的符号链接,链接名的格式为major-ID:minor-ID,对应于代表设备的major ID和minor ID。例如:

# ls -l /sys/dev/block/
总用量 0
lrwxrwxrwx 1 root root 0 1月  20 08:27 8:0 -> ../../devices/pci0000:00/0000:00:03.0/0000:08:00.0/host0/target0:1:0/0:1:0:0/block/sda
lrwxrwxrwx 1 root root 0 1月  20 08:27 8:1 -> ../../devices/pci0000:00/0000:00:03.0/0000:08:00.0/host0/target0:1:0/0:1:0:0/block/sda/sda1
lrwxrwxrwx 1 root root 0 1月  20 08:27 8:16 -> ../../devices/pci0000:00/0000:00:03.0/0000:08:00.0/host0/target0:1:0/0:1:0:1/block/sdb
lrwxrwxrwx 1 root root 0 1月  20 08:27 8:2 -> ../../devices/pci0000:00/0000:00:03.0/0000:08:00.0/host0/target0:1:0/0:1:0:0/block/sda/sda2
lrwxrwxrwx 1 root root 0 1月  20 08:27 8:3 -> ../../devices/pci0000:00/0000:00:03.0/0000:08:00.0/host0/target0:1:0/0:1:0:0/block/sda/sda3
lrwxrwxrwx 1 root root 0 1月  20 08:27 8:4 -> ../../devices/pci0000:00/0000:00:03.0/0000:08:00.0/host0/target0:1:0/0:1:0:0/block/sda/sda4

通过stat指令可以查询块/字节设备的ID,例如:

# stat -c "%t %T" /dev/sda1
8 1
# readlink /sys/dev/block/8\:1../../devices/pci0000:00/0000:00:03.0/0000:08:00.0/host0/target0:1:0/0:1:0:0/block/sda/sda1
  • /sys/devices

系统中的所有设备信息在内核中以一个树形结构组织和存储,/sys/devices就是这个树形结构的文件系统表示。系统中的所有设备信息都会存储在/sys/devices中,且每个设备只会存储一份.。/sys/class和/sys/bus中的设备都是指向/sys/devices中的子目录的符号链接,例如:

# ls -l /sys/bus/cpu/devices/cpu0
lrwxrwxrwx 1 root root 0 1月  19 20:16 /sys/bus/cpu/devices/cpu0 -> ../../../devices/system/cpu/cpu0
# ls -l /sys/class/block/sda
lrwxrwxrwx 1 root root 0 1月  19 22:02 /sys/class/block/sda -> ../../devices/pci0000:00/0000:00:03.0/0000:08:00.0/host0/target0:1:0/0:1:0:0/block/sda

/sys/devices中的设备之间也会相互引用,一个典型的例子就是cpu、node和memory。下图是一个numa的架构图,每个numa node包括一些cpu和内存,每个cpu和内存属于一个node。

Image result for numa nodes

反映在/sys/devices中,就是

  • /sys/fs 

这个目录包含一些子目录对应不同的文件系统类型,例如:

# ls /sys/fs/
cgroup  ext4  pstore  resctrl

其中最有用的一个当属cgroup,这个目录里每个子系统(subsystem,例如memory、cpuset)都有一个对应的子目录

# ls /sys/fs/cgroup
blkio  cpu  cpuacct  cpu,cpuacct  cpuset  devices  freezer  hugetlb  memory  net_cls  net_cls,net_prio  net_prio  perf_event  pids  systemd

docker/k8s就是通过在这个目录中创建子目录,并设置相应的控制文件,例如/sys/fs/cgroup/cpu,cpuacct/cpu.shares来限制容器的资源的使用;此外容器监控工具cadvisor通过读取cgroup子目录中的文件(例如:cgroup.procs)来获得容器的运行数据。

  • /sys/kernel 

 这个目录中的文件和子目录提供有关内核的信息。目前没有用过。

  • /sys/module

在这个目录中,没有个加载进内核的模块都有一个子目录,子目录名就是模块名。

  • /sys/power 

系统中电源选项。没有用过

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值