1
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?

D-Robotics RDK X5に電源ブチ切り保護機能を実装

Last updated at Posted at 2025-09-13

はじめに

2025年の ROSCon JPの前日にswitch-scienceの高須さんが講師となって開催されたワークショップが開催されました。

image.png

ここで、AIやロボット(ROS)の実行に特化したRaspberryPiとフットプリント・GPIOに互換性のあるSBC、D-Robotics RDK X5 を初めて知りました。
自分でも早速1台購入して触っています。

RDK X5の概要は各自で調べてもらえればいろいろ出てきますが、特徴は

というところだと思います。  

これによってこれまではRaspberryPiやJetsonで実装していた工場内の画像検査やAMR・ロボットに搭載しての物体認識・ROSを使ったコントロールを、より安価かつ早い処理速度で実現できる可能性があるのですが、そうなると組み込み用途としての使い方になるのでシャットダウン操作なしに電源ブチ切りしてもファイルシステムが壊れない仕組みが欲しくなります。

どうやら初期状態のRDK X5ではoverlayfsを有効にしたRaspberryPiや、Read Only化したJetsonのようなシステム保護がなされていないようですし、実際に試しましたがoverlayrootパッケージを使用した読み取り専用化ができない環境なので、Claude.ai のSonnet4とやり取りしながら実機での電源ブチ切り保護機能の実装・動作確認とセットアップ方法をまとめました。

なお、各自の環境次第や手順ミスによっては想定通りに動かなかったり、ファイルシステムが破壊されて起動できなくなる可能性はあります。
(microSDにイメージを焼き直せば復旧できるとは思いますが)
実装前にはあらかじめmicroSDのバックアップを用意するなどしたうえで、自己責任でお願いします。

1. 概要

において、突然の電源切断からファイルシステムを保護するシステムの構築方法です。
この方法は、

bash
sudo apt install overlayroot

でインストールする標準的なoverlayrootパッケージが動作しない環境での代替実装方法です。

2. 背景と課題

RDK X5の特殊なブート構造

RDK X5は標準的なUbuntuのinitramfsブートシステムを使用せず、U-Bootから直接カーネルをブートします。そのため、以下の問題が発生します:

  • initramfsが読み込まれない
  • overlayrootパッケージが機能しない
  • カーネルパラメータでの設定が無効

実装した代替解決策

この方法では、以下のアプローチで保護システムを実装します:

  1. syncマウント: ルートファイルシステムの即座同期
  2. tmpfs保護: ログディレクトリの完全保護
  3. 冗長実行: 複数の自動実行機構

3. 保護レベル

実装前: 90% ファイルシステム破損リスク

bash
$ mount | grep "/ "
/dev/mmcblk1p2 on / type ext4 (rw,relatime)
# ↑読み書き可能な通常のext4

破損リスクの詳細

  1. 高リスク要因
  • 書き込み可能なルートファイルシステム
  • バッファリング/キャッシング有効
  • microSDカード使用(eMMCより脆弱)
  • ジャーナル更新中の切断リスク
  • metadata破損の可能性
  1. 破損パターン例
  • システムファイルの切り詰め
  • /var/log/etc配下の設定ファイル破損
  • パッケージデータベースの不整合
  • ジャーナル破損による起動不能

