题
我正在写一个udev规则来自动重命名和编号具有特定MAC地址的NIC。
结果规则应该做的几乎相同75-persistent-net-generator.rules
做(匹配卡的MAC地址的前3个字节,根据安装此供应商的卡数将其命名为'mycard *',将重命名规则写入70-persistent-net.rules
)。
到目前为止我已经走了多远:
# udev rules to name rename cards to mycard
ACTION!="add", GOTO="persistent_mycard_generator_end"
SUBSYSTEM!="net", GOTO="persistent_mycard_generator_end"
# ignore the interface if a name has already been set
NAME=="mycard*", GOTO="persistent_mycard_generator_end"
# device name whitelist
KERNEL!="eth*", GOTO="persistent_mycard_generator_end"
# read MAC address
ENV{MATCHADDR}="$attr{address}"
# match interface type
ENV{MATCHIFTYPE}="$attr{type}"
# ignore non mycard MAC addresses
ENV{MATCHADDR}!="00:11:22:*", GOTO="persistent_mycard_generator_end"
# default comment
ENV{COMMENT}=="", ENV{COMMENT}="mycard connected through ($attr{driver})"
#### THIS IS THE PART I DON'T GET ####
# write rule
DRIVERS=="?*", IMPORT{program}="write_net_rules"
# rename interface if needed
ENV{INTERFACE_NEW}=="?*", NAME="mycard*"
#### THIS IS THE END OF THE PART I DON'T GET ####
LABEL="persistent_mycard_generator_end
任务<!>“我不会得到的部分<!>”;我应该做的是将一张卡(比方说是eth3)重命名为mycard0,或者它是系统中第二张卡,其中包含匹配的MAC地址mycard1,依此类推。
提前致谢, flokra
解决方案
如果将ENV {INTERFACE}设置为<!>“mycard0 <!>”;在调用write_net_rules之前,它将为您找到第一个未使用的mycardN,为其写出规则,并在ENV {INTERFACE_NEW}中返回该名称。
其他提示
OK, here's my solution (I've tested it with Debian 5.0 and Ubuntu 9.04, so I'm not sure if it works with the udev-implementations of other distributions):
75-persistent-mycard-generator.rules
ACTION!="add", GOTO="persistent_mycard_generator_end" SUBSYSTEM!="net", GOTO="persistent_mycard_generator_end" # ignore the interface if a name has already been set NAME=="?*", GOTO="persistent_mycard_generator_end" # device name whitelist KERNEL!="eth*", GOTO="persistent_mycard_generator_end" # by default match on the MAC address and interface type ENV{MATCHADDR}="$attr{address}" ENV{MATCHIFTYPE}="$attr{type}" # match interface dev_id ATTR{dev_id}=="?*", ENV{MATCHDEVID}="$attr{dev_id}" # by default match on the MAC address and interface type ENV{MATCHADDR}="$attr{address}" ENV{MATCHIFTYPE}="$attr{type}" # match interface dev_id ATTR{dev_id}=="?*", ENV{MATCHDEVID}="$attr{dev_id}" # terminate processing if card is not a mycard ENV{MATCHADDR}!="AA:BB:CC:*", GOTO="persistent_mycard_generator_end" # provide nice comments for the generated rules SUBSYSTEMS=="pci", ENV{COMMENT}="PCI device $attr{vendor}:$attr{device}" SUBSYSTEMS=="pcmcia", ENV{COMMENT}="PCMCIA device $attr{card_id}:$attr{manf_id}" SUBSYSTEMS=="usb", ENV{COMMENT}="USB device 0x$attr{idVendor}:0x$attr{idProduct}" ENV{COMMENT}=="", ENV{COMMENT}="Unknown $env{SUBSYSTEM} device($env{DEVPATH})" ATTRS{driver}=="?*", ENV{COMMENT}="$env{COMMENT} ($attr{driver})" # add mycard to comment ENV{COMMENT}="$env{COMMENT} (mycard)" # set interface name to mycard0 (initially) ENV{INTERFACE}="mycard0" # generate and write the rule DRIVERS=="?*", IMPORT{program}="write_mycard_rules" # rename the interface if requested ENV{INTERFACE_NEW}=="?*",NAME="$env{INTERFACE_NEW}" LABEL="persistent_mycard_generator_end"
write_mycard_rules
RULES_FILE='/etc/udev/rules.d/70-persistent-net.rules' . /lib/udev/hotplug.functions interface_name_taken() { local value="$(find_all_rules 'NAME=' $INTERFACE)" if [ "$value" ]; then return 0 fi return 1 } find_next_available() { raw_find_next_available "$(find_all_rules 'NAME=' "$1")" } write_rule() { local match="$1" local name="$2" local comment="$3" { if [ "$PRINT_HEADER" ]; then PRINT_HEADER= echo "# This file was automatically generated by the $0" echo "# program run by the persistent-mycard-generator.rules rules file." echo "#" echo "# You can modify it, as long as you keep each rule on a single line." fi echo "" [ "$comment" ] && echo "# $comment" echo "SUBSYSTEM==\"net\", ACTION==\"add\"$match, NAME=\"$name\"" } >> $RULES_FILE } if [ -z "$INTERFACE" ]; then echo "missing \$INTERFACE" >&2 exit 1 fi # Prevent concurrent processes from modifying the file at the same time. lock_rules_file # Check if the rules file is writeable. choose_rules_file # the DRIVERS key is needed to not match bridges and VLAN sub-interfaces if [ "$MATCHADDR" ]; then match="$match, DRIVERS==\"?*\", ATTR{address}==\"$MATCHADDR\"" fi if [ "$MATCHDRV" ]; then match="$match, DRIVERS==\"$MATCHDRV\"" fi if [ "$MATCHDEVID" ]; then match="$match, ATTR{dev_id}==\"$MATCHDEVID\"" fi if [ "$MATCHID" ]; then match="$match, KERNELS==\"$MATCHID\"" fi if [ "$MATCHIFTYPE" ]; then match="$match, ATTR{type}==\"$MATCHIFTYPE\"" fi if [ -z "$match" ]; then echo "missing valid match" >&2 unlock_rules_file exit 1 fi basename=${INTERFACE%%[0-9]*} match="$match, KERNEL==\"eth*\"" if [ "$INTERFACE_NAME" ]; then # external tools may request a custom name COMMENT="$COMMENT (custom name provided by external tool)" if [ "$INTERFACE_NAME" != "$INTERFACE" ]; then INTERFACE=$INTERFACE_NAME; echo "INTERFACE_NEW=$INTERFACE" fi else # if a rule using the current name already exists, find a new name if interface_name_taken; then INTERFACE="$basename$(find_next_available "$basename[0-9]*")" echo "INTERFACE_NEW=$INTERFACE" fi fi write_rule "$match" "$INTERFACE" "$COMMENT" unlock_rules_file exit 0
The most important changes are ENV{INTERFACE}="mycard0"
in 75-persistent-mycard-generator.rules which sets the name the card should get and match="$match, KERNEL==\"eth*\""
in write_mycard_rules which forces udev to not override the used Kernel Subsystem with the new name.