다른 날 도약하는 동안 높은 비율의 Linux 서버 충돌이 발생하는 사람이 있습니까?


365

* 참고 : 혼동 된 커널로 인해 서버에 여전히 문제가 있고 재부팅 할 수없는 경우 시스템에 설치된 gnu 날짜와 함께 제안 된 가장 간단한 해결책은 다음과 같습니다. 커널의 내부 "time_was_set"변수를 재설정하고 Java 및 기타 사용자 공간 도구에서 CPU 호깅 futex 루프를 수정합니다. 나는 자신의 시스템 에서이 명령을 추적하여 주석에서 말하는 것을 확인했습니다.

검시

Anticlimax : 사망 한 것은 클러스터에 대한 내 VPN (openvpn) 링크뿐 이었으므로 다시 구축하는 동안 몇 초 동안 흥미 진진했습니다. 그 밖의 모든 것이 좋았으며 윤초가 지났을 때 ntp가 깨끗하게 시작되었습니다.

나는 http://blog.fastmail.fm/2012/07/03/a-story-of-leaping-seconds/ 에서 오늘의 모든 경험을 작성했습니다.

Marco의 블로그 ( http://my.opera.com/marcomarongiu/blog/2012/06/01/an-humble-attempt-to-work-around-the-leap-second) 를 보면 -솔루션이 있습니다. 1 초 건너 뛰기를 피하기 위해 ntpd -x를 사용하여 24 시간에 걸쳐 시간 변화를 페이징합니다. 이것은 자신의 ntp 인프라를 실행하는 대안적인 번짐 방법입니다.


바로 오늘, GMT가 시작된 직후부터 2012 년 6 월 30 일 토요일입니다. 우리는 다른 팀이 관리하는 다른 데이터 센터에 소수의 서버가 있었으며 핑에 응답하지 않고 화면을 비 웁니다.

그것들은 모두 스톡 커널에서 커스텀 3.2.21 빌드까지 데비안 스퀴즈를 실행하고 있습니다. 대부분 Dell M610 블레이드이지만 Dell R510을 잃어 버렸으며 다른 부서에서도 다른 공급 업체의 시스템을 잃었습니다. 더 오래된 IBM x3550도 충돌했고 관련이 없다고 생각했지만 지금은 궁금합니다.

내가 스크린 덤프를 얻은 충돌은 다음과 같이 말했다.

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

불행히도 블레이드에는 모두 kdump가 구성되어 있었지만 kdump가 트리거되지 않도록 너무 세게 죽었으며 콘솔 블랭킹이 켜졌습니다. 이제 콘솔 블랭킹을 비활성화 했으므로 손가락이 넘어 다음 충돌 후에 더 많은 정보를 얻을 수 있습니다.

그것이 일반적인 스레드인지 아니면 "우리에게만"있는지 알고 싶습니다. 서로 다른 시간에 구입하고 다른 관리자가 운영하는 다른 데이터 센터에서 다른 단위 (FastMail.FM을 실행)와 현재는 다른 공급 업체 하드웨어 인 것이 정말 이상합니다. 충돌 한 대부분의 머신은 몇 주 / 개월 동안 가동되었으며 3.1 또는 3.2 시리즈 커널을 실행했습니다.

가장 최근의 충돌은 약 6 시간 동안 3.2.21을 실행하는 시스템이었습니다.

해결 방법

좋아요 사람들, 여기 내가 어떻게 해결했는지가 있습니다.

  1. 비활성화 된 ntp : /etc/init.d/ntp stop
  2. 생성 http://linux.brong.fastmail.fm/2012-06-30/fixtime.pl (코드 주석의 블로그 게시물을 참조 마르코에서 도난)
  3. fixtime.pl도약 두번째 세트가 있다는 것을 알기 위해 논증없이 달렸다
  4. fixtime.pl도약을 제거하기 위해 인수와 함께 실행

참고 :에 따라 다릅니다 adjtimex. 스퀴즈 adjtimex바이너리 의 사본을 http://linux.brong.fastmail.fm/2012-06-30/adjtimex에 넣었습니다 . 스퀴즈 64 비트 시스템에 의존하지 않고 실행됩니다. 와 같은 디렉토리에 넣으면 fixtime.pl시스템이없는 경우에 사용됩니다. 분명히 당신이 64 비트를 짜지 않으면 ... 자신을 찾으십시오.

ntp내일 다시 시작하겠습니다 .

익명의 사용자가 제안했듯이 달리기의 대안 adjtimex은 시간을 직접 설정하는 것입니다. 이는 아마도 윤초 카운터를 지울 것입니다.


58
오늘은 30 초로 도약합니다. 나는 그것이 당신의 문제임을 암시하는 것을 주저하지만 데비안 머신을 면밀히 지켜 볼 것입니다.
jscott

2
아침부터 우리는 스톡 스퀴즈 2.6.32 커널을 실행하는 다양한 벤더로부터 최소 9 가지의 데비안 스퀴즈 박스를 잃었습니다. 콘솔 블랭킹으로 인해 크래시 덤프를 얻을 수 없었습니다.
kargig

3
이 lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html에 관한 lkml 게시
Daniel S. Sterling

2
보고 해 주셔서 감사합니다! 나는 지금 내 서버를 매우 꼼꼼하게 바라보고있다.
Janne Pikkarainen 2016 년

5
LKML 스레드는 date -s "`date`"도움 이되었다고 지적 했습니다. 확실히 도움이되었습니다.
Pointy

답변:


321

이것은 ntpd가 adjtimex (2)를 호출하여 커널에 윤초를 삽입하도록 지시 할 때 라이브 록에 의해 발생합니다. lkml 게시 http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html 참조

Red Hat은 KB 기사도 업데이트해야합니다. https://access.redhat.com/knowledge/articles/15145

업데이트 : Red Hat은 여기에 단지이 문제에 대한 두 번째 KB 문서를 가지고 : https://access.redhat.com/knowledge/solutions/154713 - 이전 문서 이전, 관련이없는 문제입니다

해결 방법은 ntpd를 끄는 것입니다. ntpd가 이미 adjtimex (2) 호출을 발행 한 경우, ntpd를 비활성화하고 100 % 안전하도록 재부팅해야합니다.

이는 RHEL 6 및 최신 커널을 실행하는 다른 배포판 (약 2.6.26 이상)에는 영향을 주지만 RHEL 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"'

최신 정보:

Red Hat은 KB 기사를 다음과 같이 업데이트했습니다. "RHEL 6 고객은 NTP leapsecond 알림을 수신 할 때 NMI Watchdog이 정지를 감지하는 알려진 문제의 영향을받을 수 있습니다.이 문제는 적시에 해결됩니다. 윤초 발표에이 문제가 발생하지 않으면 더 이상 영향을받지 않습니다. "

업데이트 : 위의 언어는 Red Hat 기사에서 제거되었습니다. adjtimex (2) 충돌 문제를 자세히 설명하는 두 번째 KB 솔루션이 추가되었습니다. https://access.redhat.com/knowledge/solutions/154713

그러나 IBM 엔지니어 John Stultz가 LKML 게시물의 코드를 변경하면 윤초가 실제로 적용될 때 교착 상태가 발생할 수 있으므로 ntpd를 비활성화 한 후 adjtimex (8)를 재부팅하거나 사용하여 윤초를 비활성화 할 수 있습니다.

최종 업데이트 :

글쎄, 나는 커널 개발자는 아니지만 John Stultz의 패치를 다시 검토했다 : https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h = 6b43ae8a619d17c4935c3320d2ef9e92bdeed05d

이번에 올바르게 읽으면 윤초가 적용될 때 또 다른 교착 상태가 발생하는 것이 잘못되었습니다. KB 항목을 기반으로 한 Red Hat의 의견이기도합니다. 그러나 ntpd를 비활성화 한 경우 ntpd가 adjtimex (2)를 호출 할 때 교착 상태에 빠지지 않도록 10 분 동안 비활성화하십시오.

우리는 곧 더 이상 버그가 있는지 알아낼 것입니다 :)

