1. 程式人生 > >淺談 NCSI 及其在 Linux 上的實現

淺談 NCSI 及其在 Linux 上的實現

NCSI(Network Controller Sideband Interface)是一個由分散式管理任務組(Distributed Management Task Force, DMTF)定義的用於支援伺服器帶外管理的邊帶介面網路控制器的工業標準,由一個管理控制器和多個網路控制器組成。DMTF 為 NCSI 定義了完整的基於乙太網的控制命令請求和應答標準,此外,NCSI 還具備單執行緒,超時重傳等機制。本文結合NCSI標準,簡單演示了在 Linux 網路協議棧中註冊、初始化 NCSI 協議,並且利用 socket 介面實現一個完整的 NSCI 操作的過程。
1 評論:
王 俊元, 軟體工程師, IBM
王 寒芷, 軟體工程師, IBM
2011 年 12 月 14 日
expand
內容


在 IBM Bluemix 雲平臺上開發並部署您的下一個應用。
開始您的試用
引言
網路技術的飛速發展使得人們對於伺服器的帶外可管理性及可控制性提出了更高的要求。通過帶外管理,工程師可以在任意地點通過網路連線到相應的伺服器上,進行一系列的管理與維護,而不再需要長時間駐守在嘈雜的實驗室環境中。NCSI(Network Controller Sideband Interface)就是一個由分散式管理任務組(Distributed Management Task Force, DMTF)定義的用於支援伺服器帶外管理的邊帶介面網路控制器的工業標準。
回頁首
NCSI 的簡單介紹
一般地,伺服器的網路管理模組結構如圖 1 所示:
圖 1. 伺服器的網路管理模組結構圖
圖 1. 伺服器的網路管理模組結構圖
它主要包括:一個管理控制器(Management Controller, MC),一個或多個(NCSI 的電氣特性最多支援 4 個)網路控制器(Network Controller, NC)。網路控制器一方面連線了外部網路介面與內部主機介面,另一方面,又與管理控制器之間有一個帶外介面。
通過帶外介面的網路資料包主要分為兩類:一類是在外部網路與管理控制器之間傳輸的普通資料包,網路控制器對於這類資料包只作轉發處理;另一類是在管理控制器與網路控制器之間傳輸的攜帶控制資訊的資料包,他們往往是管理控制器對網路控制器配置的一些修改操作,對於這類資料包,網路控制器需要做出相應的響應。而管理控制器與網路控制器之間的帶外介面的電氣性質以及通訊協議,就是由 NCSI 來定義的。
此外,NCSI 還提供了相應的傳輸協議棧來保證這種帶外管理。NCSI 的傳輸協議棧如圖 2 所示:
圖 2. NCSI 的傳輸協議棧
圖 2. NCSI 的傳輸協議棧
從圖 2 中可以看到:
在 NCSI 的傳輸協議棧中,位於最底層的是物理層,NCSI 的物理層是基於 RMII 介面的;
位於物理層之上的是資料鏈路層,NCSI 的資料鏈路層是基於以太介質的;
NCSI 支援的位於資料鏈路層之上的協議主要有兩種:一種是管理控制器與網路控制器之間互動的 NCSI 命令協議,另一種是管理控制器與外部網路通訊的網路資料協議,如:ARP 協議、DHCP 協議、NetBIOS 協議等,它們只是被網路控制器在管理控制器和外部網路之間作轉發處理。在本文中,我們著重討論第一種協議,也就是控制命令協議。
回頁首
NCSI 控制命令協議
NCSI 控制命令允許管理控制器初始化、規範化自己的 NCSI 介面流量,配置 NCSI 通道過濾規則以及監控網路控制器的執行狀態。作為 NCSI 控制命令協議的主體,管理控制器是所有控制命令的發起者,而網路控制器則響應管理控制器傳送的控制命令。
NCSI 例項號(IID)
所有通過 NCSI 命令傳送的 NCSI 請求都有一個唯一的識別符號 Instance ID(IID)。IID 是一個 8 位元長的標識序列。每個 NCSI 響應包的 IID 都等於所對應的 NCSI 請求包的 IID。通過使用 IID,可以有效地識別新的 NCSI 請求,提高 NCSI 請求與響應匹配的魯棒性,並且區分新的 NCSI 請求與超時重傳的 NCSI 請求。
網路控制器在收到標記有 IID 的 NCSI 請求時,會遵循如下的操作原則:
在響應的包的相應位置會標記有該 NCSI 響應對應的 NCSI 請求的 IID。
如果收到的 NCSI 請求的 IID 與之前收到的相同,則表明這是一個超時重發的 NCSI 請求。NCSI 標準規定,此時網路控制器必須對重發的 NCSI 請求作出響應。網路控制器可以根據具體的 NCSI 命令,返回前一次 NCSI 命令的執行結果,如果該執行結果在當前時刻還沒有失效。或者,網路控制器也可以重新在當前時刻再執行一遍 NCSI 命令。
如果收到的 NCSI 請求的 IID 與之前收到的不同,則網路控制器必須將這個請求看成是一個新的 NCSI 請求。
對於一個被重新初始化的網路控制器而言,它所收到的第一個 NCSI 請求一定是一個新的請求,而不管他在沒有被重新初始化前是否收到具有相同 IID 的 NCSI 請求。
對於管理控制器而言,它在處理 IID 時遵循如下原則:
每個新的 NCSI 請求例項必須有與之前不同的 IID。
如果一個 NCSI 請求需要被重傳,則其 IID 必須與之前的 NCSI 請求的 IID 相同。
由於 NCSI 響應包的 IID 等於其對應的 NCSI 請求包的 IID,所以 IID 可以進一步被管理控制器用作確認某個特定的 NCSI 請求是否被響應的標誌。
單執行緒機制
就目前而言,網路控制器只能以單執行緒的方式支援 NCSI 命令。也就是說,網路控制器一次只能夠執行一個 NCSI 命令。只有當它對收到的某個 NCSI 請求傳送了響應包之後,才能夠繼續接受下一個 NCSI 請求。
網路控制器的這種單執行緒機制使得管理控制器在對同一個網路控制器傳送 NCSI 請求時也只能以單執行緒方式進行。當管理控制器向某個網路控制器傳送了一個 NCSI 請求後,它必須保持等待狀態,直到收到了網路控制器發出的 NCSI 響應或者超時重傳為止。
超時重傳機制
如果在 NCSI 命令超時的時間間隔內,管理控制器還沒有收到網路控制器回覆的 NCSI 響應,則管理控制器必須以相同的 IID 重發之前的 NCSI 請求。
管理控制器必須嘗試 NCSI 請求至少 3 次,才能夠報告網路控制器發生了錯誤。
在網路環境相對惡劣的情況下,可能管理控制器在收到之前傳送的 NCSI 請求的響應的時候,已經超過了超時重發的時間間隔。在這種情況下,管理控制器會收到對於同一個 NCSI 請求的兩個響應。管理控制器必須有相應的機制能夠檢測出這第二個 NCSI 響應,並且將它丟棄。
非同步事件通告包
AEN(Asynchronous Event Notification)包是網路控制器在某些狀態發生變化、且影響其介面正常工作的情況下向管理控制器主動傳送的通告資料包。由於 NCSI 命令只是網路控制器處理的眾多資料包中的一小部分,網路控制器的一系列事件都會影響到命令的正常執行。這些事件包括:鏈路狀態變化、作業系統驅動載入及解除安裝、晶片復位等等。
網路控制器對哪些事件會向管理控制器傳送 AEN 包是由管理控制器來定義的,管理控制器通過使用控制位(control bit),可以單獨地定義網路控制器對各個事件的非同步事件通告是否啟用。
AEN 包是工作在 NCSI 請求 - 應答機制之外的一種 NCSI 包。也就是說,AEN 包既不是 NCSI 請求,也不是任意 NCSI 請求的響應。AEN 包沒有應答,即使一個 AEN 包在傳輸的過程中丟失了,管理控制器也無從得知。
一個 AEN 包的 IID 始終為 0x00。
回頁首
NCSI 包結構
NCSI 的乙太網幀頭
正如前文所述,NCSI 是基於以太介質的。所有的 NCSI 包都是封裝在 IEEE 802.3 定義的乙太網幀格式中的,即:任意一個 NCSI 包都被封裝在 14 位元組的乙太網頭及 4 位元組的乙太網尾中,如圖 3 所示:
圖 3. NCSI 包的以太幀格式
圖 3. NCSI 包的以太幀格式
目的地址欄位:
NCSI 以太幀的第 0 到 5 位元組分別代表乙太網目的地址的第 5 到 0 位元組。由於傳輸 NCSI 命令的通道並沒有被分配一個特定的 MAC 地址,所以 NCSI 以太幀的目的地址為廣播地址(FF:FF:FF:FF:FF:FF)。
如果網路控制器收到了一個目的地址不是 FF:FF:FF:FF:FF:FF 的 NCSI 包,則它會直接丟棄該資料包並且返回一個錯誤響應。
源地址欄位:
NCSI 以太幀的第 6 到 11 位元組分別代表乙太網源地址的第 5 到 0 位元組。如果 NCSI 包來自於管理控制器,那麼源地址欄位可以為任意值。如果 NCSI 包來自於網路控制器,則源地址欄位必須為 FF:FF:FF:FF:FF:FF。
型別欄位:
NCSI以太幀的第 12、13 位元組分別代表乙太網型別的第 1、0 位元組。對於NCSI 控制包而言,其型別欄位為 0x88F8。
NCSI 控制包頭
每個 NCSI 包(包括 NCSI 請求包、響應包以及 AEN 包)都有一個 16 位元組長的控制包頭,以大端在先順序排列,如圖 4 所示:
圖 4. NCSI 控制包頭格式
圖 4. NCSI 控制包頭格式
Management Controller ID(MC ID)欄位
MC ID 欄位 1 位元組長,標識了 NCSI 包對應的管理控制器。在 NCSI 1.0.0a 版本中,該位元組規定為 0x00。
網路控制器每收到一個管理控制器發出的 NCSI 請求時都必須將請求包中的 MC ID 欄位拷貝到響應包的 MC ID 欄位中。
Header Revision 欄位
Header Revision 欄位 1 位元組長,標識了 NCSI 命令包頭的版本號。在 NCSI 1.0.0a 版本中,該位元組規定為 0x01.
IID 欄位
IID 欄位 1 位元組長。正如上文所述,網路控制器可以用 IID 來辨別當前 NCSI 命令是一個新的請求還是一個超時重傳的請求;管理控制器可以用 IID 來確認某個特定的 NCSI 請求是否得到了相應。
Command 欄位
Command 欄位 1 位元組長,用於標識特定的 NCSI 命令請求與響應。每個 NCSI 請求命令都對應著 0x00 到 0x7F 之間唯一的一個命令號,而對該 NCSI 請求包的響應的命令號就是把 NCSI 請求的命令號的最高位置為 1,這樣就建立了 128 個 NCSI 請求命令與相應的 128 個 NCSI 響應命令之間的一一對應關係。
Channel ID 欄位
Channel ID 欄位 1 位元組長。每個 NCSI 管理控制器可以對應一個或者多個 package,這些 package 可以屬於同一個網路控制器,也可以屬於不同的網路控制器。每個 package 的內部又可以定義一個或者多個通道(channel)。所有的 NCSI 資料包都是在某個特定的 channel 中傳輸的,Channel ID 欄位就標識了當前 NCSI 資料包所在的 channel。
Payload Length 欄位
Payload Length 欄位 12 位元長,標識了緊隨 NCSI 包頭之後的 NCSI 載荷的長度。
Reserved 欄位
圖中標有 Reserved 的區域均為保留欄位,通常被置為 0。
NCSI 控制包載荷
NCSI 控制包載荷的資料都是按照大端在先的順序排列的,包括資料、載荷填充、校驗和以及以太包填充 4 部分,如圖 5 所示:
圖 5. NCSI 控制載荷格式
圖 5. NCSI 控制載荷格式
資料(Data)部分:
NCSI 請求不含 Data 部分。
每個 NCSI 響應都有 2 位元組的響應值和 2 位元組的原因值。對於某些 NCSI 命令的響應,還有一定長度的附加資訊。
載荷填充部分:
如果 NCSI 的 Data 部分長度不是 4 位元組的整數倍,那麼就需要將其填充為 4 位元組的整數倍。所有的填充值均為 0x00.
校驗和部分:
校驗和部分 4 位元組長。管理控制器和網路控制器可以利用校驗和部分來對 NCSI 包進行校驗,也可以將校驗和部分設為全 0,從而表明該 NCSI 包不需要校驗。
以太包填充部分:
根據 IEEE 802.3 標準,所有的以太幀長度必須大於 64 位元組,也就是說,NCSI 包頭和 NCSI 載荷的長度之和必須大於 46 位元組。事實上,大部分的 NCSI 包都無法滿足這一條件。因此,幾乎所有的 NCSI 包的末尾都需要作一定長度的填充。
AEN 包格式
NCSI 的 AEN 包格式如圖 6 所示:
圖 6. AEN 包格式
圖 6. AEN 包格式
傳送 AEN 包的網路控制器需要在 NCSI 包頭的 Channel ID 欄位裡標識發生相應事件的 channel 號。
AEN 包的 NCSI 頭的 IID 欄位始終為 0x00,command 欄位始終為 0xFF,Payload Length 欄位始終為 0x04,也就是說 AEN 包的 NCSI 載荷長度為 4。
AEN 包的 NCSI 載荷中 3 位元組為保留欄位,另外一個位元組為 AEN 型別欄位,對應的含義如表 1 所示:
表 1. AEN 型別值與含義的對應關係
AEN型別值含義
0x00鏈路狀態發生了改變
0x01需要對網路控制器進行配置
0x02網路控制器驅動的狀態發生了改變
0x03 ~ 0x7F保留
0x80 ~ 0xFF各廠商自定義的 AEN 事件


