it-swarm-es.com

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

* 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 arreglará los bucles futex de CPU que acaparan en Java y otras herramientas de espacio de usuario. He forzado este comando en mi propio sistema y confirmó que está haciendo lo que dice en la lata *

[~ # ~] postmortem [~ # ~]

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 cambiar el cambio de tiempo en 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 núcleo de valores 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 bloqueó 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, todas las cuchillas supuestamente tenían kdump configurado, pero murieron tan duro que kdump no se activó, y tenían la consola en blanco activada. He desactivado la supresión de la consola ahora, así que con los dedos cruzados 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 se bloquearon habían estado funcionando durante semanas/meses y ejecutaban 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.pl sin argumento para ver que hubo un segundo set de salto
  4. corrió fixtime.pl con un argumento para eliminar el segundo salto

NOTA: depende de adjtimex. Puse una copia del archivo binario adjtimex en http://linux.brong.fastmail.fm/2012-06-30/adjtimex - se ejecutará sin dependencias en Un sistema de compresión 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 ntp nuevamente mañana.

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

363
Bron Gondwana

Esto es causado por un livelock cuando ntpd llama a adjtimex (2) para decirle al kernel que inserte un segundo intercalar. Vea 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/15471 - 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 estar 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 el segundo intercalar está programado para que ocurra 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"'

ACTUALIZACIÓN:

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 NTP = anuncio de salto de segundo. Este problema se está abordando de manera oportuna. Si sus sistemas recibieron el anuncio de segundo de salto y no experimentaron este problema, 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/15471

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 POST-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 tomado 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 se equivocó 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/15471 , 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.

En tercer lugar, ¿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 ntp_lock spinlock, 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? tal vez la posibilidad de que el livelock pareciera lo suficientemente baja como para hacer ruido no estaba justificada.
  • He escuchado informes de Java procesos bloqueándose o girando cuando se aplicó el segundo bisiesto. 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/2

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.

318
Daniel S. Sterling

Esto nos golpeó duro. Después de reiniciar muchos de nuestros hosts, lo siguiente resultó ser vergonzosamente simple y totalmente efectivo sin un reinicio de 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.

33
HikeOnPast

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

#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 con gcc -Wall -Wextra -o lsec lsec.c y ejecutar como root.

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

24
jon

Postmortem parece ./lsec no tiene efecto.

Lo que estamos viendo son muchos procesos softirqd que comen CPU (generalmente lineal a la carga 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
18
Gregor

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 que decir: "Cuando ocurre el segundo intercalar, el núcleo imprime un mensaje en el registro del sistema. Hay un posibilidad de que la impresión de este mensaje pueda hacer que el núcleo se bloquee en Red Hat Enterprise Linux ".

16
Luca Filipozzi