📶

GL.inetルーター GL-MT6000 #2: NFS サーバーにもしてしまう。

に公開

目的

  • GL.inet 社製ルーター GL-MT6000 (Flint2) 上に NFS サーバーを作りたい。
    • このルーター、国産 WiFi ルーターにはありえない高機能&カスタマイズ性があり、
    • とっても使いやすく/設定できてよいのだが、ハマりポイントも多数のため記録。

前提

https://zenn.dev/koinec/articles/869a9e0201895b
の続きのため、こちらでのユーザー作成、OpenSSH 化を前提としています。

NFS サーバー化の仕様

まず仕様を整理。

  • NFS 領域は USB スティック型 SSD を挿して利用
    • ルーターの標準領域は電源ブチ切り対応のため、OverlayFS になっており、かつ eMMC 8GB と容量は少く、NFSには向かない。
    • 今回は BUFFALO 社製 SSD-PST500U3BA/D を利用。
      これ小さいのでこのルーターに挿しても邪魔にならないので素敵。
      https://www.buffalo.jp/product/detail/ssd-pst500u3ba_d.html
  • USB SSDのファイルシステムは BTRFS を利用
    • 標準パッケージ内で利用できるファイルシステムは ntfs, fat, ext*, xfs, btrfs, f2fs, hfs, jfs, minix あたり
    • 100点のものはないが、せめてもの電源ブチ切り可能を目指すならbtrfsしかなさそう。
      • ext4 だと実害はなくても起動時毎回メタデータ壊れでfsckが走ってしまいそうなのが難点
      • btrfsも厳密には停止時にアンマウントしないとNGだ、がCoWを信じて+書き込み直後は電源きらない前提で一旦こちら採用。

NFS サーバー化の手順の流れ

実施したざっくり手順を列挙。

  1. USB 3.0 の無効化
  2. GL.inet製NASサービスの停止
  3. btrfs 領域の作成
  4. 起動時マウントスクリプトの設定
  5. nfs サーバーパッケージの導入&設定

いずれの手順にもトラップがいたので以下手順毎にメモっておきます。

1. USB 3.0 の無効化

まず問題点。

よって、泣く泣く...USB2.0 にすることで対処。
幸い?(もしくは製造時点から分かっていた?)のか、標準 Web UI の「システム」ー「概要」ページに、"USB プロトコルの切り替え" として USB2.0 / 3.0 の切り替えがカンタンにできるので、これを USB 2.0 に切り替えておく。

これでひとまず USB 3.0 の無効化は終わり。
(が、こいつがあとでさらに面倒な問題を引き起こしてしまう。。。)

ファイルシステム選定とこのルーターの問題点

次に、NFS 領域として使う USB SSD のファイルシステムの選定を悩む。とりあえず経緯は、

  • NFS 領域なので、FAT とか間違っても NTFS なんてありえない。
  • 次に、できれば電源ブチ切り可としたいので耐性あるファイルシステム探したが、電源ブチ切り完全耐性ありの標準で利用できるファイルシステムは「ない」。
  • 完全電源断耐性を諦めて、緩和を考えると以下2択?
    • ext4 でマウントオプションいじる。
    • btrfs の Copy on Write (CoW) を信じる
  • btrfs は使ったことない + WiFiルーター=いわゆる組み込みLinuxで、そこまでメモリだぶだぶでもないので、できれば避けたい。

ということで、ext4 でマウントオプションをいじろう、としたが、まぁ問題点がみつかること。これで何日も吹っ飛んだ。。。

なるべく標準機能の範囲で対処できないか (でないとアップデートが面倒?) と頑張ったが、どうやっても GL.inet 謹製ディスク管理サービスを止めざるを得ない、と判断。

なお、調査の過程で btrfs は電源ブチ切りに意外と強いっぽい、と分かったので最終的にこちらを採用にしてみた。

2. GL.inet製NASサービスの停止

ということで、GL.inet 謹製ディスク管理サービスを止めようと調査。
結論としては、以下のコマンドで以下4つを止めてしまえばよく、標準 Web UI への実害もないと判明。

flint2# service gl_nas_diskmanager stop
flint2# service gl_nas_sys stop
flint2# service gl_nas_sys_dl stop
flint2# service gl_nas_sys_up stop
flint2# service gl_nas_diskmanager disable
flint2# service gl_nas_sys disable
flint2# service gl_nas_sys_dl disable
flint2# service gl_nas_sys_up disable

上記実施後、一旦ルーターを再起動。
再起動後は、

flint2# service list
/etc/init.d/gl_nas_diskmanager    disabled         stopped
/etc/init.d/gl_nas_sys            disabled         stopped
/etc/init.d/gl_nas_sys_dl         disabled         stopped
/etc/init.d/gl_nas_sys_up         disabled         stopped

となっていることを確認してOK。

3. btrfs 領域の作成

気まずいサービスは止まったので、いよいよ USB SSD を設定。
手順は以下とした。

  1. 標準 Web UI の「プラグイン」から以下をインストール
    gdisk, kmod-fs-btrfs, btrfs-progs
  2. USB ポートに USB SSD を挿す
    ※HDDや一部のSSDは電源不足の懸念もあるらしいのでそこは注意。
    ※事前に何かのマシンで gpt テーブルを作っておく想定。
  3. gdisk コマンドで Linux パーティションを作成
  4. btrfs フォーマット実施。
    flint2# mkfs.btrfs -f /dev/sda1
    "-f" をつけないと以前のファイルシステムのデータが残っている、などの理由で怒られることがあるので注意。
  5. 試しにマウント
    flint2# mount -t btrfs /dev/sda1 /<任意のマウントポイント>
    ファイルの読み書きができればOK。

