2015闰秒对于SuSE产品的影响概述

原创作品,未经许可,转载需注明出处,bigfatbull。

SuSE对于闰秒的处理,应该分为以下两种情况。

1.1 配置且运行NTP的系统

在任何SuSE Linux 环境上,如果正确配置NTP,作为NTP客户端,使用NTP守护进程来同步本地的时间与N2015闰秒对于SuSE产品的影响概述

TP服务器的情况,SuSE Linux的内核会自动考虑到闰秒所带来的影响。在闰秒修正前的最后一天,NTP服务器会通知ntp客户端,在时间23:59:59 UTC将会有一个闰秒发生,内核会对这额外的一秒进行删除操作,并且在内核打印如下log

"Clock: inserting leap second 23: 59: 60 UTC".

内核对闰秒进行正常处理之后,系统的计算时钟应该如下,内核将会出现两次59秒。

2008-12-31 23:59:59 UTC2008-12-31 23:59:59 UTC2009-01-01 00:00:00 UTC

1.2 没配置使用NTP的系统

默认情况,如果没有配置NTP,并且使用NTP进行时间同步的系统,是不会自动修正闰秒的误差的,这将会造成系统时间比UTC时间快一秒。(注: 对于使用硬件时钟的系统,由于硬件时钟的准确性差,所以是否会修正闰秒,没有实际的意义。

对于这种系统,如果你期望也能正常修正系统的闰秒,可以采用以下方案: 将系统的timezone更新到包括2015闰秒处理的最新版本。

首先,复制/usr/share/zoneinfo/right目录下相应的文件到/etc/localtime 然后,重新设定时钟到正确的本地时间。 /usr/share/zoneinfo/right目录下包含所有自大纪元对1970-01-01 00:00:00 UTC开始以来发生的闰秒纠正本地时间信息。而/usr/share/zoneinfo目录下他时区文件没有闰秒修正补充。 

举个例子,如果一个系统是在美国/ Los_Angeles(美国太平洋)时区,你可以重新配置系统,通过运行以下命令,重新设定时钟太平洋时间报告闰秒校正时间:

 cp /usr/share/zoneinfo/right/America/Los_Angeles /etc/localtime 

注意:/usr/share/zoneinfo/right下的时区包,不要与NTP服务同时使用。

2. Linux内核Bug与闰秒的关系

首先,必须明确一个概念,闰秒跟内核的bug没有直接必然的联系。 当闰秒的发生,内核需要对闰秒进行处理,而某些SLES版本(SLES11)内核进行处理的代码部分存在了Bug, 从而造成当闰秒发生的时候,有可能造成系统的挂死。 其次,存在内核BugSLES版本的触发条件是: 

1. 服务器正确配置ntp,并且作为客户端跟ntp服务器同步时间

2. ntp的工作模式采用了adjtimex同步时钟的方式。

所以采用zoneinfo时区包更新闰秒的方式,不会触发任何内核bug,或者ntp的工作模式为“slew,也不会触发内核bug

3. Linux内核受闰秒影响的情况

SLES10 SLES9都不受闰秒的影响,闰秒不会触发SLES10SLES9的以下相关的bugSLES11受影响情况如下,并且PTF版本已经可以下载。

bnc#767684printk
SLES 11
SP1 - kernel 2.6.32.59-0.7和更新版本不受影响
SP2 - kernel 3.0.38-0.5 和更新版本不受影响
SP3 - 不受影响

bnc#768632 and bnc#769841

timer deadlock caused by do_adjtimex()

hang in ktime_get+54


SLES 11
SP1 - kernel 2.6.32.59-0.7 和更新版本不受影响
SP2 - kernel 3.0.38-0.5 和更新版本不受影响

SP3 - 不受影响

bnc#771619

100% CPU load in applications calling futex with a timeout shorter than one second
SLES11
SP1 - kernel 2.6.32.59-0.7 和更新版本不受影响
SP2 - kernel 3.0.38-0.5 更新版本不受影响
SP3 - 不受影响
bsc#915335

Deadlock after fix 771619

SLES11 - 都受影响,下一个内核版本升级修复PTF已经可提供下载

SP1下载链接:

https://ptf.suse.com/f4403ae5567e512ae4b9d6c2437e75ca/sles11-sp1/8070/x86_64/20150211 

 SP2下载链接: https://ptf.suse.com/7a8fed5a4111fab9e4335fb24eb4e6ef/sles11-sp2/8068/x86_64/20150211

SP3下载链接

https://ptf.suse.com/f4403ae5567e512ae4b9d6c2437e75ca/sles11-sp3/8057/x86_64/20150210

4. Workaround

4.1 对于必须使用NTP服务的服务器(时间精度要求高)

如果期望不通过升级内核的方式,修复这些Bug,可以采用以下workaround

一.将在发生闰秒前24小时 将NTP的模式更改为“slew”方式,然后等待闰秒发生过去之后,July 1日将NTP的工作模式修改为正常方式。修改为“slew”模式方法如下

1. 编辑/etc/sysconfig/ntp, 添加”-x” 到NTPD_OPTIONS,结果如下:

NTPD_OPTIONS="-x -g -u ntp: ntp"

2. 重启NTP服务

rcntp restart

请确保在23:59:59 UTC 06/29/2015日前做以上操作

技术原理:

改变NTP服务的slew”模式下运行,这将避免使用adjtime()的系统调用。 因为系统调用带来TIME_INS状态的内核,它会在UTC 23:59:59插入闰秒并且打印通知。 printk拥有xtime_lock锁的情况下被调用,在非常罕见的情况下,这就造成死锁从而造成非常高的系统负载。 adjtime()的系统调用可以在之前的闰秒发生前24小时更新, 所以需要在发生闰秒24小时以前更改NTP工作模式。 如果等闰秒过去之后NTP可以安全改回来了。 

二.由于受bnc#771619的影响,有可能造成使用FUTEX 的应用的CPU占有率100%。 对于这个问题的workaround,运行以下命令,更新系统的闰秒影响。(如果升级第三章的对于内核后,不会出现这个问题,推荐升级内核)

date -s "$(LC_ALL=C date) "


技术原理

因为闰秒发生后,系统本该调用clock_was_set,但是bug的内核没用调用,而设置日期/时间将触发clock_was_set()系统调用。 如果没用调用clock_was_set内核继续运行并且每个CPU hrtimer base不与实时运行同步。 开始一个新的进程并没有解决这个问题。 如果一个新的进程调用 absolute hrtimer,它会等待比正常少等待一秒钟。 如果timer调度少于当前的real time不到一秒,timer将立即触发。 

4.2 可以关闭NTP服务的服务器(建议在时间精度要求不高场景,有效方案,不需要升级内核,及更改配置文件)

对于时间精度要求不高的服务器,可以采用如下的workaround

1. 提前24小时以上,关闭ntp服务,并且不用要使用/usr/share/zoneinfo/right下的时区文件。

rcntp stop

2. 在闰秒过去之后,2015-7-1日之后,重新开启ntp服务

rcntp start

5.常见问题汇总

关于应用层获取到60秒的问题: 
1、SUSE10和SUSE11的内核是否会保存60秒? 

SuSE答复:对于内核没有墙上时钟概念,所以没有60秒的概念,应用程序能否获取到60秒的事情,根源看应用层的对内核时间xtime的解析,如果采用/usr/share/zoneinfo/right的时区包解析,那么可以获取60秒,如果/usr/share/zoneinfo/是下的时区包解析,那么应用代码将获取不到60秒,(如果这种情况下开启NTP将是两个59秒。)

2、应用层使用那些系统命令/API能获取到内核时间中的60秒? 

SuSE答复:请参考问题1的答复

 

对于一些系统命令如“date”也可以strace 看看是否打开时区文件/etc/localtime在localtime已经被right下的时区文件替换的情况下,会出现60s
3、应用获取到unix时间(如C++调用time()),然后再把unix时间转换成UTC时间(如C++调用gmtime()),这个UTC时间是否会有60秒? 
SuSE答复: 请参考问题1的答复。

如果使用/usr/share/zoneinfo/right下的时区文件会有60s,


关于规避闰秒问题的NTP配置开关: 
1、是从哪个SUSE版本开始支持?SUSE10是否支持? 

SuSE答复:SuSE的所有内核版本都支持闰秒

2、能够规避闰秒问题的具体原理是什么? 

SuSE答复:对于闰秒,不是规避,而是让内核不走有问题的代码路径:原理如下:请参考第4章Workaround。


3、打开这个开关后,内核是否还会保存60秒?应用层是否有方法获取到60秒? 

SuSE答复:内核内没有60秒的概念,内核的时钟就是一个大整数,请参考第一问题的答复。

4、打开这个开关后,是否彻底解决了闰秒问题,以后就可以像windows和solaris一样不用担心闰秒导致的问题? 

SuSE的答复:没有所谓的开关,因为内核根本没有60秒的概念,如果你们将内核升级到安全版本,请却不使用/usr/share/zoneinfo/right下的时区包,那么你们的应用将不会看到60秒的。内核已经帮应用程序规避了。


5、可否作为系统发布配置长期打开? 

SuSE的答复:workaround不建议作为长期打开的方式,这只是临时的方案,升级内核才是解决问题的根本,

关于timezone补丁: 
1、SUSE10是否支持timezone补丁? 

SuSE的答复:支持

2、如果在6月30日之后打上这个补丁,是否还能自动调整当前计算机时间? 

SUSE的答复:如果采用/usr/share/zoneinfo/right下的时区包,会自动调整时间,注意:/usr/share/zoneinfo/right下的时区包,不要与NTP服务同时使用。

3、在闰秒发生那一刻,NTP恰好同步到闰秒,相对于打上这个补丁,对应用层面的影响是否完全相同?

SuSE答复:对于内核没有墙上时钟概念,所以没有60秒的概念,应用程序能否获取到60秒的事情,根源看应用层的对内核时间xtime的解析,如果采用/usr/share/zoneinfo/right的时区包解析,那么可以获取60秒,如果/usr/share/zoneinfo/是下的时区包解析,那么应用代码将获取不到60秒,将是两个59秒。

 

6建议

根据不期望看到60秒的诉求,建议的方案如下。

第一,优选方案,升级内核到最新版本,时区包采用默认配置,不使用/usr/share/zoneinfo/right下的时区包。内核会安全的处理掉60秒,应用代码将看不到60秒。

 

第二,备选方案,内核采用workarourd,时区包采用默认配置,不使用/usr/share/zoneinfo/right下的时区包。内核会安全的处理掉60秒,应用代码将看不到60秒。

 

7. 复现方案:

7.1 Case 1: 对于没有运行NTP服务的系统

以下脚本将会在每个UTC时间00点交替插入/删除一秒。我们使用定时任务运行,在奇数天运行 "adjtimex -S16" (插入一秒)和在偶数天运行"adjtimex -S32"(删除一秒)

 

 

SLE11:

 

chkconfig ntp off

rcntp stop

[[ -x /sbin/adjtimex ]] || zypper in util-linux

cat > /etc/cron.d/test-leap-seconds << __EOF

1 0 1-31/2 * * root /sbin/adjtimex -S16

1 0 2-31/2 * * root /sbin/adjtimex -S32

__EOF

 

SLES10

chkconfig ntp off

rcntp stop

[[ -x /sbin/adjtimex ]] || zypper in util-linux

cat > /etc/cron.d/test-leap-seconds << __EOF

1 0 1-31/2 * * root /usr/sbin/adjtimex -S16

1 0 2-31/2 * * root /usr/sbin/adjtimex -S32

__EOF

 

 

7.2 Case 2: 运行NTP服务的系统

脚本将会在UTC 0点的之前关闭ntp,然后在0点之后运行adjtimex和重启ntp

 

 

 

SLE11: 

 

#CRON_TZ is not supported, let's run a script every hour at :59 and :01:

[[ -x /sbin/adjtimex ]] || zypper in util-linux

cat > /usr/local/sbin/test-leap-seconds << "__EOF"

#!/bin/bash

H=`date -u +%H`

M=`date -u +%M`

D=`date -u +%j`

if [[ $((10#$D % 2)) -eq 0 ]]; then

S=32

else

S=16

fi

if [[ $H -eq 23 ]] && [[ $M -gt 30 ]]; then

/usr/sbin/rcntp stop

/sbin/adjtimex -S$S

fi

if [[ $H -eq 0 ]] && [[ $M -lt 30 ]]; then

/usr/sbin/rcntp start

fi

__EOF

chmod a+x /usr/local/sbin/test-leap-seconds

echo "01,59 * * * * root  /usr/local/sbin/test-leap-seconds" > /etc/cron.d/test-leap-seconds

 

 

 

SLE10: 

 

#CRON_TZ is not supported, let's run a script every hour at :59 and :01:

[[ -x /sbin/adjtimex ]] || zypper in util-linux

cat > /usr/local/sbin/test-leap-seconds << "__EOF"

#!/bin/bash

H=`date -u +%H`

M=`date -u +%M`

D=`date -u +%j`

if [[ $((10#$D % 2)) -eq 0 ]]; then

S=32

else

S=16

fi

if [[ $H -eq 23 ]] && [[ $M -gt 30 ]]; then

/usr/sbin/rcntp stop

/usr/sbin/adjtimex -S$S

fi

if [[ $H -eq 0 ]] && [[ $M -lt 30 ]]; then

/usr/sbin/rcntp start

fi

__EOF

chmod a+x /usr/local/sbin/test-leap-seconds

echo "01,59 * * * * root  /usr/local/sbin/test-leap-seconds" > /etc/cron.d/test-leap-seconds

 

7.2 快速复现方案

代码见附件。

1. 使用如下命令编译

gcc fake_leap.c -o fake_leap -lrt

2. 运行

./fake_leap -s

 

 

linux-gznj:~/leapsecond/printtime # ./fake_leap -s

This runs continuously. Press ctrl-c to stop

Setting time to speed up testing

 

Setting time to Sat Feb 14 00:00:00 2015

Scheduling leap second for Sat Feb 14 00:00:00 2015

Something woke us up, returning to sleep

Fri Feb 13 23:59:50 2015 + 438498 us TIME_OK

Fri Feb 13 23:59:50 2015 + 941202 us TIME_OK

Fri Feb 13 23:59:51 2015 + 445251 us TIME_INS

Fri Feb 13 23:59:51 2015 + 949219 us TIME_INS

Fri Feb 13 23:59:52 2015 + 453259 us TIME_INS

Fri Feb 13 23:59:52 2015 + 957217 us TIME_INS

Fri Feb 13 23:59:53 2015 + 461269 us TIME_INS

Fri Feb 13 23:59:53 2015 + 965224 us TIME_INS

Fri Feb 13 23:59:54 2015 + 469272 us TIME_INS

Fri Feb 13 23:59:54 2015 + 973259 us TIME_INS

Fri Feb 13 23:59:55 2015 + 477266 us TIME_INS

Fri Feb 13 23:59:55 2015 + 981230 us TIME_INS

Fri Feb 13 23:59:56 2015 + 485272 us TIME_INS

Fri Feb 13 23:59:56 2015 + 989290 us TIME_INS

Fri Feb 13 23:59:57 2015 + 493276 us TIME_INS

Fri Feb 13 23:59:57 2015 + 997275 us TIME_INS

Fri Feb 13 23:59:58 2015 + 501274 us TIME_INS

Fri Feb 13 23:59:59 2015 +   5243 us TIME_INS

Fri Feb 13 23:59:59 2015 + 509283 us TIME_INS

Fri Feb 13 23:59:59 2015 +  16329 usTIME_OOP

Fri Feb 13 23:59:59 2015 + 517280 usTIME_OOP

Sat Feb 14 00:00:00 2015 +  21276 us TIME_WAIT

Sat Feb 14 00:00:00 2015 + 525313 us TIME_WAIT

Sat Feb 14 00:00:01 2015 +  29271 us TIME_WAIT

Sat Feb 14 00:00:01 2015 + 533294 us TIME_WAIT

Sat Feb 14 00:00:02 2015 +  37270 us TIME_WAIT

Leap complete

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值