玩蛇网提供最新Python编程技术信息以及Python资源下载!
您现在的位置: 玩蛇网首页 > linux入门教程 > 正文内容

如何读取Linux内核磁盘序列号

玩蛇网推荐图文教程:python 列表

关于如何读取Linux内核磁盘序列号,和为什么要读取这些系列号,文中都会讲到。记得以前有人说过,一定别在内核里面处理字符串。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)

{
    char *e;

    while (*s == ' ') ++s;
    if (*s)
        for (e = s + strlen(s); *--e == ' '; *e = '\0');
    return s;
}

static void dump_identity (__u16 *idw)
{
    int i;
    char pmodes[64] = {0,}, dmodes[128]={0,}, umodes[128]={0,};
    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)
{
    u8 *p = s, *end = &s[bytecount & ~1]; /* bytecount must be even */

    if (byteswap) {
        /* convert from big-endian to host byte order */
        for (p = end ; p != s;) {
            unsigned short *pp = (unsigned short *) (p -= 2);
            *pp = ntohs(*pp);
        }
    }
    /* strip leading blanks */
    while (s != end && *s == ' ')
        ++s;
    /* compress internal blanks and strip trailing blanks */
    while (s != end && *s) {
        if (*s++ != ' ' || (s != end && *s && *s != ' '))
            *p++ = *(s-1);
    }
    /* wipe out trailing garbage */
    while (p != end)
        *p++ = '\0';
}

几乎是hdparm的strip更加严格意义上的翻版!这有什么问题呢?
问题大了。这个内核没有办法给用户呈现一个原始的磁盘序列号,也就是序列号本身。为何不把处理留给应用程序呢?

Linux内核应该迅速返回最原始的二进制信息,将解析任务留给应用程序,不光是效率考虑,更多的是内核根本不知道如何去解读这些信息!幸运的是,高版本的内核不再处理磁盘序列号了,仅仅返回了原始信息,不幸的是,它带来了问题!

要不是工作中遇到了问题,我也不会闲到去折腾什么块设备驱动。系统仅仅升级了内核,然而升级前后都需要读取磁盘序列号和保存的序列号比对,老版本的内核和新版本内核对磁盘序列号读取行为的不同导致出现了不同的结果,内核也就不再对应用程序透明了!

怎么解决呢?只好修改高版本内核驱动去迎合老版本的错误方式喽。

玩蛇网文章,转载请注明出处和文章网址:http://www.iplaypy.com/linux/l6673.html [复制]



我要小额赞助,鼓励作者写出更好的教程↓↓↓

玩蛇网PythonQQ群,欢迎加入: ① 240764603 玩蛇网Python新手群
出炉日期:2017-01-18 19:11 玩蛇网 www.iplaypy.com

我要分享到:
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)

必知PYTHON教程 Must Know PYTHON Tutorials

必知PYTHON模块 Must Know PYTHON Modules