6.2. Ficheros de configuración de pDI-Tools

pDI-Tools incorpora la posibilidad de ser configurado mediante ficheros de texto. Este método no sólo facilita la configuración, sino que es mucho más fácil de controlar y ofrece mucha más potencia que las variables de entorno.

6.2.1. Como se estructura un fichero de configuración

Un fichero de configuración se estructura en secciones. La secciones son bloques dentro de un fichero de configuración. Estos bloques son indivisibles, y por lo tanto todas las secciones se encuentran al mismo nivel. Estas secciones permiten dividir el fichero de configuración en porciones que podemos activar, desactivar y reutilizar fácilmente.

En un fichero de configuración, dentro de las secciones, podemos encontrar los siguientes elementos:

6.2.1.1. Sintaxis

Un comentario se reconoce porque el primer carácter de la línea que no sea un blanco es una almohadilla #.

Las secciones, tal como hemos explicado, dividen un fichero de configuración en diferentes bloques. Una sección comienza con el identificador de sección, encerrado entre corchetes, y termina con el comienzo de una nueva sección (con otro identificador de sección), o con el propio fin del fichero de configuración.

En todo fichero de configuración siempre existe la sección implícita global. Si no se indica, al comenzar un fichero, ningún nombre de sección, se asume que todo pertenece a esta sección. También es posible introducir contenidos en ella explicitamente abriendo una sección con su nombre.

Seguidamente mostramos un fichero de configuración de ejemplo, comentado, dividido en tres secciones: global (de forma implícita), sección_de_ejemplo y otra_sección:


# .. asignaciones y comandos de la sección 'global' ..

[seccion_de_ejemplo]
  # .. asignaciones y comandos de la sección 'seccion_de_ejemplo' ..

[otra_sección]
  # .. asignaciones y comandos de la sección 'otra_sección' ..
        

Un último detalle es que las secciones pueden estar partidas por otras secciones dentro de un mismo fichero, pero cuando se cargue el fichero se procesarán como un todo todos los trozos de la sección sin verse afectada por estas divisiones. Por ejemplo, supongamos que queremos recoger la configuración contenida en la sección AAA del siguiente fichero de configuración:


[AAA]
  # .. asignaciones y comandos de la sección 'AAA' ..

[BBB]
  # .. asignaciones y comandos de la sección 'BBB' ..

[AAA]
  # .. MAS asignaciones y comandos de la sección 'AAA' ..
        

El resultado final es que se procesará la primera división con el nombre AAA, se ignorará el contenido de la sección BBB, y cuando se vuelva a encontrar la sección AAA se seguirá procesando el fichero hasta el final.

Las asignaciones se componen de un parámetro y un valor separados por un signo de igualdad (=). Una asignación debe ocurrir en su totalidad dentro de una misma línea.

Ambos lados de una asignación pueden estar entre comillas dobles que delimiten sus campos. Los espacios a los lados del signo de igualdad se ignorarán y no formarán parte ni del parámetro ni del valor. Si se delimita el parámetro o el valor mediante comillas es posible incluir comillas escapándolas con una contrabarra (\). Ejemplo de asignaciones:


[asignaciones]
  debug = 1
  be_path = "/home/gerardo/backends:/usr/local/pdi-tools/backends"
  "mi parametro" = "Toma como valor este \"string\" entre comillas"
        

Las siguientes herramientas de configuración de que disponemos son los comandos. Actualmente hay los siguientes:

Include {fichero [:sección] | :sección}

Se sustituye por el contenido de la sección global o sección del fichero fichero. Si no se especifica el fichero se busca la sección en el fichero actual. Debe vigilarse con esta opción porque actualmente no hay ningún control de recursiones y ¡es posible entrar en bucles infinitos de inclusiones!

Si en sección se especifica el valor %PLATFORM% se incluye el contenido de la sección que tenga el nombre de la plataforma en uso.

Log {mensaje}

Imprime el mensaje mensaje en el "log" de ejecución de pDI-Tools.

Warning {mensaje}

Emite el mensaje de advertencia mensaje en el "log" de ejecución de pDI-Tools.

Error {mensaje}

Imprime el mensaje de error mensaje en el "log" y termina la ejecución de pDI-Tools.

Si ejecutásemos el siguiente ejemplo en una máquina con GNU/Linux:


[global]
Include :%PLATFORM%

[common]
verbose=3

[linux-gnu]
include :common
runtime=linux.cfg
log "Se cargo la configuración para Linux."
...

[irix]
runtime=irix.cfg
warning "La configuración para Irix es muy precaria!"
...
        