도약 후 두 번째 업데이트 :

나는 지난 몇 시간 동안 ntpd 및 pre-patch (버기) 커널 코드를 읽었으며 여기에서 매우 잘못되었을 수도 있지만, 내가 생각하고있는 것을 설명하려고 노력할 것입니다.

먼저, 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"플래그를 설정하고 aporttime-wrapper를 통해 adjtimex (2)를 호출합니다.

그 시스템 호출은 커널로 향합니다. 관련 커널 코드는 다음과 같습니다. https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c

커널 코드 경로는 대략 다음과 같습니다.

  • 663 행-do_adjtimex 루틴 시작.
  • 691 행-기존 윤초 타이머를 취소합니다.
  • 709 번째 줄-ntp_lock spinlock을 잡아라 (이 자물쇠는 가능한 livelock 충돌과 관련이있다)
  • 724 행-process_adjtimex_modes를 호출하십시오.
  • 616 행-process_adj_status를 호출하십시오.
  • 줄 590-adjtimex (2) 호출에서 설정된 플래그를 기반으로 time_status 전역 변수 설정
  • 592 행-time_state 글로벌 변수를 확인하십시오. 대부분의 경우 ntp_start_leap_timer를 호출하십시오.
  • 554 행-time_status 전역 변수를 확인하십시오. STA_INS가 설정되므로 time_state를 TIME_INS로 설정하고 hrtimer_start (다른 커널 함수)를 호출하여 윤초 타이머를 시작하십시오. 타이머를 만드는 과정에서이 코드는 xtime_lock을 가져옵니다. 다른 CPU가 이미 xtime_lock ntp_lock을 잡고있는 동안 이런 일이 발생 하면 커널 라이브 록이됩니다. John Stultz가 시간제 사용을 피하기 위해 패치를 작성한 이유입니다. 이것이 오늘날 모든 사람에게 문제를 일으키는 원인입니다.
  • 598 행-ntp_start_leap_timer가 실제로 도약 타이머를 시작하지 않은 경우 time_state를 TIME_OK로 설정하십시오.
  • line 751-커널이 라이브 록하지 않는다고 가정하면 스택이 풀리고 ntp_lock spinlock이 해제됩니다.

