web-dev-qa-db-fra.com

Quelqu'un d'autre connaît des taux élevés de pannes de serveurs Linux au cours d'un deuxième jour intercalaire?

* REMARQUE: si votre serveur a encore des problèmes en raison de noyaux confus et que vous ne pouvez pas redémarrer - la solution la plus simple proposée avec gnu date installée sur votre système est: date -s now. Cela réinitialisera la variable interne "time_was_set" du noyau et corrigera les boucles de futex monopolisant le processeur dans Java et d'autres outils de l'espace utilisateur. J'ai étalonné 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, donc il y a eu quelques secondes passionnantes pendant qu'il se rétablissait. 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 de 1 seconde. Il s'agit d'une méthode de maculage alternative à l'exécution de votre propre infrastructure ntp.


Aujourd'hui, samedi 30 juin 2012 - à partir de 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, tous deviennent sombres - ne répondant pas aux pings, écran vide.

Ils exécutent tous Debian Squeeze - avec tout, depuis le noyau de stock jusqu'aux versions 3.2.21 personnalisées. La plupart sont des 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 que je pensais ne pas être lié, mais maintenant je me demande.

Le seul crash dont j'ai obtenu un vidage d'écran a dit:

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

Malheureusement, les lames avaient toutes prétendument configuré kdump, mais elles sont mortes si fort que kdump ne s'est pas déclenché - et elles ont désactivé la suppression de la console. J'ai désactivé la suppression de la console maintenant, donc les doigts croisés, j'aurai plus d'informations après le prochain crash.

Je veux juste savoir si c'est un fil conducteur ou "juste nous". Il est vraiment étrange que ce soient des unités différentes dans des centres de données différents achetés à des moments différents et gérés par différents administrateurs (j'exécute les FastMail.FM) ... et maintenant même du matériel de fournisseur différent. La plupart des machines qui sont tombées en panne fonctionnaient depuis des semaines/mois et fonctionnaient avec des noyaux de la série 3.1 ou 3.2.

Le crash le plus récent était une machine qui n'avait fonctionné qu'environ 6 heures de fonctionnement 3.2.21.

LA SOLUTION

Ok les gens, voici comment j'y ai travaillé.

  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 une seconde intercalaire
  4. a couru fixtime.pl avec un argument pour supprimer la seconde intercalaire

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

Je vais recommencer ntp demain.

Comme l'a suggéré un utilisateur anonyme - une alternative à l'exécution de adjtimex est de simplement régler l'heure vous-même, ce qui effacera probablement aussi le compteur de la seconde.

363
Bron Gondwana

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

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

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

La solution consiste à désactiver simplement 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 affecte RHEL 6 et d'autres distributions exécutant des noyaux plus récents (plus récents qu'environ 2.6.26), mais pas RHEL 5.

La raison pour laquelle cela se produit avant la seconde intercalaire est en fait programmée pour se produire est que ntpd permet au noyau de gérer la seconde intercalaire à minuit, mais doit alerter le noyau pour insérer la seconde intercalaire avant minuit. ntpd appelle donc adjtimex (2) au cours de la journée de la seconde intercalaire, moment auquel ce bogue est déclenché.

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

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

MISE À JOUR:

Red Hat a mis à jour son article de la base de connaissances pour noter: "Les clients RHEL 6 peuvent être affectés par un problème connu qui fait que NMI Watchdog détecte un blocage lors de la réception du NTP = annonce de la seconde intercalaire. Ce problème est traité en temps opportun. Si vos systèmes ont reçu l'annonce de la seconde intercalaire et n'ont pas rencontré ce problème, ils ne sont plus affectés. "

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

Cependant, le changement de code dans le message LKML par l'ingénieur IBM John Stultz note qu'il peut également y avoir un blocage lorsque la seconde intercalaire est réellement appliquée, vous pouvez donc vouloir désactiver la seconde intercalaire en redémarrant ou en utilisant adjtimex (8) après avoir désactivé ntpd.

MISE À JOUR FINALE:

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

Si je le lis bien cette fois-ci, j'avais tort qu'il y ait un autre blocage lorsque la seconde intercalaire est appliquée. Cela semble également être l'opinion de Red Hat, sur la base de leur entrée dans la base de connaissances. Cependant, si vous avez désactivé ntpd, laissez-le désactivé pendant 10 minutes supplémentaires, afin de ne pas atteindre l'impasse lorsque ntpd appelle adjtimex (2).

Nous verrons s'il y a plus de bugs bientôt :)

DEUXIÈME MISE À JOUR POST-LEAP:

J'ai passé les dernières heures à lire le code du noyau ntpd et pré-patch (buggy), et bien que je puisse me tromper ici, je vais essayer d'expliquer ce que je pense qui se passait:

Tout d'abord, ntpd appelle tout le temps adjtimex (2). Il le fait dans le cadre 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 la version 4.2.6 de ntp).

Le filtre de boucle d'horloge s'exécute assez souvent - il s'exécute chaque fois que ntpd interroge ses serveurs en amont, qui par défaut est 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 définit l'indicateur "STA_INS" et appelle adjtimex (2) (via son wrapper de portabilité).

Cet appel système fait son chemin vers le noyau. Voici le code du noyau pertinent: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c

