Question Toute autre personne connaissant un taux élevé de pannes de serveur Linux lors d'une deuxième journée bissextile?


* REMARQUE: si votre serveur rencontre toujours des problèmes dus à des noyaux confus et qu'il vous est impossible de redémarrer, la solution la plus simple proposée avec gnu date installée sur votre système est la suivante: date -s. Cela réinitialisera la variable interne "time_was_set" du noyau et corrigera les boucles futex monopolisant le processeur dans Java et d'autres outils de l'espace utilisateur. J'ai tracé cette commande sur mon propre système et confirmé qu'elle fait ce qu'elle dit sur l'étain *

AUTOPSIE

Anticlimax: la seule chose qui est morte est mon lien VPN (openvpn) vers le cluster. Il restait donc quelques secondes excitantes pendant son rétablissement. Tout le reste allait bien, et le démarrage de NTP s'est bien passé après la seconde intercalaire.

J'ai écrit toute mon expérience de la journée à http://blog.fastmail.fm/2012/07/03/a-story-of-leaping-seconds/

Si vous regardez le blog de Marco à http://my.opera.com/marcomarongiu/blog/2012/06/01/an-humble-attempt-to-work-around-the-leap-second - Il a une solution pour échelonner le changement d'heure sur 24 heures en utilisant ntpd -x pour éviter le saut d'une seconde. Il s'agit d'une méthode de macération alternative à l'exécution de votre propre infrastructure ntp.


Aujourd'hui, samedi 30 juin 2012 - débutant peu après le début de la journée, GMT. Nous avons eu une poignée de serveurs dans différents centres de données, gérés par différentes équipes qui ne fonctionnent pas - ils ne répondent pas aux pings, ils sont vierges.

Ils exécutent tous Debian Squeeze - avec tout, du noyau stock aux versions 3.2.21 personnalisées. La plupart sont des serveurs lames Dell M610, mais je viens également de perdre un Dell R510 et d'autres départements ont également perdu des machines d'autres fournisseurs. Il y avait aussi un ancien IBM x3550 qui s'est écrasé et qui, à mon avis, pourrait ne pas être apparenté, mais maintenant, je me pose des questions.

Le crash dont je viens de recevoir un vidage d'écran dit:

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

Malheureusement, kdump a été configuré pour toutes les lames, mais elles sont mortes si fort que kdump ne s'est pas déclenché - et le masquage de la console est activé. J'ai désactivé le masquage de la console maintenant, donc je croiserai les doigts pour plus d'informations après le prochain crash.