여기 몇 가지 흥미로운 것들이 있습니다.

먼저, 라인 691은 adjtimex (2)가 호출 될 때마다 기존 타이머를 취소합니다. 그런 다음 554는 해당 타이머를 다시 만듭니다. 이것은 ntpd가 클럭 루프 필터를 실행할 때마다 버그가있는 코드가 호출되었음을 의미합니다.

따라서 ntpd가 윤초 플래그를 설정하면 시스템이 중단되지 않는다고 말했을 때 Red Hat이 잘못되었다고 생각합니다. ntpd를 실행하는 각 시스템은 윤초 전 24 시간 동안 17 분 (또는 그 이상)마다 라이브 록이 생길 가능성이 있다고 생각합니다. 나는 이것이 왜 그렇게 많은 시스템이 충돌했는지 설명 할 수 있다고 믿는다. 한 번의 충돌 가능성은 시간당 3 번의 기회에 비해 적을 확률이 훨씬 낮습니다.

업데이트 : https://access.redhat.com/knowledge/solutions/154713 의 Red Hat의 KB 솔루션에서 Red Hat 엔지니어는 동일한 결론에 도달했습니다 (nttpd를 실행하면 버그가있는 코드가 계속 발생합니다). 그리고 실제로 그들은 몇 시간 전에 그렇게했습니다. 이 솔루션은 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_state 전역 변수를 TIME_OK로 재설정합니다. 이것은 윤초 직후 adjtimex (8)로 플래그를 확인한 경우에도 윤초 플래그 설정이 계속 표시되는 이유를 설명합니다.

요컨대, 오늘 가장 좋은 조언은 내가 처음으로 준 것 같습니다 : ntpd를 비활성화하고 윤초 플래그를 비활성화하십시오.

그리고 마지막 생각들 :

  • 리눅스 벤더 중 어느 누구도 John Stultz의 패치를 눈치 채지 않고 커널에 적용하지 않았습니다.
  • 왜 John Stultz가 이것이 필요한 공급 업체 중 일부에게 경고하지 않았습니까? 아마도 라이브 록의 가능성이 낮게 들려서 소음이 들리지 않는 것 같습니다.
  • 윤초가 적용될 때 Java 프로세스가 잠기거나 회전한다는보고를 들었습니다. 아마도 Google의 리드를 따라 시스템에 윤초를 적용하는 방법을 다시 생각해야합니다. http://googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html

John Stultz의 06/02 업데이트 :

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

포스트에는 왜 윤초가 futex 타이머가 조기에 지속적으로 만료되어 CPU 부하가 급증하는지에 대한 단계별 안내가 포함되어 있습니다.


7
훌륭한 답변에 감사드립니다. 나머지 서버는 충돌 대기 중입니다. 아름다운. 롤링이 다시 시작됩니다!
Bron Gondwana 2016 년

3
adjtimex발행 여부를 어떻게 알 수 있습니까? 커널이 dmesg로 인쇄합니까? ntpd를 끄기 전에 충돌하지 않은 시스템이 충돌 할 가능성은 무엇입니까?
휴 버트 카리오

3
허버트 : "adjtimex"(보통 개별적으로 포장되어 있음)를 실행하고 16 초 동안 도약 대기 중임을 나타냅니다.
Dominic Cleal

22
당신은 담당자 모자를 싫어합니다.
웨슬리

26
@WesleyDavid : 걱정하지 마세요. 담당자는 UTC 자정에 재설정됩니다. 아마도.
mmyers 2016 년

