seteuid0's blog
Themed by Diary.
[zz]RHEL 5/6 差异:时间处理机制

when you use different linux system,you will find the time’s different between the systems,here is the reason.RHEL 5/6 差异:时间处理机制06.29.2012, 系统服务 , by Roger.RHEL 5/6 差异:时间处理机制作者:Roger简介本文介绍了在 RHEL5 和 RHEL 6 两个版本系统中,对待时间的差异。目的在于帮助我们了解系统,应对OS升级的改动。概述RHEL 5/6 时间机制差异类别RHEL 5RHEL 6建议Anaconda 参数timezone –utc修改/etc/sysconfig/clock修改/etc/adjtime对用户透明,不用调整开机初始化脚本,硬件时钟到系统时钟/etc/rc.d/rc.sysinit传参调用hwclock内核直接读取rtc_cmos获取时间/etc/sysconfig/clock需要区分关机脚本,系统时钟到硬件时钟/etc/rc.d/init.d/halt传参数调用hwclock/etc/rc.d/init.d/halt直接调用hwclock/etc/sysconfig/clock需要区分NTP软件包一个包:ntp-4.2.2p1-9.el5_3.2三个包:ntp-4.2.4p8-2.el6.centos.i686ntp-perl-4.2.4p8-2.el6.centos.i686ntpdate-4.2.4p8-2.el6.centos.i686RHEL 6 把 RHEL 5 一个包拆成了三个RHEL 6 建议三个包都安装ntpd启动脚本一个脚本:/etc/rc.d/init.d/ntpd两个脚本:/etc/rc.d/init.d/ntpd/etc/rc.d/init.d/ntpdateRHEL 6 中添加了ntpdate启动脚本,相当于额外多了一个服务,需要注意RHEL 5 与 RHEL 6 中,时间这块,外围软件包改动并不大,例如hwclock,NTP。改动比较大的是:Anaconda安装系统时,timezone –utc的处理方式。开机读取硬件时钟的机制。关机写入硬件时钟的机制。linux 时间存储 原理分析首先需要了解的概念:硬件时钟系统时钟其次,BIOS里硬件时钟存的仅是一个UNIX时间戳。这个时间戳,有UTC时钟和LOCAL时钟两钟存法。UTC时间LOCAL时间(本地时间)注意点:我们所说的system clock use UTC (timezone –utc) 实际上就是指BIOS里的时钟存法。与系统的“时区”没有关系。这点不要混淆。这里举一个你常见的例子:笔记本双系统,win+linux,如果linux使用了UTC时间,那么两个系统就会差8小时。原因:Unix规范里BIOS时钟存UTC时间戳,但windows改成了只支持存LOCAL时间戳(就是你墙上的时间),而linux两个格式都支持。这时,如果你linux使用了UTC时间,就会把BIOS的时间戳当作UTC时间,而你的windows把BIOS时间戳当作LOCAL时间。所以无论你怎么调,两个系统时间都不会一致。hwclock说到linux下的时钟,一定不能忽略hwclock,硬件时钟和系统时钟的互写就全靠它了。后续我们详解hwclock的工作机制。推荐看 man clock。开机对时钟的处理我们电脑关机状态时,硬件上的晶振会持续保存一个时间,这个时间就是硬件时钟。进入BIOS便可以看到。开机后,系统将硬件时钟读入系统,然后开始维持时间的增长。硬件时钟仅开机读取一次,由于进入了OS,我们有很多途径让时钟更准确,比如NTP等,这时的硬件时钟对我们是没有用的。关机对时钟的处理要关机了,系统会把时间写入硬件时钟,相当于更新硬件时钟。RHEL 5/6 都是/etc/rc.d/init.d/halt调用hwclock来写入硬件时钟,细节上略有不同,但都是做一样的事情。hwclockRHEL 5/6 中hwclock机制并没有变化:这里需要注意的是:hwclock维护一个文件,/etc/adjtime,用来确定硬件时钟是UTC还是LOCAL。hwclock原理分析:我们直接执行hwclock,就是读取硬件时钟。01[root@centos6 install]# strace -e trace=open hwclock02open("/etc/ld.so.cache", O_RDONLY)      = 303open("/lib/libaudit.so.1", O_RDONLY)    = 304open("/lib/libc.so.6", O_RDONLY)        = 305open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 406open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 407open("/dev/rtc", O_RDONLY|O_LARGEFILE)  = 408open("/etc/adjtime", O_RDONLY|O_LARGEFILE) = 509open("/usr/share/zoneinfo/Universal", O_RDONLY) = 510open("/etc/localtime", O_RDONLY)        = 511open("/usr/share/locale/locale.alias", O_RDONLY) = 512open("/usr/share/locale/zh_CN.UTF-8/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)13open("/usr/share/locale/zh_CN.utf8/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)14open("/usr/share/locale/zh_CN/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = 515open("/usr/share/locale/zh.UTF-8/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)16open("/usr/share/locale/zh.utf8/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)17open("/usr/share/locale/zh/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)18Wed 09 May 2012 05:56:55 PM CST  -0.430311 seconds1.hwclock首先打开了/dev/rtc,读取硬件时钟.2.打开/etc/adjtime文件,通过先前的记录来估算硬件时钟的偏差,并用来校正目前的时间.3.打开/etc/localtime时区文件,将硬件时间转换为当前时区对应的时间.我们执行hwclock -w –debug,写入硬件时钟。同时打开debug模式,方便观察。01[root@centos6 install]# strace -e trace=open hwclock -w –debug02open("/etc/ld.so.cache", O_RDONLY)      = 303open("/lib/libaudit.so.1", O_RDONLY)    = 304open("/lib/libc.so.6", O_RDONLY)        = 305open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 406open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 407open("/usr/share/locale/locale.alias", O_RDONLY) = 408open("/usr/share/locale/zh_CN.UTF-8/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)09open("/usr/share/locale/zh_CN.utf8/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)10open("/usr/share/locale/zh_CN/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = 411open("/usr/share/locale/zh.UTF-8/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)12open("/usr/share/locale/zh.utf8/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)13open("/usr/share/locale/zh/LC_MESSAGES/util-linux-ng.mo", O_RDONLY) = -1 ENOENT (No such file or directory)14hwclock from util-linux-ng 2.17.215open("/dev/rtc", O_RDONLY|O_LARGEFILE)  = 416Using /dev interface to clock.17open("/etc/adjtime", O_RDONLY|O_LARGEFILE) = 518Last drift adjustment done at 1336557886 seconds after 196919Last calibration done at 1336557886 seconds after 196920Hardware clock is on UTC time21Assuming hardware clock is kept in UTC time.22Waiting for clock tick…23…got clock tick24Time read from Hardware Clock: 2012/05/09 10:38:0725open("/usr/share/zoneinfo/Universal", O_RDONLY) = 526Hw clock time : 2012/05/09 10:38:07 = 1336559887 seconds since 196927open("/etc/localtime", O_RDONLY)        = 528Time elapsed since reference time has been 0.505254 seconds.29Delaying further to reach the new time.30Setting Hardware Clock to 10:38:08 = 1336559888 seconds since 196931ioctl(RTC_SET_TIME) was successful.32Not adjusting drift factor because it has been less than a day since the last calibration.33open("/etc/adjtime", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0666) = 51.打开/dev/rtc,读取硬件时钟。2.打开/etc/adjtime文件,通过先前的记录来估算硬件时钟的偏差,并用来校正目前的时间.3.打开/etc/localtime时区文件,将硬件时间转换为当前时区对应的时间.4.ioctl写入硬件时钟5.更新/etc/adjtime文件里的时间戳/etc/adjtime由hwclock维护,默认不需要我们修改。如果修改,也仅是 RHEL 6 上修改第三行。UTC / LOCAL 。1[root@centos6 install]# cat /etc/adjtime2-0.436938 1336541643 0.000000313365416434UTC不同之处的注意点在 RHEL 5 中,开机会读取/etc/sysconfig/clock,传参数给 hwclock,因此/etc/adjtime文件失效,会以/etc/sysconfig/clock为准。关机也同样是这个原理。在 RHEL 6 中,不再有/etc/sysconfig/clock的参与,hwclock直接读取/etc/adjtime处理时间格式。Anaconda我们安装系统时,一般设置为:timezone Asia/Shanghai。也就是不使用UTC时间。RHEL 5 中,Anaconda会修改/etc/sysconfig/clock文件。1[hongmeng@login1.cm4 ~]$ cat /etc/sysconfig/clock2ZONE=“Asia/Shanghai"3UTC=false4ARC=falseRHEL 6 中,Anaconda会直接修改/etc/adjtime文件。/etc/sysconfig/clock里UTC,ARC等配置无意义。因为/etc/rc.d/rc.sysinit和/etc/rc.d/init.d/halt已经不再读取/etc/sysconfig/clock。1[root@opsinfo1 ~]# cat /etc/sysconfig/clock2ZONE=“Asia/Shanghai"1[root@opsinfo1 ~]# cat /etc/adjtime2-0.004473 1336506385 0.000000313365063854LOCAL相关源码:RHEL 5 Anaconda:1usr/lib/anaconda/timezone.py2 3        f = open(instPath + “/etc/sysconfig/clock”, “w”)4 5        f.write(‘ZONE="%s"n’ % self.tz)6        f.write(“UTC=%sn” % bool(self.utc))7        f.write(“ARC=%sn” % bool(self.arc))8 9        f.close()RHEL 6 Anaconda:01usr/lib/anaconda/timezone.py02 03        f = open(instPath + “/etc/adjtime”, “w”)04        f.write(lines[0])05        f.write(lines[1])06        if self.utc:07            f.write(“UTCn”)08        else:09            f.write(“LOCALn”)10        f.close()/etc/rc.d/rc.sysinitRHEL 5 中,开机启动脚本会读取/etc/sysconfig/clock,再传参调用hwclock。将硬件时钟写入系统时钟。01# Set the system clock.02update_boot_stage RCclock03ARC=004SRM=005UTC=006 07if [ -f /etc/sysconfig/clock ]; then08   . /etc/sysconfig/clock09 10   # convert old style clock config to new values11   if [ “${CLOCKMODE}” = “GMT” ]; then12      UTC=true13   elif [ “${CLOCKMODE}” = “ARC” ]; then14      ARC=true15   fi16fi17 18CLOCKDEF=““19CLOCKFLAGS="$CLOCKFLAGS –hctosys"20 21case “$UTC” in22    yes|true)   CLOCKFLAGS="$CLOCKFLAGS –utc"23                CLOCKDEF="$CLOCKDEF (utc)” ;;24    no|false)   CLOCKFLAGS="$CLOCKFLAGS –localtime"25                CLOCKDEF="$CLOCKDEF (localtime)” ;;26esac27case “$ARC” in28    yes|true)   CLOCKFLAGS="$CLOCKFLAGS –arc"29                CLOCKDEF="$CLOCKDEF (arc)” ;;30esac31case “$SRM” in32    yes|true)   CLOCKFLAGS="$CLOCKFLAGS –srm"33                CLOCKDEF="$CLOCKDEF (srm)” ;;34esac35 36[ -x /sbin/hwclock ] && /sbin/hwclock $CLOCKFLAGS37 38action $“Setting clock $CLOCKDEF: `date`” /bin/trueRHEL 6 中,开机启动脚本不再调用hwclock。/etc/rc.d/init.d/haltRHEL 5 中,关机脚本会读取/etc/sysconfig/clock,再传参调用hwclock。将系统时钟写入硬件时钟。01# Sync the system clock.02ARC=003SRM=004UTC=005 06if [ -f /etc/sysconfig/clock ]; then07   . /etc/sysconfig/clock08 09   # convert old style clock config to new values10   if [ “${CLOCKMODE}” = “GMT” ]; then11      UTC=true12   elif [ “${CLOCKMODE}” = “ARC” ]; then13      ARC=true14   fi15fi16 17CLOCKDEF=““18CLOCKFLAGS="$CLOCKFLAGS –systohc"19 20case “$UTC” in21   yes|true)22    CLOCKFLAGS="$CLOCKFLAGS -u”;23    CLOCKDEF="$CLOCKDEF (utc)";24    ;;25   no|false)26    CLOCKFLAGS="$CLOCKFLAGS –localtime”;27    CLOCKDEF="$CLOCKDEF (localtime)";28    ;;29esac30 31case “$ARC” in32   yes|true)33    CLOCKFLAGS="$CLOCKFLAGS -A";34    CLOCKDEF="$CLOCKDEF (arc)";35    ;;36esac37case “$SRM” in38   yes|true)39    CLOCKFLAGS="$CLOCKFLAGS -S";40    CLOCKDEF="$CLOCKDEF (srm)";41    ;;42esac43 44[ -x /sbin/hwclock ] && action $“Syncing hardware clock to system time” /sbin/hwclock $CLOCKFLAGSRHEL 6 中,关机脚本不读取/etc/sysconfig/clock,直接调用hwclock。将系统时钟写入硬件时钟。1# Save random seed2touch /var/lib/random-seed3chmod 600 /var/lib/random-seed4action $“Saving random seed: " dd if=/dev/urandom of=/var/lib/random-seed count=1 bs=512 2>/dev/null5 6[ -x /sbin/hwclock -a -e /dev/rtc ] && action $“Syncing hardware clock to system time” /sbin/hwclock –systohc/etc/sysconfig/clockRHEL 5:1ZONE=“Asia/Shanghai"2UTC=false3ARC=falseRHEL 6:1ZONE=“Asia/Shanghai"NTP软件包RHEL 5 中,NTP 只有一个软件包。1ntp-4.2.2p1-9.el5_3.2RHEL 6 中,NTP 有三个软件包。1ntp-4.2.4p8-2.el6.centos.i6862ntp-perl-4.2.4p8-2.el6.centos.i6863ntpdate-4.2.4p8-2.el6.centos.i686内容其实是一样的,RHEL 6 里只是拆分了,这块可以看NTP相关的文档。ntpd启动脚本RHEL 5:/etc/rc.d/init.d/ntpdRHEL 6:/etc/rc.d/init.d/ntpd/etc/rc.d/init.d/ntpdate影响与应对配置文件/etc/sysconfig/clock需要区分,否则 RHEL 6 写了也不生效。RHEL 5:1ZONE=“Asia/Shanghai"2UTC=false3ARC=falseRHEL 6:1ZONE=“Asia/Shanghai"另外,RHEL 6里,三个包都建议装上。