回頁首
NCSI 在 Linux 上的簡單實現
硬體支援
要實現 NCSI,首先需要選擇支援 NCSI 的 NIC,目前大部分網路晶片廠商都有支援 NCSI 的產品,比如 Broadcom 的 BCM57710,Intel 的 Intel82576 等。
在 Linux 網路協議棧中初始化 NCSI 協議族
在 Linux 的網路協議棧中初始化 NCSI 協議族需要了解 Linux 的網路協議棧,這不是本文討論的重點,本節只是簡單介紹在 Linux 網路協議棧的三個層面(Socket 層、Sock 層和 sk_buff 層)上初始化 NCSI 介面。之所以只是介紹這三層,是因為 socket{}、sock{}、sk_buff{} 是 Linux 網路協議棧中最重要的資料結構,也是資料流的連線通道。比如,傳送報文時,資料會由 socket{} 通過相應的 proto_ops{} 把資料傳給 sock{},sock{} 又通過 proto{} 把資料傳到 sk_buff;反過來,當收到報文時,sk_buff{} 通過 net_protocol{} 把資料傳給 sock{},後者又通過 proto{} 把資料傳給 socket{},socket{} 最後把資料傳給使用者層,有關這方面具體詳細細節在這裡不做過多贅述。
Socket 層,註冊 net_proto_family 結構體
清單 1. 註冊 net_proto_family 結構體到全域性陣列 net_families 中
 #define PF_NCSI    27  /* NCSI Address Family */ 
 static struct net_proto_family ncsi_family_ops = { 
      .family =  PF_NCSI, 
      .create =  ncsi_create, 
      .owner  =  THIS_MODULE, 
 }; 
 sock_register(&ncsi_family_ops);
