七、fault_code.go 超深度解析

7.1 模块定位

fault_code.go 是整个公共基础层中最复杂、最核心的文件(1922行),实现了完整的故障管理引擎,包括:

  1. 故障码加载(从JSON文件)
  2. 故障定制化配置加载(容错时间、频率统计、持续时间统计)
  3. Switch故障码加载
  4. 故障回调处理与缓存
  5. 故障频率/持续时间统计引擎
  6. HBM与AIC/AIV关联故障处理
  7. 手动隔离NPU管理
  8. 故障升级缓存

7.2 核心数据结构

FaultTypeCode

+[]int64 NotHandleFaultCodes

+[]int64 RestartRequestCodes

+[]int64 RestartBusinessCodes

+[]int64 RestartNPUCodes

+[]int64 FreeRestartNPUCodes

+[]int64 PreSeparateNPUCodes

+[]int64 SeparateNPUCodes

+[]int64 NotHandleFaultNetworkCodes

+[]int64 PreSeparateNPUNetworkCodes

+[]int64 SeparateNPUNetworkCodes

+[]int64 SubHealthFaultCodes

faultFileInfo

+[]string NotHandleFaultCodes

+[]string RestartRequestCodes

+[]string RestartBusinessCodes

+[]string RestartNPUCodes

+[]string FreeRestartNPUCodes

+[]string SeparateNPUCodes

+[]string PreSeparateNPUCodes

+[]string NotHandleFaultNetworkCodes

+[]string PreSeparateNPUNetworkCodes

+[]string SeparateNPUNetworkCodes

+[]string SubHealthFaultCodes

FaultCustomization

+GraceToleranceCustomization GraceTolerance

+[]FaultFrequencyCustomization FaultFrequency

+[]FaultDurationCustomization FaultDuration

FaultFrequencyCache

+map<int32,[]int64> Frequency

+map<int32,int64> LastFaultTime

+map<int32,int64> LastFaultRecoverTime

+int64 TimeWindow

+int64 Times

+string FaultHandling

+int64 ReleaseTimeWindow

FaultDurationCache

+map<int32,FaultDurationData> Duration

+int64 FaultTimeout

+int64 RecoverTimeout

+string FaultHandling

FaultDurationData

+bool TimeoutStatus

+[]DevFaultInfo FaultEventQueue

+int64 FaultDurationTime

+int64 FaultRecoverDurationTime

+int64 FaultAlarmTime

HbmFaultManager

+map<int32,int64> HbmOccurTimeCache

+map<int32,[]DevFaultInfo> AicFaultEventQue

+updateHbmOccurTime()

+aicFaultEventInQue()

+aicFaultEventOutQue()

ManuallyFaultInfo

+int32 LogicID

+bool FirstHandle

+int64 RecordTime

GraceToleranceCustomization

FaultFrequencyCustomization

FaultDurationCustomization

FaultFrequency

FaultDuration

7.3 全局变量与缓存体系

限流器

limiter
rate.Limiter
每分钟1000次

手动隔离缓存

manuallySeparateNpuMap
map~int32,ManuallyFaultInfo~

频率/持续时间缓存

faultFrequencyMap
map~string,*FaultFrequencyCache~

faultDurationMap
map~string,*FaultDurationCache~

faultSeverityMap
map~int64,int8~
故障码→严重度

故障事件缓存

devFaultInfoMap
map~int32,[]DevFaultInfo~
设备故障信息缓存

recoverFaultMap
map~int32,[]int64~
恢复故障缓存

recoverNetworkFaultMap
map~int32,[]int64~
网络恢复故障缓存

recoverFaultFrequencyMap
map~int32,string~
频率恢复缓存

Switch故障缓存

NotHandleFaultCodes
[]string

SubHealthFaultCodes
[]string

RestartRequestFaultCodes
[]string

PreSeparateFaultCodes
[]string

SeparateFaultCodes
[]string

故障码缓存

faultTypeCode
FaultTypeCode
故障码→处理策略分类

7.4 核心流程深度解析

7.4.1 故障码加载流程

LoadFaultCodeFromFile()

utils.LoadFile('/usr/local/faultCode.json')

LoadFaultCode(bytes)

json.Unmarshal → faultFileInfo

StringTool.HexStringToInt()
十六进制字符串→int64切片

构建FaultTypeCode结构

mappingChipFaultToNetworkFaultCodesSupport()
支持的网络故障码映射

mappingChipFaultToNetworkFaultCodesNotSupport()
不支持的网络故障码降级为NotHandle

