¿Alguien más está experimentando altas tasas de fallas del servidor Linux durante un segundo día de salto?

365

* NOTA: si su servidor todavía tiene problemas debido a núcleos confusos, y no puede reiniciar, la solución más simple propuesta con la fecha gnu instalada en su sistema es: date -s now. Esto restablecerá la variable interna "time_was_set" del núcleo y reparará los bucles futex de CPU que acaparan en Java y otras herramientas de espacio de usuario. He aplicado este comando en mi propio sistema y he confirmado que está haciendo lo que dice en la lata *

POST MORTEM

Anticlimax: lo único que murió fue mi enlace VPN (openvpn) al clúster, por lo que hubo unos segundos emocionantes mientras se restablecía. Todo lo demás estaba bien, y la puesta en marcha ntp fue limpia después de que el segundo salto había pasado.

He escrito mi experiencia completa del día en http://blog.fastmail.fm/2012/07/03/a-story-of-leaping-seconds/

Si miras el blog de Marco en http://my.opera.com/marcomarongiu/blog/2012/06/01/an-humble-attempt-to-work-around-the-leap-second , tiene una solución para Fase el cambio de tiempo durante 24 horas usando ntpd -x para evitar el salto de 1 segundo. Este es un método de difuminado alternativo para ejecutar su propia infraestructura ntp.


Justo hoy, sábado 30 de junio de 2012, comenzando poco después del comienzo del día GMT. Hemos tenido un puñado de servidores en diferentes centros de datos administrados por diferentes equipos, todos se oscurecen, sin responder a pings, pantalla en blanco.

Todos ejecutan Debian Squeeze, con todo, desde el kernel de stock hasta las compilaciones personalizadas 3.2.21. La mayoría son blades Dell M610, pero también acabo de perder un Dell R510 y otros departamentos también han perdido máquinas de otros proveedores. También hubo un IBM x3550 más antiguo que se estrelló y que pensé que podría no estar relacionado, pero ahora me pregunto.

El único bloqueo del que obtuve un volcado de pantalla dijo:

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

Desafortunadamente, todos los blades supuestamente tenían kdump configurado, pero murieron tan duro que kdump no se activó, y tenían encendida la consola. Ahora he desactivado la supresión de la consola, así que crucé los dedos. Tendré más información después del próximo bloqueo.

Solo quiero saber si es un hilo común o "solo nosotros". Es realmente extraño que sean diferentes unidades en diferentes centros de datos comprados en diferentes momentos y ejecutados por diferentes administradores (ejecuto los FastMail.FM) ... y ahora incluso hardware de diferentes proveedores. La mayoría de las máquinas que fallaron habían estado funcionando durante semanas / meses y estaban ejecutando núcleos de las series 3.1 o 3.2.

El bloqueo más reciente fue una máquina que solo llevaba unas 6 horas funcionando 3.2.21.

La solución

Ok gente, así es como trabajé para solucionarlo.

  1. ntp deshabilitado: /etc/init.d/ntp stop
  2. creado http://linux.brong.fastmail.fm/2012-06-30/fixtime.pl (código robado de Marco, vea las publicaciones del blog en los comentarios)
  3. corrió fixtime.plsin argumento para ver que había un segundo set de salto
  4. corrió fixtime.plcon un argumento para eliminar el segundo salto

NOTA: depende de adjtimex. Puse una copia del adjtimexbinario squeeze en http://linux.brong.fastmail.fm/2012-06-30/adjtimex : se ejecutará sin dependencias en un sistema squeeze de 64 bits. Si lo coloca en el mismo directorio que fixtime.pl, se usará si el sistema no está presente. Obviamente si no tiene compresión de 64 bits ... encuentre la suya.

Voy a comenzar de ntpnuevo mañana.

Como sugirió un usuario anónimo, una alternativa a la ejecución adjtimexes establecer el tiempo usted mismo, lo que presumiblemente también borrará el contador de segundos de salto.

Bron Gondwana
fuente
58
Hoy hay un segundo, el 30. Dudo en dar a entender que ese es su problema, pero estaré observando de cerca mis máquinas Debian.
jscott
2
desde la mañana Hemos perdido al menos 9 cajas diferentes de Debian Squeeze de varios proveedores, todos ejecutando stock Squeeze 2.6.32 kernel. no hemos sido capaces de conseguir un volcado de bloqueo debido al apagado de consola, así ...
kargig
3
lkml publicando sobre este lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html
Daniel S. Sterling
2
¡Gracias por informar esto! Ahora estoy mirando mis servidores muy, muy de cerca.
Janne Pikkarainen
55
El hilo LKML indicó que date -s "`date`"ayuda, ciertamente me ayudó.
Pointy

Respuestas:

321