Sock 層,填充 proto_ops 結構體,該結構體的成員變數是一些函式指標,分別對應了 NCSI 操作的函式。
清單 2. 填充 proto_ops 結構體
 static struct proto_ops ncsi_ops = { 
       .family =  PF_NCSI, 
       .owner =  THIS_MODULE, 
       .release =  ncsi_release, 
       .bind =    sock_no_bind, 
       .connect =  sock_no_connect, 
       .socketpair =  sock_no_socketpair, 
       .accept =  sock_no_accept, 
       .getname =  sock_no_getname, 
       .poll =    sock_no_poll, 
       .ioctl =  sock_no_ioctl, 
       .listen =  sock_no_listen, 
       .shutdown =  sock_no_shutdown, 
       .setsockopt =  sock_no_setsockopt, 
       .getsockopt =  sock_no_getsockopt, 
       .sendmsg =  ncsi_sendmsg, 
       .recvmsg =  ncsi_recvmsg, 
       .mmap =    sock_no_mmap, 
       .sendpage =  sock_no_sendpage, 
 };
sk_buff 層,實現從 NIC 接收 NCSI packet 的功能,其中 ncsi_rcv 是從 NIC 中接收 RAW packet 的介面。
清單 3. 實現從 NIC 接收 NCSI packet 的功能
 #define NCSI_PROTOCOL 0x88F8 
 static struct packet_type ncsi_packet_type = { 
      .type =    __constant_htons(NCSI_PROTOCOL), 
      .func =    ncsi_rcv, 
 }; 
 dev_add_pack(&ncsi_packet_type);
