Linux核心讀取磁碟序列號的問題

2021-09-21 02:50:35 字數 1866 閱讀 6224

一向的觀點就是「別在核心裡面處理字串」!事實上,確實應該如此!

linux核心的塊裝置驅動有能力讀取磁碟的序列號,這個資料儲存在磁碟的控制晶元rom裡面。核心應該以怎樣的形式將這個序列號呈現給呼叫者呢?我們ls一下這個目錄:

/dev/disk/by-id

ll /dev/disk/by-id/

...

lrwxrwxrwx 1 root root 9 10月 17 10:11 scsi-sata_st3500413as_z2a2agqa -> ../../sdb

可以看到,乙個磁碟可以用傳統的/dev/sdx來索引,也可以by-yy來索引,其中by-id就是以序列號來索引,上述輸出中,下劃線後面的就是序列號。同樣,我們可以用hdparm工具程式來讀取,可以讀到同樣的結果。在hdparm的**實現中,我們可以看到如下的**段:

static char *strip (char *s)

static void dump_identity (__u16 *idw)

, dmodes[128]=, umodes[128]=;

char *model = strip(strndup((char *)&idw[27], 40));

char *fwrev = strip(strndup((char *)&idw[23], 8));

char *serno = strip(strndup((char *)&idw[10], 20));

__u8 tpio;

printf("\n model=%.40s, fwrev=%.8s, serialno=%.20s", model, fwrev, serno);

...}

很明顯,在顯示序列號時,strip去掉了首尾的空格,因為空格顯示出來是沒有意義的。這十分正常。然而...

然而在2.6的老版本的核心比如2.6.8版本中,我們看到了do_identify中有下面的呼叫:

ide_fixstring(id->serial_no, sizeof(id->serial_no), bswap);

那麼這個ide_fixstring是幹什麼的呢?它的實現如下,詳細的注釋已經給出了答案:

void ide_fixstring (u8 *s, const int bytecount, const int byteswap)

}/* strip leading blanks */

while (s != end && *s == ' ')

++s;

/* compress internal blanks and strip trailing blanks */

while (s != end && *s)

/* wipe out trailing garbage */

while (p != end)

*p++ = '\0';

}

幾乎是hdparm的strip更加嚴格意義上的翻版!這有什麼問題呢?問題大了。這個核心沒有辦法給使用者呈現乙個原始的磁碟序列號,也就是序列號本身。為何不把處理留給應用程式呢?

linux核心應該迅速返回最原始的二進位制資訊,將解析任務留給應用程式,不光是效率考慮,更多的是核心根本不知道如何去解讀這些資訊!幸運的是,高版本的核心不再處理磁碟序列號了,僅僅返回了原始資訊,不幸的是,它帶來了問題!

要不是工作中遇到了問題,我也不會閒到去折騰什麼塊裝置驅動。系統僅僅公升級了核心,然而公升級前後都需要讀取磁碟序列號和儲存的序列號比對,老版本的核心和新版本核心對磁碟序列號讀取行為的不同導致出現了不同的結果,核心也就不再對應用程式透明了!那怎麼辦?只好修改高版本核心驅動去迎合老版本的錯誤方式了!

相容就是一大萬人坑,埋葬了不知多少精英!

讀取硬體序列號

using system using system.collections.generic using system.text using system.management namespace 讀取序列號 獲取硬碟序列號 string hdid managementclass cimobject1...

讀取硬碟序列號

pragma hdrstop pragma argsused include include include include hdd.h const word ide atapi identify 0xa1 讀取atapi裝置的命令 const word ide ata identify 0xec ...

C 讀取硬碟的序列號

include include include define dfp get version 0x00074080 define dfp send drive command 0x0007c084 define dfp receive drive data 0x0007c088 pragma pac...