Se cargaría la configuración de la sección global. No obstante se interrumpiría el proceso de esta sección para seguir procesando la sección linux-gnu. Esta a su vez interrumpiría su proceso para incluir la sección common. Una vez procesada la sección common se volvería a procesar el resto de la sección linux-gnu. Es en este momento cuando se imprime el mensaje "Se cargo la configuración para Linux". Terminada de procesar esta sección se termina de procesar la sección global justo donde se dejó al comenzar con el primer Include.

6.2.1.2. La sección global

Esta sección es un poco especial. En principio, si no se indica el nombre de ninguna sección y empiezan a aparecer asignaciones, se asume que estas pertenecen a esta sección. Así podemos tener un fichero como:


verbose = 2

[global]
debug = on

[otra_seccion]
# ...
        

Se interpretará que verbose y debug están la sección global.

La sección global (y sólo ella) es la sección que se procesa por defecto si no se ha indicado el nombre de ninguna sección. Así si alguien ejecuta el comando Include "linux.cfg" se procesará la sección global del fichero linux.cfg ignorando el resto de secciones.

6.2.1.3. La sección defaults

Esta sección existe por convención y no porque tenga alguna característica especial. Se aconseja crearla en el fichero de configuración global de pDI-Tools e introducir en ella los parámetros por defecto más usuales para el sistema.

Si se separan los parámetros por defecto de esta forma es posible incluirlos fácilmente desde un fichero de configuración de usuario sin tener que copiar todos los parámetros a mano a nuestro fichero de configuración.

6.2.1.4. La sección runtime

Al igual que la sección defaults, esta también existe por convención. Sirve para tener separada la asignación al atributo runtime. De esta forma es fácil poder incluir el runtime por defecto sin tener que copiarlo del fichero de configuración por defecto.

6.2.2. Configuración basada en varios ficheros

Mediante el comando Include es posible distribuir la configuración en diferentes ficheros de configuración, o al menos, en diferentes secciones dentro de un fichero de configuración.

Esto permite a los usuarios crear pequeños ficheros de configuración que importan partes de otros más grandes y de esta forma reciclar configuraciones. Además reciclar nos permite trabajar de una forma más ordenada y no tan propensa a errores.

6.2.3. Parámetros de funcionamiento de pDI-Tools

Seguidamente describimos y clasificamos los parámetros de funcionamiento que se pueden fijar en los ficheros de configuración.

Siempre que no se indique lo contrario, si se redefine un parámetro, el valor vigente del parámetro será el asignado en la última aparición del mismo.

6.2.3.1. Ficheros de log y depuración

pDI-Tools incorpora su propio sistema de logs y depuración. Así evita usar librerías de terceros, polucionar lo menos posible el entorno de ejecución del programa que monitoriza e interaccionar accidentalmente con otras librerías. Seguidamente comentamos los parámetros que controlan la verbosidad y mecanismos de depuración de pDI-Tools.

logfile - Fichero de log de pDI-Tools

Si se indica un fichero, se imprimirán en él todos los mensajes producidos durante la ejecución de pDI-Tools sin invadir para nada las salidas estándar (stdout y stderr).

Si no se indica el parámetro o se deja vacío, los mensajes de pDI-Tools se lanzarán a la salida de error estándar (stderr).

verbose - Nivel de verbosidad

pDI-Tools se puede configurar para que emita los mensajes según la importancia de los mismos. Este parámetro toma como valor un entero que indica el nivel de verbosidad. Cuanto mayor el valor, más detalle:

  • 0 - Silencio total (excepto errores).

  • 1 - Sólo se muestran advertencias y errores.

  • 2 - Imprime todos los mensajes excepto los de depuración.

  • 3 - Imprime toda la información de depuración disponible (ver seguidamente el parámetro debug).

debug - Modo de depuración

Si este flag está activo se realiza un montón de trabajo extra para verificar que las cosas andan bien. No se aconseja usarlo en producción, ya que a parte de lento, imprime demasiada información en el log (implica poner el parámetro verbose a 3).

Por defecto está desactivado.

6.2.3.2. Límites

Los siguientes parámetros permiten variar ciertos límites establecidos durante la inicialización de pDI-Tools. pDI-Tools hace uso en muchas ocasiones de estructuras estáticas (pools) para ganar velocidad no reservando dinámicamente memoria. Con estos parámetros podemos ajustar el consumo de memoria de pDI-Tools sin sacrificar velocidad. También es posible desactivar algunos límites y hacer que se ejecuten algoritmos que reservan memoria dinámicamente.

max_objects - Número máximo de objetos en memoria