利用套接字 socket 實現 NCSI 的操作
在 Linux 的網路協議棧中初始化了 NCSI socket 的三元組:< 地址族,型別,具體協議 >,也正好是呼叫 socket 系統函式的 3 個引數。核心中這 3 個數據結構,就可以建立 sock{} 結構。
首先,在利用套接字實現 NCSI 操作之前,為了提高程式的通用性和易讀性、減少不一致性,需要對 NCSI 協議族進行巨集定義:
清單 4. 對 NCSI 協議族進行巨集定義
 #define AF_NCSI    27  /* NCSI 地址族定義 */
其次,為了便於對 NCSI 包頭進行整體性操作,這裡根據前文所述的 NCSI 包格式,定義了 NCSI 的包頭結構 ncsihdr:
清單 5. NCSI 包頭結構的定義
 /* NCSI 包頭結構的定義 */ 
 struct ncsihdr { 
  unsigned char mc_id; 
  unsigned char hdr_rev; 
  unsigned char reserved0; 
  unsigned char cmd_iid; 
  unsigned char cmd; 
  unsigned char chnl_id; 
  unsigned short payload_len; 
  unsigned int reserved2; 
  unsigned int reserved3;  
 };
從根本上說,NCSI 主要包括 4 種原子操作:建立 NCSI socket、關閉 NCSI socket、向已建立的 NCSI socket 傳送 NCSI 命令以及從已建立的 NCSI socket 獲得 NCSI 響應。一個最簡單的 NCSI 命令操作流程如圖 7 所示:
圖 7. 一個最簡單的 NCSI 命令操作流程圖
圖 7. 一個最簡單的 NCSI 命令操作流程圖
其他任意操作都可以通過使用這 4 種原子操作的組合來實現。為簡單起見,本文僅對這 4 中最基本的 NCSI 操作給出了在 linux 下的相應實現,而對於由這 4 種操作引申而出的其它複雜操作就不做過多的贅述了。
(1) 建立 NCSI socket:
清單 6. 建立 NCSI socket
 int OpenNCSISocket () 
 { 
 // 呼叫 socket 函式建立一個能夠進行網路通訊的套接字:協議族為 AF_NCSI,套接字型別為 SOCK_RAW 
    sd = socket(AF_NCSI, SOCK_RAW, 0); 
    if (sd < 0) 
    { 
        cout << "NCSI socket creation failed" << endl; 
        return -1; 
    }    
    return sd; 
 }