return nil

网络故障码映射逻辑

  • 支持映射:NotHandle/PreSeparate/Separate 中的网络故障码 → 对应的网络故障码列表
  • 不支持映射:RestartRequest/RestartBusiness/RestartNPU/FreeRestartNPU 中的网络故障码 → 降级为 NotHandleFaultNetworkCodes(网络故障不支持重启类操作)
7.4.2 故障定制化加载流程

LoadFaultCustomizationFromFile()

加载 /usr/local/faultCustomization.json

json.Unmarshal → FaultCustomization

loadGraceToleranceCustomization()
容错时间配置

loadFaultFrequencyCustomization()
频率统计配置

setAutofillReasonReleaseTime()
设置自动填充释放时间窗口

loadFaultDurationCustomization()
持续时间统计配置

checkAndUpdateExistingUpgradeFaults()
检查并更新已存在的升级故障

return nil

容错时间参数校验

参数 最小值 默认值 最大值
WaitDeviceResetTime 60s 150s 180s
WaitProcessReadCMTime 5s 30s 90s
WaitFaultSelfHealingTime 1s 15s 30s
7.4.3 故障回调处理流程

No

Yes

Yes

No

Yes

No

Yes

No

SaveDevFaultInfo(devFaultInfo)
DCMI订阅回调

go DoSaveDevFaultInfo(devFaultInfo, true)

limiter.Allow()?

warn: 限流溢出
SetDeviceInit(logicID)
丢弃故障

defer: TriggerUpdate('故障发生')

记录故障信息日志

EventID==0?

return (无效故障)

EventID==ResetFinishFaultCode?

SetDeviceInit(logicID)
标记设备需重新初始化

faultSeverityMap[EventID]=Severity
记录严重度

Assertion==FaultRecover
且enableDelay?

time.Sleep(1s)
延迟1秒(等待DCMI同步)

devFaultInfoMapLock.Lock()

devFaultInfoMap[LogicID] = append(...)
追加故障信息

devFaultInfoMapLock.Unlock()

关键设计

  1. 异步处理SaveDevFaultInfo 通过 go 关键字异步执行,避免阻塞DCMI回调
  2. 限流保护:每分钟最多1000次回调(FaultCallBackRateLimit),超限则丢弃并标记设备需重新初始化
  3. 恢复延迟:故障恢复消息延迟1秒处理,因为DCMI订阅的恢复消息与故障码查询结果可能不同步
  4. 重置完成处理:收到 ResetFinishFaultCode(0x8C2FA009) 时标记设备需要重新初始化
7.4.4 故障频率统计引擎

No

Yes

Skip

Pass

No

Yes

GetFaultTypeFromFaultFrequency(logicId, mode)

mode有效?

return NormalNPU

faultFrequencyMapLock.Lock()

遍历 faultFrequencyMap

解析eventId为int64

mode过滤
Chip: 跳过网络码
Network: 跳过非网络码

Frequency[logicId]存在?

handleFrequencyFault(logicId, cache, eventId)

下一个

getMostSeriousFaultType()

Unlock

return 最严重类型

handleFrequencyFault 核心逻辑

未达阈值

达到频率阈值

Yes

Yes

No

No

Yes

No

Yes

No

handleFrequencyFault(logicId, cache, eventId)

timeWindowStart = now - TimeWindow

删除时间窗口外的历史故障记录

获取lastFaultTime和lastRecoverTime

Frequency[logicId] = Frequency[logicId][index:]

len >= Times?

FaultHandling==ManuallySeparateNPU?

SaveManuallyFaultInfo(logicId)

faultTypes += FaultHandling

recoverFaultFrequencyMap[logicId] = eventId

InsertUpgradeFaultCache()
写入升级缓存

lastRecoverTime >= lastFaultTime
且超时?

RemoveTimeoutReasonCache()
移除超时升级原因

CheckUpgradeFaultCache()?

InsertUpgradeFaultCache()
更新升级时间

不做处理

设计意图

  • 频率统计在滑动时间窗口内计数故障发生次数
  • 达到阈值时触发升级(写入升级缓存,持久化到CM)
  • 未达阈值但已在升级缓存中,则更新时间(保持升级状态不超时释放)
  • 超过释放时间窗口未再发生,则从升级缓存中移除
7.4.5 故障持续时间统计引擎

CountFaultDuration(device, devFaultInfoMap)

faultDurationMapLock.Lock()

collectEachFaultEvent()
收集故障事件到队列

遍历 faultDurationMap

