0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WSL2のディストロ間で共有できる仮想ディスク(VHDX)を作成して自動マウントさせる

0
Last updated at Posted at 2026-07-03

WSL に Ubuntu 26.04 が来てたので新規インストールして 24.04 からファイルの引継ぎをしていたのですが、ディストロ間のファイルの移動って結構めんどくせえなあと思い、この機に共有ディスク領域を整備してみました。

あと WSL の環境って wsl --unregister ... で中にあるデータごとまとめて簡単に吹っ飛ばせてしまうのが怖いなあと常々思っていたので、今回移行が必要になったような WSL 内の大事なファイルとかは今後ここに置いていこうかと思っています。これで 28.04 が来ても気楽にクリーンインストールできるね!

実施時環境

  • Windows 11 Pro 25H2
  • WSL 2.7.10.0
  • Ubuntu 24.04 LTS
  • Ubuntu 26.04 LTS

仮想ディスクを作成して1回だけマウントするところまでは古い Windows でも出来るかもしれませんが、今回行う自動マウントの仕組みの構築は Windows 11 が必須らしいです。

仮想ディスクを作成する

Windows に付いてるディスク管理ユーティリティを使います。

  1. ディスクの管理 を起動する(Win + R から diskmgmt.msc で起動できる)
  2. メニューバーから [操作(A)] - [VHDの作成]仮想ハードディスクの作成と接続 ダイアログを開く
  3. ダイアログに必要な内容を入力する
    • 場所(L): .vhdx ファイルを作成する場所(D:\wsl-data.vhdx
    • 仮想ハードディスクのサイズ(S): 欲しいディスクのサイズ
    • 仮想ハードディスクフォーマット: VHDX(X) を選択
    • 仮想ハードディスクの種類: 可変容量(D) を選択(これは好きな方でOK)
      image.png
  4. [OK] を押下して仮想ディスクの作成を実行
  5. 画面下のペインを下の方にスクロールすると今作成した仮想ディスクが見つかる
    image.png
  6. 左側の「不明」とか「初期化されていません」とか書いてあるところを右クリックして [VHD の切断] を選択
  7. 仮想ハードディスクの切断 確認ダイアログが出てくるので [OK] を押下
  8. 先ほど右クリックしたディスクが一覧から居なくなってれば完了

以降、この記事において VHDX ファイルは D:\wsl-data.vhdx に作成したものとします。別の場所を指定した場合は適宜読み替えてください。

(おまけ)PowerShell で作成する

上の操作は PowerShell で New-VHD が使えるなら

New-VHD -Path "D:\wsl-data.vhdx" -SizeBytes 2TB -Dynamic

とかで一発で完了するようです。

僕の環境には New-VHD がなく、追加モジュールのインストールが必要そうだったので試しませんでした。

仮想ディスクを接続してフォーマットする

仮想ディスクを接続する

  1. WSL のコンソールで lsblk を実行し、ブロックデバイスの一覧を確認する
  2. 管理者権限のコマンドプロンプトか PoweShell で wsl --mount "D:\wsl-data.vhdx" --vhd --bare を実行し、先ほど作成した仮想ディスクを WSL に接続する
  3. WSL のコンソールで再度 lsblk を実行し、増えた項目を見つけて接続した仮想ディスクのデバイス名を特定する(普通は一番下にあると思う)

ここで判明したデバイス名は次以降の作業で使うので覚えておくこと。以降、この記事では便宜上 sdX だったものとします。

仮想ディスクをフォーマットする

WSL のコンソールで

sudo mkfs.ext4 -L "wsl-data" /dev/sdX

を実行する。sdX の部分は必ず先ほど判明した仮想ディスクの名前を指定すること。間違えた名前を指定すると既存のデータが消去されるため慎重に実施すること。
またコマンドではラベルに -L "wsl-data" を指定しているが、実際は自分が分かりやすい好きな名前を付けてあげるとよい。

(確認)作成した仮想ディスクが複数のディストロで共有できることを確認する

複数の WSL のディストロのコンソールでそれぞれ

sudo mkdir -p /mnt/data
sudo mount -t ext4 /dev/sdX /mnt/data

を実行し、/mnt/data に何かファイルを置いてみてディストロを跨いで共有されていることを確認する。今回は Ubuntu 24.04Ubuntu 26.04 でこのマウントポイントを通じてファイルのやり取りができることを確認しました。

WSL の起動時に仮想ディスクが自動マウントされるようにする

共有のファイルシステムは構築できましたが、このままだと WSL がシャットダウンする度に見えなくなってしまいます。最近の WSL だとコンソールが1つも開いてないとかの状態がしばらく続くと VM アイドルと判定されて自動的にシャットダウンしてくれたりしますね。地味に迷惑なことが多い

WSL には自動マウントの機能が無いようですが、GitHub の issue に workaround を投稿されている方が居たので、それを真似して自動マウントの仕組みを作っていきます。
https://github.com/microsoft/WSL/issues/6073#issuecomment-1266405095

仮想ディスクを WSL に接続するタスクを Windows 側で作成する

  1. タスク スケジューラ を起動する(Win + R から taskschd.msc で起動できる)
  2. メニューバーから [操作(A)] - [タスクの作成(R)...]タスクの作成 ダイアログを開く
  3. ダイアログに必要な内容を入力する
    • [全般] タブ
      • 名前(M): 作成するタスクの名前(wsl-mount
      • 最上位の特権で実行する(I) にチェックを入れる
        01.png
    • [操作] タブ
      1. 新規(N)... ボタンを押下し 新しい操作 ダイアログを開く
      2. ダイアログに必要な内容を入力する
        • 操作(I): デフォルト値の プログラムの開始 のままにしておく
        • プログラム/スクリプト(P): wsl と入力
        • 引数の追加(オプション)(A): --mount "D:\wsl-data.vhdx" --vhd --bare と入力
          image.png
      3. [OK] ボタンを押下して 新しい操作 ダイアログを完了する
  4. [OK] を押下して タスクの作成 ダイアログを完了する

管理者権限で wsl --mount "D:\wsl-data.vhdx" --vhd --bare をしてくれるタスクが出来ました。元の投稿によると、わざわざタスク化するモチベーションは UAC ダイアログの回避のためとのことです。

今回はタスク名を wsl-mount としましたが、別の名前を付けた場合は以降の内容を適宜読み替えてください。

WSL の起動時に仮想ディスクをマウントするスクリプトが実行されるようにする

ここが先ほどの方が発明した workaround の肝です。WSL の起動時に特定のスクリプトが実行されるように設定し、そのスクリプトの中で先ほど作った Windows のタスクをキックして仮想ハードディスクを接続させます。コンテナの中で実行されるスクリプトがコンテナの外に居る Windows のタスクをキックするのが面白いですね。

WSL がシャットダウン状態だと仮想ディスクを接続しようとしても失敗するので、WSL 起動 -> 仮想ディスク接続の順序を守るためにこのような回り込みを行っているのだと思います。

以降の編集は仮想ディスクを自動マウントさせたいすべてのディストロでそれぞれ行ってください。

/etc/wsl.conf

まず /etc/wsl.confboot セクションに command="bash /boot.sh"追記します。

/etc/wsl.conf
[boot]
command="bash /boot.sh"

これで起動時に /boot.sh に置いたスクリプトが実行されるようになります。

元から書かれていた内容や他のセクションは消さないでください。参考までに僕の環境でインストールしたばかりの Ubuntu 26.04 における編集後の wsl.conf は以下のようになりました。

/etc/wsl.conf
[boot]
systemd=true
command="bash /boot.sh"

[user]
default=akima

akima は僕の名前です。

/boot.sh

次に /boot.sh を作成します。

/boot.sh
#!/bin/bash
/bin/bash /wsl-boot.sh > /wsl-boot.log 2>&1
sudo chmod +x /boot.sh

元記事に従い、ここでは直接仮想ディスク関係の処理は行わず /wsl-boot.sh というスクリプトに移譲しています。

/wsl-boot.sh

最後に /wsl-boot.sh を作成しますが、その前に仮想ディスクの UUID を調べておきます。

sudo blkid /dev/sdX

で表示される UUID="..." の部分を確認してください。sudo を忘れたりデバイス名を間違えると何も表示されません。

その後、/wsl-boot.sh を作成し、<仮想ディスクのUUID> の部分は調べた値に置き換えてください。

/wsl-boot.sh
#!/bin/bash

/mnt/c/Windows/system32/schtasks.exe /run /tn "wsl-mount"

VHDX_MP='/mnt/data'
VHDX_UUID='<仮想ディスクのUUID>'

mkdir -p "$VHDX_MP"
if mountpoint -q "$VHDX_MP"; then
  exit 0
fi

i=0
while :; do
  dev=$(blkid -U "$VHDX_UUID")
  if [ -n "$dev" ]; then
    break
  fi
  i=$((i + i))
  if [ "$i" -ge 5 ]; then
    echo "No device found for '$VHDX_UUID'" 1>&2
    exit 1
  fi
  sleep 1
done

mount -t ext4 "$dev" "$VHDX_MP"

/mnt/c/Windows/system32/schtasks.exe で Windows 側のタスクスケジューラのバイナリを強引に呼び出していますね。なんで Ubuntu の端末で PE フォーマットが実行できるのかは知らないけど、そういうものらしい。

このスクリプトは元記事のものから僕が手を入れています。元記事では Windows タスクで定義する wsl の引数に --bare ではなく --name data を指定して一発でファイルシステムへのマウントまで済ませることを想定しているように見えますが、これを試したところ結構な確率で「/dev/sdX にデバイスはいるが /mnt/wsl/data にはマウントされていない」という中途半端な状態になることがありました。

僕のスクリプトでも sleep 1 をしながら5回までデバイスの発見を試行していますが、これをやらないと結構失敗することがあります。多分 --name data オプションが上手く行かないのも同じ理由なんじゃないかと推測します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?