Jest to spowodowane przez blokadę aktywności, gdy ntpd wywołuje adjtimex (2), aby poinformować jądro, aby wstawiło sekundę przestępną. Zobacz publikowanie lkml http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html
Red Hat powinien również aktualizować swój artykuł KB. https://access.redhat.com/knowledge/articles/15145
AKTUALIZACJA: Red Hat ma drugi artykuł KB tylko na ten temat tutaj: https://access.redhat.com/knowledge/solutions/154713 - poprzedni artykuł dotyczy wcześniejszego niezwiązanego problemu
Obejściem problemu jest po prostu wyłączenie ntpd. Jeśli ntpd wydało już wywołanie adjtimex (2), może być konieczne wyłączenie ntpd i ponowne uruchomienie, aby być w 100% bezpiecznym.
Wpływa to na RHEL 6 i inne dystrybucje, w których działają nowsze jądra (nowsze niż około 2.6.26), ale nie RHEL 5.
Powodem tego jest występujący przed drugim skokiem jest rzeczywiście planowane jest to, że występuje jądro ntpd pozwala obsłużyć drugi skok na północy, ale musi powiadomić jądro wstawić skok sekund przed północą. W związku z tym ntpd wywołuje adjtimex (2) w dniu drugiego przestępnego momentu, w którym to momencie ten błąd jest wywoływany.
Jeśli masz zainstalowany adjtimex (8), możesz użyć tego skryptu, aby ustalić, czy flaga 16 jest ustawiona. Flaga 16 „wstawia sekundę przestępną”:
adjtimex -p | perl -p -e 'undef $_, next unless m/status: (\d+)/; (16 & $1) && print "leap second flag is set:\n"'
AKTUALIZACJA:
Red Hat zaktualizował swój artykuł KB, aby zauważyć: „Znany problem może dotyczyć klientów RHEL 6, który powoduje, że NMI Watchdog wykrywa zawieszenie po otrzymaniu powiadomienia o upływie czasu NTP. Problem ten jest rozwiązywany w odpowiednim czasie. Jeśli Twoje systemy otrzymały zawiadomienie o upłynięciu drugiej godziny i nie wystąpił ten problem, nie ma to już wpływu ”.
AKTUALIZACJA: Powyższy język został usunięty z artykułu Red Hat; i dodano drugie rozwiązanie KB szczegółowo opisujące awarię adjtimex (2): https://access.redhat.com/knowledge/solutions/154713
Jednak zmiana kodu w poście LKML przez inżyniera IBM Johna Stultza zauważa, że może również wystąpić impas, gdy sekunda przestępna jest rzeczywiście zastosowana, więc możesz chcieć wyłączyć sekundę przestępną poprzez ponowne uruchomienie lub użycie adjtimex (8) po wyłączeniu ntpd.
AKTUALIZACJA KOŃCOWA:
Cóż, nie jestem programistą jądra, ale ponownie sprawdziłem łatkę Johna Stultza tutaj: https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h = 6b43ae8a619d17c4935c3320d2ef9e92bdeed05d
Jeśli tym razem dobrze go czytam, pomyliłem się co do kolejnego impasu po zastosowaniu sekundy przestępnej. To wydaje się być również opinią Red Hata, opartą na ich wpisie w KB. Jeśli jednak wyłączyłeś ntpd, wyłącz go na kolejne 10 minut, aby nie uderzyć w impas, gdy ntpd wywołuje adjtimex (2).
Dowiemy się, czy wkrótce będą więcej błędów :)
DRUGA AKTUALIZACJA PO SKOKU:
Ostatnie kilka godzin spędziłem na czytaniu kodu jądra ntpd i pre-patcha (buggy), i chociaż mogę się tutaj bardzo mylić, postaram się wyjaśnić, co się dzieje:
Po pierwsze, ntpd cały czas wywołuje adjtimex (2). Robi to jako część swojego „filtra pętli zegara”, zdefiniowanego w local_clock w ntp_loopfilter.c. Możesz zobaczyć ten kod tutaj: http://www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (z wersji ntp 4.2.6).
Filtr pętli zegara działa dość często - działa za każdym razem, gdy ntpd odpytuje swoje serwery nadrzędne, co domyślnie co 17 minut lub dłużej. Odpowiedni bit filtra pętli zegara to:
if (sys_leap == LEAP_ADDSECOND)
ntv.status |= STA_INS;
I wtedy:
ntp_adjtime(&ntv)
Innymi słowy, w dni, w których następuje sekunda przestępna, ntpd ustawia flagę „STA_INS” i wywołuje adjtimex (2) (za pomocą opakowania przenośności).
To wywołanie systemowe dociera do jądra. Oto odpowiedni kod jądra: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c
Ścieżka kodowa jądra wygląda mniej więcej tak:
- linia 663 - początek procedury do_adjtimex.
- linia 691 - anuluj dowolny istniejący licznik sekund przestępnych.
- linia 709 - weź blokadę ntp_lock (ta blokada bierze udział w możliwej awarii livelock)
- linia 724 - wywołuje tryby_adjtimex_procesu.
- linia 616 - wywołanie proces_adj_status.
- linia 590 - ustaw zmienną globalną time_status, na podstawie flag ustawionych w wywołaniu adjtimex (2)
- wiersz 592 - sprawdź zmienną globalną time_state. w większości przypadków wywołaj ntp_start_leap_timer.
- linia 554 - sprawdź zmienną globalną time_status. STA_INS zostanie ustawiony, więc ustaw czas_czasu na TIME_INS i wywołaj hrtimer_start (kolejna funkcja jądra), aby uruchomić drugi licznik czasu przestępnego. podczas tworzenia timera ten kod pobiera xtime_lock. jeśli tak się stanie, gdy inny procesor już chwycił xtime_lock i ntp_lock, oznacza to, że jądro blokuje się. dlatego John Stultz napisał łatkę, aby uniknąć używania hrtimerów. To właśnie sprawiło wszystkim dzisiaj kłopoty.
- linia 598 - jeśli ntp_start_leap_timer tak naprawdę nie uruchomił timera przestępnego, ustaw czas_czasu na TIME_OK
- linia 751 - przy założeniu, że jądro nie blokuje się, stos jest rozwijany i zwalniana jest blokada ntp_lock.
Jest tu kilka interesujących rzeczy.
Po pierwsze, linia 691 kasuje istniejący zegar za każdym razem, gdy wywoływany jest adjtimex (2). Następnie 554 ponownie tworzy ten zegar. Oznacza to, że za każdym razem, gdy ntpd uruchamia filtr pętli zegara, wywoływany jest błędny kod.
Dlatego uważam, że Red Hat mylił się, gdy mówili, że gdy ntpd ustawi flagę drugiego skoku, system się nie zawiesi. Wierzę, że każdy system z uruchomionym NTTP miał potencjał do blokowania się co 17 minut (lub więcej) przez 24 godziny przed sekundą przestępną. Wierzę, że może to również wyjaśniać, dlaczego tak wiele systemów uległo awarii; jednorazowa szansa na awarię byłaby znacznie mniej prawdopodobna w porównaniu z 3 szansami na godzinę.
AKTUALIZACJA: W rozwiązaniu KB Red Hata pod adresem https://access.redhat.com/knowledge/solutions/154713 inżynierowie Red Hat doszli do tego samego wniosku (że uruchomienie ntpd ciągle uderzałoby w błędny kod). I rzeczywiście zrobili to kilka godzin wcześniej. To rozwiązanie nie było powiązane z głównym artykułem na https://access.redhat.com/knowledge/articles/15145 , więc do tej pory tego nie zauważyłem.
Po drugie, wyjaśnia to, dlaczego załadowane systemy częściej ulegały awariom. Załadowane systemy będą obsługiwały więcej przerwań, powodując częstsze wywoływanie funkcji jądra „do_tick”, co daje większą szansę na uruchomienie tego kodu i złapanie ntp_lock podczas tworzenia timera.
Po trzecie, czy jest szansa na awarię systemu, gdy rzeczywiście nastąpi sekunda przestępna? Nie wiem na pewno, ale być może tak, ponieważ licznik czasu, który odpala i faktycznie wykonuje regulację drugiego skoku (ntp_leap_second, na linii 388), również chwyta blokadę ntp_lock i ma wywołanie hrtimer_add_expires_ns. Nie wiem, czy to połączenie może również wywołać blokadę ruchu, ale nie wydaje się to niemożliwe.
Wreszcie, co powoduje, że flaga sekund przestępnych jest wyłączana po uruchomieniu sekundy przestępnej? Odpowiedź: ntpd przestaje ustawiać flagę drugiego skoku w pewnym momencie po północy, gdy wywołuje adjtimex (2). Ponieważ flaga nie jest ustawiona, sprawdzenie w wierszu 554 nie będzie prawdziwe i nie zostanie utworzony zegar, a wiersz 598 zresetuje zmienną globalną time_state na TIME_OK. To wyjaśnia, dlaczego jeśli sprawdziłeś flagę za pomocą adjtimex (8) tuż po drugim przestępnym czasie, nadal zobaczysz ustawioną flagę drugiego skoku.
Krótko mówiąc, najlepszą radą na dziś wydaje się być pierwsza, którą dałem przecież: wyłącz ntpd i wyłącz flagę drugiego skoku.
I kilka ostatnich myśli:
- żaden z dostawców systemu Linux nie zauważył łatki Johna Stultza i nie zastosował jej do swoich jąder :(
- dlaczego John Stultz nie powiadomił niektórych dostawców, że jest to potrzebne? być może szansa na zastój wydawała się wystarczająco niska, aby hałas nie był uzasadniony.
- Słyszałem doniesienia o blokowaniu lub wirowaniu procesów Java, gdy zastosowano sekundę przestępną. Być może powinniśmy podążać za wskazówkami Google i przemyśleć, jak stosujemy sekundy przestępne w naszych systemach: http://googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html
06/02 Aktualizacja od Johna Stultza:
https://lkml.org/lkml/2012/7/1/203
Post zawierał krok po kroku wyjaśnienie, dlaczego sekunda przestępna spowodowała, że timery futex wygasały przedwcześnie i ciągle, zwiększając obciążenie procesora.