यह एक लाइवलॉक के कारण होता है जब ntpd एक लीप सेकंड डालने के लिए कर्नेल को बताने के लिए adjtimex (2) कहता है। देखें lkml पोस्टिंग http://lkml.indiana.edu/hypermail/linux/kernel/1203.1.14545.html
Red Hat को उनके KB लेख को भी अद्यतन करना चाहिए। https://access.redhat.com/knowledge/articles/15145
अद्यतन: रेड हैट यहाँ सिर्फ इस समस्या के लिए एक दूसरे KB लेख है: https://access.redhat.com/knowledge/solutions/154713 - पिछले लेख एक पहले, असंबंधित समस्या के लिए है
काम के आसपास बस ntpd बंद करने के लिए है। यदि ntpd ने पहले से ही adjtimex (2) कॉल जारी किया है, तो आपको ntpd को निष्क्रिय करने और रिबूट को 100% सुरक्षित होने की आवश्यकता हो सकती है।
यह आरएचईएल 6 और अन्य डिस्ट्रोस को नई गुठली (लगभग 2.6.26 की तुलना में नया) से प्रभावित करता है, लेकिन आरएचईएल 5 को नहीं।
लीप सेकंड से पहले होने का कारण वास्तव में होने वाला है, यह है कि ntpd कर्नेल को आधी रात को लीप सेकंड को संभालने देता है, लेकिन कर्नेल को मध्यरात्रि से पहले लीप सेकंड को डालने के लिए सचेत करने की आवश्यकता है। ntpd इसलिए adjtimex (2) को लीप सेकेंड के दिन के दौरान कभी-कभी कहता है, जिस बिंदु पर यह बग ट्रिगर होता है।
यदि आपके पास adjtimex (8) स्थापित है, तो आप इस स्क्रिप्ट का उपयोग यह निर्धारित करने के लिए कर सकते हैं कि ध्वज 16 सेट है या नहीं। फ़्लैग 16 में "लीप सेकंड डालना" है:
adjtimex -p | perl -p -e 'undef $_, next unless m/status: (\d+)/; (16 & $1) && print "leap second flag is set:\n"'
अपडेट करें:
रेड हैट ने नोट करने के लिए अपने KB लेख को अपडेट किया है: "RHEL 6 ग्राहक एक ज्ञात समस्या से प्रभावित हो सकते हैं जो NMI वॉचडॉग को एनटीपी लीप्सकॉन्ड की घोषणा प्राप्त करते समय एक हैंग का पता लगाने का कारण बनता है। इस मुद्दे को समयबद्ध तरीके से संबोधित किया जा रहा है। यदि आपके सिस्टम को प्राप्त होता है। लेप्सकॉन्ड की घोषणा और इस मुद्दे का अनुभव नहीं किया, तो वे अब प्रभावित नहीं होते हैं। ”
अद्यतन: उपरोक्त भाषा को Red Hat लेख से हटा दिया गया था; और एक दूसरा KB समाधान adjtimex (2) क्रैश मुद्दे का विवरण देते हुए जोड़ा गया था: https://access.redhat.com/knowledge/solutions/154713
हालाँकि, IBM अभियंता जॉन स्टल्त्ज़ द्वारा एलकेएमएल पोस्ट में कोड परिवर्तन भी हो सकता है जब लीप सेकंड वास्तव में लागू होता है, इसलिए आप ntpd को अक्षम करने के बाद adjtimex (8) को रिबूट या उपयोग करके लीप सेकंड को निष्क्रिय करना चाह सकते हैं।
अंतिम अद्यतन:
ठीक है, मैं कर्नेल देव नहीं हूं, लेकिन मैंने यहां जॉन स्टुल्ट्ज के पैच की फिर से समीक्षा की: https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git=a=commit;h = 6b43ae8a619d17c4935c3320d2ef9e92bdeed05d
अगर मैं इस समय इसे पढ़ रहा हूं, तो मैं गलत था कि जब दूसरा छलांग लगाया जाता है तो एक और गतिरोध होता है। ऐसा लगता है कि Red Hat की राय उनके KB प्रविष्टि पर आधारित है। हालाँकि, यदि आपने ntpd को अक्षम कर दिया है, तो इसे 10 मिनट के लिए अक्षम रखें, ताकि ntpd adjtimex (2) कॉल करने पर आप गतिरोध से न टकराएं।
हमें पता चल जाएगा कि क्या जल्द ही कोई और कीड़े हैं :)
पोस्ट-लेप उत्तर अद्यतन:
मैंने पिछले कुछ घंटे ntpd और प्री-पैच (छोटी गाड़ी) कर्नेल कोड के माध्यम से पढ़ने में बिताए, और जब मैं यहां बहुत गलत हो सकता हूं, तो मैं यह बताने का प्रयास करूंगा कि मुझे क्या लगता है:
सबसे पहले, ntpd हर समय adjtimex (2) कॉल करता है। यह अपने "क्लॉक लूप फिल्टर" के हिस्से के रूप में करता है, जिसे ntp_loopfilter.c में local_clock में परिभाषित किया गया है। आप उस कोड को यहाँ देख सकते हैं: http://www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (ntp संस्करण 4.2.6 से)।
क्लॉक लूप फ़िल्टर काफी बार चलता है - यह हर बार चलता है जब ntpd अपने अपस्ट्रीम सर्वर को पोल करता है, जो डिफ़ॉल्ट रूप से हर 17 मिनट या उससे अधिक होता है। क्लॉक लूप फ़िल्टर की प्रासंगिक बिट है:
if (sys_leap == LEAP_ADDSECOND)
ntv.status |= STA_INS;
और तब:
ntp_adjtime(&ntv)
दूसरे शब्दों में, उन दिनों में जब एक लीप सेकंड होता है, ntpd "STA_INS" ध्वज सेट करता है और adjtimex (2) (इसके पोर्टेबिलिटी-रैपर के माध्यम से) को कॉल करता है।
वह सिस्टम कॉल कर्नेल के लिए अपना रास्ता बनाता है। यहां प्रासंगिक कर्नेल कोड है: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c
कर्नेल कोडपथ लगभग यही है:
- पंक्ति 663 - do_adjtimex दिनचर्या की शुरुआत।
- लाइन 691 - किसी भी मौजूदा लीप-सेकंड टाइमर को रद्द करें।
- लाइन 709 - ntp_lock स्पिनलॉक को पकड़ो (यह लॉक संभव लाइवलॉक क्रैश में शामिल है)
- लाइन 724 - कॉल process_adjtimex_modes।
- पंक्ति 616 - कॉल process_adj_status।
- लाइन 590 - adjtimex (2) कॉल में सेट किए गए झंडे के आधार पर time_status वैश्विक चर सेट करें
- लाइन 592 - समय-समय पर वैश्विक चर की जाँच करें। ज्यादातर मामलों में, ntp_start_leap_timer को कॉल करें।
- पंक्ति ५५४ - time_status वैश्विक चर की जाँच करें। STA_INS सेट किया जाएगा, इसलिए TIME_INS पर time_state सेट करें और लीप सेकंड टाइमर शुरू करने के लिए hrtimer_start (एक और कर्नेल फ़ंक्शन) को कॉल करें। टाइमर बनाने की प्रक्रिया में, यह कोड xtime_lock को पकड़ लेता है। यदि ऐसा होता है जबकि एक अन्य CPU पहले ही xtime_lock और ntp_lock को पकड़ लेता है, तो कर्नेल लाइवलॉक करता है। यही कारण है कि जॉन स्टल्ज ने हर्टिमर का उपयोग करने से बचने के लिए पैच लिखा था। यही आज सबको परेशान कर रहा था।
- लाइन 598 - अगर ntp_start_leap_timer ने वास्तव में लीप टाइमर शुरू नहीं किया है, तो time_state को TIME_OK पर सेट करें
- लाइन 751 - यह मानते हुए कि कर्नेल लाइवलॉक नहीं है, स्टैक अनवाउंड है और ntp_lock स्पिनलॉक जारी किया गया है।
यहां कुछ दिलचस्प बातें हैं।
सबसे पहले, लाइन 691 मौजूदा टाइमर को हर बार adjtimex (2) कहा जाता है। फिर, 554 उस टाइमर को फिर से बनाता है। इसका मतलब यह है कि प्रत्येक बार जब एनटीपीपी ने अपना क्लॉक लूप फिल्टर चलाया, तो बग्गी कोड लागू किया गया।
इसलिए मेरा मानना है कि Red Hat गलत था जब उन्होंने कहा था कि एक बार ntpd ने लीप-सेकंड फ्लैग सेट कर दिया है, तो सिस्टम क्रैश नहीं होगा। मेरा मानना है कि ntpd को चलाने वाले प्रत्येक सिस्टम में लीप-सेकंड से पहले 24 घंटे की अवधि के लिए हर 17 मिनट (या अधिक) को लाइवलॉक करने की क्षमता थी। मेरा मानना है कि यह भी समझा सकता है कि इतने सारे सिस्टम क्रैश क्यों हुए; एक बार दुर्घटनाग्रस्त होने की संभावना 3 घंटे की तुलना में हिट होने की संभावना बहुत कम होगी।
अद्यतन: https://access.redhat.com/knowledge/solutions/154713 पर Red Hat के KB समाधान में , Red Hat इंजीनियर एक ही निष्कर्ष पर आए (कि ntpd को चलाने पर लगातार छोटी गाड़ी कोड मारा जाएगा)। और वास्तव में उन्होंने ऐसा कई घंटे पहले किया था। यह समाधान https://access.redhat.com/knowledge/articles/15145 पर मुख्य लेख से जुड़ा नहीं था , इसलिए मैंने इसे अब तक नोटिस नहीं किया।
दूसरा, यह बताता है कि भारित सिस्टम के दुर्घटनाग्रस्त होने की अधिक संभावना क्यों थी। लोड सिस्टम अधिक इंटरप्ट को हैंडल कर रहा होगा, जिससे "do_tick" कर्नेल फ़ंक्शन को अधिक बार कॉल किया जा सकेगा, जिससे इस कोड को चलाने और ntp_lock को हथियाने के लिए मौका दिया जा सकता है जबकि टाइमर बनाया जा रहा था।
तीसरा, क्या लीप-सेकंड वास्तव में होने पर सिस्टम के दुर्घटनाग्रस्त होने की संभावना है? मैं निश्चित रूप से नहीं जानता, लेकिन संभवत: हाँ, क्योंकि जो टाइमर आग लगाता है और वास्तव में लीप-सेकंड समायोजन (ntp_leap_second, लाइन 388 पर) निष्पादित करता है, वह भी ntp_lock स्पिनलॉक पकड़ लेता है, और hrtimer_add_expires_ns को कॉल करता है। मुझे नहीं पता कि क्या यह कॉल लाइवलॉक का कारण बन सकता है, लेकिन यह असंभव नहीं लगता।
अंत में, लीप-सेकंड के चलने के बाद लीप-सेकंड फ्लैग को निष्क्रिय करने का क्या कारण है? उत्तरपद है कि ntpd किसी भी समय मध्यरात्रि के बाद छलांग-दूसरा ध्वज लगाना बंद कर देता है जब इसे adjtimex (2) कहते हैं। चूंकि ध्वज सेट नहीं है, लाइन 554 पर चेक सही नहीं होगा, और कोई टाइमर नहीं बनाया जाएगा, और लाइन 598 टाइम_स्टेट वैश्विक चर को TIME_OK पर रीसेट कर देगा। यह बताता है कि अगर आपने लीप सेकंड के ठीक बाद adjtimex (8) के साथ ध्वज की जांच की, तो आपको अभी भी लीप-सेकंड ध्वज सेट दिखाई देगा।
संक्षेप में, आज के लिए सबसे अच्छी सलाह यह लगती है कि मैंने सबसे पहले जो दिया था: ntpd को अक्षम करें, और लीप-सेकंड फ्लैग को अक्षम करें।
और कुछ अंतिम विचार:
- किसी भी लिनक्स विक्रेता ने जॉन स्टल्ज़ के पैच पर ध्यान नहीं दिया और इसे अपनी गुठली पर लगाया :(
- क्यों जॉन Stultz यह आवश्यक था विक्रेताओं में से कुछ को सचेत नहीं किया था? शायद लाइवलॉक का मौका कम लग रहा था कि शोर मचाया नहीं गया था।
- मैंने लीप-सेकंड लागू होने पर जावा प्रक्रियाओं की लॉकिंग या कताई की रिपोर्ट सुनी है। शायद हमें Google की लीड का अनुसरण करना चाहिए और हमारे सिस्टम में लीप-सेकंड लागू करने के तरीके पर पुनर्विचार करना चाहिए: http://googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html
जॉन स्टूल्ट से 06/02 अपडेट:
https://lkml.org/lkml/2012/7/1/203
इस पोस्ट में एक कदम-दर-चरण चलना था, क्यों लीप सेकेंड ने समय से पहले और लगातार, सीपीयू लोड को बढ़ाते हुए फ्यूटेक्स टाइमर को समाप्त कर दिया।