OpenWrt 化した Buffalo WSR-3200AX4S で、追加パッケージのインストールに使える容量を拡張する

## この記事の目的

この記事は [以前の記事](https://qiita.com/Bacalhau/items/803d97ebeae8deaf3c7e) の続編です。

この記事では CLI コマンドで WSR-3200AX4S の Flash メモリの使用可能領域を拡張する方法を説明します。

イメージを作成して Flash メモリの使用可能領域を拡張する方法は別記事を参照してください。

<!-- OpenWrt ルーターにおける /overlay 領域の拡張 -->

https://qiita.com/Bacalhau/items/6ce9c30da2b17f64cbe3#%EF%B8%8F-%E3%83%93%E3%83%AB%E3%83%89%E3%81%A7%E6%8B%A1%E5%BC%B5-%EF%B8%8F

> この記事では 5ch の **【無線 LAN】OpenWrt【強化ファーム】** の [#25](https://itest.5ch.net/mao/test/read.cgi/network/1721217342/906-910) と [#26](https://itest.5ch.net/mao/test/read.cgi/network/1721470536/543-547) の内容を参照し、OpenWrt 化すると追加パッケージに使用できる Flash メモリが **7MB** 程度 😵 になってしまう WSR-3200AX4S で、 Tailscale がインストールできる程度に Flash メモリの使用可能領域を拡張する方法 🧙 を説明します。
>
> この記事は、 **情報の整理と集約** により可読性を向上させる 🧐 ことを目的としており、[スクリプト作成者](https://itest.5ch.net/mao/test/read.cgi/network/1721217342/858-861) をはじめとする多くの方々の知見・貢献を横取りする意図はありません。😉

## 実行するスクリプト

WSR-3200AX4S に SSH で接続し、以下のスクリプトを実行します。

実行が完了したら `mount_vacant_space` を有効化するために `reboot` します。

```shell
opkg update
opkg install kmod-mtd-rw

wget -O /etc/init.d/mount_vacant_space https://pastebin.com/raw/XDja96GT
sed -i 's/\r//' /etc/init.d/mount_vacant_space
chmod 755 /etc/init.d/mount_vacant_space
/etc/init.d/mount_vacant_space enable
```

参考: スクリプト作成者による `mount_vacant_space` 導入手順説明

https://itest.5ch.net/mao/test/read.cgi/network/1721217342/906-910

## Storage はどのように変わるのか

以下はスクリプトの実行前後のスクリーンショットです。

画面の下の方の `Storage` に `ubi1:dpi` という項目が増えています。🧐

- 領域拡張前  
  ![/overlay 拡張前](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566576/b9d62192-9593-46a2-abe6-05bd05bc6e8b.png)

- 領域拡張後  
  ![/overlay 拡張後](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/566576/cb207baf-73fc-4fb7-9aac-1259decae0bd.png)

`ubi1:dpi` が空ではなく、1.7MB ほどが使用済みになっているのは [ここ](https://itest.5ch.net/mao/test/read.cgi/network/1721217342/906-910) の説明通りです。

## 追加領域を活用するには `--force-space` オプションが必要

例えば [Tailscale](https://tailscale.com/) をインストールする場合、`opkg install tailscale` ではなく `opkg --force-space install tailscale` を実行します。

普通に `opkg install tailscale` を実行してしまうと、以下のように領域不足のエラーが表示され、インストールに失敗します。😵

```shell
root@OpenWrt:~# opkg install tailscale
Installing tailscale (1.80.3-r1) to root...
Collected errors:
 * verify_pkg_installable: Only have 6788kb available on filesystem /overlay, pkg tailscale needs 22730
 * opkg_install_cmd: Cannot install package tailscale.
```

### 📌 Tailscale に関する補足

ただし、[Admonstrator](https://github.com/Admonstrator/glinet-tailscale-updater/) が提供している [Small binary の Tailscale](https://github.com/Admonstrator/glinet-tailscale-updater/releases) でも問題なく動作することを確認しているため、[Tailscale](https://tailscale.com/) を使用するのであれば最初から Small binary を使用するのがお勧めです。

https://qiita.com/Bacalhau/items/26bf74627532275f8616

40MB を超える `/overlay` 容量が使えるようになったと言っても `tailscale update` を実行すれば `no space left on device` が表示され、**泣きながら** 以下のコマンドで掃除をすることになるので、最初から Small binary を使用することをお勧めします。

```shell
rm /root/.cache/tailscale-update/tailscale*.tgz*
rm /usr/sbin/tailscale*.new*
```

## ファームウェア更新時の注意事項

憶えておくべきことは以下の一点。

- ファームウェアを更新しても `/mnt/vacant_space/usr_sbin/` 内のデータは消去されない

そのため、ファームウェア更新時は以下の手順で進む。

1. 設定のバックアップ (`System` > `Backup / Flash Firmware` > `Backup`)
2. ファームウェアの更新
3. `mount_vacant_space` の再導入  
   (`/usr/sbin/` コピー時に `/mnt/vacant_space/usr_sbin/` の同名ファイルは上書きされるはず。🤔)

もしファームウェア更新時に拡張用のパーティション(`mtd11`)を更地にしたければ、上記 2. と 3. の間に以下のコードを実行。

```shell
opkg update
opkg install kmod-mtd-rw

MTD_NUM=11
UBI_DEV="ubi1"
UBI_VOLUME="dpi"

insmod mtd-rw i_want_a_brick=1
mtd unlock /dev/mtd${MTD_NUM}

ubiformat /dev/mtd${MTD_NUM}
ubiattach /dev/ubi_ctrl -m $MTD_NUM
ubimkvol /dev/${UBI_DEV} -N $UBI_VOLUME -m
```

## 補足

### 補足 1: [`Attended Sysupgrade`](https://openwrt.org/docs/guide-user/installation/attended.sysupgrade) を使えば、ファームウェア更新後も `mount_vacant_space` の機能を維持できるか 🤔

結論から言えば、`mount_vacant_space` を使っている環境で [`Attended Sysupgrade`](https://openwrt.org/docs/guide-user/installation/attended.sysupgrade) で OpenWrt をアップグレードするべきではない。

#### 理由 1: `/etc/init.d/mount_vacant_space` は [`Attended Sysupgrade`](https://openwrt.org/docs/guide-user/installation/attended.sysupgrade) 時に消去される

(同じ `/etc/init.d/` 内の `/etc/init.d/tailscale` は消去されないので、なぜ `/etc/init.d/mount_vacant_space` が消去されるのか原因不明。😵)

#### 理由 2: OpenWrt イメージサイズが大きくなるため、もともと少ない Flash メモリがさらに圧迫される

Tailscale をインストールした WSR-3200AX4S で [`Attended Sysupgrade`](https://openwrt.org/docs/guide-user/installation/attended.sysupgrade) を実行したところ、Flash メモリの残容量が 1MB になった。 😵 ﾄﾃﾓﾂﾗｲ

### 補足 2: `/usr/sbin` 内のデータ削除のために `mtd erase WTB` で WTB パーティションを初期化したら `mount_vacant_space` が使えなくなった 😲

この [ページ](https://itest.5ch.net/mao/test/read.cgi/network/1721470536/543-547) の [546](https://itest.5ch.net/mao/test/read.cgi/network/1721470536/546) を読んで、パーティションのデータを丸ごと消そうと思って `mtd erase WTB` で WTB パーティションを初期化したら、 `mount_vacant_space` が実行できなくなった。 😵

OpenWrt イメージを書き込み直しても状況は変わらず。

いろいろと試してみたところ、以下の手順で回復できることが分かったため報告します。 🫡

> 👉 以下のコードはパーティションのフォーマットを含んでいます。
> フォーマットが不要であれば、`ubiformat /dev/mtd${MTD_NUM}` の実行は(多分)省略できます。

1. `mount_vacant_space` を無効化して再起動

   ```shell
   /etc/init.d/mount_vacant_space disable
   reboot
   ```

2. `mount_vacant_space` が実行できるよう、`ubi1` を作成し、ボリュームも作成

   ```shell
   MTD_NUM=11
   UBI_DEV="ubi1"
   UBI_VOLUME="dpi"

   insmod mtd-rw i_want_a_brick=1
   mtd unlock /dev/mtd${MTD_NUM}

   # umount /mnt/vacant_space
   # ubidetach -p /dev/mtd${MTD_NUM}

   ubiformat /dev/mtd${MTD_NUM}
   ubiattach /dev/ubi_ctrl -m $MTD_NUM
   ubimkvol /dev/${UBI_DEV} -N $UBI_VOLUME -m
   ```

3. `mount_vacant_space` を有効化して再起動

   ```shell
   /etc/init.d/mount_vacant_space enable
   reboot
   ```