4. 起動時マウントスクリプトの設定

ようやく、ってことでルーター起動時に自動でマウントしよう、とした。

ひとまず、OpenWRT標準の自動マウント機能はまともそうなので、標準 Web UI の 「システム」-「詳細設定」から「LuCIへ移動する」をクリックし、OpenWRT 標準メニューに入り、さらにLuCI画面の「システム」-「マウントポイント」からUUID指定で自動マウントを設定。

やれやれってことで再起動すると。。。ギャー、またまた「怪現象」が発生!

  • 怪現象1:何かファイルを書き込んでlsするとファイルが消える!
    • dmesg でカーネルメッセージを見るとbtrfs関連のCallTraceが出てしまう。
  • 怪現象2:/dev/sda1でマウントできているのに、/dev配下にsda1がなく、sdb1がいる!
    - つまり、マウントデバイス /dev/sda1 がおそらくマウント後に消されている

この原因の調査でまた数日ぶっ飛んだが、問題点&原因は以下の多重要因だった!

この問題の対策は色々悩んだが、最終的には

  • GL.inet謹製USBテザリングサービスを停止
  • OpenWRTのディスクマウントサービスによるマウントも諦め
    • 代替として、一定の時間 (今回は10秒) 待ってから /dev/sda1 をマウントするスクリプトを用意
    • このマウント用スクリプトを起動の最終フェーズで実行されるスクリプト /etc/rc.local から呼び出す

というちょっと強引な手段で解決(回避)することにした。

ということで、まずGL.inet謹製USBテザリングサービスを停止。

flint2# service gl_tethering stop
flint2# service gl_tethering disable

そして、10秒待ってからマウントするスクリプト /usr/local/bin/nfs_startup.sh

#!/bin/sh

sleep 10
mount -t btrfs -o noatime /dev/sda1 /data

とし、/etc/rc.local は、

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.

. /lib/functions/gl_util.sh
remount_ubifs

/usr/local/bin/nfs_startup.sh &

exit 0

のように、/usr/local/bin/nfs_startup.sh & の行を追加した。

これで再起動すると、マウントポイント /data に自動的に BTRFS がマウントされ、ファイル読み書きしても CallTrace を吐かなくなった!めでたし!

5. nfs サーバーパッケージの導入&設定

これで怪現象は無事クリアでき、USB SSD が安心してマウント/利用できるようになったので、あとはちゃらっと NFS サーバーを設定していく。

これは悩むことはなく、以下でカンタンに実現可能だった。

  1. 標準 Web UIの「プラグイン」から、nfs-kernel-server をインストール

  2. /etc/exports ファイルに公開ディレクトリの設定を書く。
    ワタクシ環境では以下としたがこれはお好みでよさげ。

    /data 192.168.8.0/24(rw,all_squash,insecure,sync)
    
  3. flint2# service nfsd start で NFS サーバーを手動起動

  4. flint2# exportfs で公開ディレクトリが表示されることを確認

  5. 端末側から NFS マウントできることを確認してみる。

  6. 最後に自動マウントスクリプトからマウント後、nfsd サービスを起動するように追記
    /usr/local/bin/nfs_startup.sh:

    #!/bin/sh
    
    sleep 10
    mount -t btrfs -o noatime /dev/sda1 /data
    
    /etc/init.d/nfsd start
    

    /etc/init.d/nfsd start を追記。

これで再起動して、再度端末から NFS マウントできたらバッチリ構築完了。

ふぅー。長かった。。。

応用

ワタクシは NFS サーバーにしたかったのでこうしたのですが、このルーター、何かルーティング以外のオシゴトをさせようと思うとほとんどのケースで USB SSD によるディスク増設は免れないものと思われます。

また、怪現象や問題点と連発はしたものの、良くも悪くも Linux Box なので調査もできて解決も図れていくところは強烈に頼もしいなぁと思った次第です。
(ブラックボックスな普通のルーターなら問題点一発出した段階でほぼ詰むので。。。)

さらに、これが解決できた以上、このルーターの本領発揮で

  • Web サーバー (apache, nginx)
  • メールサーバー (postfix, dovecot)
  • DNS サーバー (bind, unbound)
  • RADIUS サーバー (freeradius3)
  • LDAP サーバー (openldap)
  • その他 (gcc, git, zabbix-server, mariadb-server)
    などなどがプラグインメニューからインストール可能っぽく、自宅内ネットワークの高度化に結構使い倒せそうです。

なお、GL.inet 製ルーターは、USB 電源で動作するいわゆるトラベルルーター GL-MT3000 (Beryl AX) (https://www.gl-inet.com/products/gl-mt3000/) なんてのもあり、こちらも兄弟ルーターなのでほぼ同じ手順でほぼ同じことができます。(CPUコア数、メモリ量は半分なので注意)
実はこいつもポチってこちらは自宅内24h365d git サーバーとして稼働させております。(しかもこちらはUSB電源ってのが魅力に過ぎる)

さて、次はなにしようかな。。。

Discussion