在新机房发现虚拟机的宿主机获取网卡基础信息时显示的是无效数据,如下图所示:
新机房虚拟机的宿主机使用的镜像版本是CentOS Linux release 8.4.2105,kernel是5.10.26-2,经IDC团队排查,和内核版本无关系,但和ethtool版本有关系,centos8的默认带的是5.8版本,使用低版本的ethtool就没问题。
我下载了ethtool的源码包,分别有5.7/5.8/5.9版本,将编译后的二进制放在新机房的虚拟机测试机发现,5.8/5.9版本会出现展示无效数字问题,而低于5.8版本的就没这个问题。如下图所示:
那么ethtool从5.7版本到5.8版本做了什么修改才会导致展示的数字无效呢?
我们先把5.8编译出二进制,并GDB调试下
接下来我们编译5.7版本的二进制,并且GDB看下:
我们把args打印出来看到结果如下:
...
{opts = 0x42b92c"-l|--show-channels", no_dev = false, func = 0x403df0<do_gchannels>,
nlfunc = 0x0, help = 0x42b93f "Query Channels", xhelp = 0x0}
...
从这里可以看到,args[27]的数据是
{opts = 0x42b92c "-l|--show-channels", no_dev = false,func = 0x403df0 <do_gchannels>,
nlfunc = 0x0, help = 0x42b93f "QueryChannels", xhelp = 0x0}
可以看出args[27].nlfunc=0x0。
但为什么args[27].nlfunc没有对应函数呢?
因此,低于5.8版本会正常的进入到do_gchannels()函数,最终通过ioctl系统调用获取网卡配置信息
版本号是5.7以及版本号是5.8的在centos7上会走到ioctl系统调用获取网卡队列信息;版本号是5.7的在centos8上也是走到ioctl系统调用获取网卡队列信息;版本号是5.8在centos8上通过netlink获取网卡队列信息,在调用show_u32()函数转换时,由于attr是空,所以print n/a.
至于attr为什么为空,主要是由于通过netlink获取到的值为0导致。