Adakah orang lain yang mengalami tingkat crash server Linux yang tinggi pada lompatan hari kedua?

365

* CATATAN: jika server Anda masih memiliki masalah karena kernel bingung, dan Anda tidak dapat reboot - solusi paling sederhana yang diusulkan dengan tanggal gnu diinstal pada sistem Anda adalah: date -s now. Ini akan mengatur ulang variabel internal "time_was_set" kernel dan memperbaiki loop hogging CPU futex di java dan alat userspace lainnya. Saya telah menempatkan perintah ini di sistem saya dan mengonfirmasi bahwa ia melakukan apa yang tertulis di kaleng *

POSTMORTEM

Anticlimax: satu-satunya hal yang mati adalah tautan VPN (openvpn) saya ke kluster, jadi ada beberapa detik yang mengasyikkan saat ia dibangun kembali. Segala sesuatu yang lain baik-baik saja, dan memulai ntp berjalan dengan bersih setelah lompatan kedua berlalu.

Saya telah menulis pengalaman penuh saya hari ini di http://blog.fastmail.fm/2012/07/03/a-story-of-leaping-seconds/

Jika Anda melihat blog Marco di http://my.opera.com/marcomarongiu/blog/2012/06/01/an-humble-attempt-to-work-around-the-leap-second - ia memiliki solusi untuk secara bertahap mengubah waktu lebih dari 24 jam menggunakan ntpd -x untuk menghindari lompatan 1 detik. Ini adalah metode pengolesan alternatif untuk menjalankan infrastruktur ntp Anda sendiri.


Hanya hari ini, Sabtu 30 Juni 2012 - dimulai segera setelah dimulainya hari GMT. Kami memiliki beberapa server di pusat data yang berbeda yang dikelola oleh tim yang berbeda semuanya menjadi gelap - tidak merespons ping, layar kosong.

Mereka semua menjalankan Debian Squeeze - dengan segalanya mulai dari stock kernel hingga custom 3.2.21 build. Sebagian besar adalah pisau Dell M610, tetapi saya juga baru saja kehilangan Dell R510 dan departemen lain juga kehilangan mesin dari vendor lain. Ada juga IBM x3550 yang lebih tua yang mogok dan yang saya pikir mungkin tidak terkait, tetapi sekarang saya bertanya-tanya.

Satu crash yang saya dapatkan dari screen dump mengatakan:

[3161000.864001] BUG: spinlock lockup on CPU#1, ntpd/3358
[3161000.864001]  lock: ffff88083fc0d740, .magic: dead4ead, .owner: imapd/24737, .owner_cpu: 0

Sayangnya semua blade seharusnya memiliki kdump dikonfigurasi, tetapi mereka mati sangat keras sehingga kdump tidak memicu - dan mereka memiliki konsol kosong dihidupkan. Saya telah menonaktifkan konsol yang kosong sekarang, jadi semoga saja saya mendapat informasi lebih lanjut setelah kecelakaan berikutnya.

Hanya ingin tahu apakah itu utas bersama atau "hanya kita". Sangat aneh bahwa mereka adalah unit yang berbeda di pusat data yang berbeda yang dibeli pada waktu yang berbeda dan dijalankan oleh admin yang berbeda (saya menjalankan FastMail.FM) ... dan sekarang bahkan perangkat keras vendor yang berbeda. Sebagian besar mesin yang mengalami crash telah beroperasi selama beberapa minggu / bulan dan menjalankan kernel seri 3.1 atau 3.2.

Kecelakaan terbaru adalah mesin yang baru berjalan sekitar 6 jam menjalankan 3.2.21.

WORKAROUND THE

Ok orang, inilah cara saya mengatasinya.

  1. ntp dinonaktifkan: /etc/init.d/ntp stop
  2. dibuat http://linux.brong.fastmail.fm/2012-06-30/fixtime.pl (kode dicuri dari Marco, lihat posting blog dalam komentar)
  3. berlari fixtime.pltanpa argumen untuk melihat bahwa ada set kedua lompatan
  4. berlari fixtime.pldengan argumen untuk menghapus lompatan kedua

CATATAN: tergantung pada adjtimex. Saya telah meletakkan salinan adjtimexbinary squeeze di http://linux.brong.fastmail.fm/2012-06-30/adjtimex - itu akan berjalan tanpa ketergantungan pada sistem 64 bit squeeze. Jika Anda meletakkannya di direktori yang sama fixtime.pl, itu akan digunakan jika sistem yang satu tidak ada. Jelas jika Anda tidak perlu memeras 64-bit ... temukan milik Anda.

