Bu, ntpd, çekirdeğe bir artık saniye eklemesini söylemek için adjtimex (2) 'yi çağırdığında bir livelock'tan kaynaklanır. Lkml ilanı gör http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html
Red Hat ayrıca KB makalelerini de güncellemelidir. https://access.redhat.com/knowledge/articles/15145
GÜNCELLEME: Red Hat'ın burada sadece bu sayı için ikinci bir KB makalesi var: https://access.redhat.com/knowledge/solutions/154713 - önceki makale daha önce ilgisiz bir problem için
Çözüm sadece ntpd'yi kapatmak. Ntpd zaten adjtimex (2) çağrısını yaptıysa, ntpd'yi devre dışı bırakmanız ve% 100 güvenli olması için yeniden başlatmanız gerekebilir.
Bu, RHEL 6'yı ve daha yeni çekirdekleri çalıştıran (yaklaşık 2.6.26'dan daha yeni) diğer dağıtımları etkiler, ancak RHEL 5'i etkilemez.
Bunun , sıçrama saniyesinin gerçekte gerçekleşmesi planlanandan önce meydana gelmesinin nedeni, ntpd'nin çekirdeğin gece yarısını ikinci saniye idare etmesine izin vermesidir, ancak gece yarısından önce saniyeyi atması için çekirdeği uyarması gerekir. Bu nedenle ntpd artık saniye saniye boyunca adjtimex'i (2) çağırır, bu noktada bu hata tetiklenir.
Eğer adjtimex (8) kurmuşsanız, bayrak 16 ayarlanmış olup olmadığını belirlemek için bu betiği kullanabilirsiniz. Bayrak 16, "artık ikinci ekleme" dir:
adjtimex -p | perl -p -e 'undef $_, next unless m/status: (\d+)/; (16 & $1) && print "leap second flag is set:\n"'
GÜNCELLEME:
Red Hat, KB makalelerini not etmek için güncelledi: "RHEL 6 müşterileri, NTP Gözetleme bildirisini alırken NMI Gözcü'nün askıda kalmasını algılamasına neden olan bilinen bir sorundan etkilenebilir. Bu sorun zamanında ele alınıyor. artık ilan ve bu sorunu yaşamamış, o zaman artık etkilenmiyorlar. ”
GÜNCELLEME: Yukarıdaki dil Red Hat makalesinden kaldırıldı; ve adjtimex (2) kilitlenme sorununu ayrıntılandıran ikinci bir KB çözümü eklendi: https://access.redhat.com/knowledge/solutions/154713
Bununla birlikte, IBM Engineer John Stultz tarafından LKML postasındaki kod değişikliği, artık saniye gerçekten uygulandığında bir kilitlenme olabileceğine dikkat çeker, bu nedenle ntpd'yi devre dışı bıraktıktan sonra yeniden başlatmayı veya adjtimex (8) kullanarak artık saniyeyi devre dışı bırakmak isteyebilirsiniz.
NİHAİ GÜNCELLEME:
Şey, ben çekirdek devi değilim, ama John Stultz'in yamasını burada tekrar gözden geçirdim: https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h = 6b43ae8a619d17c4935c3320d2ef9e92bdeed05d
Bu sefer doğru okuyorsam, artık saniye uygulandığında başka bir kilitlenme olduğu konusunda yanılmışım. KB girişlerine göre bu, Red Hat'in görüşü gibi görünüyor. Ancak ntpd'yi devre dışı bıraktıysanız, 10 dakika daha devre dışı bırakın, böylece ntpd adjtimex'i çağırdığında kilitlenmeye girmezsiniz.
Yakında daha fazla hata olup olmadığını öğreneceğiz :)
POST-LEAP İKİNCİ GÜNCELLEME:
Son birkaç saatimi ntpd ve pre-patch (buggy) çekirdek kodunu okuyarak geçirdim ve burada çok yanlış olabilirken, neler olduğunu düşündüğümü açıklamaya çalışacağım:
İlk olarak, ntpd her zaman adjtimex'i (2) çağırır. Bunu, ntp_loopfilter.c dosyasında local_clock içinde tanımlanmış olan "saat döngüsü filtresinin" bir parçası olarak yapar. Bu kodu burada görebilirsiniz: http://www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (ntp sürüm 4.2.6'dan).
Saat döngüsü filtresi oldukça sık çalışır - ntpd her zaman dakikada bir 17 dakika veya daha fazla olan akış yukarı sunucularını sorguladığında çalışır. Saat döngüsü filtresinin ilgili biti:
if (sys_leap == LEAP_ADDSECOND)
ntv.status |= STA_INS;
Ve sonra:
ntp_adjtime(&ntv)
Başka bir deyişle, artık bir saniyenin geçtiği günlerde, ntpd "STA_INS" bayrağını ayarlar ve adjtimex (2) öğesini çağırır (taşınabilirliği sarmalayıcısı aracılığıyla).
Bu sistem çağrısı çekirdeğe doğru ilerliyor. İşte ilgili çekirdek kodu: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c
Çekirdek codepath kabaca bu:
- satır 663 - do_adjtimex rutininin başlangıcı.
- satır 691 - mevcut artık saniye sayacını iptal edin.
- satır 709 - ntp_lock çevirme kilidini tut (bu kilit olası livelock kazasında yer alır)
- satır 724 - call process_adjtimex_modes.
- satır 616 - call process_adj_status.
- line 590 - adjtimex (2) çağrısında ayarlanan bayrakları temel alarak time_status global değişkenini ayarlayın
- satır 592 - time_state global değişkenini kontrol eder. Çoğu durumda, ntp_start_leap_timer'i çağırın.
- satır 554 - time_status global değişkenini kontrol eder. STA_INS ayarlanacaktır, bu yüzden time_state değerini TIME_INS olarak ayarlayın ve artık saniye sayacını başlatmak için hrtimer_start (başka bir çekirdek işlevi) çağırın. Bir zamanlayıcı oluşturma sürecinde, bu kod xtime_lock'u alır. eğer başka bir CPU zaten xtime_lock ve ntp_lock'u yakalamışsa bu gerçekleşirse , çekirdek çekirdeklenir. Bu yüzden John Stultz hrtimers kullanmaktan kaçınmak için yamayı yazdı. Bugün herkesin başına bela açıyordu.
- satır 598 - eğer ntp_start_leap_timer bir sıçrama zamanlayıcıyı gerçekten başlatmadıysa, time_state değerini TIME_OK olarak ayarlayın
- Satır 751 - Çekirdeğin livelock olmadığı varsayılırsa, yığın çözülür ve ntp_lock döndürme kilidi serbest bırakılır.
Burada birkaç ilginç şey var.
İlk olarak, satır 691, adjtimex (2) her çağrıldığında mevcut zamanlayıcıyı iptal eder. Ardından, 554 bu zamanlayıcıyı yeniden oluşturur. Bu, ntpd'nin saat döngüsü filtresini çalıştırdığı her seferde, buggy kodunun çağrıldığı anlamına gelir.
Bu nedenle, ntpd'nin artık ikinci bayrağı koyduktan sonra sistemin çökmeyeceğini söylediklerinde Red Hat'in yanlış olduğuna inanıyorum. Ntpd çalıştıran her sistemin, artık saniyeden 24 saat boyunca her 17 dakikada (veya daha fazla) canlı kalma potansiyeline sahip olduğuna inanıyorum. Bunun neden bu kadar çok sistemin düştüğünü de açıklayabileceğine inanıyorum; tek seferlik çökme şansının saatte 3 şansa kıyasla daha düşük olması muhtemeldir.
GÜNCELLEME: Red Hat'in https://access.redhat.com/knowledge/solutions/154713 adresindeki KB çözümünde , Red Hat mühendisleri aynı sonuca vardılar (ntpd çalışanı sürekli olarak buggy koduna çarpacaktı). Gerçekten de benden birkaç saat önce yaptılar. Bu çözüm https://access.redhat.com/knowledge/articles/15145 adresindeki ana makaleyle bağlantılı değildi , bu yüzden şimdiye kadar farketmedim.
İkincisi, bu, yüklü sistemlerin neden çökme ihtimalinin daha yüksek olduğunu açıklar. Yüklenen sistemler, daha fazla kesintilerle uğraşacak ve "do_tick" çekirdek işlevinin daha sık çağrılmasına neden olacak ve zamanlayıcı oluşturulurken bu kodun ntp_lock komutunu çalıştırma ve yakalama şansını vermiştir.
Üçüncüsü, artık saniye gerçekleştiğinde sistemin çökme şansı var mı? Emin değilim, ama muhtemelen evet, çünkü artık saniye ayarını ateşleyen ve gerçekten gerçekleştiren zamanlayıcı (388 satırındaki ntp_leap_second) aynı zamanda ntp_lock döndürme kilidini kapar ve hrtimer_add_expires_ns çağrısına sahiptir. Bu çağrının bir livelock'a da neden olup olamayacağını bilemiyorum, ama imkansız gözükmüyor.
Son olarak, ikinci saniye çalıştıktan sonra ikinci saniye bayrağının devre dışı kalmasına neden olan nedir? Buradaki cevap ntpd, adjteks (2) çağırdığında gece yarısından sonraki bir noktada artık bayrağın bayrağını ayarlamayı durduruyor. Bayrak ayarlanmadığından 554 satırındaki kontrol doğru olmaz ve hiçbir zamanlayıcı oluşturulmaz ve 598 satır time_state global değişkenini TIME_OK olarak sıfırlar. Bu, eğer sadece saniye saniye sonra bayrak işaretini adjtimex (8) ile kontrol ettiyseniz neden hala ikinci saniye bayrak setini göreceğinizi açıklar.
Kısacası, bugün için en iyi tavsiye, sonuçta ilk verdiğim gibi görünüyor: ntpd'yi devre dışı bırak ve artık ikinci bayrağı devre dışı bırak.
Ve bazı son düşünceler:
- Linux satıcılarından hiçbiri John Stultz'in yamasını farketmedi ve onu çekirdeklerine uyguladı :(
- John Stultz neden ihtiyaç duyduğu bazı satıcıları uyarmadı? belki de livelock'un şansı yeterince düşük gözüküyordu.
- Artık saniye uygulandığında Java işlemlerinin kilitlendiğini veya döndüğünü duydum. Belki de Google’ın öncülüğünü izlemeli ve sistemimize artık saniye nasıl uygulayacağımızı yeniden düşünmeliyiz: http://googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html
06.02 John Stultz'dan Güncelleme:
https://lkml.org/lkml/2012/7/1/203
Yazı, artık saniyenin futex zamanlayıcılarının CPU yükünü hızlandırarak erken ve sürekli olarak sona ermesine neden olduğu adım adım gözden geçirme içeriyordu.