[root@GFVM4 ~]# hostname
GFVM4
[root@GFVM4 ~]#
[root@GFVM4 ~]#
[root@GFVM4 ~]# getent hosts gfvm4
192.168.122.151 GFVM4
[root@GFVM4 ~]# getent hosts GFVM4
fe80::5054:ff:feac:787 GFVM4
[root@GFVM4 ~]#
[root@GFVM4 ~]#
[root@GFVM4 ~]#
[root@GFVM4 ~]# ifconfig ens5
ens5: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.122.151 netmask 255.255.255.0 broadcast 192.168.122.255
inet6 fe80::5054:ff:feac:787 prefixlen 64 scopeid 0x20<link>
ether 52:54:00:ac:07:87 txqueuelen 1000 (Ethernet)
RX packets 452 bytes 33008 (32.2 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 204 bytes 26112 (25.5 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
[root@GFVM4 ~]#
Это ожидаемое поведение?
Как видите, я установил все заглавные буквы HOSTNAME GFVM4.
если я использую то же имя (ВСЕ ЗАПИСИ), он возвращает адрес ipv6. Если я использую маленькое буквенное имя хоста, он возвращает адрес ipv4.
Это правильное поведение?
Запуск Fedora21 как виртуальной машины на базе qemu.
Спасибо
Это не будет полный ответ, просто хочу поделиться своими выводами, и он слишком длинный, чтобы поместиться в комментариях ...
Во-первых, если вы хотите ответить на getent
вам нужно иметь правильную конфигурацию в /etc/nsswitch.conf
, /etc/resolv.conf
, /etc/hosts
и т.д. У меня есть Fedora 22, и в ней есть следующая строка /etc/nsswitch.conf
.
hosts: files mdns4_minimal [NUTFOUND=return] dns myhostname
getent hosts localhost
и getent hosts LOCALHOST
дают разные результаты. Но после того, как я изменился /etc/nsswitch.conf
иметь hosts: files
, они дают тот же результат.
Я думаю, что когда у вас есть несколько источников для поиска, они могут рассматривать случай по-разному и давать противоречивые результаты.
Во-вторых, вы можете попробовать getent ahost
. Оно использует getaddrinfo()
вместо того gethostbyname2()
. Это дает более последовательные ответы, по крайней мере, в моем случае. Видеть man getent
.
В-третьих, мне было интересно почитать исходный код. getent.c и смотреть след ltrace getent hosts localhost
. Там вы можете увидеть inet_pton()
и gethostbyname2()
. Вы также можете отслеживать системные вызовы по ltrace -S
и вы можете увидеть, какие файлы открыты, например /etc/hosts
.
Ниже приведен вывод ltrace
. AF_INET6 (10) пробуется перед AF_INET (2).
[a@localhost ~]$ ltrace getent hosts LOCALHOST
__libc_start_main([ "getent", "hosts", "LOCALHOST" ] <unfinished ...>
mtrace() = <void>
setlocale(LC_ALL, "") = "en_US.UTF-8"
textdomain("libc") = "libc"
argp_parse(0x606440, 3, 0x7ffc1cf8a7c8, 0) = 0
strcmp("hosts", "hosts") = 0
inet_pton(10, 0x7ffc1cf8c67a, 0x7ffc1cf8a680, 0) = 0
inet_pton(2, 0x7ffc1cf8c67a, 0x7ffc1cf8a680, 0x658e2f20) = 0
gethostbyname2(0x7ffc1cf8c67a, 10, 0x7ffc1cf8a680, 0x658e2f20) = 0
gethostbyname2(0x7ffc1cf8c67a, 2, -20, 0x7f166586c8f5) = 0x7f1665b16260
inet_ntop(2, 0xc47000, 0x7ffc1cf8a620, 46) = 0x7ffc1cf8a620
printf("%-15s %s", "127.0.0.1", "localhost.localdomain") = 37
__overflow(0x7f1665b13620, 32, 0, 0x7fffffda) = 32
fputs_unlocked(0xc47041, 0x7f1665b13620, 0x7f1665d36025, 0xfbad2a84) = 1
__overflow(0x7f1665b13620, 10, 0xc47050, 0x74736f686c61636f127.0.0.1 localhost.localdomain localhost
) = 10
+++ exited (status 0) +++
Наконец, я предлагаю либо 1) контролировать источник getent
в /etc/nsswitch.conf
; или 2) поддерживать свою собственную базу данных / словарь.
Просто предположение, но от http://linuxmanpages.net/manpages/fedora21/man1/getent.1.html:
hosts When no key is provided, use sethostent(3), gethostent(3), and endhostent(3) to enumerate the hosts database. When one or more key arguments are provided, pass each key to gethostbyaddr(3) or gethostbyname2(3), depending on whether a call to inet_pton(3) indicates that the key is an IPv6 or IPv4 address or not, and display the result.
В http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/usr.bin/getent/getent.c «if (argc == 2)» означает «% getent hosts» (ключ не указан), поэтому выполняется следующее:
for (i = 2; i < argc; i++) {
if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0)
he = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6);
else if (inet_pton(AF_INET, argv[i], (void *)addr) > 0)
he = gethostbyaddr(addr, INADDRSZ, AF_INET);
else
he = gethostbyname(argv[i]);
if (he != NULL)
hostsprint(he);
else {
rv = RV_NOTFOUND;
break;
}
}
Я не очень разбираюсь в C, и единственный источник, который я нашел с помощью быстрого поиска в Google, относится к NetBSD, но кажется, что если первый inet_pton (http://linuxmanpages.net/manpages/fedora21/man3/inet_pton.3.html) найти запись для IPv6, вторая функция для IPv4 пропускается. Кроме того, я не заметил никакого принуждения к регистру с первого взгляда (это означает, что не учитывается регистр).
Тем не менее, у вас может быть 2 записи для GFVM4, одна верхняя, а другая нижняя. Верхний, вероятно, связан с IPv6-адресом.
Было бы здорово, если бы вы могли предоставить подтверждение или нет о разных записях в разных случаях, чтобы подтвердить (или нет). Если подтвердится, я бы сказал, что это ожидаемое поведение программного обеспечения getent.