Saya akan mulai ntplagi besok.

Seperti yang disarankan oleh pengguna anonim - alternatif untuk menjalankan adjtimexadalah dengan mengatur waktu sendiri, yang mungkin juga akan menghapus penghitung leapsecond.

Gondwana Bron
sumber
58
Ada lompatan kedua hari ini, tanggal 30. Saya ragu untuk menyiratkan bahwa itu adalah masalah Anda, tetapi saya akan mengawasi mesin Debian saya dengan cermat.
jscott
2
sejak pagi hari Kami telah kehilangan setidaknya 9 kotak pemerasan debian berbeda dari berbagai vendor yang semuanya menjalankan stock squeeze 2.6.32 kernel. kami belum bisa mendapatkan crash dump karena konsol kosong juga ...
kargig
3
lkml memposting tentang lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html
Daniel S. Sterling
2
Terima kasih telah melaporkan ini! Saya sekarang menatap server saya dengan sangat, sangat dekat.
Janne Pikkarainen
5
Utas LKML menunjukkan bahwa itu date -s "`date`"membantu - itu tentu saja membantu saya.
Runcing

Jawaban:

321

Ini disebabkan oleh livelock ketika ntpd memanggil adjtimex (2) untuk memberitahu kernel untuk memasukkan leap second. Lihat lkml memposting http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html

Red Hat juga harus memperbarui artikel KB mereka. https://access.redhat.com/knowledge/articles/15145

UPDATE: Red Hat memiliki artikel KB kedua hanya untuk masalah ini di sini: https://access.redhat.com/knowledge/solutions/154713 - artikel sebelumnya adalah untuk masalah sebelumnya yang tidak terkait

Cara mengatasinya adalah dengan mematikan ntpd. Jika ntpd sudah mengeluarkan panggilan adjtimex (2), Anda mungkin perlu menonaktifkan ntpd dan reboot agar 100% aman.

Ini mempengaruhi RHEL 6 dan distro lain yang menjalankan kernel yang lebih baru (lebih baru dari kira-kira 2.6.26), tetapi tidak RHEL 5.

Alasan ini terjadi sebelum lompatan kedua sebenarnya dijadwalkan terjadi adalah bahwa ntpd memungkinkan kernel menangani lompatan kedua di tengah malam, tetapi perlu mengingatkan kernel untuk memasukkan lompatan kedua sebelum tengah malam. Oleh karena itu ntpd memanggil adjtimex (2) sekitar hari kabisat detik, saat bug ini dipicu.

Jika Anda telah memasang adjtimex (8), Anda dapat menggunakan skrip ini untuk menentukan apakah flag 16 diatur. Bendera 16 adalah "menyisipkan lompatan kedua":

adjtimex -p | perl -p -e 'undef $_, next unless m/status: (\d+)/; (16 & $1) && print "leap second flag is set:\n"'

MEMPERBARUI:

Red Hat telah memperbarui artikel KB mereka untuk mencatat: "Pelanggan RHEL 6 mungkin terpengaruh oleh masalah yang diketahui yang menyebabkan NMI Watchdog mendeteksi hang ketika menerima pengumuman NTP leapsecond. Masalah ini sedang ditangani tepat waktu. Jika sistem Anda menerima Pengumuman leapsecond dan tidak mengalami masalah ini, maka mereka tidak lagi terpengaruh. "

UPDATE: Bahasa di atas telah dihapus dari artikel Red Hat; dan solusi KB kedua ditambahkan dengan merinci masalah kecelakaan adjtimex (2): https://access.redhat.com/knowledge/solutions/154713

Namun, perubahan kode pada pos LKML oleh Insinyur IBM John Stultz mencatat mungkin juga ada jalan buntu ketika lompatan kedua benar-benar diterapkan, jadi Anda mungkin ingin menonaktifkan lompatan kedua dengan me-reboot atau menggunakan adjtimex (8) setelah menonaktifkan ntpd.

PEMBARUAN AKHIR:

Yah, saya bukan kernel dev, tapi saya meninjau patch John Stultz lagi di sini: https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h = 6b43ae8a619d17c4935c3320d2ef9e92bdeed05d