sortFaultEventsInAscendingOrder()
按AlarmRaisedTime升序排序

cleanFaultQueue()
1. 合并连续相同assertion事件
2. 清除首个无效事件

handleFaultQueue()
超时/恢复算法

下一个eventId

Unlock

结束

超时/恢复算法详解

单个尾部事件

成对遍历(每对=occur+recover)

Yes

No

Yes

No

Yes

Yes

No

No

Yes

timeoutOrRecoveryAlgorithm(logicID, eventId, timeoutStatus)

获取处理类型
timeoutStatus=true→'fault timeout'
timeoutStatus=false→'fault timeout recover'

FaultEventQueue为空?

return true(退出)

getTimeoutThreshold()
timeoutStatus=true→FaultTimeout
timeoutStatus=false→RecoverTimeout

i = 0 to len/2

duration = nextAlarmTime - preAlarmTime

duration > threshold*1000?

handleTimeoutCondition()
设置TimeoutStatus
记录DurationTime

continue(继续下一对)

i*2+1 == len?

duration = now - lastAlarmTime

duration > threshold*1000?

handleTimeoutCondition()

handleNotTimeoutCondition()

i*2 == len?

handleNotTimeoutCondition()

算法核心思想

  1. 故障事件队列按时间排序后,成对处理(occur→recover为一个周期)
  2. 如果occur到recover的间隔超过FaultTimeout阈值 → 故障超时,设置TimeoutStatus=true
  3. 如果recover到下一个occur的间隔超过RecoverTimeout阈值 → 恢复超时,设置TimeoutStatus=false
  4. 队列尾部单个事件用当前时间计算持续时间
7.4.6 HBM与AIC/AIV关联故障处理

出队逻辑

Yes

No

Yes

No

Yes

No

Yes

No

newFaultInfosForHBMErr(logicID, faultInfos)

遍历faultInfos

EventID==HbmDoubleBitFaultCode
且非FaultRecover?

hbmTool.updateHbmOccurTime()
记录HBM发生时间

EventID==AicBusFaultCode
或AivBusFaultCode?

hbmTool.aicFaultEventInQue()
入队并排序

直接加入newFaultInfos

hbmTool.aicFaultEventOutQue(logicID)
出队处理

|HBM时间 - AIC时间| < 5秒?

删除(关联故障,不报告)

now - AIC时间 > 5秒?

加入出队列表(报告)

保留在队列中

设计意图:HBM(高带宽内存)双比特错误和AIC/AIV总线错误如果在5秒内同时发生,认为是关联故障,AIC/AIV错误被抑制(不额外报告),避免重复处理。

7.4.7 故障设置与恢复流程

第二轮:处理发生和一次性故障

第一轮:处理恢复和一次性故障

Yes

No

Yes

No

Yes

Yes

No

No

Yes

Yes

No

Yes

Yes

No

SetNewFaultAndCacheOnceRecoverFault(logicID, faultInfos, device, curFaultCodesMap)

HbmDoubleBitFaultCodeStr在durationMap中?

newFaultInfosForHBMErr()
过滤HBM关联故障

使用原始faultInfos

遍历newFaultInfos

是网络故障码?

skip

Assertion==FaultRecover?

curFaultCodesMap包含?

skip recover

handleNpuFaultRecover()
从FaultCodes移除
缓存频率恢复

Assertion==FaultOnce?

recoverFaultMap[logicID] += EventID

遍历newFaultInfos

是网络故障码?

skip

Assertion==FaultOccur
或FaultOnce?

device.FaultCodes += EventID
更新FaultTimeMap

无duration配置?

insertFrequencyFaultOccur()

setAlarmRaisedTime(device)

两轮处理的设计原因:同一条故障可能在同一批次中既出现occur又出现recover(瞬时故障),两轮处理确保这种故障不会对外报告。


八、proto.go 超深度解析

8.1 模块定位

proto.go 定义了整个 device-plugin 的核心数据结构(协议体),是所有模块间数据交换的基础类型库。

8.2 核心结构体类图

NpuDevice

+[]int64 FaultCodes

+int64 AlarmRaisedTime

+[]int64 NetworkFaultCodes

+int64 NetworkAlarmRaisedTime

+map<int64,int64> FaultTimeMap

+string DevType

+string DeviceName

+string Health

+string NetworkHealth

+string DpuHealth

+bool CardDrop

+string IP

+int32 LogicID

+int32 PhyID

+int32 CardID

+int32 DeviceID

+uint32 SuperDeviceID

+string Status

+bool PodUsed

+[]RankLevel LevelList

