为什么对/ etc / hosts的更改立即生效?


18

/etc/hosts文件更改似乎立即生效。我对实现感到好奇。使用什么魔术来实现此功能?

  1. 问Ubuntu:修改/ etc / hosts后,需要重新启动哪个服务?
  2. NetApp支持:/ etc / hosts文件如何工作

5
只是关于速度的注释,主机文件通常很小,很少超过几KB。它最有可能小于用于读取文件的已编译库。经常使用的小文件通常会保留在内存中。因此,即使为每个请求读取了文件,这样做的开销也将是最小的(即:非常快)。
菲利普·库林

2
unix.stackexchange.com/questions/388875/…有关,以Philip的评论:)
Jeff Schaller

Answers:


27

魔术是打开/etc/hosts文件并读取它:

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)函数是唯一的标准名称解析接口,它将在/etc/hosts每次调用以解析主机名时打开并读取。

不使用该标准getaddrinfo(3)但仍以某种方式添加/etc/hosts到组合中的更复杂的应用程序(例如dnsmasqDNS服务器)可能inotify(7)用于监视/etc/hosts文件的更改并仅在需要时重新读取它。

浏览器和其他此类应用程序将不会这样做。他们将在/etc/hosts每次需要解析主机名时打开并阅读,即使他们没有直接使用libc的解析器,而是通过其他方式复制其工作原理。


1
您能详细说明一下摘要吗?我感兴趣的是更改如何立即反映在正在运行的代码中(应该是OS中的网络部分吗?)。
rudwna

7
@rudwna:他的意思是:“每次需要查找主机名时,解析器(C库的一部分)都会打开/ etc / hosts并进行读取。因此,如果文件内容在两次读取之间更改,则将使用下一次读取新内容”。
6

3
@rudwna同样,对于“正在运行的代码”,您立即看到更改的原因是,许多标准程序不缓存地址(或者它们具有某种智能的缓存策略,侦听/ etc / hosts的更新)。当然,有一些程序不会立即看到对/ etc / hosts的更改,需要重新启动。这完全取决于编写代码的人。/ etc / hosts本身没有什么神奇之处。
SamYonnou

9

除其他外,名称解析由进行管理/etc/nsswitch.conf。这是节选:

passwd:     files sss
shadow:     files sss
group:      files sss
hosts:      files dns myhostname
(...) 

注意hosts行。它说:“解析主机名时,首先读取/etc/hosts文件以查找主机名,如果找不到,请运行DNS查询,如果找不到,请尝试在本地配置的系统主机名”。

所以这就是为什么它这么快的原因。请注意,它不依赖于计算机上的网络服务,因此没有重新启动或重新加载的服务。


1
但是它可以使用file的缓存(例如,已解析并位于主内存中)版本/etc/hosts。为什么不使用缓存版本?
Peter Mortensen

2
@PeterMortensen,因为操作系统已经缓存了文件访问权限,甚至可以正确处理写入。
Michael Borgwardt
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.