オフライン状態においてWSLでemacsやsudoが起動中に固まる(解決済)

結論

WSLを使うときは次のように/etc/hostsにマシンのホスト名を書くべし。

127.0.0.1 localhost puffy         # puffyは私のwindowsマシン名

そうしないとemacs, sudoなどの、実行時にホスト名を解決しようとするソフトが固まる

問題の認識

数日前に買ったノートPCでWSLをしばらく快適に使っていたのですが、emacsが起動中に固まって動かなくなる問題がさきほど発生しました。その後sudoにも同じ問題が起きることがわかりました。つい数十分前には正しく使えており、かつ、その後Windows Updateはしていないし、設定変更もしていないので、これはおかしいです。

トラブルシューティング

最後に問題が発生していなかった時点(今朝9時ごろ)と問題発生を確認した時点(9時30分ごろ)の差分をしばらく考えてみたところ、前者はオンライン環境であり、後者はオフライン環境だったことを思い出しました。ネットワーク環境に関係あるのかを確認するために、オンラインにしてから同じ操作をすると、問題は発生しませんでした。ここで一つ「ネットワーク関係の疑いが強い」という切り分けに成功。

デバッグのためにstrace -o emacs.log emacsを実行すると、次のように/etc/resolv.confをopen(2)したり、uname(2)コマンドでホスト名を取ったりした後に発行した複数回のsenddmsg()にそれぞれ10秒前後時間がかかっていることがわかりました。

emacs.log

...
1492485708.123190 stat("/etc/resolv.conf", {st_mode=S_IFREG|0644, st_size=189, ...}) = 0
1492485708.123497 open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3
1492485708.123952 fstat(3, {st_mode=S_IFREG|0644, st_size=189, ...}) = 0
1492485708.124115 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fa4fe940000
1492485708.124295 read(3, "# This file was automatically ge"..., 4096) = 189
1492485708.124478 read(3, "", 4096)     = 0
1492485708.124648 close(3)              = 0
1492485708.124820 munmap(0x7fa4fe940000, 4096) = 0
1492485708.124986 uname({sys="Linux", node="puffy", ...}) = 0
1492485708.125249 socket(PF_INET, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 3
1492485708.125475 connect(3, {sa_family=AF_INET, sin_port=htons(53), sin_addr=inet_addr("192.168.43.1")}, 16) = 0
1492485708.125710 gettimeofday({1492485708, 125750}, NULL) = 0
1492485708.125859 poll([{fd=3, events=POLLOUT}], 1, 0) = 1 ([{fd=3, revents=POLLOUT}])
1492485708.126111 sendmmsg(3, {{{msg_name(0)=NULL, msg_iov(1)=[{"t\246\1\0\0\1\0\0\0\0\0\0\5puffy\0\0\1\0\1", 23}], msg_controllen=0, msg_flags=0}, 23}, {{msg_name(0)=NULL, msg_iov(1)=[{"_\200\1\0\0\1\0\0\0\0\0\0\5puffy\0\0\34\0\1", 2
3}], msg_controllen=0, msg_flags=0}, 23}}, 2, MSG_NOSIGNAL) = 2
1492485714.097840 poll([{fd=3, events=POLLIN}], 1, 5000) = 0 (Timeout)
1492485719.099159 socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 4
1492485719.099929 connect(4, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6, "fec0:0:0:ffff::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
1492485719.100742 gettimeofday({1492485719, 100932}, NULL) = 0
1492485719.101843 poll([{fd=4, events=POLLOUT}], 1, 0) = 1 ([{fd=4, revents=POLLOUT}])
1492485719.103170 sendmmsg(4, {{{msg_name(0)=NULL, msg_iov(1)=[{"t\246\1\0\0\1\0\0\0\0\0\0\5puffy\0\0\1\0\1", 23}], msg_controllen=0, msg_flags=0}, 23}, {{msg_name(0)=NULL, msg_iov(1)=[{"_\200\1\0\0\1\0\0\0\0\0\0\5puffy\0\0\34\0\1", 2
3}], msg_controllen=0, msg_flags=0}, 23}}, 2, MSG_NOSIGNAL) = 2
1492485731.096900 poll([{fd=4, events=POLLIN}], 1, 3000) = 0 (Timeout)
1492485734.098345 socket(PF_INET6, SOCK_DGRAM|SOCK_NONBLOCK, IPPROTO_IP) = 5
1492485734.099193 connect(5, {sa_family=AF_INET6, sin6_port=htons(53), inet_pton(AF_INET6, "fec0:0:0:ffff::2", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, 28) = 0
1492485734.099969 gettimeofday({1492485734, 100273}, NULL) = 0
1492485734.101202 poll([{fd=5, events=POLLOUT}], 1, 0) = 1 ([{fd=5, revents=POLLOUT}])
1492485734.102447 sendmmsg(5, {{{msg_name(0)=NULL, msg_iov(1)=[{"t\246\1\0\0\1\0\0\0\0\0\0\5puffy\0\0\1\0\1", 23}], msg_controllen=0, msg_flags=0}, 23}, {{msg_name(0)=NULL, msg_iov(1)=[{"_\200\1\0\0\1\0\0\0\0\0\0\5puffy\0\0\34\0\1", 2
3}], msg_controllen=0, msg_flags=0}, 23}}, 2, MSG_NOSIGNAL) = 2
1492485746.097900 --- SIGINT {si_signo=SIGINT, si_code=SI_KERNEL} ---
1492485746.098406 rt_sigaction(SIGINT, {SIG_DFL, [INT], SA_RESTORER|SA_RESTART, 0x7fa4fc946cb0}, {0x4a6200, ~[RTMIN RT_1], SA_RESTORER, 0x7fa4fd000330}, 8) = 0
1492485746.099849 getpgrp()             = 139
1492485746.100944 ioctl(0, TIOCGPGRP, [139]) = 0
1492485746.102129 rt_sigprocmask(SIG_BLOCK, [WINCH IO], NULL, 8) = 0
1492485746.103238 rt_sigaction(SIGIO, {SIG_IGN, [IO], SA_RESTORER|SA_RESTART, 0x7fa4fc946cb0}, {SIG_DFL, [], SA_RESTORER, 0x7f161b466cb0}, 8) = 0
1492485746.104837 exit_group(2)         = ?
1492485746.105671 +++ exited with 2 +++

resolv.confの読み出しもuname(2)の発行もホスト名に関するものであり、かつ、sendmmsg()によって送信したメッセージの中にもホスト名を示す文字列(“puffy”)が入っていたので、問題はホスト名の解決に関するものかなと推測しました。

hostnameコマンドは一瞬で"puffy"を返すので問題ないとして、/etc/hostsはどうなっているかを見ると、127.0.0.1puffyは結び付けられていませんでした。

/etc/hosts

...
127.0.0.1 localhost
...

これを次のように変更したらオフラインでもうまく動くようになりました。

/etc/hosts

...
127.0.0.1 localhost puffy
...