标签:blog http sp 文件 on 问题 log 代码 bs
本文皆是作者工作学习中的理解或感悟,欢迎大家提出问题,一起讨论!!
一.问题提出
一般的主板上都带有两个网卡接口,linux系统启动后一般命名为eth0,eth1,当然如果我们不对eth0与eth1进行后期处理的话,每次开机eth0与eth1的位置也不会固定。所以当外置网卡时,更会出现端口混乱的问题(端口名与端口的pci位置不固定,每次启动都可能变换,内核对网络端口的命名顺序是根据检测到网卡的先后顺序来的),特别是不同驱动的网卡。
二.问题分析
1、首先我们需要了解内核给网络端口命名的执行流程:
1)linux内核一般会在rc.sysinit里执行/sbin/udevd -d开始执行udev程序
2)执行udev的过程中会检测所有设备,并根据不同的设备来加载不同的驱动
3)加载完相应设备的驱动后,udev会收到一个该设备的内核事件,udev会根据相应的事件来匹配相应的规则,或者是执行某些脚本修改设备名重新书写规则(rules)
4)当规则生成后,当再次产生此设备的内核事件时,则首先会匹配这些规则
这里要注意udev的两点:
1)我们可以通过udev来修改任何设备的名字
2)在我们没修改名字之前,内核已经给给设备分配了名字(值得注意这点,否则修改的名字和内核给其他设备分配的名字冲突,则会修改失败)
2、不同的网卡设备
目前为止我已知的网卡有如下几种(都是intel的):
网卡型号 所用驱动
8086:1502 e1000e
8086:10d3 e1000e
8086:150e igb
8086:105e e1000e
8086:1521 igb
这只是我接触的几种网卡,不同种类的驱动对网卡端口的命名还是会有影响的
3.pci接口的bus id号
-bash-3.2# lspci -n -D | grep 0200
0000:00:19.0 0200: 8086:1502 (rev 05)
0000:01:00.0 0200: 8086:150e (rev 01)
0000:01:00.1 0200: 8086:150e (rev 01)
0000:01:00.2 0200: 8086:150e (rev 01)
0000:01:00.3 0200: 8086:150e (rev 01)
0000:03:00.0 0200: 8086:105e (rev 06)
0000:03:00.1 0200: 8086:105e (rev 06)
0000:04:00.0 0200: 8086:10d3
我们通过lspci -n -D可以查看所有的连在pci接口上的设备的busid号(第一列)和设备型号(最后一列)的对应列表,这里的0200代表的是网卡设备,通过大量的实验发现,无论网口的名字(eth*)怎么变化,在同一台机器上,他们的busid号是不变的。这里的8086:1502,8086:10d3是主板自带的两个端口,8086:150e是一个4口的Intel网卡,8086:105e是一个两口的intel网卡。由此,在这一型号的机器上,这一型号的网卡上,可已通过busid号,网卡型号来固定网口名。
三、问题处理
1)首先我们在udev的一个和网络有关的规则文件里添加了如下代码:
KERNEL=="eth*|ath*|wlan*|ra*|sta*", DRIVERS=="?*",IMPORT{program}="A.sh $attr{address} %b"
当有网卡的内核事件的时候,会匹配这条规则,执行A.sh这个脚本,并且将mac地址($attr{address}),busid号(%b)作为参数传给脚本
2)A.sh的功能就是根据mac地址和busid两个参数,来修改端口名,最终将新规则输出到一个新的规则文件B中。具体方法:
a)先列出一个busid和网络端口名的对应表如下:
0000:04:00.0 8086:10d3 eth0
0000:00:19.0 8086:1502 eth1
0000:01:00.0 8086:150e eth2
0000:01:00.1 8086:150e eth3
0000:01:00.2 8086:150e eth4
0000:01:00.3 8086:150e eth5
0000:03:00.0 8086:105e eth6
0000:03:00.1 8086:105e eth7
b)根据busid和这个表,来查找最终的端口名
c)根据mac地址和最终的端口名,生成新的规则,如下:
# PCI device 0x8086:0x150e (igb)
BUS=="net", DRIVER=="?*", SYSFS{address}=="90:e2:ba:52:8e:b2", NAME="eth4"
# PCI device 0x8086:0x1502 (e1000e)
BUS=="net", DRIVER=="?*", SYSFS{address}=="0c:c4:7a:06:03:f3", NAME="eth1"
# PCI device 0x8086:0x150e (igb)
BUS=="net", DRIVER=="?*", SYSFS{address}=="90:e2:ba:52:8e:b3", NAME="eth5"
# PCI device 0x8086:0x10d3 (e1000e)
BUS=="net", DRIVER=="?*", SYSFS{address}=="0c:c4:7a:06:03:f2", NAME="eth0"
# PCI device 0x8086:0x150e (igb)
BUS=="net", DRIVER=="?*", SYSFS{address}=="90:e2:ba:52:8e:b0", NAME="eth2"
#PCI device 0x8086:0x105e (e1000e)
BUS=="net", DRIVER=="?*", SYSFS{address}=="68:05:ca:12:e0:c5", NAME="eth7"
# PCI device 0x8086:0x150e (igb)
BUS=="net", DRIVER=="?*", SYSFS{address}=="90:e2:ba:52:8e:b1", NAME="eth3"
# PCI device 0x8086:0x105e (e1000e)
BUS=="net", DRIVER=="?*", SYSFS{address}=="68:05:ca:12:e0:c4", NAME="eth6"
d)之后的udev事件则通过规则B文件来匹配,故完成了重命名
3)做完2之后,进行了大量的测试,发现存在了一个问题,概率很大:也就是重命名失败了,原因是和系统分配的端口名相同,起冲突了
分析这个冲突问题:
1)首先我们有三块网卡,两种驱动
2)udev开启,扫描设备,加载驱动,内核给设备命名
3)假如内核命名的eth0 驱动是e1000e,进入了udev的规则,我们要给它改成eth3
4)但是在eth0进入udev没修改成eth3的时候,内核又将一个网络端口设备命名为eth3
5)则我们将eth0修改为eth3的时候,就会冲突,eth0 变成了eth3_rename
4)针对3)的问题,在init.d的网络服务启动之前(network),即在network脚本里靠前部分,加入一段代码,用于处理_rename问题。
1)通过ifconfig查找当前的端口名(显示全部 加参数-a)
2)通过1)查找的端口名和规则B进行比对,出现问题,则进行修改
四、以上就是对于外置网卡的处理过程,欢迎大家一起讨论。转载请注明出处!!http://www.cnblogs.com/yuzhaoxin/p/4083760.html
标签:blog http sp 文件 on 问题 log 代码 bs
原文地址:http://www.cnblogs.com/yuzhaoxin/p/4083760.html