Je veux juste savoir si c'est un dénominateur commun ou "juste nous". Il est vraiment étrange qu'ils soient des unités différentes dans différents centres de données achetés à des moments différents et gérés par différents administrateurs (j'utilise les ordinateurs FastMail.FM) ... et maintenant même du matériel de fournisseurs différents. La plupart des machines qui sont tombées en panne étaient en service depuis des semaines / mois et utilisaient des noyaux de la série 3.1 ou 3.2.

Le crash le plus récent était une machine qui fonctionnait depuis environ 3 heures 3.2.21.

Le contournement

Ok les gens, voici comment j'ai travaillé autour de cela.

  1. ntp désactivé: /etc/init.d/ntp stop
  2. créé http://linux.brong.fastmail.fm/2012-06-30/fixtime.pl (code volé à Marco, voir les articles de blog dans les commentaires)
  3. a couru fixtime.pl sans argument pour voir qu'il y avait un deuxième ensemble bissextile
  4. a couru fixtime.pl avec un argument pour supprimer le saut de seconde

NOTE: dépend de adjtimex. J'ai mis une copie du squeeze adjtimex binaire à http://linux.brong.fastmail.fm/2012-06-30/adjtimex - il fonctionnera sans dépendance sur un système squeeze 64 bits. Si vous le mettez dans le même répertoire que fixtime.pl, il sera utilisé si le système 1 n’est pas présent. Évidemment, si vous n’avez pas à compresser 64 bits… trouvez le vôtre.

Je vais commencer ntp Encore demain.

En tant qu'utilisateur anonyme suggéré - une alternative à l'exécution adjtimex est de simplement régler le temps vous-même, ce qui effacera probablement également le compteur de sauts de seconde.


366
2018-06-30 16:15


origine


Il y a une seconde aujourd'hui, le 30. J'hésite à dire que c'est votre problème, mais je surveillerai de près mes machines Debian. - jscott
depuis le matin, nous avons perdu au moins 9 boîtes de compression Debian différentes de divers fournisseurs, toutes exécutant le noyau 2.6.32 de stock. nous n'avons pas pu obtenir de vidage sur incident en raison de la suppression de la console également ... - kargig
lkml postant à ce sujet lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html - Daniel S. Sterling
Merci d'avoir signalé cela! Je regarde maintenant très étroitement mes serveurs. - Janne Pikkarainen
Le fil de discussion LKML a indiqué que date -s "`date`" aide - cela m'a certainement aidé. - Pointy


Réponses:


Cela est causé par un livelock lorsque ntpd appelle adjtimex (2) pour indiquer au noyau d'insérer une seconde intercalaire. Voir lkml post http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html

Red Hat devrait également mettre à jour son article de base de connaissances. https://access.redhat.com/knowledge/articles/15145

MISE À JOUR: Red Hat a publié un deuxième article sur la base de connaissances pour ce problème: https://access.redhat.com/knowledge/solutions/154713 - l'article précédent concerne un problème antérieur, sans rapport

La solution consiste simplement à désactiver ntpd. Si ntpd a déjà émis l'appel adjtimex (2), vous devrez peut-être désactiver ntpd et redémarrer pour être sûr à 100%.

Cela concerne RHEL 6 et les autres distributions utilisant des noyaux plus récents (plus récents que les 2.6.26 environ), mais pas RHEL 5.

La raison pour laquelle cela se produit avant la seconde intercalaire actuellement programmée est que ntpd permet au noyau de gérer la seconde intercalaire à minuit, mais il doit alerter le noyau pour qu'il insère la seconde intercalaire avant minuit. ntpd appelle donc adjtimex (2) à un moment quelconque de la journée de la seconde intercalaire, moment auquel ce bogue est déclenché.

Si vous avez installé adjtimex (8), vous pouvez utiliser ce script pour déterminer si l'indicateur 16 est défini. Le drapeau 16 est "insertion d'une seconde intercalaire":

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

METTRE À JOUR:

Red Hat a mis à jour son article de la base de connaissances pour indiquer: "Les clients de RHEL 6 peuvent être affectés par un problème connu qui permet à NMI Watchdog de détecter un blocage lors de la réception de l'annonce NTP en secondes. Ce problème est résolu rapidement. Si vos systèmes sont reçus l'annonce de la seconde de saut et n'a pas rencontré ce problème, alors ils ne sont plus affectés. "

MISE À JOUR: La langue ci-dessus a été supprimée de l'article de Red Hat. et une deuxième solution de base de connaissances a été ajoutée, détaillant le problème de crash adjtimex (2): https://access.redhat.com/knowledge/solutions/154713

Cependant, le technicien IBM, John Stultz, a modifié le code dans l'article de LKML. Il est également possible qu'un blocage se produise lorsque la seconde intercalaire est réellement appliquée. Par conséquent, vous pouvez désactiver la seconde intercalaire en redémarrant ou en utilisant adjtimex (8) après avoir désactivé ntpd.

MISE À JOUR FINALE:

Bien, je ne suis pas un développeur de noyau, mais j'ai relu le patch de John Stultz ici: https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6b43ae8a619d17c4935c220f9e92bdeed05d

Si je le lis bien cette fois, je me suis trompé sur le fait qu'il y avait une autre impasse lorsque la seconde intercalaire est appliquée. Cela semble également être l'opinion de Red Hat, basée sur son entrée dans la base de connaissances. Toutefois, si vous avez désactivé ntpd, maintenez-le désactivé pendant 10 minutes supplémentaires afin d'éviter tout blocage lorsque ntpd appelle adjtimex (2).

Nous verrons s'il y a bientôt d'autres bugs :)

