23 de septiembre de 2006

Sobre dtrace, su equivalente linuxero kprobes, qué son y como funcionan

Act.: Se me olvidó contar que systemtap tiene incluso una interfaz gráfica (capturas y más capturas)

Los que anden al loro en noticias de sistemas operativos habrán oido hablar de Dtrace, la maravillosa herramienta de Solaris que permite obtener cualquier información del sistema. Lo primero que habría que contar sobre este tipo de herramientas es que aparentemente no tienen nada de nuevo, y que como tantas otras cosas ya se implementaron en los sistemas operativos de los años 60; incluso parece ser que OS/2 tuvo un "dtrace". Ver para creer. La segunda cosa que habría que contar es que el mundo Linuxero no está ni ha estado arrinconado en este aspecto. Dtrace se merece todos los aplausos del mundo, pero Linux se merece un cierto abucheo, porque ya desde el 2000 o antes ha habido gente intentando implementar un equivalente de lo que hoy es Dtrace. Es decir, comenzaron a implementarlo más o menos al mismo tiempo que Sun, pero Sun lo ha terminado y el mundo Linuxero no.

Existen dos proyectos principales que tratan de implementar un sistema de "instrumentación": LTT (Linux Trace Toolkit) y Kprobes + Systemtap. LTT hace "instrumentación estática" y Kprobes "instrumentación dinámica". La diferencia entre ambos es muy divertida e interesante porque consta de varios detalles de esos que son decisivos y hacen que algo fracase o tenga éxito con respecto a la alternativa. LTT inserta en lugares estratégicos del código fuente unas llamadas a funciones que recogen estadísticas variadas. La clave de LTT es que es estático, es decir, se tiene que compilar y una vez compilado no lo puedes cambiar. Por esa misma razón es eficiente, puesto que el compilador puede incluso optimizar las cosas, una ventaja. Pero otra desventaja es que esa recolección de datos ocurre - puesto que está insertada en el kernel - incluso cuando nadie está pidiendo estadísticas, y eso tiene un coste que se traduce en una pérdida de rendimiento, pequeña pero existente.

De eso se pueden empezar a sacar conclusiones: Ninguna distribución va a instalar por defecto un kernel con LTT activado, puesto que afecta el rendimiento. Necesitas recompilar y reiniciar, y ese es un aspecto clave, porque si quieres saber porque tu servidor de correo es tan lento necesitas saberlo en ese momento y no puedes permitirte reiniciar.

Lo ideal sería un sistema que no tuviera coste alguno de rendimiento cuando se está utilizando. Eso es lo que hacen los entornos dinámicos como kprobes + systemtap, y Dtrace, que tambien funciona así. En esos sistemas, no hay que insertar ningún "punto de recolección de datos" en el kernel, por lo tanto no tiene ningún (cero) coste de ejecución mientras no se está utilizando. Eso permite que las distribuciones activen kprobes y que por lo tanto, un administrador pueda conectarse a un sistema via ssh y empieze a utilizar kprobes inmediatamente, sin tener que reiniciar, ni recompilar.

¿Y como funcionan? Lo que hacen kprobes y dtrace es casi magia: Pueden insertar "puntos de recolección" en prácticamente cualquier punto del kernel. Lo que hacen es ir a la zona de memoria donde se encuentra el código ejecutable de la parte del kernel que se quiere analizar (la localización de la zona se obtiene mirando en la información de depuración, la misma que utiliza GDB), quitan (pero literalmente) la instrucción ejecutable que se encuentra en el punto deseado, insertan una llamada al código de kprobes que se encarga de recolectar los datos, ejecutan la instrucción que se había borrado para insertar el salto de kprobes, y continuan ejecutandose donde lo habían dejado.

