用 open-iscsi 连上 Target 之后,iSCSI 设备的名称在系统里总是变来变去,无法固定,这给应用带来了诸多不便。为了固定系统中 iSCSI 设备的名称,可以考虑使用Linux 2.6 内核引入的 UDEV 机制。 
    关于 UDEV 的介绍,网上的资料很多,这里就不啰嗦了。英文好的同学也可以用 man udev 来查看系统自带的帮助文档。 


  • UDEV 规则文件

    UDEV 相关的配置文件、规则文件和脚本等的位置在不同系统上不尽相同,可以通过 man udev 查到。在 CentOS 上,这些文件均位于 /etc/udev 目录下。 
    UDEV 规则文件必须以 .rules 结尾,开始的数字代表规则执行的优先级,数字越小,优先级越高。当然,也可以不指定数字。 
    好了,废话不多说,直接上规则: 

    KERNEL=="sd*", BUS=="scsi", ENV{ID_PATH}=="ip-*", PROGRAM="/etc/udev/scripts/iscsidev.sh %E{ID_PATH}", SYMLINK+="iscsi/%c/part%n" 

    注意:规则文件中的一条规则必须在同一行内,不允许跨行。 
    上述规则中,"==" 为条件判断,"KERNEL"、"BUS"、"ENV{ID_PATH}"为规则必须满足的条件。这3个条件可以确认一个 iSCSI 设备或分区。其中,"ENV{ID_PATH}"表示设备的 ID_PATH 属性,该属性在 CentOS 中为 "ip-" 开头的字符串。 
    PROGRAM 指定满足规则后执行的脚本程序,SYMLINK 表示满足规则后创建指定该设备的符号链接。SYMLINK 默认创建在 /dev 目录下,所以这里只给出了相对路径。 
    规则中以"%"开始的是 UDEV 中的参数,如下: 


细的参数说明,可以查看 UDEV 的系统帮助(man udev),也可以参考简述udev的自定义规则。 


    上述规则中,iSCSI 设备的 SYMLINK 为 /dev/iscsi/<target name>/part<n>。其中,<n> 为设备的内核号码;<target name> 通过 PROGRAM 指定的脚本获得。 



  • UDEV 脚本

    iscsidev.sh 脚本的内容如下: 
    #!/bin/sh 
    # File: /etc/udev/scripts/iscsidev.sh 

    TARGET_NAME=`/bin/echo $1 | /bin/awk -F"-iscsi-" '{print $2}' | /bin/awk -F"-lun-" '{print $1"/lun"$2}'` 
    /bin/echo ${TARGET_NAME}
 

    脚本的传入参数为设备的 ID_PATH 属性,其格式为 ip-<server ip>:<port>-iscsi-<target name>-lun-<lun id>,可以通过udevadm 查询到: 

eae770df-3aa5-3755-b33f-044897a74b30.png


脚本解析传入的参数,解析出 Target 的名字,然后组成 LUN 对应设备的符号链接,并返回。 
    现在,可以登入 iSCSI Target,然后再 /dev/iscsi/ 下查看对应的符号链接了。