Jika saya membacanya dengan benar kali ini, saya salah tentang kebuntuan lain ketika lompatan kedua diterapkan. Itu tampaknya menjadi pendapat Red Hat juga, berdasarkan entri KB mereka. Namun, jika Anda telah menonaktifkan ntpd, biarkan dinonaktifkan selama 10 menit lagi, sehingga Anda tidak menemui jalan buntu ketika ntpd memanggil adjtimex (2).

Kami akan mencari tahu apakah ada bug lagi segera :)

PEMBARUAN KEDUA POST-LEAP:

Saya menghabiskan beberapa jam terakhir membaca kode kernel ntpd dan pre-patch (buggy), dan sementara saya mungkin sangat salah di sini, saya akan mencoba menjelaskan apa yang saya pikir sedang terjadi:

Pertama, ntpd memanggil adjtimex (2) sepanjang waktu. Ia melakukan ini sebagai bagian dari "clock loop filter" -nya, didefinisikan dalam local_clock di ntp_loopfilter.c. Anda dapat melihat kode itu di sini: http://www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (dari ntp versi 4.2.6).

Filter loop jam berjalan cukup sering - ini berjalan setiap kali ntpd polling server hulu, yang secara default setiap 17 menit atau lebih. Bit filter loop jam yang relevan adalah:

if (sys_leap == LEAP_ADDSECOND)
    ntv.status |= STA_INS;

Lalu:

ntp_adjtime(&ntv)

Dengan kata lain, pada hari-hari ketika ada lompatan kedua, ntpd menetapkan flag "STA_INS" dan memanggil adjtimex (2) (melalui portabilitas-pembungkusnya).

Panggilan sistem itu menuju kernel. Berikut kode kernel yang relevan: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c

Kernel codep kira-kira ini:

  • baris 663 - mulai dari do_adjtimex rutin.
  • line 691 - batalkan pengatur detik kabisat yang ada.
  • baris 709 - ambil ntp_lock spinlock (kunci ini terlibat dalam kemungkinan kecelakaan livelock)
  • baris 724 - panggil process_adjtimex_modes.
  • saluran 616 - panggil process_adj_status.
  • line 590 - set variabel global time_status, berdasarkan pada flag yang ditetapkan pada panggilan adjtimex (2)
  • baris 592 - periksa time_state variabel global. dalam banyak kasus, panggil ntp_start_leap_timer.
  • baris 554 - periksa time_status variabel global. STA_INS akan diset, jadi atur time_state ke TIME_INS dan panggil hrtimer_start (fungsi kernel lain) untuk memulai timer kedua lompatan. dalam proses membuat timer, kode ini mengambil xtime_lock. jika ini terjadi ketika CPU lain telah meraih xtime_lock dan ntp_lock, maka kernel livelocks. inilah sebabnya John Stultz menulis tambalan untuk menghindari penggunaan hrtimer. Inilah yang menyebabkan masalah semua orang hari ini.
  • baris 598 - jika ntp_start_leap_timer tidak benar-benar memulai timer kabisat, atur time_state ke TIME_OK
  • baris 751 - dengan asumsi kernel tidak livelock, stack dibatalkan dan spinlock ntp_lock dilepaskan.

Ada beberapa hal menarik di sini.

Pertama, saluran 691 membatalkan timer yang ada setiap kali adjtimex (2) dipanggil. Kemudian, 554 menciptakan kembali timer itu. Ini berarti setiap kali ntpd menjalankan clock loop filter-nya, kode buggy dipanggil.

Karena itu saya percaya Red Hat salah ketika mereka mengatakan bahwa sekali ntpd menetapkan flag leap-second, sistem tidak akan crash. Saya percaya setiap sistem yang menjalankan ntpd memiliki potensi untuk menghidupkan setiap 17 menit (atau lebih) selama 24 jam sebelum lompatan-detik. Saya percaya ini juga dapat menjelaskan mengapa banyak sistem crash; satu kali kesempatan tabrakan akan jauh lebih kecil kemungkinannya mengenai dibandingkan dengan 3 peluang per jam.

PEMBARUAN: Dalam solusi KB Red Hat di https://access.redhat.com/knowledge/solutions/154713 , para insinyur Red Hat sampai pada kesimpulan yang sama (bahwa menjalankan ntpd akan terus menerus mengenai kode kereta). Dan memang mereka melakukannya beberapa jam sebelum saya melakukannya. Solusi ini tidak ditautkan ke artikel utama di https://access.redhat.com/knowledge/articles/15145 , jadi saya tidak menyadarinya sampai sekarang.