33

이것은 우리를 강하게 맞았다. 많은 호스트를 다시 시작한 후 다음은 호스트를 다시 시작하지 않고 매우 간단하고 완벽하게 효과적이었습니다.

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

시스템 시계를 재설정하기 만하면됩니다. esh. 내가 6 시간 전에 알고있는 것.


8
date -s "`date`"나를 위해 일했다.
Pointy

@ DeanB : UTC를 오전 3시에 게시하여 시계를 재설정하면 트릭을 수행하지만 불행히도 조정하는 데 시간이 걸렸습니다. 서버 재부팅도 시작했습니다
Gregor

24

커널 시간 상태 필드에서 윤초 비트를 지우는 간단한 C 프로그램 :

#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;
}

로 저장하고 lsec.c컴파일하고 gcc -Wall -Wextra -o lsec lsec.c루트로 실행 하십시오 .

ntpd를 실행하기 전에 중지하고 윤초 후에 ntpd를 다시 시작하는 것이 좋습니다.


무엇을 (void) argc;달성합니까? 사용하지 않는 변수에 대한 경고를 제거 하시겠습니까? 사용하지 int main()않습니까? pedant가 되려고 노력하지 않고, 나는 정말로 궁금하다.
gparent

18

사후에 그것은 ./lsec 영향을 미치지 않는 것 같습니다.

우리 가보고있는 것은 CPU를 먹는 많은 softirqd 프로세스입니다 (일반적으로 Java 프로세스의 부하와 선형입니다)

ntp에 의해 이미 적용된 윤초로 POSTMORTEM을 수정하는 작업은 다음과 같습니다.

다음을 발행하는 것으로 충분합니다.

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

이것은 ntpd 재시작 또는 재부팅없이로드를 줄여야합니다. 또는 다음을 발행 할 수 있습니다.

apt-get install ntpdate
/etc/init.d/ntpd stop; ntpdate pool.ntp.org; /etc/init.d/ntpd start

sntp -s안돼 ntpdate?
errordeveloper

ntpdate는 여기서 sntp의 래퍼입니다. ntpdate도 사용하는 것이 좋습니다.
Gregor

아아 나는 실제로 바이너리 인 짜내기를위한 ntpdate 패키지가 없다는 것을 완전히 놓쳤다. 이것을 포함하도록 게시물을 편집했습니다.
Gregor

이 문제를 해결하는 비슷한 보고서 (예 : 사용 date -s)를 들었습니다 . 수정은 시스템 시간을 돌리는 대신 설정하는 것만 필요합니다 (오프셋이 작을 때 기본 ntpd 동작). 시간을 설정하면 커널의 내부 시간 관리 메커니즘이 스스로 재설정됩니다.
Patrick

4
내 Java 응용 프로그램 CPU 사용량도 (softirqd에 많은 양의 CPU 시간이 소비 됨) 급증하여 문제가 해결되었습니다.
Hubert Kario

16

http://my.opera.com/marcomarongiu/blog/2012/03/12/no-step-back 은 데비안 스퀴즈 커널이 윤초를 처리하지 않을 것임을 나타냅니다.

comp.protocols.tim.ntp의이 스레드도 관심이 있습니다. https://groups.google.com/forum/?fromgroups#!topic/comp.protocols.time.ntp/KSflIgjUdPE

즉, 윤초는 아직 발생하지 않았습니다. 23:59:60 UTC

마지막으로 https://access.redhat.com/knowledge/articles/15145 는 다음과 같이 말합니다. "도약이 발생하면 커널은 메시지를 시스템 로그에 인쇄합니다.이 메시지가 인쇄 될 가능성이 있습니다 Red Hat Enterprise Linux에서 커널 충돌을 일으킬 수 있습니다. "


그러나 3.2.21 커널은 아마도 충돌 한 머신 중 적어도 하나가 실행되고있는 것으로 추정됩니다.
Bron Gondwana

브론이 지적한 기계 중 일부에서 우리는 곧 도약을 올바르게 처리 해야하는 수정 프로그램을 실제로 출시했습니다.
Cosimo

다른 사람이 아이디어를 검토 / 제안 / 시도 할 수 있도록 수정 사항을 게시 할 수 있습니까?
kargig 2016 년

나는 고침이 없다 ... 나는 단지 정보를 수집하고 있습니다. 아마도 이것을 원래 질문에 대한 주석으로 넣어야 할 것입니다.
Luca Filipozzi

4
my.opera.com/marcomarongiu/blog/2012/06/01/… 수정에 대한 자세한 내용이 포함되어 있습니다
Bron Gondwana
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.