DEUXIÈME MISE À JOUR POST-LEAP:

J'ai passé les dernières heures à lire le code du noyau ntpd et pre-patch (buggy) et, même si je me trompe peut-être, je vais tenter d'expliquer ce qui se passait:

Tout d’abord, ntpd appelle adjtimex (2) tout le temps. Cela fait partie de son "filtre de boucle d'horloge", défini dans local_clock dans ntp_loopfilter.c. Vous pouvez voir ce code ici: http://www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (à partir de ntp version 4.2.6).

Le filtre de boucle d'horloge fonctionne assez souvent - il s'exécute chaque fois que ntpd interroge ses serveurs en amont, ce qui correspond par défaut à toutes les 17 minutes ou plus. Le bit pertinent du filtre de boucle d'horloge est:

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

Et alors:

ntp_adjtime(&ntv)

En d'autres termes, les jours où il y a une seconde intercalaire, ntpd active l'indicateur "STA_INS" et appelle adjtimex (2) (via son gestionnaire de portabilité).

Cet appel système se rend au noyau. Voici le code de noyau pertinent: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c

Le codepath du noyau est à peu près ceci:

  • ligne 663 - début de la routine do_adjtimex.
  • ligne 691 - annule toute minuterie en secondes intercalaires existante.
  • ligne 709 - récupère le spinlock ntp_lock (ce verrou est impliqué dans un possible crash de livelock)
  • ligne 724 - appelez process_adjtimex_modes.
  • ligne 616 - appelez process_adj_status.
  • ligne 590 - définit la variable globale time_status, en fonction des indicateurs définis dans l'appel adjtimex (2)
  • ligne 592 - vérifie la variable globale time_state. dans la plupart des cas, appelez ntp_start_leap_timer.
  • ligne 554 - vérifie la variable globale time_status. STA_INS sera défini, donc définissez time_state sur TIME_INS et appelez hrtimer_start (une autre fonction du noyau) pour démarrer le temporisateur. dans le processus de création d'une minuterie, ce code récupère le xtime_lock. si cela se produit alors qu'un autre processeur a déjà saisi le fichier xtime_lock et le ntp_lock, puis le noyau livelocks. C'est pourquoi John Stultz a écrit le correctif pour éviter d'utiliser des horloges. C'est ce qui causait des problèmes à tout le monde aujourd'hui.
  • ligne 598 - si ntp_start_leap_timer n'a pas démarré un retardateur, définissez time_state sur TIME_OK
  • ligne 751 - en supposant que le noyau ne fonctionne pas, la pile est déroulée et le verrou tournant ntp_lock est libéré.

Il y a quelques choses intéressantes ici.

Premièrement, la ligne 691 annule la minuterie existante chaque fois que adjtimex (2) est appelé. Ensuite, 554 recrée ce minuteur. Cela signifie que chaque fois que ntpd a exécuté son filtre de boucle d’horloge, le code du buggy a été appelé.

C’est pourquoi j’ai cru que Red Hat avait tort de dire qu’une fois que ntpd aurait défini le drapeau de la seconde intercalaire, le système ne planterait plus. Je pense que chaque système exécutant ntpd pouvait potentiellement survivre toutes les 17 minutes (ou plus) pendant les 24 heures précédant le saut de seconde. Je pense que cela peut aussi expliquer pourquoi autant de systèmes se sont écrasés. une chance unique de tomber serait beaucoup moins susceptible de frapper que 3 chances par heure.