Esto es causado por un livelock cuando ntpd llama a adjtimex (2) para decirle al kernel que inserte un segundo intercalar. Consulte la publicación de lkml http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html

Red Hat también debería actualizar su artículo de KB también. https://access.redhat.com/knowledge/articles/15145

ACTUALIZACIÓN: Red Hat tiene un segundo artículo de KB solo para este problema aquí: https://access.redhat.com/knowledge/solutions/154713 : el artículo anterior es para un problema anterior no relacionado

La solución es simplemente desactivar ntpd. Si ntpd ya emitió la llamada adjtimex (2), es posible que deba deshabilitar ntpd y reiniciar para que sea 100% seguro.

Esto afecta a RHEL 6 y otras distribuciones que ejecutan núcleos más nuevos (más nuevos que aproximadamente 2.6.26), pero no RHEL 5.

La razón por la que esto ocurre antes de que el segundo intercalar esté realmente programado es que ntpd permite que el núcleo maneje el segundo intercalar a la medianoche, pero necesita alertar al núcleo para que inserte el segundo intercalar antes de la medianoche. Por lo tanto, ntpd llama a adjtimex (2) en algún momento durante el día del segundo intercalario, momento en el que se activa este error.

Si tiene instalado adjtimex (8), puede usar este script para determinar si el marcador 16 está configurado. El indicador 16 está "insertando un segundo intercalar":

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

ACTUALIZAR:

Red Hat ha actualizado su artículo de KB para tener en cuenta: "Los clientes de RHEL 6 pueden verse afectados por un problema conocido que hace que NMI Watchdog detecte un bloqueo al recibir el anuncio de segundo salto de NTP. Este problema se está solucionando de manera oportuna. Si sus sistemas recibieron el anuncio del segundo salto y no experimentó este problema, entonces ya no se ven afectados ".

ACTUALIZACIÓN: El idioma anterior se eliminó del artículo de Red Hat; y se agregó una segunda solución KB que detalla el problema de bloqueo adjtimex (2): https://access.redhat.com/knowledge/solutions/154713

Sin embargo, el cambio de código en la publicación LKML del ingeniero de IBM John Stultz señala que también puede haber un punto muerto cuando se aplica el segundo intercalario, por lo que es posible que desee deshabilitar el segundo intercalar reiniciando o usando adjtimex (8) después de deshabilitar ntpd.

ACTUALIZACIÓN FINAL:

Bueno, no soy un desarrollador de kernel, pero revisé el parche de John Stultz nuevamente aquí: https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h = 6b43ae8a619d17c4935c3320d2ef9e92bdeed05d

Si lo estoy leyendo bien esta vez, me equivoqué acerca de que hay otro punto muerto cuando se aplica el segundo intercalar. Esa parece ser también la opinión de Red Hat, basada en su entrada KB. Sin embargo, si ha deshabilitado ntpd, manténgalo deshabilitado durante otros 10 minutos, para que no llegue al punto muerto cuando ntpd llame a adjtimex (2).

Descubriremos si hay más errores pronto :)

SEGUNDA ACTUALIZACIÓN POSTERIOR AL SALTO:

Pasé las últimas horas leyendo el código del kernel ntpd y pre-patch (buggy), y aunque pueda estar muy equivocado aquí, intentaré explicar lo que creo que estaba sucediendo:

Primero, ntpd llama a adjtimex (2) todo el tiempo. Lo hace como parte de su "filtro de bucle de reloj", definido en local_clock en ntp_loopfilter.c. Puede ver ese código aquí: http://www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (de la versión ntp 4.2.6).

El filtro de bucle de reloj se ejecuta con bastante frecuencia: se ejecuta cada vez que ntpd sondea sus servidores ascendentes, que por defecto es cada 17 minutos o más. El bit relevante del filtro de bucle de reloj es:

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

Y entonces:

ntp_adjtime(&ntv)

En otras palabras, en los días en que hay un segundo intercalar, ntpd establece el indicador "STA_INS" y llama a adjtimex (2) (a través de su contenedor de portabilidad).

Esa llamada al sistema llega al núcleo. Aquí está el código de kernel relevante: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c

