Guía Prelink de Gentoo Linux

Stefan Jones  Autor
John P. Davis  Editor
Jorge Paulo  Editor
Sven Vermeulen  Editor
Erwin  Editor
José Alberto Suárez López  Traductor
John Christian Stoddart  Traductor
José Luis Rivero  Traductor
Enrique Barbeito García  Traductor

Actualizado 2 de abril, 2007

1.  Introducción

¿Qué es Prelink y en qué me puede ayudar?

La mayoría de aplicaciones comunes hacen uso de librerías compartidas. Estas librerías compartidas necesitan ser cargadas en memoria en tiempo de ejecución y las distintas referencias simbólicas deben ser resueltas. Para la mayoría de los pequeños programas, este tiempo de carga es muy rápido. Pero para los programas escritos en C++ y que utilicen muchas librerías, el tiempo de carga puede llevar bastante tiempo.

En la mayoría de sistemas, las librerías no se cambian muy a menudo y cuando se ejecuta un programa, las operaciones para cargarlo son siempre las mismas. Prelink se aprovecha de esto para llevar el linkado a cabo y almacenarlo en el ejecutable, prelinkándolo en realidad.

El prelinkado puede reducir los tiempos de inicialización de las aplicaciones. Por ejemplo, el tiempo de carga de un programa típico de KDE puede ser reducido hasta un 50%. El único mantenimiento requerido es ejecutar prelink cada vez que se actualice una librería para un ejecutable prelinkado.

Aviso: Prelink no funciona en Gentoo Hardened. Esto es debido a que ambos proyectos tratan de cambiar el espacio de mapeo de direcciones de las librerías compartidas. De todos modos, prelink con la opción -R utiliza direcciones aleatorias, proporcionando así mayor grado de protección.

Resumen

2.  Configurar Prelink

Instalar los programas

Lo primero que necesita es instalar la herramienta prelink. El proceso de emerge comprueba automáticamente que su sistema pueda hacer prelink sin peligro.

Listado de Código 2.1: Instalando Prelink

# emerge prelink

Algunas personas obtienen errores emergiendo prelink a causa de las pruebas fallidas. Estas pruebas se pusieron por razones de seguridad; si las desactiva, el comportamiento de prelink puede ser impreciso. Normalmente los errores de emerge dependen únicamente de los paquetes base: binutils, gcc, y glibc. Intente re-emerger estos paquetes en ese orden.

Nota: Sugerencia: Si obtiene un error, pruebe a compilar y probar prelink usted mismo (./configure ; make ; make check ). Ante un fallo, puede ver los ficheros *.log en el directorio testsuite. Le pueden proporcionar algunas pistas de utilidad.

Si obtiene una serie de pasos que reproducen el error de emerge en otro sistema, por favor compruebe Bugzilla y realice un nuevo informe de error si éste todavía no ha sido reportado.

Preparar su sistema

Asegúrese también de que no tiene el parámetro -fPIC puesto en sus CFLAGS/CXXFLAGS. Si lo tiene, necesitará reconstruir todo su sistema sin él.

Configuración

Ejecutando env-update se creará el fichero /etc/prelink.conf que le dice a prelink qué ficheros prelinkar.

Listado de Código 2.2: Ejecutando env-update

# env-update

Desafortunadamente, no puede prelinkar ficheros que hayan sido compilados con antiguas versiones de binutils. La mayoría de estas aplicaciones vienen de paquetes binarios precompilados instalados en /opt. Creando el siguiente fichero, le diremos a prelink que no intente prelinkarlos.

Listado de Código 2.3: /etc/env.d/60prelink

PRELINK_PATH_MASK="/opt"

Nota: Puede añadir más o menos directorios a la lista, separados por dos puntos (:).

3.  Prelinkado

Uso de Prelink

Utilizo el siguiente comando para prelinkar todos los binarios de los directorios dados por /etc/prelink.conf.

Listado de Código 3.1: Prelinkando los ficheros listados

# prelink -amR

Aviso: Se ha observado que si tiene poco espacio en disco y prelinka por completo su sistema, hay una posibilidad de que sus binarios queden truncados. El resultado es un sistema destrozado. Utilice el comando file o readelf para comprobar el estado de un fichero binario. De modo alternativo, compruebe la cantidad de espacio libre de su disco duro con df -h.

Las opciones explicadas:
-a "All": prelinka todos los binarios
-m Conserva el espacio de la memoria virtual. Esta opción es necesaria si tiene muchas librerías que tengan que ser prelinkadas.
-R Al azar - hace aleatoria la asignación de la dirección. Esta opción aumenta la seguridad frente a desbordamientos de búfer.

Nota: Para más opciones y detalles vea man prelink.

Prelink como tarea programada

