Linux下udev详细介绍

每次在搭建Oracle RAC环境中,遇到问题最多的就是关于ASM磁盘的的问题,通过查看网上许多搭建RAC的文档,发现Oracle 10g RAC大家普遍的修改/etc/udev/rules.d/60-raw.rules,而一些搭建Oracle11R2的RAC,大家都在配置的是/etc/udev/rules.d/99-oracle-asmdevices.rules这个文件,面对这样一种情况,我不是很明白,这两个文件到底有什么区别,这个问题困扰了我很久,直到今天遇到这样一个问题:使用udev管理asmdisk执行/sbin/scsi_id不显示UUID。通过查询相关的资料才算是对这个问题有了更深层次的理解。

   
      Linux平台通过udev的方式将块设备转换为字符设备,并固定设备的权限和所有者,这种需求只在安装11gR1之前的RAC数据库的时候需要这样做,安装11gR2RACASM可以直接使用块设备。udev除了用于将块设备转换为字符设备外,还可用于固定设备文件名称。


之后,通过实验来验证这个结论,详细的步骤请参考我的另一篇博文:

使用udev管理asmdisk执行/sbin/scsi_id不显示UUID



目录


一、udev简介

二、udev的优势

2.1 动态管理

2.2 自定义命名规则

2.3 设定设备的权限和所有者/ 组

2.4 udev 添加/删除设备文件的过程。

三、配置和使用udev(CentOS6.4)

3.1 检查udev在CentOS6.5中的版本和运行情况

3.2 udev的配置文件

3.3 通过udev设定设备文件的权限

3.4 udev的规则和规则文件

四、制定udev 规则和查询设备信息的实例

4.1 查找设备的信息(属性)来制定udev规则

4.2 udev的简单规则

4.3 其他常用的udev命令

一、udev简介

udev 是Linux2.6 内核里的一个功能,它替代了原来的devfs,成为当前Linux 默认的设备管理工具。udev以守护进程的形式运行,通过侦听内核发出来的uevent 来管理/dev目录下的设备文件。不像之前的设备管理工具,udev在用户空间(user space) 运行,而不在内核空间(kernel space) 运行。


二、udev的优势

2.1 动态管理

当设备添加/ 删除时,udev的守护进程侦听来自内核的uevent,以此添加或者删除/dev下的设备文件,所以udev 只为已经连接的设备产生设备文件,而不会在/dev下产生大量虚无的设备文件。

 

2.2 自定义命名规则

通过Linux 默认的规则文件,udev在/dev/ 里为所有的设备定义了内核设备名称,比如/dev/sda、/dev/hda、/dev/fd等等。由于udev 是在用户空间(user space) 运行,Linux用户可以通过自定义的规则文件,灵活地产生标识性强的设备文件名,比如/dev/boot_disk、/dev/root_disk、/dev/color_printer等等。


2.3 设定设备的权限和所有者/ 组

udev可以按一定的条件来设置设备文件的权限和设备文件所有者/ 组。在不同的udev 版本中,实现的方法不同。


2.4 下面的流程图显示udev 添加/删除设备文件的过程。



PS:

1.设备文件:由于本文以较通俗的方式讲解udev,所以设备文件是泛指在/dev/下,可被应用程序用来和设备驱动交互的文件。而不会特别地区分设备文件、设备节点或者设备特殊文件。


2.sysfssysfs是Linux 2.6 内核里的一个虚拟文件系统(/sys)。它把设备和驱动的信息从内核的设备模块导出到用户空间(userspace)。从该文件系统中,Linux用户可以获取很多设备的属性。


3.devpath本文的devpath是指一个设备在sysfs文件系统(/sys)下的相对路径,该路径包含了该设备的属性文件。udev里的多数命令都是针对devpath操作的。例如:sda的devpath是/block/sda,sda2的devpath是/block/sda/sda2。


4.内核设备名称:设备在sysfs里的名称,是udev 默认使用的设备文件名。

三、配置和使用udev(CentOS6.4)

3.1 检查udev在CentOS6.5中的版本和运行情况

[root@test boot]# rpm -qa | grep -i udev

udev-147-2.46.el6.x86_64

libgudev1-147-2.46.el6.x86_64

python-gudev-147.1-4.el6_0.1.x86_64

libudev-147-2.46.el6.x86_64

system-config-printer-udev-1.1.16-23.el6.x86_64


[root@test boot]# ps -ef | grep -i udev

root     27957     1  0 10:23 ?        00:00:00 /sbin/udevd -d

root     28584 27957  0 10:34 ?        00:00:00 /sbin/udevd -d

root     29017  1955  0 13:28 pts/0    00:00:00 grep -i udev 