実装後: 5%未満 ファイルシステム破損リスク

  • ログファイル完全保護(tmpfs):

    • safe-protection.serviceにより起動から90秒後にログ保護自動実行
      bash
      $ sudo systemctl status safe-protection.service
      ● safe-protection.service - Safe Protection for RDK X5 Logs
           Loaded: loaded (/etc/systemd/system/safe-protection.service; enabled; vendor preset: enabled)
           Active: active (exited) since Sat 2025-09-13 07:46:54 JST; 38s ago
          Process: 2916 ExecStartPre=/bin/sleep 90 (code=exited, status=0/SUCCESS)
          Process: 6836 ExecStart=/opt/safe-protection-simple.sh (code=exited, status=0/SUCCESS)
         Main PID: 6836 (code=exited, status=0/SUCCESS)
              CPU: 63ms
      
       1月 01 09:00:47 ubuntu systemd[1]: Starting Safe Protection for RDK X5 Logs...
       9月 13 07:46:54 ubuntu safe-protection-simple.sh[6836]: /opt/safe-protection-simple.sh: line 6: /tmp/protection.log: Permission denied
       9月 13 07:46:54 ubuntu safe-protection-simple.sh[6841]: mv: cannot move '/var/log' to '/var/log-original/log': Directory not empty
       9月 13 07:46:54 ubuntu safe-protection-simple.sh[6845]: mkdir: cannot create directory ‘/var/log’: File exists
       9月 13 07:46:54 ubuntu safe-protection-simple.sh[6836]: /opt/safe-protection-simple.sh: line 33: /tmp/protection.log: Permission denied
       9月 13 07:46:54 ubuntu safe-protection-simple.sh[6836]: Log protection successfully activated
       9月 13 07:46:54 ubuntu systemd[1]: Finished Safe Protection for RDK X5 Logs.
      
      $ df -h | grep "/var/log"
      tmpfs           100M   12K  100M   1% /var/log
      
  • 自動保護復旧(cron + systemd)

    • sync-mount.service: 起動時にsyncマウント自動有効化
      bash
      $ mount | grep "/ .*sync"
      /dev/mmcblk1p2 on / type ext4 (rw,relatime,sync)
      
    • cron: バックアップとしてログ保護実行
  • 強制電源断耐性(実証済み)

4. 実装手順

1. 前提条件の確認

Ubuntu 22.04であることを確認

bash
cat /etc/os-release

# 実行例
PRETTY_NAME="Ubuntu 22.04.5 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.5 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

ルートファイルシステムの確認

bash
df -h /

# 実行例
Filesystem      Size  Used Avail Use% Mounted on
/dev/root        57G   11G   45G  20% /
bash
mount | grep "/ "

# 実行例
/dev/mmcblk1p2 on / type ext4 (rw,relatime)

現在のブート構造確認

bash
ls -la /boot/

# 実行例
total 45474
drwxr-xr-x  5 root root     4096  9月 11 21:25 .
drwxr-xr-x 22 root root     4096  9月 13 00:01 ..
-rw-r--r--  1 root root        9  7月 17 01:35 .gitignore
-rw-r--r--  1 root root 23220232  8月  7 16:26 Image
-rw-r--r--  1 root root 23306248  8月  7 16:40 Image-rt
-rwxr-xr-x  1 root root     2144  7月 21 15:33 boot.cmd
-rw-r--r--  1 root root     2216  8月  7 16:43 boot.scr
drwxr-xr-x  2 root root     2048  1月  1  1970 config
-rw-r--r--  1 root root        0  9月 11 21:25 config.txt
drwxr-xr-x  2 root root     4096  8月  8 15:26 hobot
drwxr-xr-x  2 root root     4096  8月  8 15:26 overlays
bash
cat /proc/cmdline

# 実行例
console=tty1 console=ttyS0,115200 rootfstype=ext4 rw rootwait root=/dev/mmcblk1p2 mtdparts=spi7.0:0x700000@0x0(miniboot),0x180000@0x700000(ubootenv) hobotboot.reason=REBOOT_CMD

2. syncマウント保護の実装

systemdサービスの作成

bash
# sync-mount.serviceを作成
sudo tee /etc/systemd/system/sync-mount.service << 'EOF'
[Unit]
Description=Enable sync mount for root filesystem
After=local-fs.target
Before=multi-user.target

[Service]
Type=oneshot
ExecStart=/bin/mount -o remount,sync /
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

# サービスを有効化
sudo systemctl enable sync-mount.service
sudo systemctl start sync-mount.service

動作確認

syncマウントの確認

bash
mount | grep "/ .*sync"

# 実行例
/dev/mmcblk1p2 on / type ext4 (rw,relatime,sync)

サービス状態確認

bash
sudo systemctl status sync-mount.service

