// 此模板仅供参考,如果不适用可以修改
问题描述
当前存在这样一个需求:NPU节点由于没有NTP配置,所以需要从CPU节点获取时间进行同步,保证时间信息一致
【NPU节点时间RTC时间同步时,当识别到时间与主机时间出现偏差,需要从CPU节点进行一次BMC时间校准同步】
此时存在以下问题:
- 在调用SetDateTime修改bmc时间后,是否会被rtc重新同步导致修改后的时间信息覆盖,进而导致时间同步失败;
- 如果会被rtc覆盖,那么是否应该调整时间信息获取的优先级,或者调用类似于SetRtcTime的方法同时修改rtc的时间、防止rtc时间同步的影响
- 是否需要做一种同步策略,当开始从CPU节点进行时间同步时,参考NTP的策略做成互斥或者不允许其他时间修改的策略
期望结果
期望效果为:NPU节点在轮询CPU节点的时间并且发现时间差值较大时,修改自身时间保持与CPU节点的时间一致,不会被rtc覆盖;
在通过其他方式(例如ipmi命令等)无法修改bmc时间
尝试过的解决方案
当前实现的方案是使用SetDateTime接口设置BMC时间【相关代码如下】:
相关接口:
bmc.kepler.Managers.Time.SetDateTime
-- 使用SetDateTime接口设置BMC时间
function time_sync_service:set_system_time_via_interface(timestamp)
-- 获取Time对象
local time_objects = client:GetTimeObjects()
if not time_objects or next(time_objects) == nil then
log:error('get time objects failed')
return false
end
local time_obj = next(time_objects)
-- 格式化时间为ISO 8601格式
local datetime_str = os.date('%Y-%m-%dT%H:%M:%S+00:00', timestamp)
-- 构造SetDateTime请求参数
local time_params = {
DateTime = datetime_str
}
log:info('setting bmc time via SetDateTime: %s', datetime_str)
-- 调用SetDateTime方法
local ok, result = pcall(time_obj.SetDateTime, context.new(), time_params)
if not ok then
log:error('SetDateTime failed: %s', result)
return false
end
log:info('set bmc time successfully via SetDateTime: %s', datetime_str)
return true
end
答案内容由AI生成,仅供参考:
根据您提供的回答内容,已找到明确标有“总结”章节的内容。现原样提取如下:
总结
- 结论:在无NTP场景下,
SetDateTime 设置的时间确实会被RTC时间覆盖。BMC软件每6秒就会从RTC硬件芯片同步一次时间。
- 根源:BMC (
bmc_time 组件) 依赖于硬件RTC芯片作为其核心时间源。
- 解决方案建议:
- 首选方案:寻找并调用一个直接修改RTC芯片硬件时间的API(如果存在),从根本上更新系统时间。
- 备选方案:在您的
time_sync_service 中实现一个与RTC同步互斥的机制(例如,设置一个“手动同步中”的标志位,临时挂起RTC轮询同步),待设置完成后再恢复。
点击此处查看详细分析解答
根据您提供的Context中的信息,针对您的问题,回答如下:
1. 通过 SetDateTime 修改 BMC 时间是否会被 RTC 覆盖?
是的,会被覆盖。
在Context中,有明确的讨论和直接证据指出了这一点:
- 社区用户
zhangbaocun 的明确答复:在讨论通过IPMI设置时间的问题时,zhangbaocun 明确指出:“这是ipmi设置的时候bmc的软件时间,每隔6秒bmc又会从rtc同步时间,所以设置了又会被修改”。[reference_id: #3]
- 社区用户
spjisgood_2lbdb 的补充说明:该用户也确认了相同的现象,指出通过IPMI设置的时间会被RTC的轮询同步覆盖。[reference_id: #3]
bmc_time 组件的同步机制:bmc_time 组件的 Scanner_Rtc 配置中有一个 Period 属性,其值为 6000(即6000毫秒),这直接证明了系统会每隔6秒从RTC芯片读取并同步一次时间。[reference_id: #2]
因此,在无NTP场景下,单独调用 SetDateTime 修改BMC时间后,该时间会在最多6秒后被RTC时间覆盖,导致同步失败。
2. 如何避免被覆盖及同步策略建议
根据Context中的信息,可以总结出以下策略和结论:
(1)调整时间获取优先级或同时修改RTC时间
- 同时修改RTC时间是最佳路径:根据
sunpeijun 的回复,bmc_time 组件的 Time_Bmc 对象通过 CpuBrdRtc 属性关联到RTC芯片(Eeprom_Rtc),并通过 Scanner_Rtc 读取芯片的原始二进制数据(包含年月日时分秒)。[reference_id: #2]
- 这意味着,BMC的时间源是RTC芯片。为了避免被覆盖,最根本的解决方案是直接修改RTC芯片的时间。如果直接调用类似
SetRtcTime 的方法(需要您的系统支持)来修改RTC芯片的寄存器的值,那么BMC时间也会随之更新,且不会被覆盖。
- 注意:Context中并未提供名为
SetRtcTime 的具体API或方法。您需要确认您的BMC固件是否提供了直接操作RTC硬件寄存器的接口。
(2)关于互斥策略(类似于NTP)
- NTP与RTC的同步是互斥的:
sunpeijun 在回答RTC同步问题时特别指出:“除此问题外,也要关注是否开启了NTP,因为开启NTP时是不会同步RTC时间的”。[reference_id: #2]
- 建议实现类似的互斥逻辑:您的设想是合理的。可以参考NTP的策略实现在您的
time_sync_service 中:
- 创建一个标志位:当
time_sync_service 从CPU节点获取时间并准备调用 SetDateTime 时,设置一个同步标志(例如 manual_sync_in_progress)。
- 暂停RTC同步:在
bmc_time 或相关的RTC同步服务中检查此标志。如果标志为真,则暂停从RTC芯片轮询同步时间的操作。
- 恢复RTC同步:在CPU节点时间成功写入BMC后,清除该标志,并恢复正常的RTC同步。
总结
- 结论:在无NTP场景下,
SetDateTime 设置的时间确实会被RTC时间覆盖。BMC软件每6秒就会从RTC硬件芯片同步一次时间。
- 根源:BMC (
bmc_time 组件) 依赖于硬件RTC芯片作为其核心时间源。
- 解决方案建议:
- 首选方案:寻找并调用一个直接修改RTC芯片硬件时间的API(如果存在),从根本上更新系统时间。
- 备选方案:在您的
time_sync_service 中实现一个与RTC同步互斥的机制(例如,设置一个“手动同步中”的标志位,临时挂起RTC轮询同步),待设置完成后再恢复。
您当前使用 SetDateTime 的代码实现是正确的,但无法独立解决RTC覆盖的问题。您需要按照以上建议,结合系统提供的其他接口或逻辑来实现时间同步不被覆盖的目标。
接口的初始使用场景就是无rtc场景
所以并没有考虑与rtc做互斥
并且无法简单的设计成接口设置后就弃用RTC
比如RTC短时间内无效,后续恢复了还是否同步
或者RTC时间被设置后BMC预期是要同步的
因此如果有优先级诉求建议在bmc_core sig 申报议题
决策是否增加配置项/固定优先级等方式