在 C 語言中,errno 是一個全局變量,用于存儲最近發(fā)生的系統(tǒng)調(diào)用或庫函數(shù)調(diào)用的錯誤代碼。正確使用 errno 可以幫助開發(fā)者診斷程序中的錯誤并采取適當?shù)拇胧O旅媸侨绾握_使用 errno 的指南:
首先,需要包含 <errno.h> 頭文件,它定義了 errno 變量以及其他與錯誤相關的宏和常量。
1#include <errno.h>
在調(diào)用可能導致錯誤的函數(shù)之后,應當檢查函數(shù)的返回值,判斷是否出現(xiàn)了錯誤。例如,打開文件的 open() 函數(shù),如果返回 -1 表示發(fā)生錯誤。
1int fd=open("example.txt", O_RDONLY);
2if (fd==-1) {
3 // 出現(xiàn)錯誤
4}
在檢查到錯誤之后,應當立即讀取 errno 的值。這是因為 errno 是一個全局變量,可能會被隨后的系統(tǒng)調(diào)用覆蓋。
1if (fd==-1) {
2 int saved_errno=errno;
3 // 處理錯誤
4}
perror 函數(shù)可以用來打印一個描述錯誤的字符串,通常用于調(diào)試目的。
1if (fd==-1) {
2 perror("Failed to open file");
3}
strerror 函數(shù)可以將 errno 的值轉(zhuǎn)換為人類可讀的錯誤描述字符串。
1if (fd==-1) {
2 const char *error_str=strerror(errno);
3 printf("Failed to open file: %s\n", error_str);
4}
errno 宏可以幫助你確定具體的錯誤原因。例如,EACCES 表示權(quán)限錯誤,ENOENT 表示找不到文件等。
1if (fd==-1) {
2 if (errno==EACCES) {
3 printf("Permission denied\n");
4 } else if (errno==ENOENT) {
5 printf("File not found\n");
6 } else {
7 printf("Other error: %s\n", strerror(errno));
8 }
9}
在處理完錯誤后,可以顯式地將 errno 設置為 0,以清除之前的錯誤狀態(tài)。
1if (fd==-1) {
2 // 處理錯誤
3 errno=0; // 清除錯誤狀態(tài)
4}
下面是一個完整的示例,展示了如何使用 errno 來處理文件打開錯誤:
1#include <stdio.h>
2#include <errno.h>
3#include <string.h>
4#include <fcntl.h>
5
6int main() {
7 int fd=open("example.txt", O_RDONLY);
8 if (fd==-1) {
9 int saved_errno=errno;
10 const char *error_str=strerror(saved_errno);
11 printf("Failed to open file: %s\n", error_str);
12
13 if (saved_errno==EACCES) {
14 printf("Permission denied\n");
15 } else if (saved_errno==ENOENT) {
16 printf("File not found\n");
17 } else {
18 printf("Other error: %s\n", error_str);
19 }
20 } else {
21 // 文件成功打開,可以進行其他操作
22 close(fd);
23 }
24
25 return 0;
26}
通過正確使用 errno,你可以更好地理解和處理 C 語言程序中的錯誤情況。
導致交換機接口出現(xiàn)err-disable的幾個常見原因:
引用
1. EtherChannel misconfiguration
2. Duplex mismatch
style="TEXT-INDENT: 2em">3. BPDU port guard
4. UDLD
5. Link-flap error
6. Loopback error
7. Port security violation
第一個當F EC兩端配置不匹配的時候就會出現(xiàn)err-disable.假設Switch A把FEC模式配置為on,這時Switch A是不會發(fā)送PAgP包和相連的Switch B去協(xié)商FEC的,它假設Switch B已經(jīng)配置好FEC了。但實事上Swtich B并沒有配置FEC,當Switch B的這個狀態(tài)超過1分鐘后,Switch A的STP就認為有環(huán)路出現(xiàn),因此也就出現(xiàn)了err-disable.解決辦法就是把FEC的模式配置為channel-group 1 mode desirable non-silent這個意思是只有當雙方的FEC協(xié)商成功后才建立channel,否則接口還處于正常狀態(tài)。
第二個原因就是雙工不匹配。一端配置為half-duplex后,他會檢測對端是否在傳輸數(shù)據(jù),只有對端停止傳輸數(shù)據(jù),他才會發(fā)送類似于ack的包來讓鏈路up,但對端卻配置成了full-duplex,他才不管鏈路是否是空閑的,他只會不停的發(fā)送讓鏈路up的請求,這樣下去,鏈路狀態(tài)就變成err-disable了。
三、第三個原因BPDU,也就是和portfast和BPDU guard有關。如果一個接口配置了portfast,那也就是說這個接口應該和一個pc連接,pc是不會發(fā)送spanning-tree的BPDU幀的,因此這個口也接收BPDU來生成spanning-tree,管理員也是出于好心在同一接口上配置了BPDU guard來防止未知的BPDU幀以增強安全性,但他恰恰不小心把一個交換機接到這個同時配置了portfast和BPDU guard接口上,于是這個接口接到了BPDU幀,因為配置了BPDU guard,這個接口自然要進入到err-disable狀態(tài)。解決辦法:no spanning-tree portfast bpduguard default,或者直接把portfast關了。
第四個原因是UDLD.UDLD是cisco的私有2層協(xié)議,用于檢測鏈路的單向問題。有的時候物理層是up的,但鏈路層就是down,這時候就需要UDLD去檢測鏈路是否是真的up的。當AB兩端都配置好UDLD后,A給B發(fā)送一個包含自己port id的UDLD幀,B收到后會返回一個UDLD幀,并在其中包含了收到的A的port id,當A接收到這個幀并發(fā)現(xiàn)自己的port id也在其中后,認為這鏈路是好的。反之就變成err-disable狀態(tài)了。假設A配置了UDLD,而B沒有配置UDLD:A給B發(fā)送一個包含自己port id的幀,B收到后并不知道這個幀是什么,也就不會返回一個包含A的port id的UDLD幀,那么這時候A就認為這條鏈路是一個單向鏈路,自然也就變成err-disable狀態(tài)了。
第五個原因就是鏈路的抖動,當鏈路在10秒內(nèi)反復up、down五次,那么就進入err-disable狀態(tài)。
第六個原因就是keepalive loopback.在12.1EA之前,默認情況下交換機會在所有接口都發(fā)送keepalive信息,由于一些不通交換機協(xié)商spanning-tree可能會有問題,一個接口又收到了自己發(fā)出的keepalive,那么這個接口就會變成err-disable了。解決辦法就是把keepalive關了。或者把ios升到12.2SE.
最后一個原因,相對簡單,就是由于配置了port-security violation shutdown.