MISE À JOUR: dans la solution de base de connaissances de Red Hat à https://access.redhat.com/knowledge/solutions/154713 Les ingénieurs de Red Hat sont parvenus à la même conclusion (l’exécution de ntpd ne cesserait de frapper le code du buggy). Et en effet, ils l'ont fait plusieurs heures avant moi. Cette solution n'était pas liée à l'article principal de https://access.redhat.com/knowledge/articles/15145 , donc je ne l'ai pas remarqué jusqu'à présent.

Deuxièmement, cela explique pourquoi les systèmes chargés étaient plus susceptibles de tomber en panne. Les systèmes chargés gèrent un plus grand nombre d'interruptions, ce qui entraîne l'appel de la fonction de noyau "do_tick" plus souvent, ce qui donne une chance supplémentaire à ce code de s'exécuter et de récupérer le ntp_lock pendant la création du temporisateur.

Troisièmement, y a-t-il une chance que le système se bloque lorsque la seconde intercalaire se produit réellement? Je ne sais pas avec certitude, mais peut-être que oui, car le minuteur qui déclenche et exécute l'ajustement en saut de seconde (ntp_leap_second, ligne 388) saisit également le spinlock ntp_lock et appelle hrtimer_add_expires_ns. Je ne sais pas si cet appel pourrait également causer un délai de livraison, mais cela ne semble pas impossible.

Enfin, qu'est-ce qui provoque la désactivation du drapeau de la seconde intercalaire une fois la seconde intercalaire écoulée? La réponse est que ntpd cesse de définir l'indicateur de seconde intercalaire à partir de minuit, lorsqu'il appelle adjtimex (2). Comme l'indicateur n'est pas défini, la vérification de la ligne 554 ne sera pas vraie, aucune minuterie ne sera créée et la ligne 598 réinitialisera la variable globale time_state en TIME_OK. Cela explique pourquoi, si vous avez coché le drapeau avec adjtimex (8) juste après la seconde de saut, vous verriez toujours le drapeau défini.

En bref, le meilleur conseil pour aujourd'hui semble être le premier que j'ai donné après tout: désactiver ntpd et désactiver l'indicateur de saut de seconde.