+int UsedAicoreQuota

+int UsedHbmQuota

DavinCiDev

+string IP

+int32 LogicID

+int32 PhyID

+int32 CardID

+int32 DeviceID

Device

+string DeviceID

+string DeviceIP

+string SuperDeviceID

+[]RankLevel LevelList

Instance

+string PodName

+string ServerID

+string HostIP

+int32 SuperPodId

+[]Device Devices

+int32 RackId

+string ServerIndex

+string ServerIP

Option

+bool GetFdFlag

+bool UseAscendDocker

+bool UseVolcanoType

+bool AutoStowingDevs

+bool PresetVDevice

+bool Use310PMixedInsert

+bool GraceToleranceOn

+int ListAndWatchPeriod

+int HotReset

+uint ShareCount

+int32 AiCoreCount

+string BuildScene

+[]string ProductTypes

+string RealCardType

+string CardType

+int64 LinkdownTimeout

+bool DealWatchHandler

+bool EnableSwitchFault

+bool CheckCachedPods

+bool EnableSlowNode

+int ThirdPartyScanDelay

+int DeviceResetTimeout

+string SoftShareDevConfigDir

+bool UseSingleDieMode

NodeDeviceInfoCache

+NodeDeviceInfo DeviceInfo

+int32 SuperPodID

+int32 ServerIndex

+string CheckCode

+int32 RackID

NodeDeviceInfo

+map<string,string> DeviceList

+int64 UpdateTime

DevStatusSet

+sets.String UnHealthyDevice

+sets.String NetUnHealthyDevice

+sets.String DpuUnHealthyDevice

+sets.String HealthDevices

+sets.String RecoveringDevices

+map<string,sets.String> FreeHealthyDevice

+[]DeviceFault DeviceFault

+sets.String AllDevices

DeviceFault

+string FaultType

+string NPUName

+string LargeModelFaultLevel

+string FaultLevel

+string FaultHandling

+string FaultCode

+map<string,FaultTimeAndLevel> FaultTimeAndLevelMap

SwitchFaultEvent

+uint EventType

+uint SubType

+string FaultID

+string AssembledFaultCode

+uint PeerPortDevice

+uint PeerPortId

+uint SwitchChipId

+uint SwitchPortId

+uint Severity

+uint Assertion

+int EventSerialNum

+int NotifySerialNum

+int64 AlarmRaisedTime

+string AdditionalParam

+string AdditionalInfo

SwitchFaultInfo

+[]string FaultCode

+string FaultLevel

+int64 UpdateTime

+string NodeStatus

+map<string,FaultTimeAndLevel> FaultTimeAndLevelMap

TaskResetInfo

+[]TaskDevInfo RankList

+int64 UpdateTime

+int RetryTime

+bool FaultFlushing

+int GracefulExit

+bool RestartFaultProcess

TaskDevInfo

+int RankId

+DevFaultInfo DevFaultInfo

DevFaultInfo

+int32 LogicId

+string Status

+string Policy

+string InitialPolicy

+[]int64 ErrorCode

+string ErrorCodeHex

SuperPodInfo

+int32 ScaleType

+int32 SuperPodId

+int32 ServerId

+int32 RackId

+int8 SuperPodType

+[]int8 Reserve

NpuBaseInfo

+*int32 DeviceID

+string IP

+uint32 SuperDeviceID

+[]RankLevel LevelList

NpuAllInfo

+[]string AllDevTypes

+[]NpuDevice AllDevs

+[]NpuDevice AICoreDevs

8.3 Option 结构体详解

Option 是全局运行参数单例 ParamOption 的类型,通过命令行参数初始化,贯穿整个组件:

var ParamOption Option  // 全局单例

Option 参数分类

软共享

SoftShareDevConfigDir
软共享配置目录

热重置

HotReset
-1:关闭 0:推理 1:在线训练 2:离线训练

DeviceResetTimeout
设备重置超时

ThirdPartyScanDelay
第三方扫描延迟

功能开关

AutoStowingDevs
自动收纳故障设备

PresetVDevice
预设虚拟设备

GraceToleranceOn
容错开关

EnableSwitchFault
Switch故障开关

EnableSlowNode
慢节点开关

UseSingleDieMode
单Die模式

设备配置

RealCardType
实际芯片型号

CardType
标准卡类型

AiCoreCount
AI Core数量

ShareCount
共享设备数

ProductTypes
产品类型列表

运行模式

GetFdFlag
是否获取FD设备

UseAscendDocker
是否使用Ascend Docker