(2) 關閉 NCSI socket:
清單 7. 關閉 NCSI socket
 int CloseNCSISocket(int sd) 
 { 
    close(sd);    // 呼叫 close 函式關閉已建立的套接字
    return 0; 
 }
(3) 向已建立的 NCSI socket 傳送 NCSI 命令:
清單 8. 向已建立的 NCSI socket 傳送 NCSI 命令
 int SendRawNCSIPacket( int sd,      // 已建立的 NCSI socket 
                      int Port_Num,    //NCSI 命令傳送到的乙太網介面號
                       unsigned char cmd,    //NCSI 命令號
                       unsigned char channel_id,  // 承載 NCSI 命令的通道號
                       unsigned char *pu8Data,  // 指向 NCSI 載荷的指標
                       unsigned short data_length//NCSI 載荷的長度
                    ) 
 { 
      int status; 
      struct ncsihdr *ncsih;      //NCSI 包頭
      struct iovec xmit_iovec[2];    // 建立 linux I/O 向量 iovec 結構陣列
      struct msghdr xmit_message;     // 建立 linux 資訊頭 msghdr 結構陣列
  unsigned char pkt_buffer[60];      // 傳送緩衝區
  unsigned char *ncsi_payload ;    //NCSI 載荷指標


 // 封裝乙太網幀頭
  memset(pkt_buffer, 0, 60); 
  memset(pkt_buffer, 0xff, 12);      // 目的地址和源地址均為 0xFF FF FF FF FF FF 
  pkt_buffer[12] = 0x88; 
  pkt_buffer[13] = 0xf8;            // 乙太網幀頭型別欄位為 0x88f8,表示 NCSI 命令


 // 封裝 NCSI 包頭
 ncsih = (struct ncsihdr *) (pkt_buffer+14); 
  ncsih->mc_id = 0x0;      // 設定管理控制器 ID 為 0x0 
  ncsih->hdr_rev = 0x1;      // 設定 NCSI 頭版本號圍 0x1 
  ncsih->cmd_iid = inciid();     // inciid() 是一個函式,用於獲得當前傳送資料包的 instance id 
  ncsih->cmd = cmd;      // 設定 NCSI 命令的命令號
  ncsih->chnl_id = channel_id;    // 設定 NCSI 命令傳輸的通道號
  // 設定 NCSI 載荷的長度。由於網路位元組序使用的都是大端模式,所以要呼叫 htons 進行相應的轉換
  ncsih->payload_len = htons(data_length);


 // 封裝 NCSI 載荷
  ncsi_payload = (unsigned char *)(pkt_buffer + 14 + sizeof(struct ncsihdr)); 
  if ( (pu8Data!=NULL) && (data_length!=0) ) 
  { 
            memcpy(ncsi_payload, pu8Data, data_length); 
  } 


  // 封裝 xmit_message 
  xmit_message.msg_name = NULL; 
  xmit_message.msg_namelen = 0; 
  xmit_message.msg_iov = xmit_iovec; 
  xmit_message.msg_iov[0].iov_base = (void *)&Port_Num; 
  xmit_message.msg_iov[0].iov_len = sizeof(int); 
      xmit_message.msg_iov[1].iov_base = (void *)pkt_buffer; 
  xmit_message.msg_iov[1].iov_len = 60; 
  xmit_message.msg_iovlen = 2; 
  xmit_message.msg_control = NULL; 
  xmit_message.msg_controllen = 0; 
  xmit_message.msg_flags = 0; 


 // 呼叫 linux 的 sendmsg 傳送 NCSI 請求
  status = sendmsg(sd, &xmit_message, 0); 
      return status; 
 }