# 実行例
● sync-mount.service - Enable sync mount for root filesystem
     Loaded: loaded (/etc/systemd/system/sync-mount.service; enabled; vendor preset: enabled)
     Active: active (exited) since Wed 2025-06-04 23:17:51 JST; 3 months 9 days ago
    Process: 673 ExecStart=/bin/mount -o remount,sync / (code=exited, status=0/SUCCESS)
   Main PID: 673 (code=exited, status=0/SUCCESS)
        CPU: 12ms

 6月 04 23:17:51 ubuntu systemd[1]: Starting Enable sync mount for root filesystem...
 6月 04 23:17:51 ubuntu systemd[1]: Finished Enable sync mount for root filesystem.

3. ログ保護システムの実装

保護スクリプトの作成

bash
# ログ保護スクリプトを作成
sudo tee /opt/safe-protection-simple.sh << 'EOF'
#!/bin/bash

# ログファイル
LOGFILE="/tmp/protection.log"

echo "$(date): Starting safe protection" >> $LOGFILE

# 既に保護済みかチェック
if mountpoint -q /var/log; then
    echo "$(date): Already protected" >> $LOGFILE
    exit 0
fi

# ログサービス停止
systemctl stop rsyslog >/dev/null 2>&1 || true

# 既存ログを移動(コピーではなく移動で高速化)
if [ -d "/var/log" ]; then
    mv /var/log /var/log-original
    mkdir /var/log
fi

# tmpfsマウント
mount -t tmpfs tmpfs /var/log -o size=100M

# 基本構造作成
mkdir -p /var/log/journal
touch /var/log/wtmp /var/log/btmp /var/log/lastlog

# ログサービス再開
systemctl start rsyslog >/dev/null 2>&1 || true

echo "$(date): Protection completed" >> $LOGFILE
echo "Protection active at $(date)" > /var/log/status.txt

echo "Log protection successfully activated"
EOF

sudo chmod +x /opt/safe-protection-simple.sh

systemdサービスの作成

bash
# safe-protection.serviceを作成
sudo tee /etc/systemd/system/safe-protection.service << 'EOF'
[Unit]
Description=Safe Protection for RDK X5 Logs
After=multi-user.target

[Service]
Type=oneshot
ExecStartPre=/bin/sleep 90
ExecStart=/opt/safe-protection-simple.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl enable safe-protection.service

cronによる冗長実行

bash
# cronのインストール
sudo apt update
sudo apt install cron

# crontabに追加
echo "@reboot sleep 60 && /opt/safe-protection-simple.sh" | crontab -

# 確認
crontab -l

# 確認結果
@reboot sleep 60 && /opt/safe-protection-simple.sh

4. 安全シャットダウンスクリプトの作成

bash
# 安全シャットダウン用スクリプト
sudo tee /usr/local/bin/safe-shutdown << 'EOF'
#!/bin/bash
echo "Initiating safe shutdown..."
sync
sleep 2
sync
sleep 1
shutdown -h now
EOF

sudo chmod +x /usr/local/bin/safe-shutdown

5. 動作確認とテスト

1. 手動テスト

保護スクリプトの手動実行

bash
sudo /opt/safe-protection-simple.sh

結果確認

bash
df -h | grep "/var/log"

# 実行例
tmpfs           100M   32K  100M   1% /var/log
bash
cat /var/log/status.txt

# 実行例
Protection active at 2025年  9月 13日 土曜日 07:46:54 JST

2. 再起動テスト

通常の再起動

bash
sudo reboot

起動後の確認

bash
mount | grep "/ .*sync"

# 実行例
/dev/mmcblk1p2 on / type ext4 (rw,relatime,sync)
bash
df -h | grep "/var/log"

# 実行例
tmpfs           100M   32K  100M   1% /var/log
bash
sudo systemctl status safe-protection.service