sys-devel/prelink-20060213 y posteriores instalan una tarea programada en /etc/cron.daily/prelink. Para activarla, edite el fichero de configuración /etc/conf.d/prelink. Esto ejecutará prelink en segundo plano a diario, como es necesario, ahorrándole lanzar el comando manualmente.

Acelerar KDE después del Prelinkado

El tiempo de carga de KDE puede reducirse muchísimo después del prelinkado. Si informa a KDE de que ha sido prelinkado él desactivará la carga de kdeinit (ya que no se requiere más) por lo que acelerará KDE aún más.

Ponga KDE_IS_PRELINKED="true" en /etc/env.d/*kdepaths* para informar del prelinkado a KDE.

Borrar prelink

Si ha cambiado de de opinión acerca del prelinkado, antes de desinstalar el paquete prelink necesitará eliminar su correspondiente tarea programada en /etc/cron.daily y /etc/conf.d/prelink. A continuación, tendrá que eliminar el prelinkado de todos los binarios:

Listado de Código 3.2: Eliminar el prelinkado de todos los binarios

# prelink -au

Finalmente, desinstale el paquete prelink:

Listado de Código 3.3: Desinstalar prelink

# emerge -aC prelink

4.  Problemas conocidos y soluciones

"No puedo prelinkar contra librerías compartidas non-PIC"

La causa de este problema está en la errónea compilación de las librerías compartidas que fueron compiladas sin la opción -fPIC de gcc para todos sus ficheros objeto.

Aquí están las librerías que no han sido o no pueden ser arregladas:

Si su problema de librería no está listado, por favor publíquelo con, preferiblemente, un parche para añadir la opción -fPIC al CFLAGS pertinente.

Cuando prelinko mi sistema algunos binarios estáticos dejan de funcionar

Por lo que a glibc concierne, el binario 100% estático no existe. Si compila estáticamente un binario con glibc, éste puede depender de otros ficheros del sistema. A continuación tiene una explicación de Dick Howell,

"Supongo que la idea es que todo estuviera en el fichero descargado, de modo que nada dependa de las librerías locales del sistema al que va dirigido. Desafortunadamente con Linux, y creo que con todo lo que use GLIBC, esto todavía no es del todo cierto. Ahí está "libnss" (servicio de nombres (name service switch), algunas personas parece que lo llaman sistema de seguridad de red (network security system)) que proporciona funciones para acceder a varias bases de datos de autenticación, información de red y otras cosas. Se supone que hace programas independientes del entorno de red real configurado de la máquina. Una buena idea, pero los cambios a GLIBC pueden llevar a problemas cargándolo. Además, no puede linkar "libnss" estáticamente ya que está configurado individualmente para cada máquina. El problema viene, pienso, principalmente de linkar estáticamente otras librerías de GLIBC, en particular "libpthread", "libm" y "libc" de donde vienen llamadas incompatibles a funciones de "libnss"."

Prelink se para con "prelink: dso.c:306: fdopen_dso: Assertion `j == k' failed."

Es un problema conocido, amablemente diagnosticado aquí. Prelink no puede arreglárselas con los ejecutables UPX-comprimidos. En cuanto a prelink-20021213 no hay solución excepto esconder los ejecutables mientras esté realizando el prelinkado. Vea la sección de Configuración para tener un modo sencillo de hacer ésto.

Uso grsecurity y parece que el prelinkado no funciona.

Para usar prelink en un sistema con grsecurity que use una base mmap() aleatoria, es necesario quitar "randomized mmap() base" del fichero /lib/ld-2.3.*.so. Esto puede hacerse con la utilidad chpax, pero debe hacerse cuando el fichero no esté en uso (p.e. iniciando desde un disco de rescate)

Prelink falla con el error "prelink: Can't walk directory tree XXXX: Too many levels of symbolic links"

Sus enlaces simbólicos están demasiado anidados. Esto ocurre cuando un enlace simbólico se apunta a sí mismo. Por ejemplo, /usr/lib/lib -> lib es el más común. Para solucionarlo, puede buscar el enlace manualmente o emplear la herramienta proporcionada por el paquete symlinks:

Listado de Código 4.1: Arreglar enlaces simbólicos

# emerge symlinks
# symlinks -drv /

Puede encontrar más detalles en Bugzilla y en este hilo del foro.

5.  Conclusión

El prelinkado puede acelerar drásticamente los tiempos de inicialización de un gran número de aplicaciones. Su soporte está incorporado en Portage. El prelinkado también es fiable ya que siempre puede deshacer los cambios para cualquier binario si se encuentra con algún problema. ¡Sólo recuerde que cuando actualice glibc u otras librerías con las que haya prelinkado, necesitará ejecutar prelink de nuevo! Resumiendo ¡Buena suerte!