Tengo un pequeño programa Java que llama en bucle a InetAddress.getByName("example.com") cada segundo. Cuando lo ejecuto en un cuadro CentOS 6.4 usando 'strace -f' veo que /etc/resolv.conf se abre y se lee una vez:
$ grep /etc/resolv.conf strace.out
[pid 24810] open("/etc/resolv.conf", O_RDONLY) = 6
Cuando lo ejecuto en Debian 7 veo que /etc/resolv.conf se abre o se actualiza repetidamente con stat():
$ grep /etc/resolv.conf strace.out
[pid 41821] open("/etc/resolv.conf", O_RDONLY) = 10
[pid 41821] stat("/etc/resolv.conf", {st_mode=S_IFREG|0644, st_size=92, ...}) = 0
[pid 41821] open("/etc/resolv.conf", O_RDONLY) = 10
[pid 41821] stat("/etc/resolv.conf", {st_mode=S_IFREG|0644, st_size=92, ...}) = 0
[pid 41821] stat("/etc/resolv.conf", {st_mode=S_IFREG|0644, st_size=92, ...}) = 0
Ambos sistemas tienen /etc/nsswitch.conf configurado con
hosts: archivos dns
Ninguno de los sistemas tiene un demonio de almacenamiento en caché de nombres en ejecución.
Utilicé la misma versión de Oracle HotSot Java JVM en ambas máquinas para descartar cualquier diferencia de Java.
La caja CentOS 6.4 tiene instalado glibc 2.12. La caja Debian 7 tiene instalado glibc 2.13.
¿A qué se debe el comportamiento diferente entre los dos sistemas operativos con respecto a abrir y leer /etc/resolv.conf?
Respuesta1
Los desarrolladores de RedHat glibc consideran que algunos errores en su software no son errores. Uno de estos errores es la relectura de resolv.conf después de cambiarlo. glibc considera que la responsabilidad es de la aplicación, por lo que todas y cada una de las aplicaciones deberán crear su propia lógica para ello.
Debido a que esto es absolutamente una locura, los desarrolladores de eglibc han solucionado este problema. Entonces, en sistemas que no son eglibc, su aplicación deberá tener su propia lógica para reinicializar nss_dns, o de lo contrario deberá reiniciarse después de un cambio en resolv.conf. En sistemas eglibc (Debian y cosas basadas en Debian), obtienes una libc con menos errores.
Descubrimos esto de la manera más difícil después de cambiar resolv.conf, desmantelar servidores DNS antiguos y luego tener que reiniciar más de 1200 servidores mysql. No hace falta decir que esto no es divertido.
Respuesta2
No sólo las versiones de la biblioteca C son diferentes, sino que CentOS usa la biblioteca GNU C ( glibc
) mientras que Debian usa Embedded GLIBC ( eglibc
), por lo que la implementación real de las llamadas al sistema de búsqueda de nombres es completamente diferente.
Probablemente eso explicaría el comportamiento diferente de las llamadas al sistema entre estas dos distribuciones.
Supongo que InetAddress.getByName
se traduce en getaddrinfo()
. Puede comenzar leyendo el código fuente de cada llamada al sistema en las versiones e implementaciones de la biblioteca C relevantes.
Asegúrese de leer el código fuente de las versiones reales del paquete que está utilizando. Los paquetes en EL 6.4 han tenido más de 2 años de mejoras en comparación con sus versiones originales. Supongo que lo mismo ocurre con los paquetes de Debian.