igb_uio.ko 的 md5sum 为啥又变化了?

问题描述

最近在合代码到 kni 模块后,重新编译发布 dpdk,发现 igb_uio.ko md5sum 也变化了

这个问题也遇到过好多次,但是一直没有深究过。今天再次遇到了这个问题,这次就不能放过它了!

没有变化的内容

针对 igb_uio.ko md5sum 变化的问题,可以确定如下条件保持不变:

  1. igb_uio.c 源码
  2. 内核头文件
  3. 编译器版本

有了上面这三个条件,igb_uio.ko 讲道理不应该变化。可是它确确实实变化了,那又是什么因素影响呢?难道是 ko 中存在时间戳的原因?

用工具扩大输入信息来对比

由于 ko 文件格式是 elf 格式,我选择使用 objdump 与 readelf 来从两个 md5sum 不同的 igb_uio.ko 版本上获取更多的信息。

objdump -d 对比

objdump -d 对比发现生成的反汇编指令完全一致!这符合代码没有修改这一条件

readelf -a 对比

readelf -a 对比发现有很多差别,而其中变化很多的内容都指向了 debug_str 字段,那 ko 中的这些字段是咋生成的呢?

CONFIG_DEBUG_INFO 配置

网上搜索这个 debug_str 获知这个内容与内核的 CONFIG_DEBUG_INFO 配置有关系,当内核使能了这个配置后,生成的 ko 中会带有调试信息。

首先确认了下我们编译的内核中都开启了这个配置,符合预期!

objdump -s 获取到的信息

有了上面的基础后,我通过执行 objdump -s igb_uio.ko 继续扩展输入信息,这次我注意到如下信息:

Contents of section .debug_line:
 0000 240a0000 02007407 00000101 fb0e0d00  $.....t.........
 0010 01010101 00000001 0000012f 686f6d65  .........../home
 0020 2f77616e 676c6f6e 677a6865 6e672f62  /wanglongzheng/b
 0030 75696c64 5f666f72 5f72656c 65617365  uild_for_release
 0040 2f647064 6b2d3136 2e30342d 76322d6c  /dpdk-16.04-v2-l

这个信息中还记录了编译的路径,那么很显然当这个路径修改后,ko 文件的内容会改变,md5sum 也随之改变。

是 dpdk 源码路径变化导致 igb_uio.ko md5sum 变化吗?

objdump -s 看到的信息能够说明,dpdk 源码路径变化会导致 igb_uio.ko 文件的 md5sum 变化。 基于这一事实,不难确定我本次 release dpdk 路径应该与上一次有所区别

我仔细浏览提交记录,发现编译路径确实有差别,但是这并不是充分条件,也许只是其中的一个变化罢了,时间戳这些也可能存在。

既然我已经确定了编译路径的变化会导致 igb_uio.ko 文件的 md5sum 变化,那么只要使用同一个编译路径编译后 igb_uio.ko md5sum 与仓库中的版本一致就能够说明确实只有编译路径这一个因素的影响。

使用前几个 dpdk release 版本的编译路径重新编译,果然编译出了与仓库中 igb_uio.ko md5sum 相同的版本。

如何让 igb_uio.ko 源码不变化,release 内容也不变化?

基于上面的认识,要让 igb_uio.ko 在源码不变化的情况下保持 release 内容不变,需要保证如下几个因素固定:

  1. 编译器版本一致
  2. 内核配置一致
  3. 在内核 config 开启了 CONFIG_DEBUG_INFO 时,编译路径一致
  4. 编译环境中对编译有影响的环境变量设定内容一致

第四点是我额外添加的内容,由于我们是使用自动编译工具编译 dpdk,环境变量影响不大,但实际上环境变量也是一个非常重要的条件,故而也列举出来。

有没有更好的方式?

其实对于 igb_uio 这种内核模块,一个很好的方式是将它合入到维护的内核代码中,这样每次编译内核的时候就会自动 release,也许一个更好的方式是使用 vfio 这种方式,vfio 据我了解要比 igb_uio 的权限控制更灵活一些,而其代码本身就在内核源码树中,只需要开启相关的内核配置就行了。

总结

本文描述了 igb_uio.ko md5sum 变化的问题,尽管这一问题得到了解决,却意义不大。

一个更加合理的方式应当是将 igb_uio 从 dpdk 中剥离出来合入内核源码,或者使用 vfio 这种替代方式。

dpdk 中的 igb_uio 其源码依赖某几个 dpdk 内部头文件,这是不合理的。这是一种耦合性,这一耦合性带来的影响是我们不得不考虑 igb_uio.ko 的版本与 dpdk 中的头文件版本是否一致,增加了维护工作的成本,这一点值得思考!

上一篇:三次握手最后一个ack没有收到怎么办?


下一篇:跨平台SSH软件-Termius链接 阿里云服务器