Kedua, ini menjelaskan mengapa sistem yang dimuat lebih cenderung macet. Sistem yang dimuat akan menangani lebih banyak interupsi, menyebabkan fungsi kernel "do_tick" dipanggil lebih sering, memberikan lebih banyak peluang untuk kode ini untuk menjalankan dan mengambil ntp_lock ketika timer sedang dibuat.

Ketiga, apakah ada kemungkinan sistem crash ketika lompatan kedua benar-benar terjadi? Saya tidak tahu pasti, tetapi mungkin ya, karena timer yang menyala dan benar-benar menjalankan penyesuaian leap-second (ntp_leap_second, pada baris 388) juga mengambil ntp_lock spinlock, dan memiliki panggilan ke hrtimer_add_expires_ns. Saya tidak tahu apakah panggilan itu juga dapat menyebabkan livelock, tetapi sepertinya itu tidak mungkin.

Akhirnya, apa yang menyebabkan flag leap-second dinonaktifkan setelah leap-second berjalan? Jawabannya ada ntpd berhenti mengatur lompatan-bendera di beberapa titik setelah tengah malam ketika panggilan adjtimex (2). Karena flag tidak disetel, tanda centang pada baris 554 tidak akan benar, dan tidak ada timer akan dibuat, dan baris 598 akan mengatur ulang variabel global time_state ke TIME_OK. Ini menjelaskan mengapa jika Anda memeriksa flag dengan adjtimex (8) tepat setelah leap second, Anda masih akan melihat set flag leap-second.

Singkatnya, saran terbaik untuk hari ini adalah yang pertama kali saya berikan: disable ntpd, dan nonaktifkan flag leap-second.

Dan beberapa pemikiran terakhir:

  • tidak ada vendor Linux yang memperhatikan patch John Stultz dan menerapkannya pada kernel mereka :(
  • mengapa John Stultz tidak memperingatkan beberapa vendor bahwa ini diperlukan? mungkin peluang livelock tampak cukup rendah sehingga kebisingan tidak dijamin.
  • Saya telah mendengar laporan tentang proses Java mengunci atau memutar ketika leap-second diterapkan. Mungkin kita harus mengikuti petunjuk Google dan memikirkan kembali bagaimana kita menerapkan lompatan detik ke sistem kita: http://googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html

06/02 Pembaruan dari John Stultz:

https://lkml.org/lkml/2012/7/1/203

Posting tersebut berisi langkah demi langkah mengapa lompatan kedua menyebabkan timer futex berakhir sebelum waktunya dan terus menerus, sehingga meningkatkan beban CPU.

Daniel S. Sterling
sumber
7
Terima kasih atas jawabannya. Jadi seluruh server kami duduk menunggu untuk mogok. Menyenangkan. Bergulir memulai kembali di sini kita datang!
Bron Gondwana
3
Bagaimana saya tahu jika adjtimexsudah dikeluarkan, apakah kernel mencetak sesuatu dalam dmesg? Peluang apa yang ada pada sistem yang tidak crash sebelum mematikan ntpd akan crash?
Hubert Kario
3
Hubert: jalankan "adjtimex" (biasanya dikemas secara terpisah) dan cari bendera 16 untuk menunjukkan lompatan kedua tertunda.
Dominic Cleal
22
Anda akan membenci topi rep.
Wesley
26
@WesleyDavid: Jangan khawatir, tutup rep akan diatur ulang pada tengah malam UTC. Mungkin.
mmyers
33

Ini sangat memukul kami. Setelah memulai kembali banyak dari host kami, berikut ini ternyata menjadi sangat sederhana dan memalukan efektif tanpa host restart:

/etc/init.d/ntp stop
ntpdate 0.us.pool.ntp.org
/etc/init.d/ntp start

Yang diperlukan hanyalah mengatur ulang jam sistem. Sheesh. Apa yang saya berikan untuk mengetahui hal ini enam jam yang lalu.

HikeOnPast
sumber
8
date -s "`date`"bekerja untukku.
Runcing
@DeanB: Saya memposting pukul 3 pagi UTC yang mengatur ulang jam melakukan trik, sayangnya butuh beberapa saat untuk dimoderasi. Kami juga mulai me-reboot server
Gregor
24

Program C sederhana yang menghapus bit lompatan kedua di bidang status waktu kernel:

#include <sys/timex.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char **argv) {
    struct timex txc;
    int ret;

    (void) argc;
    (void) argv;

    bzero(&txc, sizeof(txc));
    txc.modes = 0;  /* fetch */
    ret = adjtimex(&txc);
    if (ret < 0) {
        perror("adjtimex (get)");
        return 1;
    }

    txc.modes = ADJ_STATUS;
    txc.status &= ~16;
    ret = adjtimex(&txc);
    if (ret < 0) {
        perror("adjtimex (set)");
        return 1;
    }

    return 0;
}

