一、设备文件管理方法

          devfs

        Linux早期采用的静态管理方法

        /dev目录下有大量静态文件

        绝大多数文件没有对应的硬件连接

        内核版本2.6.13开始被完全取代

          udev

        只有连到系统上来的设备才在/dev下创建设备文件

        与主、次设备编号无关

        为设备提供持久、一致的名字

二、接入设备事件链

          内核发现设备并导入设备状态到sysfs

          udev接到事件通知

          udev创建设备节点或是运行指定程序

          udev通知hald守护进程

          HAL探测设备信息

          HAL创建设备对象结构

          HAL通过系统消息总线广播该事件

          用户程序也可以监控该事件

三、udev

          从内核收到添加/移除硬件事件时,udev将会分析:

        /etc/udev/rules.d目录中的规则

        根据规则中的命令产生哪些输出

        /sys目录下信息

          基于分析结果,udev会:

        处理设备命名

        决定要创建哪些设备文件或链接

        决定如何设置属性

        决定触发哪些事件

事件监控

#  udevadm  monitor

1、主配置文件/etc/udev/udev.conf

        udev_root:创建设备文件位置,默认为/dev

        udev_rulesudev规则文件位置,默认为/etc/udev/rules.d

        udev_logsyslog优先级,缺省为err

2、编写规则

          文件位置及格式

        /etc/udev/rules.d/<rule_name>.rules

        例:75-custom.rules

          规则格式

        <match-key><op><value>[,]<assignment-key><op>value[,]

        BUS=="usb",SYSFS{serial}=="20043512321411d34721",NAME="udisk"

3udev匹配操作

          操作符

        ==:表示匹配

        != :表示不匹配

          匹配示例

        ACTION=="add"

        KERNEL=="sd[a-z]1"

        BUS=="scsi"

        DRIVER!="ide-cdrom"

        PROGRAM=="myapp.pl",RESULT=="test"

4udev赋值操作

          操作符

        =:指定赋予的值

        +=:添加新值

        :=:指定值,且不允许被替换

          示例

        NAME="udisk"

        SYMLINK+="data1"

        OWNER="student"

        MODE="0600"

5udev规则替换

          可以简化或缩写规则

          例:
KERNEL=="sda*",SYMLINK+="iscsi%n"

          常用替代变量

        %k:内核所识别出来的设备名,如sdb1

        %n:设备的内核编号,如sda3中的3

        %p:设备路径,如/sys/block/sdb/sdb1

        %%%符号本身

 3、测试动态生成/dev目录下的文件

#  rm  -f  /dev/*

#  ls  /dev/

#  start_udev

#  ls  /dev/

 

4、例一:

U盘被内核识别出来的名字叫sdc,那么这个U盘上的分区叫udisk1udisk2udisk3……

#  cd  /etc/udev/rules.d/

#  vim  99-udisk.rules

BUS=="usb", ACTION=="add", KERNEL=="sd[a-z]*", SYMLINK+="udisk%n"

插入的U盘,如果是sdc,那么就会出现udisk1udisk2这样的链接文件

 

4、例二:只识别某一个特定的U盘。先插入U盘,如插入的U盘被识别为/dev/sdc

[root@rhel6-1 rules.d]# udevadm info --query=path --name=/dev/sdc1

/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/host9/target9:0:0/9:0:0:0/block/sdc1

 

[root@rhel6-1 rules.d]# udevadm info --query=all --attribute-walk --path=/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/host9/target9:0:0/9:0:0:0/block/sdc1

 

[root@rhel6-1 rules.d]# vim 99-udisk.rules

ACTION=="add", ATTRS{manufacturer}=="Kingston", ATTRS{product}=="DataTraveler G2", ATTRS{serial}=="0014780BBDBCEA9075C90001", KERNEL=="sd[a-z]*", SYMLINK+="myudisk%n"

如果重新重入U盘,/dev目录下将出现udisk*的符号链接。换成其他U盘,这个链接将不会出现。

 

5、某一个iscsi设备总是被命名为remotedisk。比如,iscsi设备被识别为sdb

[root@rhel6-1 rules.d]# udevadm info --query=path --name=/dev/sdb 

[root@rhel6-1 rules.d]# udevadm info --query=all --attribute-walk --path=/devices/platform/host3/session1/target3:0:0/3:0:0:1/block/sdb

[root@rhel6-1 rules.d]# vim  99-iscsidisk.rules

ACTION=="add", SUBSYSTEMS=="scsi", ATTRS{vendor}=="IET     ", ATTRS{model}=="VIRTUAL-DISK    ", ATTRS{rev}=="0001" SYMLINK+="remotedisk%n"

只有硬盘被重新加载的时候,udev规则才会生效,所以将iscsi存储先logout,再login

#   iscsiadm --mode node --targetname iqn.2013-12.com.tarena.tech:rack1.sata.disk1 --portal 192.168.194.20:3260 –logout

iscsiadm --mode node --targetname iqn.2013-12.com.tarena.tech:rack1.sata.disk1 --portal 192.168.194.20:3260 –login

6、例三:

当设备插入到系统中后,根据执行某一个命令获得的结果来命名设备

#  vim  99-iscsidisk.rules

KERNEL=="sd*", SUBSYSTEMS=="scsi", PROGRAM=="/lib/udev/scsi_id --whitelisted --device=/dev/%k --replace-whitespace", RESULT=="1IET_00010001", SYMLINK+="iscsidisk%n"

 

7、案例分析1

          BUS=="scsi", SYSFS{serial}=="123456789", NAME="byLocation/rack1-shelf2-disk3

          KERNEL=="sd*", BUS=="scsi", PROGRAM=="/lib/udev/scsi_id -g -s %p", RESULT=="SATA ST340014AS 3JX8LVCA", NAME="backup%n"

          KERNEL=="sd?1", BUS=="scsi", SYSFS{model}=="DSCT10", SYMLINK+="camera"

8、案例分析2

          KERNEL=="sd*", SYSFS{idVendor}=="0781", SYSFS{idProduct}=="5150", SYMLINK+="keycard", OWNER="student", GROUP="student", MODE="0600

          ACTION=="add", KERNEL=="ppp0", RUN+="/usr/bin/wall PPP Interface Added"