3.2 udev的配置文件

[root@test ~]# cat /etc/udev/udev.conf

# The initial syslog(3) priority: "err", "info", "debug" or its

# numerical equivalent. For runtime debugging, the daemons internal

# state can be changed with: "udevadm control --log-priority=".

udev_log="err"


udev_logsyslog记录日志的级别,默认值是err。如果改为info或者debug的话,会有冗长的udev日志被记录下来。

实际上在CentOS 里,除了配置文件里列出的参数udev_log外,Linux用户还可以修改参数udev_root和udev_rules,只不过这2 个参数是不建议修改的,所以没显示在udev.conf 里。syslog默认会记录udev 的日志,Linux用户只能修改日志的级别(err、info、degub等);设备的权限不能在udev.conf 里设定,而是要在规则文件(*.rules) 里设定。


3.3 通过udev设定设备文件的权限

在CentOS 6.4 的udev,已经没有权限文件,所有的权限都是通过规则文件(*.rules)来设置,在下面的规则文件配置过程会介绍到。


3.4 udev的规则和规则文件

规则文件是udev里最重要的部分,默认是存放在/etc/udev/rules.d/下。所有的规则文件必须以“.rules”为后缀名。CentOS有默认的规则文件,这些默认规则文件不仅为设备产生内核设备名称,还会产生标识性强的符号链接。例如:


[root@test ~]# ls /dev/disk/by-uuid/

18f9b7a4-f6a9-4a87-a63b-2660b12c87db  8ac6170e-8e4d-4385-a166-92c2aaeb75ca

5e2405ac-1cb5-4a90-a6c9-67c2c245667b  c42b1176-beaf-4e52-98e3-1b6d386908c0


但这些链接名较长,不易调用,所以通常需要自定义规则文件,以此产生易用且标识性强的设备文件或符号链接。

udev按照规则文件名的字母顺序来查询全部规则文件,然后为匹配规则的设备管理其设备文件或文件链接。虽然udev不会因为一个设备匹配了一条规则而停止解析后面的规则文件,但是解析的顺序仍然很重要。通常情况下,建议让自己想要的规则文件最先被解析。比如,创建一个名为 /etc/udev/rules.d/10-myrule.rules的文件,并把你的规则写入该文件,这样udev就会在解析系统默认的规则文件之前解析到你的文件。

在规则文件里,除了以“#”开头的行(注释),所有的非空行都被视为一条规则,但是一条规则不能扩展到多行。规则都是由多个键值对(key-valuepairs)组成,并由逗号隔开,键值对可以分为条件匹配键值对(以下简称“匹配键”)和赋值键值对(以下简称“赋值键”),一条规则可以有多条匹配键和多条赋值键。匹配键是匹配一个设备属性的所有条件,当一个设备的属性匹配了该规则里所有的匹配键,就认为这条规则生效,然后按照赋值键的内容,执行该规则的赋值。下面是一个简单的规则:

KERNEL=="sda",NAME="my_root_disk", MODE="0660"

KERNEL是匹配键,NAME和MODE是赋值键。这条规则的意思是:如果有一个设备的内核设备名称为sda,则该条件生效,执行后面的赋值:在/dev下产生一个名为my_root_disk的设备文件,并把设备文件的权限设为0660。

仅当操作符是“==”或者“!=”时,其为匹配键;若为其他操作符时,都是赋值键。


udev规则的所有操作符:

“==”:比较键、值,若等于,则该条件满足;

“!=”:比较键、值,若不等于,则该条件满足;

“=”:对一个键赋值;

“+=”:为一个表示多个条目的键赋值。

“:=”:对一个键赋值,并拒绝之后所有对该键的改动。目的是防止后面的规则文件对该键赋值。


udev规则的匹配键:

ACTION:事件 (uevent)的行为,例如:add(添加设备)、remove(删除设备)。

KERNEL:内核设备名称,例如:sda, cdrom。

DEVPATH:设备的devpath 路径。

SUBSYSTEM:设备的子系统名称,例如:sda 的子系统为block。

BUS:设备在 devpath 里的总线名称,例如:usb。

DRIVER:设备在 devpath 里的设备驱动名称,例如:ide-cdrom。

ID:设备在 devpath 里的识别号。

SYSFS{filename}:设备的 devpath 路径下,设备的属性文件“filename”里的内容。

例如:SYSFS{model}==“ST936701SS”表示:如果设备的型号为ST936701SS,则该设备匹配该匹配键。

在一条规则中,可以设定最多五条SYSFS 的匹配键。

ENV{key}:环境变量。在一条规则中,可以设定最多五条环境变量的匹配键。

PROGRAM:调用外部命令。

RESULT:外部命令 PROGRAM 的返回结果。例如:

PROGRAM=="/lib/udev/scsi_id -g -s $devpath", RESULT=="35000c50000a7ef67"

调用外部命令/lib/udev/scsi_id查询设备的SCSI ID,如果返回结果为35000c50000a7ef67,则该设备匹配该匹配键。


udev 的重要赋值键:

NAME:在/dev下产生的设备文件名。只有第一次对某个设备的NAME 的赋值行为生效,之后匹配的规则再对该设备的NAME 赋值行为将被忽略。如果没有任何规则对设备的NAME 赋值,udev将使用内核设备名称来产生设备文件。

SYMLINK:为/dev/下的设备文件产生符号链接。由于udev 只能为某个设备产生一个设备文件,所以为了不覆盖系统默认的udev 规则所产生的文件,推荐使用符号链接。

OWNER, GROUP, MODE:为设备设定权限。

ENV{key}:导入一个环境变量。


udev 的值和可调用的替换操作符:

在键值对中的键和操作符都介绍完了,最后是值(value)。Linux用户可以随意地定制udev 规则文件的值。例如:my_root_disk,my_printer。同时也可以引用下面的替换操作符:

$kernel, %k:设备的内核设备名称,例如:sda、cdrom。

$number, %n:设备的内核号码,例如:sda3的内核号码是3。

$devpath, %p:设备的devpath路径。

$id, %b:设备在devpath里的ID 号。

$sysfs{file}, %s{file}:设备的sysfs里file 的内容。其实就是设备的属性值。例如:$sysfs{size}表示该设备( 磁盘) 的大小。

$env{key}, %E{key}:一个环境变量的值。

$major, %M:设备的major 号。

$minor %m:设备的minor 号。

$result, %c:PROGRAM返回的结果。

$parent, %P:父设备的设备文件名。

$root, %r:udev_root的值,默认是/dev/。

$tempnode, %N:临时设备名。

%%:符号% 本身。

$$:符号$ 本身。

KERNEL=="sd*", PROGRAM="/lib/udev/scsi_id -g -s %p", \ RESULT=="35000c50000a7ef67", SYMLINK="%k_%c"

该规则的执行:如果有一个内核设备名称以sd 开头,且SCSI ID 为35000c50000a7ef67,则为设备文件产生一个符号链接“sda_35000c50000a7ef67”.


四、制定udev 规则和查询设备信息的实例

4.1 查找设备的信息(属性)来制定udev规则

当我们为指定的设备设定规则时,首先需要知道该设备的属性,比如设备的序列号、磁盘大小、厂商ID、设备路径等等。通常我们可以通过以下的方法获得:

查询sysfs文件系统:

前面介绍过,sysfs里包含了很多设备和驱动的信息。

例如:设备sda 的SYSFS{size} 可以通过cat/sys/block/sda/size得到;SYSFS{model}信息可以通过cat/sys/block/sda/device/model得到。

udevadm info命令:(Centos5.3为udevinfo命令)

udevadm info 可以查询udev 数据库里的设备信息。例如:用udevadm info 查询设备sda 的model 和size 信息:


[root@test ~]# udevadm info -a -p /sys/block/sda | egrep "model|size"

    ATTR{size}=="62914560"

    ATTRS{model}=="VBOX HARDDISK   "


[root@test ~]# udevadm info -a -p /sys/block/sda

Udevadm info starts with the device specified by the devpath and then

walks up the chain of parent devices. It prints for every device

found, all possible attributes in the udev rules key format.

A rule to match, can be composed by the attributes of the device

and the attributes from one single parent device.


  looking at device '/devices/pci0000:00/0000:00:0d.0/host2/target2:0:0/2:0:0:0/block/sda':

    KERNEL=="sda"

    SUBSYSTEM=="block"

    DRIVER==""

    ATTR{range}=="16"

    ATTR{ext_range}=="256"

    ATTR{removable}=="0"

    ATTR{ro}=="0"

    ATTR{size}=="62914560"

    ATTR{alignment_offset}=="0"

    ATTR{discard_alignment}=="0"

    ATTR{capability}=="52"

    ATTR{stat}=="   30322     6547  1191594   333118     7382    94590   811468   137604        0   154932   470661"

    ATTR{inflight}=="       0        0"


  looking at parent device '/devices/pci0000:00/0000:00:0d.0/host2/target2:0:0/2:0:0:0':

    KERNELS=="2:0:0:0"

    SUBSYSTEMS=="scsi"

    DRIVERS=="sd"

    ATTRS{device_blocked}=="0"

    ATTRS{type}=="0"

    ATTRS{scsi_level}=="6"

    ATTRS{vendor}=="ATA     "

    ATTRS{model}=="VBOX HARDDISK   "

    ATTRS{rev}=="1.0 "

    ATTRS{state}=="running"

    ATTRS{timeout}=="30"

    ATTRS{iocounterbits}=="32"

    ATTRS{iorequest_cnt}=="0x95a8"

    ATTRS{iodone_cnt}=="0x957d"

    ATTRS{ioerr_cnt}=="0x5"

    ATTRS{modalias}=="scsi:t-0x00"

    ATTRS{evt_media_change}=="0"

    ATTRS{dh_state}=="detached"

    ATTRS{queue_depth}=="31"

    ATTRS{queue_ramp_up_period}=="120000"

    ATTRS{queue_type}=="simple"


  looking at parent device '/devices/pci0000:00/0000:00:0d.0/host2/target2:0:0':

    KERNELS=="target2:0:0"

    SUBSYSTEMS=="scsi"

    DRIVERS==""


  looking at parent device '/devices/pci0000:00/0000:00:0d.0/host2':

    KERNELS=="host2"

    SUBSYSTEMS=="scsi"

    DRIVERS==""


  looking at parent device '/devices/pci0000:00/0000:00:0d.0':

    KERNELS=="0000:00:0d.0"

    SUBSYSTEMS=="pci"

    DRIVERS=="ahci"

    ATTRS{vendor}=="0x8086"

    ATTRS{device}=="0x2829"

    ATTRS{subsystem_vendor}=="0x0000"

    ATTRS{subsystem_device}=="0x0000"

    ATTRS{class}=="0x010601"

    ATTRS{irq}=="21"

    ATTRS{local_cpus}=="1"

    ATTRS{local_cpulist}=="0"

    ATTRS{modalias}=="pci:v00008086d00002829sv00000000sd00000000bc01sc06i01"

    ATTRS{numa_node}=="-1"

    ATTRS{enable}=="1"

    ATTRS{broken_parity_status}=="0"

    ATTRS{msi_bus}==""


  looking at parent device '/devices/pci0000:00':

    KERNELS=="pci0000:00"

    SUBSYSTEMS==""

DRIVERS=="" 


4.2 udev的简单规则

产生网卡设备文件的规则:

SUBSYSTEM=="net", SYSFS{address}=="AA:BB:CC:DD:EE:FF", NAME="public_NIC"

该规则表示:如果存在设备的子系统为net,并且地址(MAC address) 为“AA:BB:CC:DD:EE:FF”,为该设备产生一个名为public_NIC 的设备文件。

为指定大小的磁盘产生符号链接的规则


SUBSYSTEM=="block", SYSFS{size}=="71096640", SYMLINK ="my_disk"

该规则表示:如果存在设备的子系统为block,并且大小为71096640(block),则为该设备的设备文件名产生一个名为my_disk 的符号链接。

通过外部命令为指定序列号的磁盘产生设备文件的规则


KERNEL=="sd*[0-9]", PROGRAM=="/lib/udev/scsi_id -g -s %p", \ RESULT=="35000c50000a7ef67", NAME +="root_disk%n"

该规则表示:如果存在设备的内核设备名称是以 sd 开头( 磁盘设备),以数字结尾( 磁盘分区),并且通过外部命令查询该设备的SCSI_ID 号为“35000c50000a7ef67”,则产生一个以root_disk开头,内核号码结尾的设备文件,并替换原来的设备文件(如果存在的话)。例如:产生设备名/dev/root_disk2,替换原来的设备名/dev/sda2。

运用这条规则,可以在/etc/fstab里保持系统分区名称的一致性,而不会受驱动加载顺序或者磁盘标签被破坏的影响,导致操作系统启动时找不到系统分区。


4.3 其他常用的udev命令

udevadm test(udevadm的子命令):针对一个设备,在不需要uevent 触发的情况下模拟一次udev的运行,并输出查询规则文件的过程、所执行的行为、规则文件的执行结果。

Simulate a udev event run for the given device, and print debugoutput


start_udev:start_dev命令重启udev守护进程,并对所有的设备重新查询规则目录下所有的规则文件,然后执行所匹配的规则里的行为。通常使用该命令让新的规则文件立即生效:

[root@test ~]# start_udev

Starting udev: [ OK ]


start_udev一般没有标准输出,所有的udev相关信息都按照配置文件(udev.conf)的参数设置,由syslog记录。

作者:SEian.G(苦练七十二变,笑对八十一难)

ITPUBhttp://blog.itpub.net/31015730/

51CTOhttp://seiang.blog.51cto.com/



来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/31015730/viewspace-2142429/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/31015730/viewspace-2142429/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值