NTP-Systemzeit unterscheidet sich von der Hardwarezeit

NTP-Systemzeit unterscheidet sich von der Hardwarezeit

auf einem CentOS 6.5-Server habe ich gerade NTP mit Folgendem ausgeführt:

service ntpd start

Die Systemzeit ist korrigiert, aber die Hardwarezeit ist immer noch falsch. Ist das normal? Wie kann ich das beheben?

ntpstat meldet:

unsynchronized
polling server every 64s

Antwort1

Zunächst einmal: Die Hardwarezeit auf einem Linux-System wird in UTC gespeichert, daher ist ein Unterschied zu Ihrer Zeitzone zu erwarten. Und ja, das führt beim Dual-Boot zu Problemen.

Darüber hinaus überträgt ein Linux-System die NTP-Zeit nicht immer und sofort an die RTC („Hardware-Uhr“), aber es sollte dies zumindest beim Herunterfahren tun.

Antwort2

Es ist möglich, dass NTP die Zeit tatsächlich korrigiert, aber langsam. Normalerweise tut es das, um zu verhindern, dass Programme sich aufregen, weil N Sekunden in Sekundenbruchteilen vergangen sind. Viele Programme verwenden die Zeit, um ihre Arbeit intern zu ordnen.

Die Uhr wird also so geändert, dass die Sekunden nur geringfügig erhöht oder verringert werden, beispielsweise um 0,1 Sekunden pro Sekunde (oder sogar weniger). Es kann eine Weile dauern, bis beide Uhren synchronisiert sind.

Überprüfen Sie den Zeitunterschied und prüfen Sie, ob er mit der Zeit abnimmt.

Wenn der Unterschied nach einem „ordnungsgemäßen“ Ausschalten (also einem Herunterfahren, nicht einem Hardware-Ausschalten) weiterhin besteht, sollten Sie überprüfen, ob das System richtig programmiert ist. In meinem System geschieht dies in einer Befehlsdatei, die beim Herunterfahren ausgeführt wird:

/etc/rc.d/rc.0 enthält:

# Save the system time to the hardware clock using hwclock --systohc.
if [ -x /sbin/hwclock ]; then
  # Check for a broken motherboard RTC clock (where ioports for rtc are
  # unknown) to prevent hwclock causing a hang:
  if ! grep -q -w rtc /proc/ioports ; then
    CLOCK_OPT="--directisa"
  fi
  if grep -q "^UTC" /etc/hardwareclock 2> /dev/null ; then
    echo "Saving system time to the hardware clock (UTC)."
    /sbin/hwclock $CLOCK_OPT --utc --systohc
  else
    echo "Saving system time to the hardware clock (localtime)."
    /sbin/hwclock  $CLOCK_OPT --localtime --systohc
  fi
fi

Sie können den Befehl manuell versuchen: sudo hwclock --systohc. Wenn das nicht funktioniert, liegt möglicherweise ein Hardwareproblem vor.

Wie wichtig ist es, beide Uhren zu synchronisieren? Das hängt davon ab, welche Software Sie verwenden. Die Hardware-Uhr wird verwendet, um die Systemuhr beim Start einzustellen. Bis NTP einsetzt, verwendet Ihr Computer diese Zeit. Jede während dieser Zeitspanne verwendete Datei wird mit der falschen Zeit markiert. Dies könnte für einige wichtig sein ...

Antwort3

Da die vorhandenen Antworten die wichtigste Tatsache übersehen, sage ich Ihnen: NTP passt dieSystem Uhr(Software-Uhr). Das Einstellen der Systemuhr in Linuxnichtdie Hardware-Uhr anpassen(Eigentlich habe ich vor etwa 20 Jahren einen Patch geschrieben, der dieses Problem behebt, aber der wurde nie akzeptiert.)

Was aktuelle Systeme typischerweise tun, ist die Aktualisierung der Hardware-Uhr von der Systemzeit entweder währendsauberHerunterfahren oder in einem periodischen Job.

Das Problem beim Aktualisieren der Hardware-Uhr besteht darin, dass der Kernel nicht weiß, ob die Hardware-Uhr auf die lokale Zeit oder auf UTC eingestellt ist. Daher muss er beim Aktualisieren der Hardware-Uhr einen unbekannten Offset anwenden. Das andere Problem besteht darin, dass Linux einen fehlerhaften Code hatte (ich habe die letzten 20 Jahre nicht überprüft), um die Minuten und Sekunden der Hardware-Uhr anhand der Systemuhr zu aktualisieren, wenn letztere als „synchronisiert“ markiert ist.

Der alte Code lautete einst:

     * If we have an externally synchronized Linux clock, then update
     * CMOS clock accordingly every ~11 minutes. Set_rtc_mmss() has to be
     * called as close as possible to 500 ms before the new second starts.
     */
    if ((time_status & STA_UNSYNC) == 0 &&
        xtime.tv_sec > last_rtc_update + 660 &&
        xtime.tv_usec >= 500000 - ((unsigned) tick) / 2 &&
        xtime.tv_usec <= 500000 + ((unsigned) tick) / 2) {
        if (set_rtc_mmss(xtime.tv_sec) == 0)
            last_rtc_update = xtime.tv_sec;
        else
            last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */

verwandte Informationen