Help us understand the problem. What is going on with this article?

(今はまだ)WSL1にUbuntu 20.04を入れるな

TL;DR - 不眠症になったUbuntu

  • What: WSL1とUbuntu 20.04 (Focal Fossa)を併用するな
  • Why: glibc 2.31でnanosleepがWSL1非対応のシステムコールを使うようになったせい
    • Ubuntuに限らずglibc 2.31(2020年2月リリース)を利用するディストリビューションは危険
  • How to avoid: Ubuntuを19.10 (Eoan Ermine)以下で使うかWSLを2に上げろ
    • 他ディストリビューションでも同様に、glibc 2.31を使わないバージョンを選ぶように
バージョン WSL1 WSL2 実例
glibc 2.31 Ubuntu 20.04 (Focal Fossa), Arch Linux(2月以降?)1, Fedora 32, OpenSUSE Tumbleweed
<glibc 2.31 Ubuntu 19.10(Eoan Ermine), 18.04 LTS (Bionic Beaver), Debian 10 (Buster), Fedora 31, OpenSUSE Leap 15

具体的にこんな事が起きるぞ

Ubuntu 18.04からアップグレードできない

そもそもdo-release-upgrade -dが途中でコケるなどしてアップグレードできない。筆者環境のUbuntu 18.04 LTSはsudo apt upgradeするとE: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).などと言われた2

それで sudo apt --fix-broken install すると…

sleep: cannot read realtime clock: Invalid argument
dpkg: error processing package libc6:amd64 (--configure):
 installed libc6:amd64 package post-installation script subprocess returned error exit status 1
Errors were encountered while processing:
 libc6:amd64
E: Sub-process /usr/bin/dpkg returned an error code (1)

エラーが出る。この sleep: cannot read realtime clock: Invalid argument が例の問題が発生したことを示している。ちなみに日本語では実時間の時計を読み取ることができません: 無効な引数です と出るようだ。

rustup がツールチェインをインストールできない

(UNIX-likeでの)Rustの環境構築はcurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shをシェルに貼り付けるだけなのだが、

info: profile set to 'default'
info: default host triple is x86_64-unknown-linux-gnu
info: syncing channel updates for 'stable-x86_64-unknown-linux-gnu'
info: latest update on 2020-04-23, rust version 1.43.0 (4fb7144ed 2020-04-20)
info: downloading component 'cargo'
info: downloading component 'clippy'
info: downloading component 'rust-docs'
info: downloading component 'rust-std'
info: downloading component 'rustc'
info: downloading component 'rustfmt'
info: installing component 'cargo'
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `22`,
 right: `4`', src/libstd/sys/unix/thread.rs:166:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `22`,
 right: `4`', src/libstd/sys/unix/thread.rs:166:21
stack backtrace:

なんということでしょう。

