web-dev-qa-db-ja.com

AF_NETLINKソケットトランザクションに数秒かかる原因は何ですか?

私の問題

カーネルへのAF_NETLINKクエリは、たとえば次のstraceトレースで、応答するまでに断続的に数秒かかります。

10:42:38.864353 socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_ROUTE) = 3
10:42:38.864377 setsockopt(3, SOL_SOCKET, SO_SNDBUF, [32768], 4) = 0
10:42:38.864399 setsockopt(3, SOL_SOCKET, SO_RCVBUF, [1048576], 4) = 0
10:42:38.864418 setsockopt(3, SOL_NETLINK, NETLINK_EXT_ACK, [1], 4) = 0
10:42:38.864436 bind(3, {sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, 12) = 0
10:42:38.864459 getsockname(3, {sa_family=AF_NETLINK, nl_pid=16296, nl_groups=00000000}, [12]) = 0
10:42:38.864491 sendto(3, {{len=40, type=RTM_GETLINK, flags=NLM_F_REQUEST|NLM_F_DUMP, seq=1588581759, pid=0}, {ifi_family=AF_UNSPEC, ifi_type=ARPHRD_NETROM, ifi_index=0, ifi_flags=0, ifi_change=0}, {{nla_len=8, nla_type=IFLA_EXT_MASK}, 1}}, 40, 0, NULL, 0) = 40
10:42:51.894848 recvmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=MSG_TRUNC}, MSG_PEEK|MSG_TRUNC) = 2608

バックグラウンド

時々、IPアドレスを解決しようとしているときにソフトウェアがハングすることに気づきました。主にブラウザだけでなく、新しいsshsやDNSを必要とするその他のものも。

Wiresharkを使用して、DNSクエリパケットがネームサーバーに送信される前にハングが発生したことを確認できたので、それ自体が遅延ネームサーバーではありません。

いくつかの関連するプロセスをトレースすると、プロセスが最初に/etc/resolv.confを読み取ることがあり、IPV6アドレスが含まれていることがわかりました。

# Generated by NetworkManager
search example.de otherexample.de
nameserver 192.168.178.1
nameserver 2a02:8070:c19e:b400:xxxx:xxxx:xxxx:xxxx
nameserver fd00::9a9b:cbff:xxxx:xxxx

次に、コメント以外の何も含まれていない/etc/gai.confを読み取り、明らかに、AF_NETLINKソケットを使用してインターフェイスのリストを取得します。

ほとんどの場合、sendtoと対応するrecvmsgは数ミリ秒しか離れていませんが、場合によっては、これが永遠に感じられるものをハングさせます。