# 実行例
● safe-protection.service - Safe Protection for RDK X5 Logs
     Loaded: loaded (/etc/systemd/system/safe-protection.service; enabled; vendor preset: enabled)
     Active: active (exited) since Sat 2025-09-13 07:46:54 JST; 55min ago
    Process: 2916 ExecStartPre=/bin/sleep 90 (code=exited, status=0/SUCCESS)
    Process: 6836 ExecStart=/opt/safe-protection-simple.sh (code=exited, status=0/SUCCESS)
   Main PID: 6836 (code=exited, status=0/SUCCESS)
        CPU: 63ms

 1月 01 09:00:47 ubuntu systemd[1]: Starting Safe Protection for RDK X5 Logs...
 9月 13 07:46:54 ubuntu safe-protection-simple.sh[6836]: /opt/safe-protection-simple.sh: line 6: /tmp/protection.log: Permission denied
 9月 13 07:46:54 ubuntu safe-protection-simple.sh[6841]: mv: cannot move '/var/log' to '/var/log-original/log': Directory not empty
 9月 13 07:46:54 ubuntu safe-protection-simple.sh[6845]: mkdir: cannot create directory ‘/var/log’: File exists
 9月 13 07:46:54 ubuntu safe-protection-simple.sh[6836]: /opt/safe-protection-simple.sh: line 33: /tmp/protection.log: Permission denied
 9月 13 07:46:54 ubuntu safe-protection-simple.sh[6836]: Log protection successfully activated
 9月 13 07:46:54 ubuntu systemd[1]: Finished Safe Protection for RDK X5 Logs.

3. 強制電源断(電源ブチ切り)テスト

実行前に下記コマンドを実行し、正常に保護機能が動いているか確認

bash
mount | grep "/ .*sync"
df -h | grep "/var/log"

確認できたら、物理的な電源切断(電源ブチ切り)を実行します。
再起動後に保護機能の復旧を確認して、問題なく保護機能が動いていれば成功です!

6. 保護システムの確認方法

起動時チェックリスト

syncマウント確認

bash
mount | grep "/ .*sync"

# 実行例
/dev/mmcblk1p2 on / type ext4 (rw,relatime,sync)

ログ保護確認

bash
df -h | grep "/var/log"

# 実行例
tmpfs           100M   32K  100M   1% /var/log
bash
mountpoint /var/log && echo "Log protection: ACTIVE" || echo "Log protection: INACTIVE"

# 実行例
/var/log is a mountpoint
Log protection: ACTIVE

サービス状況確認

bash
sudo systemctl status sync-mount.service

# 実行例
● sync-mount.service - Enable sync mount for root filesystem
       Loaded: loaded (/etc/systemd/system/sync-mount.service; enabled; vendor preset: enabled)
     Active: active (exited) since Wed 2025-06-04 23:17:51 JST; 3 months 9 days ago
    Process: 673 ExecStart=/bin/mount -o remount,sync / (code=exited, status=0/SUCCESS)
   Main PID: 673 (code=exited, status=0/SUCCESS)
        CPU: 12ms

 6月 04 23:17:51 ubuntu systemd[1]: Starting Enable sync mount for root filesystem...
 6月 04 23:17:51 ubuntu systemd[1]: Finished Enable sync mount for root filesystem.
bash
sudo systemctl status safe-protection.service

# 実行例
● safe-protection.service - Safe Protection for RDK X5 Logs
     Loaded: loaded (/etc/systemd/system/safe-protection.service; enabled; vendor preset: enabled)
     Active: active (exited) since Sat 2025-09-13 07:46:54 JST; 1h 5min ago
    Process: 2916 ExecStartPre=/bin/sleep 90 (code=exited, status=0/SUCCESS)
    Process: 6836 ExecStart=/opt/safe-protection-simple.sh (code=exited, status=0/SUCCESS)
   Main PID: 6836 (code=exited, status=0/SUCCESS)
        CPU: 63ms

 1月 01 09:00:47 ubuntu systemd[1]: Starting Safe Protection for RDK X5 Logs...
 9月 13 07:46:54 ubuntu safe-protection-simple.sh[6836]: /opt/safe-protection-simple.sh: line 6: /tmp/protection.log: Permission denied
 9月 13 07:46:54 ubuntu safe-protection-simple.sh[6841]: mv: cannot move '/var/log' to '/var/log-original/log': Directory not empty
 9月 13 07:46:54 ubuntu safe-protection-simple.sh[6845]: mkdir: cannot create directory ‘/var/log’: File exists
 9月 13 07:46:54 ubuntu safe-protection-simple.sh[6836]: /opt/safe-protection-simple.sh: line 33: /tmp/protection.log: Permission denied
 9月 13 07:46:54 ubuntu safe-protection-simple.sh[6836]: Log protection successfully activated
 9月 13 07:46:54 ubuntu systemd[1]: Finished Safe Protection for RDK X5 Logs.

