udev——设备文件管理的用户空间实现( 二 )


其实,早在2.2版本内核里,动态分配次设备号已经在USB设备驱动子系统和串口设备驱动子系统实现,并取得成功 。但是还是那个问题,用户还是没法知道哪个设备分配了哪个设备号,只能通过查对系统日志来确定设备号 。有了sysfs,这个问题被解决 。
2.3 /dev is too big
很多发行版系统中, /dev下的设备文件并不是完全与实际设备配对的,有很多是空的 。在系统启动的时候,/dev被填入可能使用的节点,并不根据是否存在实际设备 。例如,在Red Hat 9,/dev有18,000个设备文件 。
为系统创建一大堆暂时甚至一直无用的设备文件,肯定产生性能和管理问题 。因此很多操作系统把设备文件管理的任务移入内核,因为内核总是确切知道有多少实际设备的 。设备文件管理的内核方案就是基于ram的文件系统——devfs 。Linux也使用了这一方案,并且在数个流行的发行版上得到实现 。
2.4 devfs
很多UNIX类操作系统都实现了devfs,用以解决前面提到的设备文件管理上的一些问题 。Linux也实现了devfs,解决了不少人的燃眉之急 。但是,基于Linux的devfs实现只解决部分需求,如devfs只是解决了“/dev太大了”的问题,仍然存在一些没有解决的问题 。另外,devfs 还带入新问题 。引起新问题包括:
第一,devfs 的命名方案与授权命名不兼容 。由于这种不兼容性,在devfs系统与静态/dev系统间切换需额外的配置,devfs的作者们必须实现某种与静态/dev命名的兼容模式 。
第二,命名策略()被移进内核 。
没解决的问题包括,第一,设备号依然能静态分配;第二,设备与设备文件的映射依然不固定 。
3 udev’s goals
在出现前面提到的所有问题的同时,udev项目已启动 。其目标如下:
基于两个事实,第一个目标——“在用户空间中运行”——已经很容易做到 。首先,/sbin/ 实现了当系统添加或删除设备向用户空间发送事件消息;其次,结合在sysfs中能展示所有设备的元信息 。其余的目标可把udev的项目拆分成三个独立的子系统:
3.1
鉴于不同的设备命名方案的需要,udev的设备命名部分已被独立出来,成为独立的子系统—— 。命名策略移出udev的二进制后,不同需求的用户可根据需要自定设备命名方案 。与udev之间实现了一个标准的接口,udev可以通过标准接口透明地调用命名一个特定的设备 。
udev的初始版本,逻辑仍然是有几个源文件链接进入udev的二进制 。目前只有一个命名方案实施,就是由指定的 。这个方案很简单,设备名命名基本上与sysfs使用相同的名称,这个方案适用于目前大多数Linux用户 。
udev项目目标之一是为用户提供一种基于一套策略来命名设备的方法 。目前版本为用户提供了一个五个步骤序列来确定一个给定的设备的名称 。这些步骤按指定顺序征询,如果设备的名称可以在任何一步确定,就使用步确定的名称 。现有的步骤如下:
标签或序号总线设备号总线拓扑名称简单替换内核指定的名称
第一步,添加到系统的设备会被检查它是否有一个某种类型的设备的唯一的标识符 。例如,USB设备检查USB序列号,SCSI设备的检查UUID,块设备检查文件系统的标签 。如果匹配用户提供的标识符(在配置文件中),匹配结果被接受 。
第二步,检查设备的总线号 。对于很多总线,这个数字一般不随时间变化,并保证所有的总线号要在系统中的任何一个点在时间上是唯一的 。一个很好的例子是PCI总线的号很少改变 。再次,如果总线号匹配由用户提供的,匹配结果名称用于该设备 。
第三步,检查设备在总线上的位置 。例如,一个USB设备位于根集线器第一端口连接的次集线口的第三个端口上 。这种拓扑结构不会改变,即便机器重新启动总线号改变,除非用户物理上移动了设备 。如果总线上的拓扑位置和用户提供的位置相匹配,请求的名称被指定给设备 。