標籤: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
插入外置網卡連接埠順序混亂--linux系統