Número máximo de objetos que puede haber en memoria (entre el binario, librerías y los backends). Es conveniente que sea un número algo alto, pero tampoco demasiado grande ya que si no consumimos mucha memoria.

Por defecto es 40.

max_threads - Número máximo de "threads"

El parámetro max_threads fija la máxima cantidad de "threads" que se pueden monitorizar. Es conveniente que el número no sea demasiado bajo, ya que si se superase el número de "threads" abortaría la ejecución del programa. Este parámetro reserva una tabla de max_threads punteros.

Por defecto su valor es 100.

Nota

Sólo tiene efecto si se realizan interposiciones de código mediante el mecanismo de "callback".

num_threads - Número de "threads" que se deben pre-inicializar

No puede tener un valor mayor que max_threads. Indica el número de "threads" que se espera usar. De esta forma la inicialización y reserva de memoria se hace al inicio del programa y no durante la ejecución, evitando que la instrumentación tenga mucho impacto en la ejecución del programa.

Se pueden introducir los siguientes valores:

  • -1 - Inicializa todos los "threads" a la vez (en total max_threads) de golpe durante la inicialización. Esto implica el peor caso en consumo de memoria.

  • 0 - No inicializamos ningún "thread". Se irán inicializando según se necesiten.

  • +x - Inicializa x "threads". Si se supera el número el resto se van inicializando durante la ejecución del programa hasta un máximo de max_threads.

Por defecto vale 0.

Nota

Sólo tiene efecto si se realizan interposiciones de código mediante el mecanismo de "callback".

cb_max_stubs - Cantidad máxima de "stubs" que pueden haber en memoria

Indica cuantos "stubs" como máximo habrá en memoria. Es importante considerar que si vamos a poner un "callback" sobre un objeto que llama a X funciones diferentes, es conveniente que este parámetro tome un valor mayor que X o si no será imposible instalar el "callback".

El valor por defecto varía según la plataforma ya que se calcula con la función _pdi_arch_defaultMaxStubs(). Esta función devuelve, generalmente, el tamaño de página de la arquitectura dividida por el tamaño de un "stub". Por ejemplo, en INTEL® 386 esta función asigna 204 como valor por defecto a cb_max_stubs (4096 bytes por página y 20 bytes por "stub").

Nota

Sólo tiene efecto si se realizan interposiciones de código mediante el mecanismo de "callback".

cb_stack_size - Tamaño de la pila por "thread" para las interposiciones mediante "callback"

Al monitorizar los "threads" necesitamos una zona de memoria donde guardar información sobre que se está monitorizando en un determinado momento. Evidentemente, cada "thread" ha de tener su espacio separado. Esto se realiza mediante una pila cuyo tamaño viene definido por esta variable. Si durante una monitorización hay problemas ("Segmentation Fault"), pruebe a incrementar esta variable. Si con valores grandes sigue teniendo problemas quizás debería empezar a sospechar que hay una monitorización recursiva.

Por defecto vale 1024.

Nota

Sólo tiene efecto si se realizan interposiciones de código mediante el mecanismo de "callback".

6.2.3.3. Backends y runtime

Mediante los siguientes parámetros se construye la lista de ficheros de comandos que irán cargando los "backends" y realizando las interposiciones de código.

Estos parámetros no se comportan igual que el resto cuando se repiten. En el caso del parámetro runtime, se emite un error y se termina la ejecución si se define más de una vez. En el caso del parámetro config, cada vez que aparece se añade el valor que le acompaña al final de una lista.

Cuando se terminan de procesar todos los ficheros de configuración, se antepone el valor del parámetro runtime a la lista de ficheros de comandos formada por los parámetros config.

Existen también acciones (atributos sin valor) que pueden reiniciar los valores asignados a runtime y a config.

Seguidamente enumeramos y explicamos estos atributos.

runtime - Fichero de configuración de sistema

Es un fichero de comandos de reenlace pero a nivel de sistema. Es el primero en cargar de todos los ficheros de configuración, y además es único. Sólo puede haber un fichero de configuración del runtime. Generalmente sirve para cargar backends sobre funciones críticas del sistema como fork(2) o exec(2).

config - Fichero de comandos de reenlace

Indica un fichero de comandos de reenlace. Puede indicarse este parámetro tantas veces como ficheros de comandos de reenlace se tengan.

reset_runtime - Olvida el runtime configurado actualmente

A este parámetro no se le puede asignar ningún valor. Cuando se encuentra provoca que se olvide el valor asignado al parámetro runtime, pudiéndolo volver a definir si se desea.

reset_config - Olvida la lista de ficheros de comandos configurada actualmente

A este parámetro no se le puede asignar ningún valor. Cuando se encuentra provoca que se olvide la lista de ficheros de comandos configurada hasta el momento con el parámetro config.