rust-lang側でもすでにissueが立っている(rust-lang/rustup#2245: rustup panic with WSLv1 + glibc 2.31, #2293)。


以上は確認した限り。Homebrewでもなんかエラーが出てるが普通にインストールは進む。

対処

Ubuntu 20.04 and WSL 1 - Ubuntu Community Hub

For WSL 1 users, I recommend you sit tight on Ubuntu 18.04 for now. The patch for issue 4989 will take some time to be backported. Ubuntu 18.04 is an LTS release, short for long-term servicing, and is supported through 2023 so you will continue to get security patches and backports from Canonical in the meantime.

WSL1 のユーザーには、Ubuntu 18.04に留まることを勧める。問題 4989 (訳注: この問題のこと。たぶんmicrosoft/WSL#4898のTypo。) へのパッチがバックポートされるまでしばらくかかるだろう。Ubuntu 18.04 はLTS、つまり長期サポート(Long-Term Servicing)で、2023年まではセキュリティパッチやバックポートをCanonical社から受け取ることができる。

要約すると、問題を修正するパッチが来るまではUbuntu18.04で待ってろということ。

Ubuntu 20.04を避ける

今からUbuntuを導入する時は…

今からWSL1を導入し、Ubuntuをインストールしようという人は「Ubuntu 18.04 LTS」というアプリをインストールすればよい。逆に「Ubuntu 20.04 LTS」という見えてる地雷や、分かりづらいが単に「Ubuntu」と書いてあるアプリも20.04をインストールしてしまう。16.04はいつの間にか消えてた。

今Ubuntuを使ってる時は…

すでにUbuntu 19.10以下が導入されている人は、そのまま待機すればよい。「Ubuntu」「Ubuntu 18.04」アプリに時々アップデートが届く(らしい)が、これはUbuntu本体のアップグレードとは無関係なので安心してOK。逆にUbuntuのシェルでdo-release-upgradeを実行するとアップグレードが始まってしまうので注意。


WSL1 へのパッチを待つ

「パッチがバックポートされるまでは」という言葉でおや?と思ったかもしれないが、Microsoftのこちらの方のコメントによれば修正が来ており、バックポートを検討中であるらしい。

Windows Insider Fastリングの19608.1006では解決されてるとのコメントもあるが、Windows Insider Previewのアナウンスでは特に言及されていないし、2月ぐらいのビルドまでさかのぼってもこの問題が解決されたという話はなかった。サイレント修正とみるべきか。

WSL2 を導入する

2020-05-28追記: WSL 2 を搭載した Windows 10の次期バージョン May 2020 Update3 がリリースされた。WSL2はマジのLinuxカーネルを使うためこの問題は起きない。詳しいことはググってくれないか。

WSL1にも1なりの長所があるので廃止の予定はなく、現にこうやってWSL1のためにパッチが出されている。1, 2という序列のある名前よりも、もっと対等な感じの名前を捻出できなかったものだろうかとは思う。

その他の方法

といったのも提案されている。

Arch Linuxではdowngradeコマンドを使ってバージョンを下げられるようだ。

Ubuntu 20.04なら俺の横で寝てるよ

アップグレードを実行してしまった手遅れな人4たちへ。

とりあえず、変なことをしていなければmvcpは使えるはずなので、必要なデータはWindows側(/mnt/c)に退避させるのがいいと思う。筆者は必要なデータがそもそもWindows側に置いてあったのでかまわず実験台に載せていろいろしてしまったが。

#4898のコメント番号611583534に対処が書いてある。…のだが、筆者が試したらUbuntuが完全に死んだ5のであまり信頼できない。コメント自体も :thumbsup: が3で :thumbsdown: が7で、しかもこの後に“as soon as I did that, my WSL broke completely”というコメントまで届いているのでうーんという感じ。

image.png
度重なる実験の結果、起動しようとするとこうなるようになってしまったUbuntu。適当にググった結果SIGSEGV(セグメンテーション違反)らしい。たいへんだ。

どうしてこうなった

glibc 2.31がsleepでWSL1非対応のシステムコールを使うようになったから

そもそもWSL1は、Linux上で動くソフトウェアが「Linuxカーネルのこの機能を使わせろ」と要求してくるのをWindows NTカーネルのために翻訳して仲介する役割を果たすものだった。外国人客に対応するため、ただの日本人に英語自動翻訳機を取り付けたようなものだ。翻訳機の英語力はネイティブスピーカーに劣るので、知らない言葉を言われると翻訳できない。
それに対してWSL2はLinuxカーネルをまるまる載せている。つまり英語ネイティブの脳を日本人にくっつけた感じ。英語ネイティブ(Linuxカーネル)なので、翻訳機の知らない言葉(WSL1に実装されていないシステムコール)でも理解できる。身体はネイティブの脳が直接動かすのでレスポンスも早い。その代わりエネルギーを浪費する(動作が重い)。

この問題が広まっているのは Ubuntu 20.04でglibcが2.31にアップグレードしてからだろうが、Arch Linuxでは2月にアップグレードされているためすでに問題が発生していたようだ(参考: yuk7/ArchWSL#108, 02/12、VSCode(WSL1)でCPU使用率が下がらない場合の原因と対処法 - Qiita, 03/03)。ArchWSLはMicrosoft Storeにないのでそもそも存在を初めて知ったが、作者が日本人でしかも19歳ですごいと思った(小学生並みの感想)。

では、もう少しだけ原因を知りたいのでさっきの投稿をもう一回持ってくる。

Issue 4989

An example of the WSL team continuing to service WSL 1 for now is a patch for issue 4989. Issue 4989 arises from a patch in glibc 2.31 that implements a nanosleep() library call in a more UNIX-like manner based on CLOCK_REALTIME. Emulating UNIX system clocks on an NT kernel is tricky. WSL 1 implemented the most popular clock-based system calls, but not all of them, and did not build CLOCK_REALTIME support into nanosleep. But because this is such a fundamental change in glibc the WSL team is very graciously implementing support for CLOCK_REALTIME in nanosleep in WSL 1 and will be backporting it in updates to existing builds. This is a challenging task that will take some time. In contrast, other more obscure system clock calls, like the one raised in issue 4973, will likely not see implementation in WSL 1.

訳すと、

この問題はglibc 2.31が nanosleep() ライブラリ をCLOCK_REALTIMEを使った、よりUNIX-likeな方法で呼び出すようになったことに起因する。Windows NTカーネル上でUNIXシステムクロックをエミュレートするのは大変だ。WSLは最も一般的なクロックベースのシステムコールを実装しているが、全部実装されてるわけではなく、nanosleepにはCLOCK_REALTIMEのサポートが入っていない。しかしこれはglibcの根本的な変更であるため、ありがたいことにWSLチームはnanosleepにCLOCK_REALTIMEのサポートを実装してくれ、それは既存のビルドにもアップデートで提供されるだろう。これは挑戦的で時間のかかることだ。一方、その他のあまりポピュラーでないシステムクロックコール、たとえば#4973で話題になってるようなものは、たぶんWSL1には実装されないだろう。

Linuxに詳しくないので全然わからないのだが、CLOCK_REALTIMEというのは時刻を取得するときのフラグのひとつらしい。(?)
この記事によればフラグは複数種あって、どうやらWSL1はそもそもCLOCK_REALTIMEに非対応であるらしい。microsoft/WSL#2503は2017年9月に立てられた、CLOCK_REALTIMEがWSLでEINVALとともに失敗することのissueだ。「時計システムなんてエミュレート実装すんのめんどくさいし後回しでよくね?」的に当時は実装しないまま放置されていたのがglibc側のアップデートでこっちが呼ばれるようになって…という感じだろうか。

glibc側を掘る

microsoft/WSL#4898へのコメントによれば、glibcの/posix/nanosleep.cにコードが追加されたのが原因なようだ。そのコミットがこちら。2019年11月06日のコミットなので、8月に出た2.30と2020年2月に出た2.31のちょうど中間に存在している。descriptionの文章を見る感じではGNU HurdのためにつねにCLOCK_REALTIMEで呼び出すようにしたっぽい。

まとめ

  • WSL2はいいぞ。たぶん
  • Linuxなんもわからん、というか/bin/sleepはGNUがやってるなんて初めて知ったよ
  • ArchWSL使ってみたいな
  • Hurdの名前をこんなところで見るとは思わなかった
  • みんながいろいろと解決策を模索している感じが見てて面白いし勉強になる

  1. Arch Linux詳しくないのでわからないのだが、リポジトリを見る感じでは2月にglibcが2.31に上がっているっぽい感じはする 

  2. 筆者は英語環境のままにしている。理由は不明 

  3. バージョン番号では2004、開発中のバージョン番号は20H1、ビルド番号では19041.207。as known asが多すぎる 

  4. 筆者のこと 

  5. 筆者はアホなので、その後のコメントの方法を試したせいなのかこいつのせいなのかが全くわからない 

mmns
JK(Jōhōkē Kōkōsē)
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした