إعادة التسمية والترقيم التلقائي لـ nics باستخدام udev
-
10-07-2019 - |
سؤال
أنا أكتب وفقًا لقاعدة udev لإعادة تسمية وترقيم بطاقات NIC تلقائيًا باستخدام عناوين MAC محددة.
يجب أن تفعل القاعدة الناتجة نفس الشيء تقريبًا 75-persistent-net-generator.rules
يقوم بمطابقة البايتات الثلاثة الأولى من عنوان MAC الخاص بالبطاقة، وقم بتسميتها "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}.
نصائح أخرى
حسنًا، هذا هو الحل (لقد اختبرته مع Debian 5.0 وUbuntu 9.04، لذا لست متأكدًا مما إذا كان يعمل مع تطبيقات udev للتوزيعات الأخرى):
75-مستمرة-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
أهم التغييرات هي ENV{INTERFACE}="mycard0"
في 75-persistent-mycard-generator.rules الذي يحدد الاسم الذي يجب أن تحصل عليه البطاقة و match="$match, KERNEL==\"eth*\""
في write_mycard_rules الذي يفرض على udev عدم تجاوز نظام Kernel الفرعي المستخدم بالاسم الجديد.