如何解决Linux内核dns_resolver

Linux提供了一个工具,让内核及其模块依靠用户空间工具来parsingDNS名称。 举例来说,CIFS使用它来支持DFS中的引荐。

我看到的问题是,我不能让内核来parsing一个特定的DNS名称,我不明白为什么它失败。

要了解根本原因,我已经通过运行以下命令在CIFS和内核dnsparsing器中启用了debugging输出:

echo "1" > /sys/module/dns_resolver/parameters/debug # dns_resolver echo "7" > /proc/fs/cifs/cifsFYI # CIFS 

这是我在dmesg中发生故障时所看到的:

 fs/cifs/cifs_dfs_ref.c: DFS: ref path: \ESOTEST\dfstest\FS_SERV fs/cifs/cifs_dfs_ref.c: DFS: node path: \FS\FS_SERV fs/cifs/cifs_dfs_ref.c: DFS: fl: 2, srv_type: 0 fs/cifs/cifs_dfs_ref.c: DFS: ref_flags: 0, path_consumed: 24 fs/cifs/netmisc.c: address conversion returned 0 for FS fs/cifs/netmisc.c: address conversion returned 0 for FS [ls ] ==> dns_query((null),FS,2,(null)) fs/cifs/dns_resolve.c: dns_resolve_server_name_to_ip: unable to resolve: FS fs/cifs/cifs_dfs_ref.c: cifs_compose_mount_options: Failed to resolve server part of \\FS\FS_SERV to IP: 

-22

这是一个成功的解决scheme的输出:

 fs/cifs/cifs_dfs_ref.c: DFS: node path: \ESOTEST\File-Server fs/cifs/cifs_dfs_ref.c: DFS: fl: 2, srv_type: 0 fs/cifs/cifs_dfs_ref.c: DFS: ref_flags: 0, path_consumed: 28 fs/cifs/netmisc.c: address conversion returned 0 for ESOTEST fs/cifs/netmisc.c: address conversion returned 0 for ESOTEST [ls ] ==> dns_query((null),ESOTEST,7,(null)) [ls ] call request_key(,ESOTEST,) [ls ] ==> dns_resolver_match(ESOTEST,ESOTEST) [ls ] <== dns_resolver_match() = 1 [ls ] <== dns_query() = 14 fs/cifs/dns_resolve.c: dns_resolve_server_name_to_ip: resolved: ESOTEST to 192.168.56.102 fs/cifs/cifsfs.c: Devname: \\ESOTEST\File-Server flags: 0 

我使用Windows作为DNS服务器,我可以从机器上parsing名称“FS”:

 $ ping FS PING FS.esodomain.com (192.168.56.104) 56(84) bytes of data. 64 bytes from fs.esodomain.com (192.168.56.104): icmp_seq=1 ttl=128 time=1.37 ms 64 bytes from fs.esodomain.com (192.168.56.104): icmp_seq=2 ttl=128 time=0.630 ms 

我也尝试使用key.dns_resolver手动执行testing,它似乎工作:

 $ key.dns_resolver -vv -D "FS" 'hello' I: Key description: 'dns_resolver;-1;-1;0;FS' I: Callout info: 'hello' D: Get A/AAAA RR for hostname:'FS', options:'hello' D: Opt hello D: Resolve 'FS' with 1ff D: getaddrinfo = 0 D: RR: 0,2,1,6,10,(null) D: append '192.168.56.104' I: The key instantiation data is '192.168.56.104' 

/etc/request-key.conf的内容是:

 create dns_resolver * * /sbin/key.dns_resolver %k create user debug:* negate /bin/keyctl negate %k 30 %S create user debug:* rejected /bin/keyctl reject %k 30 %c %S create user debug:* expired /bin/keyctl reject %k 30 %c %S create user debug:* revoked /bin/keyctl reject %k 30 %c %S create user debug:loop:* * |/bin/cat create user debug:* * /usr/share/keyutils/request-key-debug.sh %k %d %c %S negate * * * /bin/keyctl negate %k 30 %S 

我摆弄这个的原因是我试图让Windows DFS共享成功挂载。 我能够装载和访问根服务器上托pipe的文件夹,但是当我尝试访问指向外部服务器的子文件夹时,我得到:

 ls: cannot access /mnt/dfstest/FS_SERV/: Invalid argument 

我在3.7.10内核上:

 Linux gentoo 3.7.10-gentoo-r1 #3 SMP Fri Apr 19 17:32:20 PDT 2013 x86_64 Intel(R) Xeon(R) CPU E5620 @ 2.40GHz GenuineIntel GNU/Linux 

在networking捕获中,我看不到任何“FS”的DNS请求,而我看到“ESOTEST”的请求。 这表明这个请求没有被提出。

你会推荐什么后续步骤来解决这个问题?

这似乎是由Linux内核引起的。 具体来说,由dns_resolver。 决议中甚至没有尝试“FS”。

dns_resolver(net / dns_resolver / dns_query.c)中的以下行似乎导致了这一点:

 if (namelen < 3) return -EINVAL; 

我不知道为什么有这个检查。 我会尝试将其他服务器从“FS”重新命名为更长的东西。 我将尝试删除此检查重新编译内核。

更新:是的,这是原因,它重新命名为更长的名称后的主机名