UseVolcanoType
是否使用Volcano调度

BuildScene
center/edge

8.4 GetAllDeviceInfoTypeList — 设备信息类型清单

func GetAllDeviceInfoTypeList() map[string]struct{} {
    return map[string]struct{}{
        // 910健康/不健康/网络不健康
        GetAscend910Key(""):                               {},
        GetAscend910Key(api.CmCardUnhealthySuffix):        {},
        GetAscend910Key(api.CmCardNetworkUnhealthySuffix): {},
        // 历史遗留键
        HuaweiUnHealthAscend910: {}, HuaweiNetworkUnHealthAscend910: {},
        // 910物理+虚拟设备类型
        api.ResourceNamePrefix + api.Ascend910: {},
        api.ResourceNamePrefix + Ascend910vir2: {},
        // ... 所有虚拟设备类型
        // 310/310P物理+虚拟设备类型
        api.ResourceNamePrefix + api.Ascend310: {},
        api.ResourceNamePrefix + api.Ascend310P: {},
        // AI Core资源
        api.ResourceNamePrefix + AiCoreResourceName: {},
    }
}

设计意图:返回所有需要在ConfigMap中追踪的设备信息键名,用于设备信息上报和同步。


九、proto_v2.go 超深度解析

9.1 模块定位

proto_v2.go 定义A5芯片特有的 DPU(Data Processing Unit) 数据结构。

9.2 数据结构

type DpuCMData struct {
    Name      string  // 网卡接口名称
    Operstate string  // 接口操作状态
    DeviceID  string  // 接口设备ID
    VendorID  string  // 接口厂商ID
}

type DpuInfo struct {
    BusType      string              // 总线类型
    DPUList      []DpuCMData         // DPU列表
    NpuToDpusMap map[string][]string // NPU到DPU的映射
    UpdateTime   int64               // 更新时间戳
}

DpuInfo

DpuCMData

Name
接口名

Operstate
操作状态

DeviceID
设备ID

VendorID
厂商ID

BusType
总线类型

DPUList[]
DPU设备列表

NpuToDpusMap
NPU→DPU映射

UpdateTime
更新时间


十、send_stat.go 超深度解析

10.1 模块定位

SendStats 用于收集和分析 gRPC 发送操作的统计结果,特别用于检测连续发送失败,以触发重新注册kubelet或重启device-plugin。

10.2 数据结构

type sendResult struct {
    sendTime time.Time  // 发送时间
    success  bool       // 是否成功
}

type SendStats struct {
    rwLock      sync.RWMutex     // 读写锁
    sendResults []sendResult     // 发送结果环形缓冲
    recordLen   int              // 最大记录长度
}

10.3 核心方法流程

GetLastSendStatus()

rwLock.RLock()

len==0?

return true

return sendResults[n-1].success

RUnlock()

GetConsecutiveFailures()

rwLock.RLock()

从后向前遍历
遇到success则停止

return count

RUnlock()

RecordSendResult(success)

rwLock.Lock()

success?

sendResults[:0]
清空所有记录

append(sendResults, result)

len > recordLen?

sendResults = sendResults[len-recordLen:]

Unlock()

NewSendStats(recordLength)

recordLength有效?
0 < len <= 1024

recordLength = 128

初始化SendStats

10.4 使用场景

Yes

No

Yes

No

gRPC发送

RecordSendResult(ok)

GetConsecutiveFailures()

>= 5?

重新注册kubelet

>= 15?

重启device-plugin


十一、file_manager.go 超深度解析

11.1 模块定位

提供文件管理工具,包括文件写入、创建、删除,以及重置文件和DataTrace文件的路径生成与清理。

11.2 核心函数

软共享文件管理

RemoveSoftShareDeviceFileAndDir(ns, jobName)
路径: {SoftShareDeviceConfigDir}{ns}.{job}

DataTrace文件管理

RemoveDataTraceFileAndDir(ns, jobName)
路径: /user/cluster-info/datatrace-config/{ns}.data-trace-{job}

重置文件管理

GenResetDirName(ns, name)
/user/restore/reset/{ns}.{name}

GenResetFileName(ns, name)
{dir}/reset.json

GenResetTypeFileName(ns, name)
{dir}/restartType

RemoveResetFileAndDir(ns, name)
1. 删除reset.json
2. 删除restartType
3. 删除目录

文件创建

CreateFileIfNotExist(path, dirPerm, filePerm)

isFileNotExist()?

skip: file exists

prepare + open

文件写入

WriteToFile(info, path)
默认权限0666

