udev


理解和认识udev

原贴:http://www.linuxsky.org/doc/admin/200710/139.html

去论坛讨论 来源: 作者: 发布时间:2007-10-08

因 为本身从事存储行业,在工作中多次碰到用户有这样的要求:我的linux系统中原来有一块SCSI硬盘,系统分配的设备文件是/dev/sda。现在新增 加了一个外置的磁盘阵列,通过SCSI卡连接。但接上这个磁盘阵列后,/dev/sda变成了磁盘阵列的硬盘了,原来内置的SCSI硬盘变成了 /dev/sdb,我希望将设备文件固定下来。
    过去,我总是对用户说,这个比较麻烦,因为/dev/sda等文件都是linux内核自动分配的。很难固定下来,除非你更改加载SCSI卡驱动程序的顺 序,让内置硬盘连接的SCSI卡比外接磁盘阵列连接的SCSI卡的驱动模块先加载到内核,这样就能保证/dev/sda总是指向内置的硬盘。但这种解决方 法毕竟不太完美,而且对于其他的即插即用设备,如USB设备等都不适用。
    近来,通过安装和升级linux-2.6内核,发现这个问题已经可以通过2.6内核新的sysfs文件系统和udev程序得到解决。下面就是我在学习了udev配置后的一点心得。我喜欢用FAQ的形式来说明。

问:什么是udev?
答:udev是一种工具,它能够根据系统中的硬件设备的状态动态更新设备文件,包括设备文件的创建,删除等。设备文件通常放在/dev目录下。使用udev后,在/dev目录下就只包含系统中真正存在的设备。

问:udev支持什么内核?
答:udev只支持linux-2.6内核,因为udev严重依赖于sysfs文件系统提供的信息,而sysfs文件系统只在linux-2.6内核中才有。

问:udev是一个内核程序还是用户程序?
答:udev是一个用户程序(user-mode daemon)。

问:udev和devfs有什么差别?
答:udev能够实现所有devfs实现的功能。但udev运行在用户模式中,而devfs运行在内核中。据称:devfs具有一些不太容易解决的先天缺陷。

问:udev的配置文件放在哪里?
答:udev是一个用户模式程序。它的配置文件是/etc/udev/udev.conf。这个文件一般缺省有这样几项:

udev_root="/dev" ; udev产生的设备文件的根目录是/dev
udev_db="/dev/.udevdb" ; 通过udev产生的设备文件形成的数据库
udev_rules="/etc/udev/rules.d" ;用于指导udev工作的规则所在目录。
udev_log="err" ;当出现错误时,用syslog记录错误信息。

问:udev的工作过程是怎样的?
答:由于没有研究过udev的源程序,不敢贸然就说udev的工作过程。我只是通过一些网上的资料和udev的说明文档,大致猜测它的工作过程可能是这样的。

  1. 当内核检测到在系统中出现了新设备后,内核会在sysfs文件系统中为该新设备生成一项新的记录,一般sysfs文件系统会被 mount到 /sys目录中。新记录是以一个或多个文件或目录的方式来表示。每个文件都包含有特定的信息。(信息是如何表述的,还要另外研究?)
  2. udev在系统中是以守护进程的方式udevd在运行,它通过某种途径(到底什么途径,目前还没搞懂。)检测到新设备的出现,通过查找设备对应的sysfs中的记录得到设备的一些信息。
  3. udev 会根据/etc/udev/udev.conf文件中的udev_rules指定的目录,逐个检查该目录下的文件,这个目录下的文件都是针对某类或某个设 备应该施行什么措施的规则文件。udev读取文件是按照文件名的ASCII字母顺序来读取的,如果udev一旦找到了与新加入的设备匹配的规则,udev 就会根据规则定义的措施对新设备进行配置。同时不再读后续的规则文件。

问:udev的规则文件的语法是怎样的?
答:udev的规则文件以行为单位,以"#"开头的行代表注释行。其余的每一行代表一个规则。每个 规则分成一个或多个“匹配”和“赋值”部分。“匹配”部分用“匹配“专用的关键字来表示,相应的“赋值”部分用“赋值”专用的关键字来表示。“匹配”关键 字包括:ACTION,KERNEL,BUS, SYSFS等等,“赋值”关键字包括:NAME,SYMLINK,OWNER等等。具体详细的描述可以阅读udev的man文档。

    下面举个例子来说明一下,有这样一条规则:
SUBSYSTEM=="net", ACTION=="add", SYSFS{address}=="00:0d:87:f6:59:f3", IMPORT="/sbin/rename_netiface %k eth0"
    这个规则中的“匹配”部分有三项,分别是SUBSYSTEM,ACTION和SYSFS。而"赋值"部分有一项,是IMPORT。这个规则就是说,当系统 中出现的新硬件属于net子系统范畴,系统对该硬件采取的动作是加入这个硬件,且这个硬件在SYSFS文件系统中的“address”信息等于“00: 0d..."时,对这个硬件在udev层次施行的动作是调用外部程序/sbin/rename_netiface,传递的参数有两个,一个是“%k”,代 表内核对该新设备定义的名称。另一个是”eth0“。
    从上面这个例子中可以看出,udev的规则的写法比较灵活的,尤其在“匹配”部分中,可以通过诸如”*“, ”?“,[a-c],[1-9]等shell通配符来灵活匹配多个匹配项。具体的语法可以参考udev的man文档。

