SONiC decode một QSFP-DD CMIS 4.0 ra field vendor lộn xộn trong khi module SFF vẫn parse bình thường
Công cụ inventory của bên mình đi qua từng switch và ghi lại vendor, part number, serial cho mỗi pluggable ngay từ CLI của SONiC. Nó chạy tốt ở mọi nơi trừ một lô module QSFP-DD, nơi các field định danh trả về lộn xộn và asset database đầy rác.
- Switch: SONiC, cage QSFP-DD
- Module: QSFP-DD, CMIS 4.0, vendor part T-DP4CNH-NCI, serial L23340629 19 in trên nhãn
- Các module kiểu SFF cũ hơn trong cùng chassis decode sạch sẽ
$ show interface transc eeprom
Vendor Name: T-DP4CNH-NCI
Vendor PN: <unreadable>
Vendor SN: <garbled characters>
Encoding: <shifted>
Connector: <shifted>
Vậy là part number lại xuất hiện ở chỗ đáng lẽ là vendor name, serial thì không đọc được, và encoding lẫn connector cũng bị lệch. Đã kiểm tra:
- reseat module và đọc lại, output giống hệt tới từng byte
- nhãn thực sự ghi T-DP4CNH-NCI và L23340629 19, nên các chuỗi đó có tồn tại bên trong module
- một QSFP28 ở cage bên cạnh in đúng vendor, PN và SN với cùng một lệnh
Đây là module ghi sai EEPROM của chính nó, hay CLI đang đọc sai byte cho một linh kiện CMIS? Và có cách nào lấy được một lần đọc thực sự tin cậy được trong lúc chờ đợi không?
Comments 6
Đang ở branch nào? Có những bất nhất tên key đã biết giữa
show interfaces transceiver eepromvà sfputil trong 202012, đã được xử lý xong ở 202205, và đáng loại trừ điều đó trước khi đào sâu hơn.Đăng output của
sudo sfputil show eeprom -dcho cùng port đó. Nếu sfputil cho ra cùng những chuỗi lộn xộn, lỗi nằm trong đường decode dùng chung. Nếu nó báo lỗi thay vào đó thì bạn đang ở vùng đất khác - có những platform ở đây chỉ trả lờiCannot get Module EEPROM data: Invalid argumentvà chẳng bao giờ đi xa tới mức decode được gì cả.Đã chạy cả hai:
sudo sfputil show eeprom -dvàshow interfaces transceiver eeprom -dtrên cùng port. Lộn xộn y hệt nhau, cùng field, cùng rác ở chỗ đáng lẽ là serial. Không cóInvalid argumentở đâu cả, bản thân lần đọc đi qua trót lọt không kêu ca gì.Nên hai lệnh này đồng ý với nhau, chỉ là đồng ý trên một câu trả lời sai. Các port QSFP28 bên cạnh vẫn sạch qua cả hai lệnh, khiến nó trông như đặc thù của linh kiện CMIS này hơn là của platform.
Pattern đó là chữ ký của một parser được áp vào một memory map nó không hiểu: part number nằm ở field vendor name, serial không đọc được, connector và encoding bị lệch. Một module hỏng hay một lần đọc I2C hỏng sẽ cho ra một lỗi hoặc một khối toàn số 0, chứ không phải những chuỗi sai một cách gọn gàng như vậy.
Đường decode nằm trong
sonic_platform_base/sonic_sfp/sfputilbase.py, và ở đó ba chuỗi định danh được lấy từ các offset hardcode theo memory map SFF cũ, bất kể thứ gì đang cắm vào. Một QSFP-DD CMIS 4.0 không giữ khối định danh của nó ở đúng những địa chỉ đó - spec CMIS 4.0 mô tả nó ở section 8.3 - nên code đang đọc đúng byte thật từ đúng module, chỉ là không phải những byte nó tin là đang đọc, và nó in ra bất cứ thứ gì chiếm đúng vùng đó. Đó cũng là lý do không có gì fail một cách rõ ràng cả: không bước nào nhìn vào identifier byte rồi chuyển sang layout CMIS.Kết luận thực tế là không gì ngoài một parser hiểu được memory map CMIS mới sửa đúng được chuyện này, và tới khi nào cái đó xuất hiện trong branch của bạn thì output CLI cho linh kiện này chưa đạt chuẩn inventory. Cho asset database, đọc raw các page rồi tự decode lấy thay vì scrape CLI.
Cho lần đọc raw, driver optoe mới là thứ cần: nó phơi bày EEPROM của SFP, QSFP và CMIS để đọc và ghi trực tiếp, nên có thể kéo byte ra và tự decode trong script của mình. Đó là thứ duy nhất mình sẽ đưa vào asset database cho linh kiện CMIS ở thời điểm này.
Một cảnh báo nếu đi tìm offset. Bảng mà ai cũng trích dẫn là bảng SFF - A0h byte 20-35 cho vendor name, 40-59 cho PN, rev và SN. Đó chính xác là những offset tạo ra rác trên một module CMIS, nên đừng dùng lại chúng ở đó. Cùng một lưu ý trên một host Linux khi dùng làm công cụ bench:
ethtool -mcho view đã decode vàethtool -echo byte raw đều ổn với linh kiện SFP, nhưng kiểm tra xem build của bạn thực sự hiểu gì trước khi tin vào các field nó in ra cho CMIS.Xử lý CMIS còn mỏng ở nhiều chỗ hơn là chỉ mỗi bộ decode EEPROM. Bên mình đưa vào khai thác một khay optic InnoLight 800G QSFP-DD, T-DP8CNH-NNO và T-DP8CNT-NNO, và cứ khoảng mỗi lần cắm thứ hai lại để lại một port chết: datapath báo DataPathDeactivated, log mang một timeout cho 'ConfigSuccess', và từ đó port down vĩnh viễn - không retry, không gì tự đưa nó quay lại cả.
Thủ phạm hóa ra là
decommission_all_datapaths()trong cmis.py. Nó đi qua cả chuỗi liên tiếp - DEINIT, xóa application ID về 0, rồi INIT - và không bao giờ kiểm tra một bước có thực sự có hiệu lực trước khi bắt đầu bước tiếp theo hay không. Linh kiện của bên mình cần đúng sự xác nhận đó, nên datapath bị bỏ lại ở trạng thái cấu hình nửa vời và state machine cứ ngồi chờ hết giờ của nó. Một bản fix thật sự phải chờ bất đồng bộ, vì không thể block bên trong state machine CMIS inline của xcvrd, và lần cuối mình kiểm tra thì chưa ai land được bản nào. Bug khác, nhưng cùng một chủ đề: một đường CMIS được gắn tạm vào code viết cho linh kiện SFF.Một điều chỉnh cho hướng cả thread đang trôi dạt tới, vì hai kiểu lỗi này cứ bị lẫn lộn vào nhau suốt.
Cannot get Module EEPROM data: Invalid argument, hay một QSFP biến mất khỏi sfputil sau một lần power cycle cho tới khi driver được fix, hay một platform đơn giản là chưa implement get_transceiver_info - đó là các lỗ hổng platform và driver, và chúng chặn bạn lại trước khi bất kỳ decode nào xảy ra.Cái được mô tả ở đây là điều ngược lại: một lần đọc hoàn chỉnh, thành công, rồi sau đó bị diễn giải sai layout field. Đừng đổi module hay đuổi theo version driver vì chuyện này. Byte bên trong module đó vẫn ổn, và bất kỳ tool nào decode chúng đúng kiểu CMIS sẽ cho thấy đúng serial trên nhãn.