(4) 從已建立的 NCSI socket 獲得 NCSI 響應:
清單 9. 從已建立的 NCSI socket 獲得 NCSI 響應
 int RecvRawNCSIPacket( int sd,        // 已建立的 NCSI socket 
                       unsigned char *pu8NCSIpacket,  // 用於存放接收資料的緩衝區
                       int buf_size,        // 接收緩衝區的大小
                       int *Port_Num,      // 接收 NCSI 響應的乙太網介面號
                       int wait_time        // 等待時間,單位毫秒
             ) 
 { 
      int status; 
 struct msghdr recv_message;    // 建立 linux 資訊頭 msghdr 結構陣列
 struct iovec recv_iovec[3];    // 建立 linux I/O 向量 iovec 結構陣列


 if ( (NULL == pu8NCSIpacket) || (0 == buf_size ) 
       return -1; 


  // 封裝 recv_message 
 recv_message.msg_name = NULL; 
 recv_message.msg_namelen = 0; 
 recv_message.msg_iov = recv_iovec; 
 recv_message.msg_iov[0].iov_base = (void *)&wait_time; 
 recv_message.msg_iov[0].iov_len = sizeof(int); 
 recv_message.msg_iov[1].iov_base = (void *) pu8NCSIpacket; 
 recv_message.msg_iov[1].iov_len = buf_size; 
 recv_message.msg_iov[2].iov_base = (void *)Port_Num; 
 recv_message.msg_iov[2].iov_len = sizeof (int *); 
 recv_message.msg_iovlen = 3; 
 recv_message.msg_control = NULL; 
 recv_message.msg_controllen = 0; 
 recv_message.msg_flags = 0; 


 // 呼叫 linux 的 recvmsg 接收 NCSI 響應
 status = recvmsg(sd, &recv_message, 0); 
 return status; 
 }
回頁首
總結
本文結合 DMTF 的 NCSI 標準,對 NCSI 的控制命令協議以及包結構作了詳細的描述,並在此基礎之上,進一步簡單演示了在 Linux 網路協議棧中註冊、初始化 NCSI 協議,並且利用 socket 介面實現一個完整的 NSCI 操作的過程,希望能夠為使用 NCSI 標準進行帶外管理的網路管理人員及 linux 網路程式設計愛好者提供有益的參考。
參考資料
學習
Network Controller Sideband Interface (NC-SI) Specification (2007-06-26, 1.0.0a). 該手冊詳盡地介紹了 DMTF 的 NCSI 標準。
《Understanding Linux Network Internals》這本書詳細介紹了 Linux 核心網路協議棧的框架,介面以及資料流的傳送,接收過程等。
在 developerWorks Linux 專區 尋找為 Linux 開發人員(包括 Linux 新手入門)準備的更多參考資料,查閱我們 最受歡迎的文章和教程。
在 developerWorks 上查閱所有 Linux 技巧 和 Linux 教程。
訪問 developerWorks Lotus 專區。

隨時關注 developerWorks 技術活動和網路廣播。

from: http://www.ibm.com/developerworks/cn/linux/l-cn-ncsi/

相關推薦

NCSI 及其Linux 實現

NCSI(Network Controller Sideband Interface)是一個由分散式管理任務組(Distributed Management Task Force, DMTF)定義的用於支援伺服器帶外管理的邊帶介面網路控制器的工業標準,由一個管理控制器和多個

simhash及其python實現

轉自http://blog.csdn.net/madujin/article/details/53152619 2016-11-13 21:52 1479人閱讀 評論(0) 收藏 舉報 作者原創,轉載請註明出處。 一直想寫個總結來回顧simhash,一直沒抽

URI 及其轉義

replace 標識符 typedef 字符轉義 from always cif subject 自身 URI URI,全稱是 Uniform Resource Identifiers,即統一資源標識符,用於在互聯網上標識一個資源,比如 https://www.upyun.

如何在Linux實現:Eureka服務的開機自啟動?

參數 src class blog nohup echo 創建文件 too hup 【問題描述】   由於最近在使用Spring Eureka的註冊中心服務,而辦公室每天晚上要斷電,每天早上過來後需要手工啟動Eureka服務非常麻煩。   需要實現:開機自動該服務的功能。

雲計算發展歷程的,學習Linux運維

雲計算雲計算是一個提供便捷的通過網絡訪問一個可定制的IT資源共享池能力的按使用量付費的模式(IT資源包括網絡,服務器,存儲,應用,服務),這些資源能夠快速部署,並只需要很少的管理工作或很少的服務供應商的交互。 ×××老師簡單地說:雲計算是一種未來信息技術的一種主要架構,服務雲+消費端。雲端通過集中的資源提供各

Linux實現ssh免密碼登陸遠程服務器

Linux上實現ssh免密碼登陸遠程服務平常使用ssh登陸遠程服務器時,都需要使用輸入密碼,希望可以實現通過密鑰登陸而免除輸入密碼,從而可以為以後實現批量自動部署主機做好準備。 環境如下: IP地址 操作系統 服務器端 10.0.0.10 CentOS 6.5 x86 客戶端 10.0.0

1.3Spring(IOC容器的實現)

tap 就是 parser pojo file abstract throw cdd moni 這一節我們來討論IOC容器到底做了什麽。 還是借用之前的那段代碼 ClassPathXmlApplicationContext app = new ClassPathXmlAp

分散式鎖--基於Zookeeper實現

淺談分散式鎖--基於Zookeeper實現篇: 1、基於zookeeper臨時有序節點可以實現的分散式鎖。其實基於ZooKeeper,就是使用它的臨時有序節點來實現的分散式鎖。 來看下Zookeeper能不能解決前面提到的問題。     鎖無法釋放:使用

分散式鎖--基於資料庫實現

淺談分散式鎖--基於資料庫實現篇 1、基於資料庫表     要實現分散式鎖,最簡單的方式可能就是直接建立一張鎖表,然後通過操作該表中的資料來實現了。     當我們要鎖住某個方法或資源時,我們就在該表中增加一條記錄,想要釋放鎖的

JavaScript模擬$(HTML字串)實現建立DOM物件

JavaScript裡動態建立標準DOM物件一般使用:document.createElement()方法。 但在實際使用過程中,可能會希望直接根據HTML字串建立DOM節點,模擬$(HTML字串)建立DOM物件的方法。 1、思路: ① 用document.createElement()

Android與Linux系統的差異

最近忙於查詢Linux和android平臺的資料,今天將其整理整理,根據本人拙見分享給大家。 Android和Linux作為現行主流的作業系統,無論在消費類產品還是在工控領域,都有廣泛的應用。都說Android系統是脫胎於Linux系統,那麼是不是Android是不是屬於Linux的一種

CentOS 下安裝openOffice,並在Linux實現office轉PDF

安裝openOffice 前提是系統已經安裝好java環境,網上很多需要解除安裝系統自帶java環境的,我覺得沒必要,直接使用也ok。 進入下載的openOffice所在目錄,執行(tar -zxvf Apache_OpenOffice_4.1.5_Linux

[轉]資料庫設計技巧()、(下)(必須要仔細閱讀)

淺談資料庫設計技巧(上)   說到資料庫,我認為不能不先談資料結構。1996年,在我初入大學學習計算機程式設計時,當時的老師就告訴我們說:計算機程式=資料結構+演算法。儘管現在的程式開發已由面向過程為主逐步過渡到面向物件為主,但我還是深深贊同8年前老師的告訴我們的公式:計算機程式=資料結構+演算

instanceof 和 typeof 的實現原理

typeof 實現原理 typeof 一般被用於判斷一個變數的型別,我們可以利用 typeof 來判斷number, string, object, boolean, function, undefined, symbol 這七種型別,這種判斷能幫助

關聯規則以及Apriori演算法matlab實現

關聯規則分析也叫做購物籃分析,最早是為發現超市銷售資料庫中不同商品之間的關聯關係。例如一個超市的經理想要更多的瞭解顧客的購物習慣,比如“哪組商品可能會在一次購物中同時被購買?”或者“某顧客購買了個人電腦,那該顧客三個月後購買數碼相機的概率有多大?”他可能會發現如

windows和linux下記憶體分配規律

首先先說明下,本文中程式碼來自牛刀教程。寫的很不錯。給我不少的啟發。謝謝了 我們都知道,在使用C語言時,比如定義一個數組,一個變數。那麼系統都會隨機的分配記憶體。那麼你知道記憶體分配的規律嗎? 讓我們用兩個實驗來說明windows和linux下,記憶體分配方式的不同。 同一

md5加密 以及C++實現

md5加密是我們生活中十分常見的加密演算法。 起因:我是最近在寫一個H5 的專案時接觸到的這個演算法,這個演算法極大的引起了我的好奇心,是登陸介面,要求是將使用者輸入的密碼使用md5加密之後,再傳回伺服器,當時我十分不理解原因是什麼. 廢話少說 原因

利用forever在Linux實現Node.js專案自啟動

在一臺計算機上手動跑Node專案簡單,node xx.js就搞定了,想讓Node專案後臺執行,雖然不能直接用node命令搞定,但是在安裝了forever這個包以後,還是很輕鬆的。不過要是在遠端伺服器上構建Node專案,如果沒法自啟動,一旦伺服器重啟,那麼專案必須通過管理員遠

實人認證程式實現

淺談實人認證的技術可行性和驗證必要性 之前的實名認證模式是使用者手動上傳手持身份證照片,後臺管理員來稽核。無法做到實時認證,且需要人力成本。 實人認證模式 : 身份證照片 本人自

TIDB及其整體架構 | docker-compose單機部署TIDB叢集 | 多臺主機使用docker部署TIDB叢集 | 網路容器的作用

TiDB 是 PingCAP 公司設計的開源分散式 HTAP (Hybrid Transactional and Analytical Processing) 資料庫,結合了傳統的 RDBMS 和 NoSQL 的最佳特性。TiDB 相容 MySQL, 支援無限的水平擴充套件,