- Java锁的逻辑(结合对象头和ObjectMonitor)
- 还在用饼状图?来瞧瞧这些炫酷的百分比可视化新图形(附代码实现)⛵
- 自动注册实体类到EntityFrameworkCore上下文,并适配ABP及ABPVNext
- 基于Sklearn机器学习代码实战
几年前, Linux内核为网络接口分配名称采用的是一种简单和直观的方式:一个固定的前缀和一个递增的序号。比如,内核使用 eth0 名称以标识启动后第一个加载的网络设备,第二个加载的设备名称是 eth1 ,第三个是 eth2 ,以此类推。。。如果用户想要在系统启动后添加一个新的网卡,那么内核也会按这个规则为它分配新的设备名称.
不过,内核分配的网卡名称有一个隐患:每次系统启动时网络设备的加载顺序是不固定的(多数发生在为系统增加网卡,否则加载顺序基本固定),当系统重启时,内核可能会为因加载顺序为同一个网络设备分配一个与之前不同的名称,原本名称为eth0的网卡,可能经过一次系统重启后就变成了eth1。这样就会对部分涉及到网卡数据采集的应用程序产生影响,因此经开发者们商讨后,决定采用一致性网络设备命名规则.
一致性网络设备命名规则采用udev设备管理器来实现对网络设备的重命名,该方式通过获取网卡的固件、结构、未知等信息,从而固定一张网卡的名称,这样做带来了如下几点好处:
接下来本文将详细介绍该网络设备命名规则.
udev是Linux上的一种设备管理器,它用于在设备发生事件时,管理设备文件的权限,或者在 /dev 目录下创建额外的软链接,也可以重命名网络设备。内核往往通过设备发现顺序来分配无法预测的设备名称,而udev则基于设备属性或配置生成软链接或网络设备名称,提供了识别这些设备的可靠方式.
systemd-udevd.service 是udev的守护进程,它会直接从内核监听设备的事件,包括添加、移除、状态改变。当udev获取到一个设备事件时,它会从一系列的规则文件中读取匹配到的规则,并应用对应的动作,比如说保存额外信息到udev数据库中,或者创建设备软链接等等.
所有udev处理的设备信息都会保存到udev数据库中,这些数据可以通过 libudev 库访问,也可以通过 udevadm info <devpath> 命令读取.
更多udev的信息,比方说udev规则文件的语法,可以通过 man udev 命令查看.
一些常用的udev命令:
# 获取udev数据库中记录的指定设备信息
# udevadm info /sys/class/net/eno1
P: /devices/pci0000:00/0000:00:1c.4/0000:09:00.0/net/eno1
E: DEVPATH=/devices/pci0000:00/0000:00:1c.4/0000:09:00.0/net/eno1
...
E: INTERFACE=eno1
E: SUBSYSTEM=net
# 调试指定设备的添加/移除事件
# udevadm test -a add /sys/class/net/eno1
calling: test
version 239 (239-76.el8)
...
Unload module index
Unloaded link configuration context.
# 调试udev内置程序
# udevadm test-builtin net_setup_link /sys/class/net/eno1
calling: test-builtin
Load module index
...
Unload module index
Unloaded link configuration context.
udev在执行规则文件时,会事先添加一些基本的环境变量,主要如下:
DEVPATH=/devices/pci0000:00/0000:00:1c.4/0000:09:00.0/net/eno1
INTERFACE=eno1
IFINDEX=2
ACTION=add
SUBSYSTEM=net
LC_CTYPE=C.UTF-8
当启用一致性网络设备命名规则时, udev 设备管理器会根据一系列的规范来创建设备的名称,根据网络设备的类型,设备名称会以如下规则生成一个两字母前缀:
en
表示以太网设备 wl
表示无线局域网设备(WLAN) ww
表示无线广域网设备(WWAN) 接着, udev 会根据如下格式为以生成的网络设备名称后追加内容:
o<板载索引号>
s<PCIe热插拔索引号>[f<function号>][d<device号>]
[P<PCI域位置>]p<bus号>s<slot号>[f<function号>][d<device号>]
x<MAC地址>
[P<PCI域位置>]p<bus号>s<slot号>[f<function号>][u<usb端口>][…][c<config>][i<interface>]
一致性网络设备命名规则采用udev来实现对网络设备的重命名,因此重命名的规则也都记录在udev的配置文件中,udev使用如下的顺序处理网络设备命名规则.
60-net.rules 的作用是通过网络接口配置文件更改网络设备命名,它获取匹配网络设备MAC地址的配置文件,并将该配置文件中的设备名作为新设备名.
文件内容如下,当添加设备时,对于net子系统中任意非空设备驱动且type属性为1的设备,执行 /lib/udev/rename_device 程序,如果程序输出不为空,那么将设备名设置为程序输出.
ACTION=="add", SUBSYSTEM=="net", DRIVERS=="?*", ATTR{type}=="1", PROGRAM="/lib/udev/rename_device", RESULT=="?*", NAME="$result"
/lib/udev/rename_device 是一个协助处理程序,它从 INTERFACE 环境变量中读取网络设备名称,随后通过 /sys/class/net/%s/address 获取MAC地址,如果 /etc/sysconfig/network-scripts/ifcfg-* 中有文件的 HWADDR 参数匹配到对应MAC地址,那么将输出该文件中 DEVICE 参数的值,否则输出空.
71-biosdevname.rules 一般在需额外安装的 biosdevname 软件包中,该规则的作用是通过从bios获取的设备文件名更改网络设备命名,它只会在 biosdevname 内核参数为1时才生效.
文件内容如下,当添加设备时,对于 net 子系统中任意名称为空(未重命名过), type 属性为1且 DEVTYPE 环境变量为空的设备,如果 biosdevname 内核参数为1,那么执行 /sbin/biosdevname --smbios 2.6 --nopirq --policy physical -i %k 程序(%k是设备的内核名称),将其输出作为新名称.
SUBSYSTEM!="net", GOTO="netdevicename_end"
ACTION!="add", GOTO="netdevicename_end"
NAME=="?*", GOTO="netdevicename_end"
ATTR{type}!="1", GOTO="netdevicename_end"
ENV{DEVTYPE}=="?*", GOTO="netdevicename_end"
# kernel command line "biosdevname={0|1}" can turn off/on biosdevname
IMPORT{cmdline}="biosdevname"
ENV{biosdevname}=="?*", ENV{UDEV_BIOSDEVNAME}="$env{biosdevname}"
# ENV{UDEV_BIOSDEVNAME} can be used for blacklist/whitelist
# but will be overwritten by the kernel command line argument
ENV{UDEV_BIOSDEVNAME}=="0", GOTO="netdevicename_end"
ENV{UDEV_BIOSDEVNAME}=="1", GOTO="netdevicename_start"
# off by default
GOTO="netdevicename_end"
LABEL="netdevicename_start"
# using NAME= instead of setting INTERFACE_NAME, so that persistent
# names aren't generated for these devices, they are "named" on each boot.
SUBSYSTEMS=="pci", PROGRAM="/sbin/biosdevname --smbios 2.6 --nopirq --policy physical -i %k", NAME="%c" OPTIONS+="string_escape=replace"
LABEL="netdevicename_end"
75-net-description.rules 的作用是通过一些udev内置程序获取网络设备的信息并设置为环境变量,用于后续步骤.
文件内容如下,当添加网络设备时,调用 net_id 内置程序获取设备信息并设置内部环境变量,对于usb类型的网络设备,调用 usb_id 以及 hwdb 内置程序获取设备信息并设置内部环境变量,对于pci类型的网络设备,根据一些内核中的设备属性以及 hwdb 内置程序设置内部环境变量.
ACTION=="remove", GOTO="net_end"
SUBSYSTEM!="net", GOTO="net_end"
IMPORT{builtin}="net_id"
# ID_NET_NAMING_SCHEME=rhel-8.0
# ID_NET_NAME_MAC=enxac1f6b848502
# ID_OUI_FROM_DATABASE=Super Micro Computer, Inc.
# ID_NET_NAME_ONBOARD=eno1
# ID_NET_LABEL_ONBOARD=enIntel Ethernet I350AM2 #1
# ID_NET_NAME_PATH=enp9s0f0
SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id", IMPORT{builtin}="hwdb --subsystem=usb"
SUBSYSTEMS=="usb", GOTO="net_end"
SUBSYSTEMS=="pci", ENV{ID_BUS}="pci", ENV{ID_VENDOR_ID}="$attr{vendor}", ENV{ID_MODEL_ID}="$attr{device}"
# ID_BUS=pci
# ID_VENDOR_ID=0x8086
# ID_MODEL_ID=0x1521
SUBSYSTEMS=="pci", IMPORT{builtin}="hwdb --subsystem=pci"
# ID_PCI_CLASS_FROM_DATABASE=Network controller
# ID_PCI_SUBCLASS_FROM_DATABASE=Ethernet controller
# ID_VENDOR_FROM_DATABASE=Intel Corporation
# ID_MODEL_FROM_DATABASE=I350 Gigabit Network Connection
LABEL="net_end"
80-net-setup-link.rules 的作用是通过一些udev内置程序获取网络设备的信息并设置为环境变量,用于后续步骤.
文件内容如下,当添加网络设备时,调用 path_id 内置程序获取设备信息,随后调用 net_setup_link 内置程序,如果先前没有重命名设备,且内置程序输出的 ID_NET_NAME 环境变量不为空,那么将该环境变量的值设置为新设备名称.
SUBSYSTEM!="net", GOTO="net_setup_link_end"
IMPORT{builtin}="path_id"
# ID_PATH=pci-0000:09:00.0
# ID_PATH_TAG=pci-0000_09_00_0
ACTION!="add", GOTO="net_setup_link_end"
IMPORT{builtin}="net_setup_link"
# ID_NET_DRIVER=igb
# ID_NET_LINK_FILE=/usr/lib/systemd/network/99-default.link
# ID_NET_NAME=eno1
NAME=="", ENV{ID_NET_NAME}!="", NAME="$env{ID_NET_NAME}"
LABEL="net_setup_link_end"
net_setup_link 内置程序会读取 /usr/lib/systemd/network/99-default.link 配置文件,从而决定最后网络设备应该使用的名称:
[Link]
NamePolicy=kernel database onboard slot path
AlternativeNamesPolicy=database onboard slot path
MACAddressPolicy=persistent
该文件的 NamePolicy 参数标记了网络设备命名的优先级顺序:内核名称 > udev硬件数据库中记录名称 > onboard名称( ID_NET_NAME_ONBOARD, eno ) > slot名称( ID_NET_NAME_SLOT, ens ) > path名称( ID_NET_NAME_PATH, enp ).
另外, AlternativeNamesPolicy 则记录了网络设备的别名,如果有该配置项,那么应用程序也可以通过别名来访问网络设备.
如果想要换回原先的网络设备命名规则,即 ethN 命名,需要在内核参数中添加 net.ifnames=0 以及 biosdevname=0 参数.
可以在grub引导程序中修改,在 /etc/default/grub 中的 GRUB_CMDLINE_LINUX 参数中追加,并通过 grub2-mkconfig -o /boot/grub2/grub.cfg 命令生成新grub配置文件,重启系统后生效.
除此之外,可能还要修改 /etc/sysconfig/network-scripts/ifcfg-* 网卡配置文件中的 DEVICE 参数,防止重启后出现网卡无法拉起或者网络设备名称换回失败的情况.
通过udev设备管理器,我们可以很方便的更改以及定制网络设备命名规则,比如如果想要基于MAC地址固定某个网络设备的名称,那么可以创建 /etc/udev/rules.d70-fix-eno2.rules 文件,内容如下:
SUBSYSTEM=="net",ACTION=="add",ATTR{address}=="ac:1f:6b:84:85:03",ATTR{type}=="1",NAME="myfixif"
其中 ATTR{address} 表示MAC地址, ATTR{type}=="1" 表示是 Ethernet 类型.
修改后重启生效.
Chapter 1. Consistent network interface device naming Red Hat Enterprise Linux 8 | Red Hat Customer Portal 。
Linux┊详解udev - 无双的小宝 - 博客园 (cnblogs.com) 。
udev(7) - Linux manual page (man7.org) 。
最后此篇关于Linux网络设备命名规则简介的文章就讲到这里了,如果你想了解更多关于Linux网络设备命名规则简介的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我需要在 nginx-ingress 版本上允许来自多个来源的请求:http://localhost:4200、http://localhost:4242 等1.7.1.但我无法对多个来源执行此操作,
我正在部署我使用 APIGILITY 开发的 API到 IIS。由于 IIS 不支持 .htaccess,我试图从 .htaccess 文件的内容创建 web.config 文件。我使用 IISv7.
我正在尝试更改上面 css 样式中的“宽度”规则。在“inspect element”中你可以看到宽度是1008px。我不希望它是 1008px 但它不会让我在 css 样式中更改它你可以看到它被“删
外部css赋值有2种方法,我用的是第一种;大多数网站使用第二种方法。我想知道我是否做错了! 第一种方法: 为几乎每个 css 规则创建一个类并在任何地方使用它们。 blah blah .f_
RDF使用 WEB 标识符 (URIs) 来标识资源,使用属性和属性值来描述资源 RDF 资源、属性和属性值 RDF使用 WEB 标识符来标识事物,并通过属性和属性值来描述资源。 关于资源、属性
我想挖掘特定的 rhs 规则。文档中有一个示例证明这是可能的,但仅适用于特定情况(如下所示)。先来一个数据集来说明我的问题: input {b=100002} 0.2500000 0.250000
我想让 nginx 从网站根目录(:http://localhost:8080/)提供一个静态文件,但它为我的代理通行证提供服务;它提供“/”规则而不是“=/”。 这是我的 nginx 配置的样子:
根据gnu make documentation , 如果一个规则通过一次调用生成多个目标(例如,一个配方执行一个带有多个输出文件的工具),你可以使用 '&:' 规则语法来告诉 make。但是,当在多
我已阅读Firebase Documentation并且不明白什么是 .contains()。 以下是文档中 Firebase 数据库的示例规则: { "rules": { "rooms"
关闭。这个问题是opinion-based 。目前不接受答案。 想要改进这个问题吗?更新问题,以便 editing this post 可以用事实和引文来回答它。 . 已关闭 6 年前。 Improv
我正在尝试做一些多态性练习,但我无法弄清楚这种多态性是如何工作的。我没有找到任何关于这种练习的深入信息。希望大家能给我一些解释。 练习1: class Top { public void m(
为了调试复杂的 XSLT 转换,我将其分为几个部分:首先构建 %.1.xml,然后使用它构建 %.2.xml ,最后构建 %.3.xml。一切正常,但如果我要求 Make 构建最后一个,Make 总是
我尝试了 hacerrank 的 slove 练习 Click我不知道如何添加这些规则: ► 它可以包含 4 个一组的数字,并用一个连字符“-”分隔。 ► 不得有 4 个或更多连续重复数字。 这是我的
我正在尝试编写一个小测验,我希望“再试一次”按钮遵循与“else”之前的“if”语句相同的规则 using System; public class Program { public stat
在我的 Spring/Boot Java 项目中,我有一组服务方法,例如以下一个: @Override public Decision create(String name, String descr
我正在阅读 Covariant virtual function .上面写着 假设 B::f 覆盖了虚函数 A::f。如果满足以下所有条件,A::f 和 B::f 的返回类型可能不同: 1) The
我工作的公司想要分发(在公共(public)链接中)具有内部签名的应用程序。我很确定 Apple 否认这种事情,但我在官方文档/契约(Contract)中没有找到任何相关信息。 有谁知道它到底是如何工
我是 CSS 新手。我观察到一个奇怪的 CSS 行为,其中一个元素具有以下 CSS 属性 .container .header{ color: #FFFFFF; font-size: 2em;
这个问题在这里已经有了答案: Is there a CSS selector for elements containing certain text? (21 个答案) 关闭 7 年前。
我有以下 CSS: workoutcal.css: .errorlist{ color:red; } 以下基本模板: base.html: {% load static %} {
我是一名优秀的程序员,十分优秀!