Simpan sebagai lsec.c, kompilasi dengan gcc -Wall -Wextra -o lsec lsec.cdan jalankan sebagai root.

Anda mungkin ingin menghentikan ntpd sebelum menjalankannya, dan mulai ulang ntpd setelah detik kabisat.

jon
sumber
Apa yang (void) argc;berhasil? Heningkan peringatan untuk variabel yang tidak digunakan? Tidakkah menggunakan int main()hasil yang sama? Tidak mencoba menjadi pedant, saya benar-benar ingin tahu.
gparent
18

Postmortem tampaknya ./lsec tidak berpengaruh.

Apa yang kami lihat adalah banyak proses softirqd memakan CPU (biasanya linier dengan beban proses java)

Apa yang berfungsi untuk memperbaiki POSTMORTEM dengan detik kabisat yang sudah diterapkan oleh ntp adalah sebagai berikut:

Tampaknya cukup untuk hanya mengeluarkan:

export LANG="en_EN"; date -s "`date`"

Ini harus mengurangi beban tanpa ntpd restart atau reboot. Atau Anda dapat mengeluarkan:

apt-get install ntpdate
/etc/init.d/ntpd stop; ntpdate pool.ntp.org; /etc/init.d/ntpd start
Gregor
sumber
mengapa sntp -sdan tidak ntpdate?
errordeveloper
ntpdate hanyalah pembungkus untuk sntp di sini, tentu tidak apa-apa untuk menggunakan ntpdate juga.
Gregor
ah saya benar-benar ketinggalan ada paket ntpdate untuk memeras di mana sebenarnya itu adalah biner. Saya telah mengedit posting saya untuk memasukkan ini.
Gregor
Saya pernah mendengar laporan serupa tentang memperbaiki masalah ini (seperti menggunakan date -s). Kedengarannya seperti perbaikan hanya membutuhkan pengaturan waktu sistem alih-alih mematikannya (perilaku ntpd default saat offset kecil). Saya menduga pengaturan waktu menyebabkan mekanisme penyimpanan waktu internal kernel untuk mengatur ulang sendiri.
Patrick
4
Aplikasi java saya juga menggunakan CPU berduri (dengan jumlah waktu CPU yang dihabiskan di softirqd), ini memperbaikinya.
Hubert Kario
16

http://my.opera.com/marcomarongiu/blog/2012/03/12/no-step-back tampaknya mengindikasikan bahwa kernel pemerasan Debian tidak akan menangani leap second.

Utas ini di comp.protocols.tim.ntp menarik, juga: https://groups.google.com/forum/?fromgroups#!topic/comp.protocols.time.ntp/KSflIgjUdPE

Yang mengatakan, lompatan kedua belum terjadi: 23:59:60 UTC

Akhirnya, https://access.redhat.com/knowledge/articles/15145 memiliki yang berikut untuk mengatakan: "Ketika lompatan kedua terjadi, kernel mencetak pesan ke log sistem. Ada kemungkinan bahwa pencetakan pesan ini dapat menyebabkan kernel macet di Red Hat Enterprise Linux. "

Luca Filipozzi
sumber
Tetapi kernel 3.2.21 seharusnya, mungkin - yang merupakan salah satu dari setidaknya satu mesin yang rusak berjalan
Bron Gondwana
Pada beberapa mesin yang ditunjukkan Bron, sebenarnya kami telah meluncurkan perbaikan yang seharusnya menangani lompatan kedua yang akan datang.
Cosimo
dapatkah Anda memposting perbaikan di tempat sehingga orang lain dapat meninjau / menyarankan ide / mencoba?
kargig
Saya tidak memiliki perbaikan ... Saya hanya mengumpulkan info. Mungkin seharusnya menempatkan ini sebagai komentar terhadap pertanyaan awal.
Luca Filipozzi
4
my.opera.com/marcomarongiu/blog/2012/06/01/… mengandung lebih banyak detail tentang cara memperbaikinya
Bron Gondwana