歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Linux bonding的初始狀態問題以及解決

Linux bonding的初始狀態問題以及解決

日期:2017/2/28 14:54:01   编辑:Linux教程

問題:

Linux下啟動一個bonding網卡,往其裡面添加兩個根本就沒有插著網線的網卡,拉起該bonding後,ifconfig發現其有RUNNING標志,然後將其一個slave插上網線再拔掉,ifconfig就沒有RUNNING標志了。

分析:

這個問題實際上無傷大雅,只是在第一次欺騙一下OS而已,然而卻會影響到keepalived的track_interfaces配置,進而影響基於VRRP的熱備切換,導致擁有沒有插著網線的機器的熱備組中的若干台機器一旦重啟,其熱備狀態就會混亂。沒有插線的機器無論如何也不能是MASTER,可是keepalived看到了bonding網卡的RUNNING標志,誤認為其已經可以使用,進而可能成為MASTER狀態。

解析與修正:

如果僅僅為了短平快的解決當下問題,那麼最簡單不過的就是將keepalived中基於RUNNING的判斷換成基於LOWER_UP的判斷,LOWER_UP就是標識網卡有沒有插線的(但不絕對,還可能受別的因素影響,但是大多數情況-顯然並非全部情況下可以這麼認為),事實證明這是完全可以的,問題解決了。但是卻違反了track_interfaces的初衷,因此這種改法不好!

在徹底修正這個問題之前還是需要了解網卡的各種狀態以及層次。總體來講,網卡state分為管理state和操作state。

管理state:這個狀態是自上而下配置的,表示管理員的意願

操作state:這個state是網卡自身現狀,表示網卡目前是否已經准備好並且有能力為用戶服務。

現在看看Linux系統中網卡的各種state:

IFF_LOWER_UP-線纜已經接好且上電

IFF_RUNNING-操作state是UP(那麼什麼時候操作state會是DOWN呢?1.在管理state為DOWN的時候,即管理員用命令down了網卡;2.網卡沒有插線

理解了這些狀態之後,即使沒有keepalived,狀態也不會,這就不是熱備切換的問題了,keepalived並沒有錯,即便是修正了keepalived,那麼bonding還是會影響到其它使用它的程序的...正是bonding驅動的bug導致了狀態判斷錯誤。

bond_open的返回值是0,因此bonding網卡默認就是START狀態的,因為在物理網卡enslave進bonding網卡的時候需要bonding網卡是IF_UP狀態的。可以在bond_enslave的最後看到一個頻繁調用的函數:bond_set_carrier。該函數判斷bonding網卡的所有slave的狀態,如果全部為DOWN,則將bonding本身也設置成DOWN。這應該是一個周期調用的函數,調用周期取決於bonding的miimon參數,另外在幾個關鍵點也會調用bond_set_carrier,比如在新的slave被bongding的時候,即調用bond_enslave的時候。基本上bond_set_carrier的邏輯是這樣的:

static int bond_set_carrier(struct bonding *bond)
{
struct slave *slave;
int i;

if (bond->slave_cnt == 0)
goto down;

if (bond->params.mode == BOND_MODE_8023AD)
return bond_3ad_set_carrier(bond);
//遍歷所有的slave,只要有一個UP,那麼bonding就UP
bond_for_each_slave(bond, slave, i) {
if (slave->link == BOND_LINK_UP) {
if (!netif_carrier_ok(bond->dev)) {
netif_carrier_on(bond->dev);
return 1;
}
return 0;
}
}

down:
if (netif_carrier_ok(bond->dev)) {
netif_carrier_off(bond->dev);
return 1;
}
return 0;
}

Copyright © Linux教程網 All Rights Reserved