WriteToFileWithPerm(info, path, dirPerm, filePerm)

prepareFileBeforeWrite()
1. 检查绝对路径
2. 创建父目录

openAndCheckFile()
1. OpenFile
2. CheckPath
3. 返回closeFunc

f.WriteString(info)

11.3 文件路径体系

/user/restore/reset/
  └── {namespace}.{configmap-name}/
      ├── reset.json          # 重置信息数据
      └── restartType         # 重启类型(hotReset等)

/user/cluster-info/datatrace-config/
  └── {namespace}.data-trace-{jobName}/  # DataTrace配置目录

{SoftShareDeviceConfigDir}{namespace}.{jobName}/  # 软共享设备配置目录

十二、atomic_bool.go 超深度解析

12.1 模块定位

提供基于 sync/atomic原子布尔值原语,用于多协程间的无锁状态同步。

12.2 实现解析

type AtomicBool struct{ v uint32 }  // 用uint32存储bool值(0=false, 1=true)

func NewAtomicBool(initial bool) *AtomicBool {
    return &AtomicBool{v: boolToUint(initial)}
}

func (b *AtomicBool) Load() bool {
    return atomic.LoadUint32(&b.v) == 1  // 原子加载并比较
}

func (b *AtomicBool) Store(new bool) {
    atomic.StoreUint32(&b.v, boolToUint(new))  // 原子存储
}

func boolToUint(b bool) uint32 {
    if b { return 1 }
    return 0
}

设计意图:Go标准库没有提供原子布尔类型,通过uint32+atomic操作封装实现。相比互斥锁,原子操作更轻量高效。


十三、slice_common.go 超深度解析

13.1 模块定位

提供切片操作工具集,包括int32/int64/string切片的包含判断、元素移除、索引查找、十六进制转换等。

13.2 工具类型

var Int32Tool int32Tool   // int32切片工具单例
var Int64Tool int64Tool   // int64切片工具单例
var StringTool stringTool // string切片工具单例

13.3 方法清单

int32Tool

+Contains([]int32, int32) : bool

int64Tool

+SameElement([]int64, []int64) : bool

+Remove([]int64, int64) : []int64

+Index([]int64, int64) : int

+ToHexString([]int64) : string

+Abs(int64, int64) : int64

+Contains([]int64, int64) : bool

stringTool

+HexStringToInt([]string) : []int64

+Contains([]string, string) : bool

13.4 核心方法解析

13.4.1 Int64Tool.Remove — 递归移除
func (i int64Tool) Remove(sources []int64, target int64) []int64 {
    if len(sources) == 0 { return sources }
    index := i.Index(sources, target)    // 查找目标索引
    if index == -1 { return sources }     // 未找到返回原切片
    // 递归移除:append跳过index位置元素后,继续移除可能重复的target
    return i.Remove(append(sources[:index], sources[index+1:]...), target)
}

设计意图:递归移除所有等于target的元素,而非仅移除第一个。

13.4.2 Int64Tool.SameElement — 交集判断
func (i int64Tool) SameElement(sources, targets []int64) bool {
    for _, source := range sources {
        for _, target := range targets {
            if source == target { return true } // 有任一相同元素即返回true
        }
    }
    return false
}

时间复杂度:O(n*m),适用于小切片(故障码列表通常很短)。

13.4.3 StringTool.HexStringToInt — 十六进制批量转换
func (s stringTool) HexStringToInt(sources []string) []int64 {
    intSlice := make([]int64, 0, len(sources))
    for _, source := range sources {
        num, err := strconv.ParseInt(source, Hex, 0)  // Hex=16
        if err != nil {
            hwlog.RunLog.Errorf("parse hex int failed and skip it, string: %s", source)
            continue  // 跳过无效的十六进制字符串
        }
        intSlice = append(intSlice, num)
    }
    return intSlice
}
13.4.4 泛型Contains函数
func Contains[T comparable](sources []T, target T) bool {
    for _, sourceNum := range sources {
        if sourceNum == target { return true }
    }
    return false
}

设计意图:Go 1.18+泛型支持,提供通用包含判断。与Int32Tool.Contains功能重叠,但更通用。


十四、upgradefault.go 超深度解析

14.1 模块定位

upgradefault.go 实现故障升级缓存管理系统,管理因频率统计或持续时间统计触发的故障升级原因,支持缓存的增删改查、ConfigMap持久化、手动隔离自动填充等高级功能。

14.2 核心概念

升级原因值

UpgradeTime
升级发生时间

升级原因键

FaultCode
故障码(十六进制字符串)

