/etc/hosts file seem to take effect immediately. I'm curious about the implementation. What magic is used to achieve this feature?
The magic is opening the
/etc/hosts file and reading it:
strace -e trace=file wget -O /dev/null http://www.google.com http://www.facebook.com http://unix.stackexchange.com 2>&1 | grep hosts open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 4 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 5 open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 4
getaddrinfo(3) function, which is the only standard name resolving interface, will just open and read
/etc/hosts each time it is called to resolve a hostname.
More sophisticated applications which are not using the standard
getaddrinfo(3), but are still somehow adding
/etc/hosts to the mix (e.g. the
dnsmasq DNS server) may be using
inotify(7) to monitor changes to the
/etc/hosts files and re-read it only if needed.
Browsers and other such applications will not do that. They will open and read
/etc/hosts each time they need to resolve a host name, even if they're not using libc's resolver directly, but are replicating its workings by other means.
Name resolution, amongst other things, is managed by
/etc/nsswitch.conf. Here is an excerpt:
passwd: files sss shadow: files sss group: files sss hosts: files dns myhostname (...)
hosts line. It says: "When resolving a hostname, first read
/etc/hosts file to lookup the hostname, if not found then run a DNS query, if not found then try the locally configured system hostname".
So here's why it is so fast. Note that it does not depend on the network services on the machine, so there's no service to restart or reload.