Différence de résolution de noms entre CentOS et Debian

13

J'ai un petit programme Java qui boucle en appelant InetAddress.getByName ("example.com") chaque seconde. Lorsque je l'exécute sur une boîte CentOS 6.4 en utilisant 'strace -f', je vois que /etc/resolv.conf est ouvert et lu une fois:

$ grep /etc/resolv.conf strace.out
[pid 24810] open("/etc/resolv.conf", O_RDONLY) = 6

Quand je l'exécute sur Debian 7, je vois que /etc/resolv.conf est ouvert à plusieurs reprises ou stat () 'd:

$ 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

Les deux systèmes ont /etc/nsswitch.conf configuré avec

hôtes: fichiers dns

Aucun des deux systèmes n'a de démon de mise en cache de noms en cours d'exécution.

J'ai utilisé la même version de la JVM Java Oracle HotSot sur les deux machines pour exclure toute différence Java.

La boîte CentOS 6.4 a installé la glibc 2.12. La boîte Debian 7 a installé la glibc 2.13.

Qu'est-ce qui explique le comportement différent entre les deux systèmes d'exploitation en ce qui concerne l'ouverture et la lecture de /etc/resolv.conf?

user1311618
la source
Pouvez-vous s'il vous plaît coller des traces complètes.
Danila Ladner

Réponses:

10

Les développeurs de la glibc RedHat considèrent que certains bogues de leur logiciel ne sont pas des bogues. L'un de ces bogues est la relecture de resolv.conf après modification. la glibc considère que la responsabilité de l'application, donc chaque application devra créer sa propre logique pour cela.

Parce que c'est absolument fou, les développeurs d'eglibc ont résolu ce problème. Ainsi, sur les systèmes non-eglibc, votre application devra avoir sa propre logique pour réinitialiser nss_dns, sinon elle devra être redémarrée après une modification de resolv.conf. Sur les systèmes eglibc (Debian et les choses basées sur Debian), vous obtenez une libc moins boguée.

Nous l'avons découvert à la dure après avoir changé resolv.conf, mis hors service d'anciens serveurs DNS et ensuite avoir redémarré plus de 1200 serveurs mysql. Inutile de dire que ce n'est pas amusant.

Dennis Kaarsemaker
la source
Pourquoi est-ce considéré comme "absolument fou"? Et pourquoi la glibc a-t-elle procédé de cette façon?
Michael Hampton
1
Parce qu'au lieu de réparer la glibc, ils imposent le fardeau à chaque application là-bas ... Quant à savoir pourquoi ils le font? Je ne sais pas. Je ne peux pas lire l'esprit de Dreppers, et je ne suis pas sûr de vouloir savoir ce qui s'y passe ...
Dennis Kaarsemaker
1
La chose est: je ne suis pas sûr que la glibc soit réellement cassée. Pourquoi faut /etc/resolv.conf-il relire à chaque recherche DNS? Est-il vraiment censé changer cela fréquemment? Maintenant, si le comportement n'était pas documenté, je pourrais comprendre ...
Michael Hampton
1
Ce n'est pas relu à chaque recherche, ce serait également cassé :) Le comportement est non documenté et vraiment contre-intuitif: glibc prend la responsabilité d'initialiser la bibliothèque nss_dns, mais rend par la suite l'application responsable de la réinitialisation, même si ces applications ne le font pas savoir quoi que ce soit sur nss et comment cela fonctionne. Comment est-ce pas foutu?
Dennis Kaarsemaker
1
Dennis a raison, gai dans EL6 est intentionnellement cassé parce que le comportement du buggy est devenu le "comportement attendu" - access.redhat.com/site/solutions/541163
suprjami
4

Non seulement les versions de la bibliothèque C sont différentes, mais CentOS utilise la bibliothèque GNU C ( glibc) tandis que Debian utilise Embedded GLIBC ( eglibc), donc l'implémentation réelle des appels système de recherche de nom est complètement différente.

Cela expliquerait probablement le comportement différent des appels système entre ces deux distributions.

Je suppose que cela se InetAddress.getByNametraduit par getaddrinfo(). Vous pouvez commencer par lire la source de chaque appel système dans l'implémentation et les versions de la bibliothèque C pertinentes.

Assurez-vous de lire la source à partir des versions de package réelles que vous utilisez. Les packages d'EL 6.4 ont fait plus de 2 ans d'améliorations par rapport à leurs versions originales en amont. Je suppose que c'est la même chose pour les paquets Debian.

suprjami
la source