FaultLevel
故障级别

UpgradeType
升级类型

缓存键

LogicId
逻辑设备ID(int32)

PhyId
物理设备ID(int32)

故障升级类型

FrequencyUpgradeType
频率统计触发升级

DurationUpgradeType
持续时间触发升级

AutofillUpgradeType
自动填充(手动隔离同步)

14.3 数据结构类图

UpgradeFaultReason

+int64 UpgradeTime

+UpgradeFaultReasonKey UpgradeFaultReasonKey

UpgradeFaultReasonKey

+string FaultCode

+string FaultLevel

+UpgradeTypeEnum UpgradeType

UpgradeFaultReasonSet

+map<UpgradeFaultReasonKey,UpgradeFaultReason> items

+equals(UpgradeFaultReasonSet) : bool

+batchAdd(UpgradeFaultReasonSet)

+toList() : []UpgradeFaultReason

+checkLevel(string) : bool

+removeLevel(string) : UpgradeFaultReasonSet

+remove(...ReasonKeyMatcher) : UpgradeFaultReasonSet

+copy() : UpgradeFaultReasonSet

UpgradeFaultReasonMap<T>

+map<T,UpgradeFaultReasonSet> map

+Equals(UpgradeFaultReasonMap) : bool

+addReasons(T, UpgradeFaultReasonSet)

+remove(T, ...ReasonKeyMatcher) : UpgradeFaultReasonSet

+GetKeys() : []T

+copy() : UpgradeFaultReasonMap

+ConvertCacheToCm(func)(UpgradeFaultReasonMap<PhyId>, error)

+ConvertCmToCache(func)(UpgradeFaultReasonMap<LogicId>, error)

+CmToString(string) : string

+FixManuallySeparateReason([]PhyId) : []PhyId

+UpdateReason(T, int64, string, string, UpgradeTypeEnum) : bool

UpgradeFaultCacheManager

-UpgradeFaultReasonMap<LogicId> cache

-sync.Mutex cacheLock

-UpgradeFaultReasonMap<LogicId> removedEvent

14.4 核心流程

14.4.1 故障升级缓存写入

UpdateReason逻辑

No

Yes

Yes

No

Yes

No

InsertUpgradeFaultCache(logicId, faultTime, faultCode, faultLevel, upgradeType)

cacheLock.Lock()

cache.UpdateReason(logicId, faultTime, faultCode, faultLevel, upgradeType)

reasonMap[key]存在?

创建新UpgradeFaultReasonSet

reasonSet[reasonKey] = reasonVal

旧值存在?

旧值 != 新值?

updated = true

updated = false

if updated: 记录日志

cacheLock.Unlock()

14.4.2 ConfigMap与缓存转换

字符串→CM(StringToReasonCm)

json.Unmarshal → map[string][]UpgradeFaultReason

遍历deviceName

deviceNameToPhyId(deviceName)

ReasonListToSet(reasons)

reasonCm[phyId] = reasonSet

CM→字符串(CmToString)

遍历reasonMap[PhyId]

deviceName = prefix + '-' + phyId

cm[deviceName] = reasonSet.toList()

ObjToString(cm)

CM→缓存(ConvertCmToCache)

遍历reasonMap[PhyId]

phyToLogicConvertFunc(phyId)

reasonCache[LogicId] = reasons.copy()

return reasonCache

缓存→CM(ConvertCacheToCm)

遍历reasonMap[LogicId]

logicToPhyConvertFunc(logicId)

reasonCm[PhyId] = reasons.copy()

return reasonCm

14.4.3 手动隔离修复(FixManuallySeparateReason)

步骤2:移除多余的手动隔离

步骤1:填充缺失的手动隔离

No

Yes

No

Yes

Yes

No

reasonMap.FixManuallySeparateReason(manuallySeparateNPU[])

遍历manuallySeparateNPU

reasonMap[phyId]存在?

UpdateReason(phyId, now, 'AutofillFaultCode',
ManuallySeparateNPU, AutofillUpgradeType)

已存在ManuallySeparateNPU级别?

UpdateReason()
自动填充

跳过

记录autoFillPhyIds

遍历reasonMap中的phyId

在manuallySeparateNPU列表中?

保留

remove(phyId, LevelMatcher(ManuallySeparateNPU))

return autoFillPhyIds

设计意图:当ConfigMap中的 ManuallySeparateNPU 配置变更时,同步更新升级缓存:

  1. 新增的手动隔离NPU → 自动填充升级原因
  2. 移除的手动隔离NPU → 从缓存中删除对应升级原因
  3. 返回自动填充的PhyId列表(用于日志和事件通知)