6.2.3.4. Rutas de búsqueda

Estos parámetros establecen rutas de búsqueda. Sirven para poder especificar los backends y ficheros de comandos sólo mediante su nombre, pDI-Tools con ayuda de estos parámetros ya tratará de resolver la ubicación de los archivos.

be_path - Rutas de búsqueda de los backends

Aquí indicamos los lugares donde podemos encontrar los backends. La sintaxis es sencilla: directorios separados por dos puntos (:).

Si se especifica varias veces este parámetro, el resultado final es como haber concatenado uno tras otro (separados por dos puntos) los distintos valores asignados.

Por defecto be_path contiene el directorio al fichero de runtime y al directorio de los "backends", ambos configurados por Autoconf (generalmente estos directorios son PREFIX/backends y PREFIX/runtime)

becfg_path - Rutas de búsqueda de los ficheros de comandos

Aquí indicamos los lugares donde podemos encontrar los ficheros de comandos de reenlace. La sintaxis y uso es igual que en el parámetro be_path acabado de comentar.

Por defecto becfg_path contiene el directorio a los ficheros de comandos de backends y al directorio de configuración de pDI-Tools, ambos directorios configurados por Autoconf (generalmente son PREFIX/becfg y PREFIX/etc).

lib_path - Rutas de búsqueda de las librerías y DSO (objetos compartidos).

Este parámetro indica donde se deben buscar las librerías y DSO que se van a usar. Se inicializa con el contenido de la variable de entorno LD_LIBRARY_PATH y con los directorios /lib y /usr/lib.

Si se asigna el valor especial %LD_LIBRARY_PATH% se sustituirá por el valor de la variable de entorno LD_LIBRARY_PATH.

En el resto la sintaxis y uso es igual que en los anteriores parámetros.

reset_be_path - Olvida las rutas de búsqueda de los backends

A este parámetro no se le puede asignar ningún valor. Cuando se encuentra provoca que se olvide el valor asignado a los parámetros be_path.

reset_becfg_path - Olvida las rutas de búsqueda de los ficheros de comandos de reenlace

A este parámetro no se le puede asignar ningún valor. Cuando se encuentra provoca que se olvide el valor asignado a los parámetros becfg_path.

reset_lib_path - Olvida las rutas de búsqueda de las librerías y objetos compartidos

A este parámetro no se asigna ningún valor. Cuando se encuentra provoca que se olvide el valor asignado a los parámetros lib_path.

6.2.3.5. Otros parámetros

Por último explicamos algunos parámetros que no se clasifican en ninguna de las anteriores categorías.

allow_lib_as_be - Cualquier función de cualquier DSO puede tomar el control en una interposición de código

En principio está prohibido redigirir una llamada desde un DSO a otro DSO que no sea un "backend". No obstante es posible que en algún caso pueda ser interesante relajar esta restricción y esto es para lo que sirve este parámetro si se activa.

Por defecto esta opción está desactivada.

Nota

Aún así, si esta opción está activada, pDI-Tools seguirá emitiendo un mensaje de aviso cada vez que se cree un reenlace hacia una función que no pertenezca a un "backend".

donttouch_backends - No instrumentar los backends

Si está activada esta opción, no se podrá instrumentar sobre los "backends", o lo que es lo mismo, no se podrán hacer reenlaces sobre funciones de los "backends". Es aconsejable tener activada esta opción.

Por defecto esta opción está activada.

Nota

Si esta opción está activada los comodines no engloban a los backend, sino sólo a los objetos regulares (y a libpdi.so si la opción donttouch_pdi está desactivada).

donttouch_pdi - No instrumentar a pDI-Tools

Si esta opción está desactivada se podrá instrumentar el DSO libpdi.so. Evidentemente se desaconseja seriamente desactivar esta opción a no ser que se desee, por algún motivo, que pDI-Tools se autoinstrumente.

Por defecto esta opción está activada.

cb_allow_handler - Permitir usar un "callback handler" alternativo al definir un "callback"

Parámetro booleano. Si está activado se permite usar un "callback handler" propio. Si está desactivado, pDI-Tools obliga a tener vacio o poner a NULL el cuarto parámetro de las reglas "callback".

Por defecto esta opción está desactivada.

no_check_on_config - No comprueba los ficheros durante la creación de un "script" de reenlace.

Parámetro booleano. No se chequea si un objeto existe mientras se está creando una configuración de interposiciones ("script" de reenlace). Si este "flag" está activo se detectará si el objeto existe o no durante la instalación de las interposiciones.

Por defecto este "flag" está desactivado.