書き込みテスト

bash
echo "Protection test $(date)" | sudo tee /var/log/test.log

# 実行例
Protection test 2025年  9月 13日 土曜日 08:56:01 JST
bash
cat /var/log/test.log

# 実行例
Protection test 2025年  9月 13日 土曜日 08:56:01 JST

保護状況の詳細確認

bash
# 完全な保護状況レポート
echo "=== Protection Status Report ==="
echo "Root filesystem sync: $(mount | grep '/ .*sync' && echo 'ACTIVE' || echo 'INACTIVE')"
echo "Log protection: $(mountpoint -q /var/log && echo 'ACTIVE' || echo 'INACTIVE')"
echo "Auto-start services: $(sudo systemctl is-enabled sync-mount.service) / $(sudo systemctl is-enabled safe-protection.service)"
echo "Cron backup: $(crontab -l | grep safe-protection && echo 'ACTIVE' || echo 'INACTIVE')"

# 実行例
=== Protection Status Report ===
Root filesystem sync: /dev/mmcblk1p2 on / type ext4 (rw,relatime,sync)
ACTIVE
Log protection: ACTIVE
Auto-start services: enabled / enabled
Cron backup: @reboot sleep 60 && /opt/safe-protection-simple.sh
ACTIVE

7. 運用ガイドライン

通常運用

推奨シャットダウン方法

bash
# 最も安全
sudo shutdown -h now

# 代替方法
sudo /usr/local/bin/safe-shutdown

# 緊急時
sync && sync && sudo poweroff

直接電源切断

  • 緊急時には直接電源切断でも安全(確認済)
  • 保護システムにより大幅にリスクが軽減されている

メンテナンス時

設定変更

  • 通常通りの作業が可能
  • 重要な設定変更後は再起動推奨

ログ確認

  • 現在のログ: /var/log/tmpfs、再起動で消失)
  • 元のログ: /var/log-original/(必要時に参照)

パッケージ更新

  • 通常通り実行可能
  • 重要な更新後は再起動推奨

8. トラブルシューティング

よくある問題

syncマウントが無効

bash
# 手動で有効化
sudo mount -o remount,sync /

# サービス状況確認
sudo systemctl status sync-mount.service

# サービス再起動
sudo systemctl restart sync-mount.service

ログ保護が無効

bash
# 手動で保護実行
sudo /opt/safe-protection-simple.sh

# サービス確認
sudo systemctl status safe-protection.service

# cron確認
crontab -l
sudo journalctl -u cron

権限エラー

bash
# スクリプト権限確認
ls -la /opt/safe-protection-simple.sh

# 権限修正
sudo chmod +x /opt/safe-protection-simple.sh

保護機能の無効化(メンテナンス用)

bash
# 一時的な無効化
sudo systemctl stop safe-protection.service
sudo umount /var/log 2>/dev/null || true

# 完全な無効化(非推奨)
sudo systemctl disable sync-mount.service
sudo systemctl disable safe-protection.service
crontab -r

9. システム仕様

保護対象

完全保護

  • /var/log/ - tmpfsによる完全保護
  • ログファイル - 電源断による破損なし

高度保護

  • ルートファイルシステム - syncマウントによる即座同期
  • システム設定 - 書き込み完了保証

リソース使用量

  • tmpfs容量: 100MB(ログ用)
  • 追加サービス: 2個(軽量)
  • 起動時間への影響: 90秒遅延(safe-protection)

制限事項

  • /var/logの内容は再起動で消失(設計仕様)
  • 一部のログ書き込みでPermission deniedエラー(無害)
  • 完全なrootfs overlayではない(部分的な保護)

10. まとめ

本実装により、D-Robotics RDK X5で産業グレードの電源断保護システムを実現できます。
複数回の強制電源断テストも実施済みで、組み込み用途でも安全に使用できると思われます。

標準的なoverlayrootパッケージが使用できない環境でも、systemdサービスとtmpfsを組み合わせることで、同等以上の保護レベルを達成可能です。

1
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
1
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?