CodingBox Q&A Ask question

SONiC 把一个 CMIS 4.0 的 QSFP-DD 解码成乱码的厂商字段,而 SFF 模块解析正常

Asked Active Viewed 101 AI translation from English
5

我们的资产盘点工具会遍历每台交换机,直接从 SONiC CLI 里记录每个可插拔模块的厂商、料号和序列号。到处都正常,唯独一批 QSFP-DD 模块,身份字段读回来是乱码,资产数据库里全是垃圾数据。

  • 交换机:SONiC,QSFP-DD 笼子
  • 模块:QSFP-DD,CMIS 4.0,厂商料号 T-DP4CNH-NCI,标签上印的序列号是 L23340629 19
  • 同一台设备里较老的 SFF 类型模块解析正常
$ show interface transc eeprom
Vendor Name: T-DP4CNH-NCI
Vendor PN:   <unreadable>
Vendor SN:   <garbled characters>
Encoding:    <shifted>
Connector:   <shifted>

所以本该是厂商名称的位置出现了料号,序列号读不出来,encoding 和 connector 也都错位了。我检查过的东西:

  • 重新插拔模块再读一次,输出逐字节完全一样
  • 标签上确实写着 T-DP4CNH-NCI 和 L23340629 19,所以这些字符串确实存在于模块里
  • 相邻笼子里的一个 QSFP28,用同一条命令能正确打印厂商、料号和序列号

这是模块自己 EEPROM 写错了,还是 CLI 对一个 CMIS 类型的部件读错了字节?在问题解决之前,有没有办法拿到一个我能真正信任的读数?

Comments 6

你用的是哪个分支?在 202012 里,show interfaces transceiver eeprom 和 sfputil 之间存在已知的字段命名不一致问题,这个问题在 202205 里已经修复了,值得先排除这个可能再往深挖。

把同一个端口上 sudo sfputil show eeprom -d 的输出贴出来。如果 sfputil 给出同样乱码的字符串,问题就出在共享的解码路径上。如果它反而报错,那就是另一码事了——我们有些平台上它只会回一句 Cannot get Module EEPROM data: Invalid argument,根本走不到解码那一步。

4 GermanycoreadminDE Show original (English) AI translation

两个都跑了:在同一个端口上执行了 sudo sfputil show eeprom -d 和 show interfaces transceiver eeprom -d。乱码情况一模一样,同样的字段,序列号该出现的地方是同样的垃圾数据。哪儿都没出现 Invalid argument,读取本身没有任何报错就通过了。

所以这两个命令是一致的,只不过它们一致地给出了错误答案。相邻的 QSFP28 端口用这两个命令都是干净的,这看起来更像是这个具体的 CMIS 部件的问题,而不是平台层面的问题。

2 Indiawaverunner21IN Show original (English) AI translation

这种模式正是解析器套用了一个它不理解的内存布局的典型特征:料号出现在厂商名称字段里,序列号读不出来,connector 和 encoding 都错位了。如果模块坏了或者 I2C 读取出问题,你得到的会是报错或者一堆零,而不是这种整整齐齐但是错的字符串。

解码逻辑在 sonic_platform_base/sonic_sfp/sfputilbase.py 里,那三个身份字符串是按硬编码写死在老式 SFF 映射表上的偏移量去取的,不管实际插的是什么模块。CMIS 4.0 的 QSFP-DD 身份信息块根本不在那些地址上——CMIS 4.0 规范的 8.3 节里描述了它实际的位置——所以这段代码确实是从正确的模块里读到了真实的字节,只不过读的不是它以为自己在读的那些字节,然后把落在那个范围里的东西原样打印出来。这也是为什么它从来不会干脆报错:没有任何一步会去看标识字节、据此切换到 CMIS 的布局。

实际结论是,除非有一个真正理解 CMIS 映射的解析器,否则这个问题解决不了,在你的分支里落地这个修复之前,这个部件的 CLI 输出就不能算是可以入库的资产数据。资产数据库那边,建议直接读原始页面自己解码,而不是抓取 CLI 输出。

3 Vietnamlambdaeng12VN Show original (English) AI translation

要读原始数据的话,你想要的是 optoe 驱动:它把 SFP、QSFP 和 CMIS 的 EEPROM 暴露出来供直接读写,这样你就能自己把字节拿出来、用自己的脚本解码。目前对于 CMIS 部件,我只会把这种方式的结果喂给资产数据库。

如果你要去找偏移量,有个提醒。大家常引用的那张表是 SFF 的表——A0h 字节 20-35 是厂商名称,40-59 是料号、版本号和序列号。这些偏移量正是在 CMIS 模块上产生你那堆垃圾数据的元凶,所以在 CMIS 上不要照搬。同样的提醒也适用于把 Linux 主机当台架工具用的场景:ethtool -m 看解码后的视图、ethtool -e 看原始字节,这两个对 SFP 部件没问题,但对 CMIS 部件,得先确认你的构建版本到底理解到什么程度,再决定信不信它打印出来的字段。

2 Chinacorebyte73CN Show original (English) AI translation

CMIS 处理不完善的地方不止 EEPROM 解码器这一处。我们上线了一批 InnoLight 的 800G QSFP-DD 光模块,型号 T-DP8CNH-NNO 和 T-DP8CNT-NNO,大概每插两次就会有一次端口直接死掉:数据通路报 DataPathDeactivated,日志里带着 'ConfigSuccess' 的超时,从那之后端口就永久 down 了——不会重试,也没有任何自己恢复的迹象。

最后查到问题出在 cmis.py 里的 decommission_all_datapaths()。它按顺序一步接一步地走完整个流程——DEINIT,把应用 ID 清零,然后 INIT——但从不检查上一步是否真的生效就开始下一步。我们这批模块恰恰需要那个确认,所以数据通路被留在半配置状态,状态机就干等着它的计时器超时。真正的修复得异步等待,因为不能在 xcvrd 内联的 CMIS 状态机里阻塞,据我所知目前还没人把这个修复合进去。不同的 bug,同样的主题:一条 CMIS 路径被硬塞进了本来为 SFF 部件写的代码里。

4 Indiarackpilot49IN Show original (English) AI translation

对这段讨论的走向纠正一点,因为这两种失败模式经常被混为一谈。Cannot get Module EEPROM data: Invalid argument,或者一个 QSFP 在断电重启后从 sfputil 里消失、直到驱动修好才恢复,又或者一个平台压根没实现 get_transceiver_info——这些是平台和驱动层面的缺口,它们会在任何解码发生之前就把你挡住。

这里描述的是相反的情况:一次完整、成功的读取,之后被按错误的字段布局解读了。不要因为这个去换模块或者折腾驱动版本。那个模块里的字节本身是好的,任何按 CMIS 正确解码它的工具都会给你看到标签上那个序列号。

3 CanadalantechCA Show original (English) AI translation
Log in to comment. Log in