14.4.4 配置变更更新已有升级故障

Frequency

Duration

Autofill

Yes

No

Yes

No

Yes

No

Yes

No

Yes

No

checkAndUpdateExistingUpgradeFaults(freqConfig, durConfig)

cacheLock.Lock()

遍历upgradeFaultCacheMgr.cache

遍历reasonSet

UpgradeType?

getUpdatedFrequencyFaultReason()

freqConfig中有此FaultCode?

FaultLevel变更?

更新FaultLevel

保持原值

移除(策略已删除)

getUpdatedDurationFaultReason()

durConfig中有此FaultCode?

FaultLevel变更?

更新FaultLevel

保持原值

移除(策略已删除)

保持原值(Autofill不处理)

更新reasonSet

updatedReasonSet为空?

delete(logicId)

cache[logicId] = updatedReasonSet

14.5 ReasonKeyMatcher — 函数式匹配器

type ReasonKeyMatcher func(UpgradeFaultReasonKey) bool

func CodeMatcher(faultCode string) ReasonKeyMatcher {
    return func(key UpgradeFaultReasonKey) bool {
        return faultCode == key.FaultCode
    }
}

func LevelMatcher(faultLevel string) ReasonKeyMatcher {
    return func(key UpgradeFaultReasonKey) bool {
        return faultLevel == key.FaultLevel
    }
}

func TypeMatcher(upgradeType UpgradeTypeEnum) ReasonKeyMatcher {
    return func(key UpgradeFaultReasonKey) bool {
        return upgradeType == key.UpgradeType
    }
}

设计意图:使用函数式编程模式,通过组合匹配器实现灵活的缓存键过滤。可以链式组合:RemoveTimeoutReasonCache(logicId, CodeMatcher(code), TypeMatcher(FrequencyUpgradeType))


十五、模块间调用关系全景图

pkg/common 内部调用关系

基础工具

故障引擎

工具函数

数据结构

常量层

slice_common.go

constants.go

proto.go

common.go

device.go

fault_code.go

upgradefault.go

file_manager.go

send_stat.go

constants_v2.go

proto_v2.go

atomic_bool.go

完整数据流图

输出

pkg/common 处理

输入源

DCMI接口
故障回调

Kubernetes
Pod/CM事件

JSON文件
故障码/定制化配置

故障码加载
LoadFaultCodeFromFile

定制化加载
LoadFaultCustomizationFromFile

故障回调
SaveDevFaultInfo

频率统计
GetFaultTypeFromFaultFrequency

持续时间统计
CountFaultDuration

故障分类
GetFaultType

升级缓存
InsertUpgradeFaultCache

Switch故障
GetSwitchFaultInfo

手动隔离
SaveManuallyFaultInfo

ConfigMap
设备信息/故障信息

Kubelet
设备健康状态

K8s Event
故障事件通知

重置决策
重置/隔离/重启


附录:关键设计模式总结

设计模式 应用位置 说明
单例模式 ParamOption, Int32Tool, Int64Tool, StringTool, hbmTool 全局唯一实例
工厂模式 NewHbmFaultManager, NewSendStats, NewAtomicBool, NewFileWatch 对象创建
策略模式 ReasonKeyMatcher (CodeMatcher/LevelMatcher/TypeMatcher) 函数式匹配策略
观察者模式 updateTriggerChan, TriggerUpdate/GetUpdateChan 事件触发通知
装饰器模式 FilterPods的conditionFunc参数 可插拔过滤条件
泛型 Contains[T], Keys[T,U], DeviceKey[T] Go 1.18+类型参数
读写锁 SendStats.rwLock, faultFrequencyMapLock, faultDurationMapLock 读多写少场景
限流器 limiter (rate.Limiter) 故障回调限流
原子操作 AtomicBool (atomic.LoadUint32/StoreUint32) 无锁并发
sync.Map Ascend910ResetGoroutine 并发安全Map

本文档基于 mind-cluster-v26.0.1 版本源码完成,涵盖 pkg/common 全部12个文件的逐行级分析,包含架构图、流程图、类图共30余个Mermaid图表。

Logo

鲲鹏昇腾开发者社区是面向全社会开放的“联接全球计算开发者,聚合华为+生态”的社区,内容涵盖鲲鹏、昇腾资源,帮助开发者快速获取所需的知识、经验、软件、工具、算力,支撑开发者易学、好用、成功,成为核心开发者。

更多推荐