Guía Prelink de Gentoo Linux
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 enlazado a cabo y almacenarlo en el
ejecutable, preenlazándolo en realidad.
El prelenlazado 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 preenlazado.
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
-
El preenlazado se hace con un programa llamado, sorprendentemente,
prelink. Cambia el binario para hacerlo más rápido en su
inicialización.
-
Si las librerías dependientes de una aplicación cambian después de que la
haya preenlazado, necesitará preenlazar de nuevo la aplicación; de no ser
así, perderá la ganancia de velocidad. Esto es para decir que cada vez que
actualice un paquete con portage que actualice librerías, éstas necesitarán
preenlazarse de nuevo.
-
El cambio del binario es completamente reversible. prelink tiene una
función para deshacer dicho cambio.
-
Las actuales versiones de Portage pueden manejar, vía prelink, los
cambios de las sumas MD5 y los mtimes de los binarios.
-
No necesita poner FEATURES="prelink" en su fichero
make.conf; Portage soportará prelink automáticamente si puede
encontrar el binario prelink.
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 preenlazado
sin peligro.
Listado de Código 2.1: Instalar Prelink |
# emerge prelink
|
Algunas personas obtienen errores al hacer emerge 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
por su cuenta (./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
Al ejecutar env-update se creará el fichero
/etc/prelink.conf que le dice a prelink qué ficheros
preenlazar.
Listado de Código 2.2: Ejecutar env-update |
# env-update
|
Desafortunadamente, no puede preenlazar ficheros que se hayan compilado con
antiguas versiones de binutils. La mayoría de estas aplicaciones vienen de
paquetes binarios precompilados instalados en /opt. Al crear
el siguiente fichero, le diremos a prelink que no intente preenlazarlos.
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.
Preenlazado
Uso de Prelink
Utilizo la siguiente orden para preenlazar todos los binarios de los
directorios dados por /etc/prelink.conf.
Listado de Código 3.1: Preenlazar los ficheros listados |
# prelink -amR
|
Aviso:
Se ha observado que si tiene poco espacio en disco y preenlaza por
completo su sistema, hay una posibilidad de que sus binarios queden
truncados. El resultado es un sistema destrozado. Utilice la orden
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": preenlaza 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 preenlazado.
|
| -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 la orden
manualmente.
Acelerar KDE después del preenlazado
El tiempo de carga de KDE puede reducirse muchísimo después del preenlazado.
Si informa a KDE de que ha sido preenlazado, éste 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=1 en /etc/env.d/*kdepaths* para
informar del preenlazado a KDE.
Eliminar prelink
Si ha cambiado de de opinión acerca del preenlazado, 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 preenlazado de todos los binarios:
Listado de Código 3.2: Eliminar el preenlazado 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 preenlazar 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:
-
Las librerías en el paquete wine, incluyendo winex. De todos modos, el
preenlazado no aceleraría los ejecutables de MS Windows.
-
La librería en media-video/mjpegtools,
/usr/lib/liblavfile-1.6.so.0.
-
Las librerías OpenGL de NVIDIA,
/usr/lib/opengl/nvidia/lib/libGL.so.*. Debido a razones de
rendimiento fueron compiladas sin soporte PIC.
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 preenlazo 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 enlazar "libnss" estáticamente ya que está
configurado individualmente para cada máquina. El problema viene, pienso,
principalmente de enlazar 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 preenlazado.
Vea la sección de Configuración para tener
un modo sencillo de hacer ésto.
Uso grsecurity y parece que el preenlazado 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 preenlazado puede acelerar drásticamente los tiempos de inicialización
de un gran número de aplicaciones. Su soporte está incorporado en Portage.
El preenlazado también es fiable ya que siempre puede deshacer los cambios
para cualquier binario si se encuentra con algún problema. ¡Solo recuerde
que cuando actualice glibc u otras librerías con las que haya preenlazado,
necesitará ejecutar prelink de nuevo! Resumiendo ¡Buena suerte!
El contenido de este documento, a no ser que se especifique
expresamente, está registrado bajo los términos de la licencia
CC-BY-SA-2.5. Se aplican las
Pautas de
Utilización del logotipo y nombre de Gentoo.
|