Et quelques réflexions finales:

  • aucun des vendeurs de Linux n'a remarqué le correctif de John Stultz et l'a appliqué à leurs noyaux :(
  • pourquoi John Stultz n'a-t-il pas averti certains des fournisseurs que c'était nécessaire? peut-être que la chance du livelock semblait assez faible pour que le bruit ne soit pas garanti.
  • J'ai entendu parler de processus Java bloqués ou en rotation lorsque la seconde intercalaire était appliquée. Peut-être devrions-nous suivre l'exemple de Google et repenser la manière dont nous appliquons des secondes intercalaires à nos systèmes: http://googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html

06/02 Mise à jour de John Stultz:

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

Le message contenait une explication pas à pas des raisons pour lesquelles la seconde intercalaire avait provoqué une expiration prématurée et continue des minuteries futex, alourdissant ainsi la charge du processeur.


322
2018-06-30 19:56



Merci pour l'excellente réponse. Donc, le reste de nos serveurs sont assis en attente de crash. Charmant. Le roulement redémarre ici nous arrivons! - Bron Gondwana
Comment puis-je savoir si le adjtimex a été publié, le noyau affiche-t-il quelque chose dans dmesg? Quelle est la probabilité qu’un système qui ne s’est pas arrêté avant de désactiver ntpd tombe en panne? - Hubert Kario
Hubert: lancez "adjtimex" (il est généralement emballé séparément) et recherchez l'indicateur 16 pour indiquer une seconde intercalaire en attente. - Dominic Cleal
Vous allez détester le bonnet de rep. - Wesley
@WesleyDavid: Pas de problème, la limite de répétition sera réinitialisée à minuit UTC. Peut être. - mmyers


Cela nous a frappé fort. Après avoir redémarré plusieurs de nos hôtes, les éléments suivants se sont révélés être d'une simplicité embarrassante et pleinement efficaces sans redémarrage d'hôte:

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

Tout ce qui est nécessaire est de réinitialiser l'horloge système. Sheesh. Ce que j'ai donné, je le sais depuis six heures.


33
2017-07-01 07:49



date -s "`date`" a travaillé pour moi. - Pointy
@DeanB: J'ai posté à 3 heures du matin UTC pour réinitialiser l'horloge. Malheureusement, il a fallu un certain temps pour se modérer. Nous avons également démarré le redémarrage des serveurs - Gregor


Un simple programme en C qui efface le bit de seconde intercalaire dans le champ d'état temporel du noyau:

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

Enregistrer sous lsec.c, compiler avec gcc -Wall -Wextra -o lsec lsec.c et lancez en tant que root.

Vous voudrez probablement arrêter ntpd avant de l'exécuter et redémarrer ntpd après la seconde intercalaire.


24
2018-06-30 23:13



Qu'est-ce que (void) argc; accomplir? Faire taire l'avertissement pour la variable non utilisée? Ne pas utiliser int main() accomplir la même chose? N'essayant pas d'être un pédant, je suis vraiment curieux. - gparent


Post mortem, il semble que ./lsec n'a pas d'effet.

Nous voyons beaucoup de processus softirqd consommant du processeur (généralement linéaires par rapport à la charge des processus java)

Ce qui fonctionne pour réparer POSTMORTEM avec les secondes intercalaires déjà appliquées par NTP est le suivant:

Il semble suffire de simplement émettre:

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

Cela devrait réduire la charge sans redémarrage ni redémarrage de ntpd. Sinon, vous pouvez émettre:

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

18
2017-07-01 03:41



Pourquoi sntp -s et pas ntpdate? - errordeveloper
ntpdate est juste un wrapper à sntp ici, bien sûr que c'est bien d'utiliser ntpdate également. - Gregor
ah j'ai complètement raté il y a un paquet ntpdate pour squeeze où il s'agit en fait d'un fichier binaire. J'ai modifié mon message pour l'inclure. - Gregor
J'ai aussi entendu des rapports similaires sur la résolution de ce problème (comme l'utilisation de date -s). Il semble que le correctif nécessite simplement de régler l’heure du système au lieu de la modifier (le comportement par défaut de ntpd lorsque offset est faible). Je suppose que la définition de l'heure entraîne la réinitialisation des mécanismes de chronométrage internes du noyau. - Patrick
L’utilisation du processeur par mes applications java a également augmenté (avec beaucoup de temps processeur dans softirqd), cela a été corrigé. - Hubert Kario


http://my.opera.com/marcomarongiu/blog/2012/03/12/no-step-back semble indiquer que le noyau squeeze de Debian ne gérera pas la seconde intercalaire.

Cette discussion sur comp.protocols.tim.ntp est intéressante, mais aussi: https://groups.google.com/forum/?fromgroups#!topic/comp.protocols.time.ntp/KSflIgjUdPE

Ceci dit, la seconde intercalaire n’est pas encore arrivée: 23:59:60 UTC

Finalement, https://access.redhat.com/knowledge/articles/15145 a le texte suivant: "Lorsque la seconde intercalaire se produit, le noyau imprime un message dans le journal système. Il est possible que l'impression de ce message provoque le blocage du noyau dans Red Hat Enterprise Linux."


17
2018-06-30 18:47



Mais le noyau 3.2.21 devrait, vraisemblablement - ce qu’au moins une des machines en panne tournait - Bron Gondwana
Sur certaines de ces machines qui, selon Bron, ont indiqué que nous avions en fait mis au point un correctif qui devrait correctement prendre en charge la seconde intercalaire à venir. - cosimo
pouvez-vous poster le correctif quelque part afin que les autres puissent examiner / suggérer des idées / essayer? - kargig
Je n'ai pas de solution ... Je ne fais que collecter des informations. Peut-être aurait-il dû mettre cela comme un commentaire contre la question initiale. - Luca Filipozzi
my.opera.com/marcomarongiu/blog/2012/06/01/… contient plus de détails sur la correction - Bron Gondwana