Witam,
Mała ale istotna errata do mojego poprzedniego listu oraz rozwiązanie
problemu.
Dnia poniedziałek, 12 października 2009 o 18:28:48 Bartosz Lis napisał(a):
Witam,
Testuję jądro 2.6.31.2-0.1. Mam problemy z serwerem ntp:
# /usr/sbin/ntpd -dd -c /etc/ntp/ntp.conf
ntpd 4.2@1.1607-o Mon Oct 12 11:43:33 UTC 2009 (1)
addto_syslog: Attemping to register mDNS
*** WARNING *** The program 'ntpd' uses the Apple Bonjour compatibility
layer of Avahi.
*** WARNING *** Please fix your application to use the native API of Avahi!
*** WARNING *** For more information see http://0pointer.de/avahi-
compat?s=libdns_sde=ntpd
addto_syslog: Unable to register mDNS
addto_syslog: signal_no_reset: signal 13 had flags 1400
addto_syslog: set_process_priority: Leave priority alone: priority_done is
2 addto_syslog: precision = 0.978 usec
create_sockets(123)
addto_syslog: ntp_io: estimated max descriptors: 1024, initial socket
boundary: 16
addto_syslog: Listening on interface #0 wildcard, 0.0.0.0#123 Disabled
addto_syslog: bind() fd 17, family AF_INET6, port 123, scope 0, addr ::,
mcast=0 flags=0x81 fails: Address already in use
addto_syslog: unable to bind to wildcard socket address :: - another
process may be running - EXITING
Rzecz jasna, przed zawracaniem komukolwiek głowy sprawdziłem, że nic innego
nie chodzi na udp123. Wygląda to tak, jakby przy otwarciu przez proces
portu 123 na wildcardowym adresie IP 0.0.0.0 jądro nieproszone otwierało
mu także ten port na wildcardowym adresie IPv6 :: . Kiedy w następnym
kroku proces otwiera sobie własnoręcznie port 123 na adresie IPv6 ::
otrzymuje informację że ktoś mu ten adres wcześniej zajął.
Problem ten nie występuje w dowolnej kombinacji:
Tu powyżej pomyliłem się przy pisaniu mila: jest o jedno nie za dużo,
powinno być:
Problem ten występuje w dowolnej kombinacji:
dystrybucja: th
architektury: x86_64, i686
jądro: kernel-2.6.31.1-0.1 (zbudowane samodzielnie z CVSa),
kernel-2.6.31.2-0.1 (pobrany z test)
ntp: ntp-4.2.4p6-2 (z dystrybucji), ntp-4.2.4p7-2 (zbudowane samodzielnie z
CVSa),
glibc: glibc-2.10.1-14
Problem nie występuje dla jądra 2.6.28.10-3. Testowane były te same
architektury i wersje ntp oraz cała reszta konfiguracji komputerów
testowych. Marudzenie o apple bonjour to stara sprawa, która w niczym nie
przeszkadza.
Co ciekawe, netstat wywołany osobno z opcją --inet i osobno z opcją inet6
przy jądrze 2.6.28.10-3 wypisuje osobno otwarte porty na TCP/UDP oraz
osobno TCPv6/UDPv6. W przypadku jądra 2.6.31.2-0.1, której bym opcji nie
użył zawsze dostaję listę wszystkich otwartych portów v4 i v6.
Po ponownym sprawdzeniu zachowania netstata okazuje się że jest dziwnie, ale
nie tak jak pisałem. Wersja jądra nie ma tu nic do rzeczy. Po prostu opcje
--inet i --inet6 działają identycznie w stosunku do portów TCP v4 i v6 - każda
wyświetla porty otwarte na obu wersjach protokołów. W przypadku UDP opcja
--inet pokazuje to co otwarto na portach v4, a --inet6 to co otwarto na
portach v6
Podejrzewam więc, że problem pojawił się w którymś z jąder 2.6.29-31
Na listach dyskusyjnych poświęconych ntp sugerowano:
echo 1 /proc/sys/net/ipv6/bindv6only
- nie pomaga.
Będę już zadowolony, jeśli ktoś mi podpowie jak wyłączyć IPv6 (którego nie
używam) nie rekompilując jądra. Jest spora szansa, że to załatwi problem.
Pogrzebałem w źródłach ntpd i udało mi się rozwiązać sprawę przez włączanie
opcji SO_REUSEADDR na:
1. adresie wildcardowym IPv6 na czas jego bindowania,
2. wcześniej zabindowanym adresie wildcardowym IPv4 na czas bindowania
jakiegokolwiek adresu IPv6.
Po poprawkach ntpd działa dobrze na architekturach i686 i x86_64 przy każdym z
jąder, o którym była wczesniej mowa w liście.
Stosowny patch poniżej. Można dodać go jako osobny patch lub dokleić do
ntp-ipv6.patch .
Pozdrawiam jeszcze raz,
--
Bartosz Lis @ Institute of Comp. Science, Technical University of Lodz, Poland
bartoszl @ ics.p.lodz.pl
8
--- ntp-4.2.4p5/ntpd/ntp_io.c.orig 2009-05-18 08:21:15.0 +
+++ ntp-4.2.4p5/ntpd/ntp_io.c 2009-10-13 16:35:48.0 +
@@ -920,7 +920,7 @@
interface-ignore_packets = ISC_TRUE;
interface-fd = open_socket(interface-sin,
-interface-flags, 1, interface);
+interface-flags, 0, interface);
if (interface-fd != INVALID_SOCKET) {
wildipv6 = interface;
@@ -2443,6 +2443,9 @@
if (!is_wildcard_addr(addr)) {
set_wildcard_reuse(addr-ss_family, 1);
}
+ if (addr-ss_family == AF_INET6) {
+ set_wildcard_reuse(AF_INET, 1);
+ }
#endif
/*
@@ -2456,6 +2459,9 @@
* addresses if a wildcard address already bound
* to the port and REUSE_ADDR is not set
*/
+ if (addr-ss_family == AF_INET6) {
+ set_wildcard_reuse(AF_INET, 0);
+