そのため、問題はDNSでさえないことに気づきました。実際、ループでip aを実行すると、数秒間ハングすることもありました。そのため、各ip aand logging the output and thestrace`を2つの異なるファイルに配置しながらこれを行いました。これは、問題が1分に1回、約12〜13秒間発生することを示しています。

10:41:58.561713 sendto(3, {{len=40, type=RTM_GETLINK, flags=NLM_F_REQUEST|NLM_F_DUMP, seq=1588581719, pid=0}, {ifi_family=AF_UNSPEC, ifi_type=ARPHRD_NETROM, ifi_index=0, ifi_flags=0, ifi_change=0}, {{nla_len=8, nla_type=IFLA_EXT_MASK}, 1}}, 40, 0, NULL, 0) = 40
10:41:58.561943 recvmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=MSG_TRUNC}, MSG_PEEK|MSG_TRUNC) = 2608

10:42:38.864491 sendto(3, {{len=40, type=RTM_GETLINK, flags=NLM_F_REQUEST|NLM_F_DUMP, seq=1588581759, pid=0}, {ifi_family=AF_UNSPEC, ifi_type=ARPHRD_NETROM, ifi_index=0, ifi_flags=0, ifi_change=0}, {{nla_len=8, nla_type=IFLA_EXT_MASK}, 1}}, 40, 0, NULL, 0) = 40
10:42:51.894848 recvmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=MSG_TRUNC}, MSG_PEEK|MSG_TRUNC) = 2608

10:43:42.269435 sendto(3, {{len=40, type=RTM_GETLINK, flags=NLM_F_REQUEST|NLM_F_DUMP, seq=1588581823, pid=0}, {ifi_family=AF_UNSPEC, ifi_type=ARPHRD_NETROM, ifi_index=0, ifi_flags=0, ifi_change=0}, {{nla_len=8, nla_type=IFLA_EXT_MASK}, 1}}, 40, 0, NULL, 0) = 40
10:43:54.894689 recvmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=MSG_TRUNC}, MSG_PEEK|MSG_TRUNC) = 2608

10:44:45.276410 sendto(3, {{len=40, type=RTM_GETLINK, flags=NLM_F_REQUEST|NLM_F_DUMP, seq=1588581886, pid=0}, {ifi_family=AF_UNSPEC, ifi_type=ARPHRD_NETROM, ifi_index=0, ifi_flags=0, ifi_change=0}, {{nla_len=8, nla_type=IFLA_EXT_MASK}, 1}}, 40, 0, NULL, 0) = 40
10:44:57.894722 recvmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=MSG_TRUNC}, MSG_PEEK|MSG_TRUNC) = 2608

10:45:48.273509 sendto(3, {{len=40, type=RTM_GETLINK, flags=NLM_F_REQUEST|NLM_F_DUMP, seq=1588581949, pid=0}, {ifi_family=AF_UNSPEC, ifi_type=ARPHRD_NETROM, ifi_index=0, ifi_flags=0, ifi_change=0}, {{nla_len=8, nla_type=IFLA_EXT_MASK}, 1}}, 40, 0, NULL, 0) = 40
10:46:00.894574 recvmsg(3, {msg_name={sa_family=AF_NETLINK, nl_pid=0, nl_groups=00000000}, msg_namelen=12, msg_iov=[{iov_base=NULL, iov_len=0}], msg_iovlen=1, msg_controllen=0, msg_flags=MSG_TRUNC}, MSG_PEEK|MSG_TRUNC) = 2608

最初のペアは、正常に発生することの例です。他のペアは、問題が1分に1回発生し、約12秒間続く方法を示しています。

その間、ネットワークに大きな変化はありません。これらの一時停止の最初の前後のip aの出力の例を次に示します。

Mon May  4 10:42:38 CEST 2020
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope Host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope Host 
       valid_lft forever preferred_lft forever
2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether a8:5e:45:60:e4:be brd ff:ff:ff:ff:ff:ff
    inet 192.168.178.131/24 brd 192.168.178.255 scope global dynamic noprefixroute enp3s0
       valid_lft 83515sec preferred_lft 83515sec
    inet6 2a02:8070:c19e:b400:bec7:94b4:34f1:86b4/64 scope global dynamic noprefixroute 
       valid_lft 7078sec preferred_lft 3478sec
    inet6 fe80::d27:8efd:f696:3c47/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: wlp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether d0:ab:d5:0e:02:09 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.10/24 brd 192.168.10.255 scope global dynamic noprefixroute wlp7s0
       valid_lft 602858sec preferred_lft 602858sec
    inet6 fe80::c694:6683:6353:e9c9/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
4: wlxf4f26d08d54e: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether f4:f2:6d:08:d5:4e brd ff:ff:ff:ff:ff:ff
Mon May  4 10:42:52 CEST 2020
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope Host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope Host 
       valid_lft forever preferred_lft forever
2: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether a8:5e:45:60:e4:be brd ff:ff:ff:ff:ff:ff
    inet 192.168.178.131/24 brd 192.168.178.255 scope global dynamic noprefixroute enp3s0
       valid_lft 83514sec preferred_lft 83514sec
    inet6 2a02:8070:c19e:b400:bec7:94b4:34f1:86b4/64 scope global dynamic noprefixroute 
       valid_lft 7077sec preferred_lft 3477sec
    inet6 fe80::d27:8efd:f696:3c47/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: wlp7s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether d0:ab:d5:0e:02:09 brd ff:ff:ff:ff:ff:ff
    inet 192.168.10.10/24 brd 192.168.10.255 scope global dynamic noprefixroute wlp7s0
       valid_lft 602857sec preferred_lft 602857sec
    inet6 fe80::c694:6683:6353:e9c9/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
4: wlxf4f26d08d54e: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether f4:f2:6d:08:d5:4e brd ff:ff:ff:ff:ff:ff

質問

カーネルがAF_NETLINK/RTM_GETLINKソケット呼び出しへの応答を1分に1回、数秒間遅らせる原因は何でしょうか。

私の知る限り、これらの呼び出しは、他のプロセスではなく、カーネルによって直接処理されます(タイムアウトのためにstraceできます)。これは正しいです?

もしそうなら、何がそれらの要求でカーネルブロックを何度も何度も作ることができますか?どうすればデバッグできますか?

EduardoTrápaniのコメントのおかげで、私は問題を解決することができました。

上記のwlxf4f26d08d54e出力でip aインターフェースを提供していたUSB WIFIアダプターを取り外すとすぐに、問題は解消しました。

lsusbによると、そのデバイスの正確な仕様は次のとおりです。

Bus 001 Device 010: ID 0bda:8179 Realtek Semiconductor Corp. RTL8188EUS 802.11n Wireless Network Adapter

興味深いことに、/var/log/syslogにはそのデバイスに関するエントリがまったくありません。ただし、起動時に認識され、プラグを抜いた点が異なります。ですから、接続不良などはないと思います。

https://linux-hardware.org/index.php?id=usb:0bda-8179 によると、このドライバはバージョン3.12からカーネルに組み込まれており、ほぼどこでも機能するため、私の特定の問題が何であったか本当にわかりません。

しかし、今は解決されてうれしいです。