El codepath del kernel es más o menos esto:

  • línea 663 - inicio de la rutina do_adjtimex.
  • línea 691 - cancela cualquier temporizador de segundo intercalar existente.
  • línea 709: tome el spinlock ntp_lock (este bloqueo está involucrado en el posible bloqueo del livelock)
  • línea 724: llame a process_adjtimex_modes.
  • línea 616: llame a process_adj_status.
  • línea 590 - establece la variable global time_status, basada en las banderas establecidas en la llamada adjtimex (2)
  • línea 592: verifique la variable global time_state. en la mayoría de los casos, llame a ntp_start_leap_timer.
  • línea 554: verifique la variable global time_status. STA_INS se establecerá, por lo tanto, establezca time_state en TIME_INS y llame a hrtimer_start (otra función del kernel) para iniciar el segundo temporizador. En el proceso de creación de un temporizador, este código toma el xtime_lock. Si esto sucede mientras otra CPU ya ha capturado el xtime_lock y el ntp_lock, entonces el núcleo se activa. Es por eso que John Stultz escribió el parche para evitar el uso de hrtimers. Esto es lo que estaba causando problemas a todos hoy.
  • línea 598: si ntp_start_leap_timer no inició realmente un temporizador de salto, establezca time_state en TIME_OK
  • línea 751: suponiendo que el kernel no tiene livelock, la pila se desenrolla y se libera el spinlock ntp_lock.

Hay un par de cosas interesantes aquí.

Primero, la línea 691 cancela el temporizador existente cada vez que se llama a adjtimex (2). Entonces, 554 recrea ese temporizador. Esto significa que cada vez que ntpd ejecutó su filtro de bucle de reloj, se invocó el código de error.

Por lo tanto, creo que Red Hat estaba equivocado cuando dijeron que una vez que ntpd había establecido el indicador de segundo intercalar, el sistema no se bloqueaba. Creo que cada sistema que ejecuta ntpd tenía el potencial de bloquear en vivo cada 17 minutos (o más) durante el período de 24 horas antes del salto de segundo. Creo que esto también puede explicar por qué tantos sistemas fallaron; una probabilidad única de estrellarse sería mucho menos probable que golpeara en comparación con 3 oportunidades por hora.

ACTUALIZACIÓN: En la solución KB de Red Hat en https://access.redhat.com/knowledge/solutions/154713 , los ingenieros de Red Hat llegaron a la misma conclusión (que ejecutar ntpd continuamente golpearía el código con errores). Y de hecho lo hicieron varias horas antes que yo. Esta solución no estaba vinculada al artículo principal en https://access.redhat.com/knowledge/articles/15145 , por lo que no lo noté hasta ahora.

En segundo lugar, esto explica por qué los sistemas cargados tenían más probabilidades de fallar. Los sistemas cargados manejarán más interrupciones, lo que provocará que la función del núcleo "do_tick" se invoque con más frecuencia, lo que brinda más posibilidades de que este código se ejecute y tome el ntp_lock mientras se crea el temporizador.

Tercero, ¿hay alguna posibilidad de que el sistema falle cuando ocurre el segundo salto? No estoy seguro, pero posiblemente sí, porque el temporizador que dispara y realmente ejecuta el ajuste del segundo intercalar (ntp_leap_second, en la línea 388) también toma el spinlock ntp_lock y tiene una llamada a hrtimer_add_expires_ns. No sé si esa llamada también podría causar un bloqueo en vivo, pero no parece imposible.

Finalmente, ¿qué causa que se deshabilite el indicador de segundo intercalar después de que se haya ejecutado el segundo intercalar? La respuesta es ntpd deja de establecer el indicador de segundo intercalar en algún momento después de la medianoche cuando llama a adjtimex (2). Como el indicador no está configurado, la verificación en la línea 554 no será verdadera y no se creará ningún temporizador, y la línea 598 restablecerá la variable global time_state a TIME_OK. Esto explica por qué si marca el indicador con adjtimex (8) justo después del segundo intercalar, aún verá el conjunto de indicadores del segundo intercalar.

En resumen, el mejor consejo para hoy parece ser el primero que di después de todo: deshabilitar ntpd y deshabilitar el indicador de segundo intercalar.