问:udev怎样做到不管设备连接的顺序而维持一个统一的设备名?
答: 实际上,udev是通过对内核产生的设备名增加别名的方式来达到上述目的的。前面说过,udev是用户模式程序,不会更改内核的行为。因此,内核依然会我 行我素地产生设备名如sda,sdb等。但是,udev可以根据设备的其他信息如总线(bus),生产商(vendor)等不同来区分不同的设备,并产生 设备文件。udev只要为这个设备文件取一个固定的文件名就可以解决这个问题。在后续对设备的操作中,只要引用新的设备名就可以了。但为了保证最大限度的 兼容,一般来说,新设备名总是作为一个对内核自动产生的设备名的符号链接(link)来使用的。

    例如:内核产生了sda设备名,而根据信息,这个设备对应于是我的内置硬盘,那我就可以制定udev规则,让udev除了产生/dev/sda设备文件 外,另外创建一个符号链接叫/dev/internalHD。这样,我在fstab文件中,就可以用/dev/internalHD来代替原来的 /dev/sda了。下次,由于某些原因,这个硬盘在内核中变成了sdb设备名了,那也不用着急,udev还会自动产生/dev/internalHD这 个链接,并指向正确的/dev/sdb设备。所有其他的文件像fstab等都不用修改。

问:怎样才能找到这些设备信息,并把他们放到udev的规则文件中来匹配呢?
答:这个问题比较难,网上资料不多,我只找到一篇文章来介绍如何写udev的规则。他的基本方法是通过udevinfo这个实用程序来找到那些可以作为规则文件里的匹配项的项目。有这样两种情况可以使用这个工具:
    第一种情况是,当你把设备插入系统后,系统为设备产生了设备名(如/dev/sda)。那样的话,你先用udevinfo -q path -n /dev/sda,命令会产生一个该设备名对应的在sysfs下的路径,如/block/sda。然后,你再用udevinfo -a -p /sys/block/sda,这个命令会显示一堆信息,信息分成很多块。这些信息实际来自于操作系统维护的sysfs链表,不同的块对应不同的路径。你 就可以用这些信息来作为udev规则文件中的匹配项。但需要注意的是,同一个规则只能使用同一块中显示的信息,不能跨块书写规则。
    第二种情况是,不知道系统产生的设备名,那就只有到/sys目录下去逐个目录查找了,反复用udevinfo -a -p /sys/path...这个命令看信息,如果对应的信息是这个设备的,那就恭喜你。否则就再换个目录。当然,在这种情况下,成功的可能性比较小。



udev策略  


更多UDEV规则可以看这里:

http://www.reactivated.net/writing_udev_rules.html

http://docs.oracle.com/cd/E52668_01/E54669/html/ol7-s2-devices.html

http://free-electrons.com/doc/udev.pdf



解决设备名冲突的问题,像fat32那种类型是没有uuid的,而集群(gfs:集群集文件系统)也不支持uuid(在集群中必须掌握的),所以这时就需要用到udev策略了。

    设备的名字可以自己定义。

    当插入这个设备的时候,内核会自己识别到,然后导出这个设备的状态(sys目录中)。/sys/proc是内存中的设备。

    例如在计算机中插入U盘后,自己也定义了这个设备名,但内核还会自己给它定义一个名字为sdb,只是插入看见的设备的那个依然还会是自己定义的名字(udev策略)。

如果直接改/sys下的文件的话,重启后是不会生效的。

udev策略规则的配置文件在/etc/udev/rules.d/目录下

udev策略 - zhuzhu - 五事九思 (大连Linux主机维护) 

数字越大代表越后被执行,而最后执行的策略会覆盖之前的策略。换句话来说就是数字越大,优先级越高。

而取值范围是01-99,文件名字的格式要安照以上的方式来创建这个规则的文件。

 

 

规则:

==:用于比较

=:反向选择

=:用户赋值

+=:额外添加值

例如:

BUS=="usb",SYSFS{serial}=="71507E8E",SYMLINK+="mydisk"

如果总线是“usb”的,如果序列号"71507E8E",则设备名叫"mydisk"

ACTION==add  如果动作为添加

KERNEL==sd[a-z]1  如果内核识别的是这个,那么名字为(自己定义)

BUS==iscsi 如果总线是iscsi

DRIVER!=ide-cdrom   如果设备不是ide-cdrom

SYSFS{serial}=="71507E8E"如果设备号是这个

PROGRAM==script RESULT==some return string如果执行这个脚本,输出的是some return string会怎么样。

GROUP=groupname     这个设备的所属组

OWNER=username      这个设备的所属用户

RUN+=命令的绝对路径  一但这个设备进入以后会执行什么命令或执行的脚本。

MODE=”0600”  赋予权限

 

udevadm monitor :检测新设备插入的状态 只要有新的设备插入,就会有信息输出到屏幕上。

udevadm info --attribute-walk --name=sdb

udevadm info -a -p /sys/block/sdb/

udevadm info -a -p /block/sdb/

以上命令都可以查看到设备的详细信息,在这里面便可以取值,但必须你取的这个值要保证它的唯一性,将来你取的这个值不能与别人冲突。其中有一些值就可以在这里面直接拿出来用,然后粘贴到你/etc/udev/rules.d/目录下的规则文件里即可。

/sbin/scsi_id --whitelisted --replace-whitespace --device /dev/sda 

而这个命令是专门来查询scsi设备的id号的。并且去除下划线。

udev策略 - zhuzhu - 五事九思 (大连Linux主机维护) 

这个结果不是内核识别出来的,是这个命令识别出来的。而

udevadm info -a -p /sys/block/sdb/  这个的结果才是内核识别出来的结果。

集群中设置的udev策略:

KERNEL=="sd*",SUBSYSTEM=="block",PROGRAM=="/sbin/scsi_id --whitelisted --replace-whitespace --device $tempnode",RESULT=="1IET_00010001",SYMLINK+="mydisk%n"

/etc/init.d/iscsi restart    ——修改完以后重启服务,让它重新把策略激活一下。

或者使用如下命令start_udev重启udev

# start_udev
Starting udev: 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值