Como dije, se trata de casi magia, una idea que parece absurda y dificil (me pregunto como narices han implementado eso en el caos de instrucciones de longitud variable que es x86) pero que realmente funciona, es implementable y está ahí. Es por ese sistema por lo que no necesitan insertar puntos de recolección en tiempo de compilacion y por lo que es tan atractivo. La desventaja es que son ligeramente más lento que ĺos puntos de recolección estáticos de LTT, pero solo ligeramente, y se están ensayando con alternativas (djprobes) que reducen esa desventaja aun más.

Lo realmente impresionante de Dtrace y kprobes es su espectro de aplicaciones. Se podría utilizar kprobes para ideas que hoy en día resultan dificiles de imaginar, como utilizar su infraestructura para parchear en caliente el kernel en caso de un fallo de seguridad. Tambien se puede utilizar, y es uno de sus principales atractivos, para sustituir otras técnicas de depuración. ¿Cuantas veces has visto código con código de depuración desactivado por defecto con un "#define DEBUG 0", que necesita ser recompilado (y reiniciado en el caso de un kernel no modular) para obtener información de depuración? Con kprobes y dtrace se pueden eliminar todos esos horribles printk()s de depuración de las fuentes: Puedes utiliar kprobes para monitorizar cualquier punto de tu código, obtener información de las variables, etc etc, y puedes hacerlo sin tener que recompilar nada, y puedes cambiar instantaneamente de opinión sobre qué información quieres conseguir, o obtener al mismo tiempo información de otras partes del sistema. Puedes pasar a un usuario a miles de kilómetros un script de dtrace que te facilite información sobre un servidor en funcionamiento, y saber qué ocurre, sin tener que pedirle que cambie ese define a "#define DEBUG 1" y que recompile y reinicie.

Y aun hay más. Dtrace no solo puede monitorizar el kernel, tambien puede monitorizar el espacio de usuario, asi que todo lo que se aplica aquí puede aplicarse tambien a los programas normales y corrientes. Kprobes aun no puede hace: no ha madurado aun lo suficiente, pero están trabajando en ello. Dtrace sin embargo si que lo hace, y se han implementado ya "monitorizadores" para java o incluso javascript, de manera que puedes utilizar dtrace para analizar como funciona el sistema de arriba a abajo mientras se ejecutan cálculos intensivos en el navegador. Tambien se puede utilizar para reemplazar a herramientas de estadísticas. Por ejemplo, en 2.6.17 o 2.6.16 se incluyó blktrace, una infraestructura que permite obtener estadísticas detalladísimas de todo lo que ocurre en las peticiones a disco. En realidad blktrace es algo similar a LTT, un instrumentador estático: inserta "puntos de recolección de datos" en las fuentes, aunque su intención no fuera otra que obtener estadísticas del disco. Tambien podrían englobarse aquí a herramientas como sar, vmstat, o incluso ps. En el caso de blktrace, el desarrollador que lo implementó ya ha anunciado que en cuando kprobes + systemtap estén maduros, eliminará todo el código de blktrace, puesto que podrá ser implementado en forma de scripts de kprobes + systemtap.

En Linux, por cierto, systemtap es la otra parte del sistema (el término dtrace engloba al equivalente de kprobes + systemtap): kprobes se encarga del reemplazo de instrucciones, almacenamiento de la información capturada, etc etc; systemtap implementa un lenguaje que permite escribir scripts; posteriormente son analizados por otra parte de systemtap que se encarga de validar las peticiones del usuario (es posible construir peticiones de kprobes que cuelguen el sistema, y no se deben permitir) y finalmente construyen las peticiones que se mandan a kprobes, y se recolectan y se muestran los datos al usuario. Y eso es todo. Kprobes + systemtap se puede empezar a utilizar hoy mismo, tan solo hay que activar kprobes en el kernel, que ya está (a diferencia de LTT) en el kernel, e instalar el paquete systemtap, y a disfrutar.

1 comentario:

  1. No tengo activado kprobes en mi nucleo, pero para la próxima que tenga que hacerlo, lo añadire por curiosidad -que siempre es la peridición de los gatos-.

    ResponderEliminar