Y algunas reflexiones finales:

  • ninguno de los proveedores de Linux notó el parche de John Stultz y lo aplicó a sus núcleos :(
  • ¿Por qué John Stultz no alertó a algunos de los vendedores que esto era necesario? quizás la posibilidad de que el livelock pareciera lo suficientemente bajo como para hacer ruido no estaba justificada.
  • He escuchado informes de procesos Java que se bloquean o giran cuando se aplica el segundo intercalario. Quizás deberíamos seguir el ejemplo de Google y repensar cómo aplicamos los segundos bisiestos a nuestros sistemas: http://googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html

06/02 Actualización de John Stultz:

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

La publicación contenía un recorrido paso a paso de por qué el segundo salto provocó que los temporizadores futex expiraran prematura y continuamente, aumentando la carga de la CPU.

Daniel S. Sterling
fuente
77
Gracias por la excelente respuesta. Por lo tanto, el resto de nuestros servidores están esperando a que se bloquee. Encantador. Rolling reinicia aquí vamos!
Bron Gondwana
3
¿Cómo sé si adjtimexse ha emitido el, el núcleo imprime algo en dmesg? ¿Qué posibilidades hay de que un sistema que no se bloqueó antes de desactivar ntpd se bloquee?
Hubert Kario
3
Hubert: ejecute "adjtimex" (generalmente se empaqueta por separado) y busque el indicador 16 para indicar un segundo intermitente pendiente.
Dominic Cleal
22
Vas a odiar el límite de repeticiones.
Wesley
26
@WesleyDavid: No se preocupe, el límite de representantes se restablecerá a la medianoche UTC. Tal vez.
mmyers
33

Esto nos golpeó duro. Después de reiniciar muchos de nuestros hosts, lo siguiente resultó ser vergonzosamente simple y totalmente efectivo sin un reinicio del host:

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

Todo lo que se requiere es reiniciar el reloj del sistema. Sheesh Lo que he dado por haberlo sabido hace seis horas.

HikeOnPast
fuente
8
date -s "`date`"trabajó para mi.
Puntiagudo
@DeanB: publiqué a las 3 am UTC que restablecer el reloj funciona, desafortunadamente me tomó un tiempo moderarme. También comenzamos a reiniciar los servidores
Gregor
24

Un programa simple en C que borra el segundo bit de salto en el campo de estado de tiempo del núcleo:

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

Guardar como lsec.c, compilar gcc -Wall -Wextra -o lsec lsec.cy ejecutar como root.

Es probable que desee detener ntpd antes de ejecutarlo y reiniciar ntpd después del segundo salto.

jon
fuente
¿Qué (void) argc;logra? ¿Silenciar la advertencia para la variable no utilizada? ¿El uso no int main()lograría lo mismo? No trato de ser pedante, tengo una curiosidad genuina.
gparent
18

Postmortem parece ./lsec no tiene ningún efecto.

Lo que estamos viendo es una gran cantidad de procesos softirqd que comen CPU (generalmente lineal a la carga de los procesos de Java)

Lo que funciona para arreglar POSTMORTEM con segundos intercalares ya aplicados por ntp es lo siguiente:

Parece ser suficiente simplemente emitir:

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

Esto debería reducir la carga sin reiniciar o reiniciar ntpd. Alternativamente, puede emitir:

apt-get install ntpdate
/etc/init.d/ntpd stop; ntpdate pool.ntp.org; /etc/init.d/ntpd start
Gregor
fuente
¿Por qué sntp -sno ntpdate?
errordeveloper 01 de
ntpdate es solo un contenedor para sntp aquí, seguro que también está bien usar ntpdate.
Gregor
Ah, me perdí por completo que hay un paquete ntpdate para Squeeze donde en realidad es un binario. He editado mi publicación para incluir esto.
Gregor
También he escuchado informes similares sobre la solución de este problema (como el uso date -s). Parece que la solución solo requiere establecer la hora del sistema en lugar de girarla (el comportamiento ntpd predeterminado cuando el desplazamiento es pequeño). Supongo que establecer el tiempo hace que la mecánica interna de mantenimiento del tiempo del núcleo se reinicie.
Patrick
44
El uso de CPU de mis aplicaciones Java también aumentó (con una gran cantidad de tiempo de CPU en softirqd), esto lo solucionó.
Hubert Kario
16

http://my.opera.com/marcomarongiu/blog/2012/03/12/no-step-back parece indicar que el núcleo de compresión de Debian no manejará el segundo salto.

Este hilo en comp.protocols.tim.ntp es de interés, también: https://groups.google.com/forum/?fromgroups#!topic/comp.protocols.time.ntp/KSflIgjUdPE

Dicho esto, el segundo salto aún no ha sucedido: 23:59:60 UTC

Finalmente, https://access.redhat.com/knowledge/articles/15145 tiene lo siguiente para decir: "Cuando se produce el segundo salto, el núcleo imprime un mensaje en el registro del sistema. Existe la posibilidad de que la impresión de este mensaje puede hacer que el núcleo se bloquee en Red Hat Enterprise Linux ".

Luca Filipozzi
fuente
Pero el kernel 3.2.21 debería, presumiblemente, que es lo que al menos una de las máquinas bloqueadas estaba funcionando
Bron Gondwana
En algunas de esas máquinas que Bron indicó que en realidad hemos lanzado una solución que debería manejar correctamente el próximo segundo salto.
Cosimo
¿puede publicar la solución en algún lugar para que otros puedan revisar / sugerir ideas / probar?
kargig
No tengo una solución ... solo estoy recopilando información. Quizás debería haber puesto esto como un comentario en contra de la pregunta original.
Luca Filipozzi
44
my.opera.com/marcomarongiu/blog/2012/06/01/… contiene más detalles sobre cómo solucionarlo
Bron Gondwana