Le chemin de code du noyau est à peu près ceci:

  • ligne 663 - début de la routine do_adjtimex.
  • ligne 691 - annule tout temporisateur de seconde intercalaire existant.
  • ligne 709 - saisissez le spinlock ntp_lock (ce verrou est impliqué dans le crash de livelock possible)
  • ligne 724 - appelez process_adjtimex_modes.
  • ligne 616 - appelez process_adj_status.
  • ligne 590 - définir la variable globale time_status, en fonction des indicateurs définis dans l'appel adjtimex (2)
  • ligne 592 - vérifiez la variable globale time_state. dans la plupart des cas, appelez ntp_start_leap_timer.
  • ligne 554 - vérifiez la variable globale time_status. STA_INS sera défini, définissez donc time_state sur TIME_INS et appelez hrtimer_start (une autre fonction du noyau) pour démarrer la seconde intercalaire. dans le processus de création d'une minuterie, ce code saisit le xtime_lock. si cela se produit alors qu'un autre processeur a déjà saisi le xtime_lock et le ntp_lock, alors le noyau se verrouille. c'est pourquoi John Stultz a écrit le patch pour éviter d'utiliser hrtimers. C'est ce qui causait des problèmes à tout le monde aujourd'hui.
  • ligne 598 - si ntp_start_leap_timer n'a pas réellement démarré un temporisateur de saut, définissez time_state sur TIME_OK
  • ligne 751 - en supposant que le noyau ne se verrouille 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 le temporisateur existant chaque fois que adjtimex (2) est appelé. Ensuite, 554 recrée ce temporisateur. Cela signifie que chaque fois que ntpd exécutait son filtre de boucle d'horloge, le code de buggy était invoqué.

Par conséquent, je crois que Red Hat avait tort quand ils ont dit qu'une fois que ntpd avait défini le drapeau de la seconde intercalaire, le système ne plantait pas. Je crois que chaque système exécutant ntpd avait le potentiel de se verrouiller toutes les 17 minutes (ou plus) pendant la période de 24 heures avant la seconde intercalaire. Je crois que cela peut aussi expliquer pourquoi tant de systèmes se sont écrasés; une chance unique de s'écraser serait beaucoup moins susceptible de frapper que 3 chances par heure.

MISE À JOUR: Dans la solution KB de Red Hat à https://access.redhat.com/knowledge/solutions/15471 , les ingénieurs de Red Hat sont parvenus à la même conclusion (que l'exécution de ntpd atteindrait continuellement le code buggy ). Et en effet, ils l'ont fait plusieurs heures avant moi. Cette solution n'était pas liée à l'article principal sur 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èreront plus d'interruptions, provoquant un appel plus fréquent de la fonction de noyau "do_tick", ce qui donnera plus de chance à ce code de s'exécuter et de saisir le ntp_lock pendant la création du temporisateur.

Troisièmement, y a-t-il une chance que le système tombe en panne lorsque la seconde intercalaire se produit réellement? Je ne sais pas avec certitude, mais peut-être oui, car le temporisateur qui se déclenche et exécute en fait l'ajustement des secondes intercalaires (ntp_leap_second, à la ligne 388) saisit également le verrou tournant ntp_lock et a un appel à hrtimer_add_expires_ns. Je ne sais pas si cet appel pourrait également provoquer un livelock, mais cela ne semble pas impossible.

Enfin, qu'est-ce qui provoque la désactivation de l'indicateur de seconde intercalaire après l'exécution de la seconde intercalaire? La réponse est que ntpd arrête de définir l'indicateur de seconde intercalaire à un moment donné après minuit lorsqu'il appelle adjtimex (2). Étant donné que l'indicateur n'est pas défini, la vérification sur la ligne 554 ne sera pas vraie et aucun temporisateur ne sera créé et la ligne 598 réinitialisera la variable globale time_state à TIME_OK. Cela explique pourquoi si vous vérifiez le drapeau avec adjtimex (8) juste après la seconde intercalaire, vous verrez toujours le drapeau de la seconde intercalaire 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 seconde intercalaire.

Et quelques réflexions finales:

  • aucun des fournisseurs Linux n'a remarqué le correctif de John Stultz et ne l'a appliqué à leurs noyaux :(
  • pourquoi John Stultz n'a-t-il pas alerté certains des fournisseurs que c'était nécessaire? peut-être que la chance du livelock semblait suffisamment faible pour faire du bruit n'était pas justifiée.
  • J'ai entendu parler de Java processus se bloquant ou tournant lorsque la seconde intercalaire était appliquée. Peut-être devrions-nous suivre l'exemple de Google et repenser la façon dont nous appliquons les 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/2

Le message contenait une explication pas à pas de la raison pour laquelle la seconde intercalaire a provoqué l'expiration prématurée et continue des minuteries futex, augmentant ainsi la charge du processeur.

318
Daniel S. Sterling

Cela nous a durement touchés. Après avoir redémarré un grand nombre de nos hôtes, les éléments suivants se sont révélés d'une simplicité embarrassante et pleinement efficaces sans redémarrage de l'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é pour l'avoir su il y a six heures.

33
HikeOnPast

Un programme C simple 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 exécutez 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
jon

Il semble que l'autopsie ./lsec n'a pas d'effet.

Ce que nous voyons, c'est beaucoup de processus softirqd consommant du CPU (généralement linéaire à la charge de Java processus)

Ce qui fonctionne pour corriger POSTMORTEM avec des secondes intercalaires déjà appliquées par ntp est le suivant:

Il semble suffisant de simplement émettre:

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

Cela devrait réduire la charge sans redémarrage ni redémarrage de ntpd. Vous pouvez également émettre:

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

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

Ce fil sur comp.protocols.tim.ntp est également intéressant: https://groups.google.com/forum/?fromgroups#!topic/comp.protocols.time.ntp/KSflIgjUdPE

Cela dit, la seconde intercalaire n'a pas encore eu lieu: 23:59:60 UTC

Enfin, https://access.redhat.com/knowledge/articles/15145 a ceci à dire: "Lorsque la seconde intercalaire se produit, le noyau imprime un message dans le journal système. Il y a un chance que l'impression de ce message puisse provoquer le crash du noyau dans Red Hat Enterprise Linux. "

16
Luca Filipozzi