質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • Linux

    3907questions

    Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

  • Raspberry Pi

    848questions

    Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Raspberry Pi 3のリードオンリー化

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 3
  • VIEW 7,994

ProgPi

score 12

Raspberry Pi3を使用した組込みシステムを開発してます。
電源ブチギリ時の保護の為、UnionFSを使用してリードオンリー化を
行おうと思い、
1) RAM-DISK作成
2) SDカードのリードオンリー化
のページを参照しながら、実験していたのですが、
上記の設定後、 $ sudo protect を実行して、
一度目のreboot時には、$ df -h を実行した時に
unionfs-fuseのファイルシステムが見えて、成功したかに
思えたのですが、再度rebootしたところ、起動しなくなり
SDカードの中身を確認したところ、/boot の中身が全て消えていました。
同じような経験をされた方、いらっしゃいませんでしょうか?
どのように解決に導いたか等、ご教示頂けると幸いです。

■ 環境・要求事項
** OS:Raspbian Kernel:4.4.38-v7+
** 保存が必要なデータはUSBメモリに記憶する。
** lazarusで作成したGUI画面を液晶に表示させる。
** Webサーバ(lighttpd)を搭載し遠隔地からステータス表示・制御可能。
** ラズパイのGPIO、GPIO-sirialを使用(外部デバイス制御の為)
** 現在は開発の為、SSH,Sambaを使用しているが実際の使用時には不要。
** 電源ブチギリ時のSDカード保護の為、SDカード全体をリードオンリーにしたい。

■ 発生している問題
** protectで起動した時、bootパーテーションが全て消去されている。
** このとき、rootfsは全て正常でした。

■ 再現手順
1) SWAPサービス無効

$ sudo apt-get install chkconfig
$ sudo chkconfig dphys-swapfile off


2) テンポラリファイル生成抑制
/etc/fstabを以下のように編集

proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1  /boot           vfat    defaults          0       2
/dev/mmcblk0p2  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
# ↓追加
tmpfs  /tmp          tmpfs  defaults,size=32m   0   0
tmpfs  /var/tmp      tmpfs  defaults,size=16m   0   0
tmpfs  /var/log      tmpfs  defaults,size=32m   0   0
tmpfs  /var/www/mrtg tmpfs  defaults,size=2m    0   0


3) 一旦再起動してdf -hでtmpfsができていることを確認

4) unionfs-fuseパッケージインストール

$ sudo apt-get install unionfs-fuse

5) スクリプトのコピー

$ sudo cp /usr/share/doc/unionfs-fuse/examples/S01a-unionfs-fuse-live-cd.sh /etc/init.d/a-unionfs-fuse-live-cd
$ sudo cp /usr/share/doc/unionfs-fuse/examples/rc.local.omit-pid.sh /usr/local/sbin/a-unionfs-fuse-omit-pid.sh

6) /etc/init.d/a-unionfs-fuse-live-cd を以下のようにする

#!/bin/sh

### BEGIN INIT INFO     
# Provides: a-unionfs-fuse-live-cd            
# Required-Start: mountall-bootclean
# Required-Stop:
# Default-Start: S
# Default-Stop:
# X-Start-Before: procps udev-mtab urandom
# Short-Description: UnionFS mode
# Descrition: Shutdown process will not be required 
### END INIT INFO

# Copyright: Bernd Schubert <bernd.schubert@fastmail.fm>
# BSD license, see LICENSE file for details
FUSE_OPT="-o allow_other,use_ino,suid,dev,nonempty"
CHROOT_PATH="/tmp/unionfs"
UNION_OPT="-ocow,chroot=$CHROOT_PATH,max_files=32768"
UBIN=/usr/bin/unionfs-fuse
cd /boot
file=noprotect
if [ -e ${file} ]; then
    echo "${file} exists"
    exit 0
fi
mount -o remount,ro /dev/mmcblk0p1 /boot
mount -t proc proc /proc
mount -t tmpfs tmpfs /tmp
mkdir -p $CHROOT_PATH/root
mkdir -p $CHROOT_PATH/rw
mkdir -p /tmp/union
mount --bind / $CHROOT_PATH/root
$UBIN $FUSE_OPT $UNION_OPT /rw=RW:/root=RO /tmp/union
mount -t proc proc /tmp/union/proc
cd /tmp/union
mkdir oldroot
pivot_root . oldroot
mount -o remount,ro /dev/root /oldroot 
for d in dev run run/lock sys run/shm dev/pts boot 
do
mount --bind /oldroot/$d /$d
done
init q
/usr/local/sbin/a-unionfs-fuse-omit-pid.sh   
 exit 0


7) initスクリプト有効化

$ sudo update-rc.d a-unionfs-fuse-live-cd defaults


8) モード切替スクリプト作成(noprotect)
$ sudo vi /usr/local/bin/noprotec

#!/bin/sh
mount -o rw,remount /boot
cd /boot
if [ -e "protect" ]; then
    rm /boot/protect
fi
if [ -e "noprotect" ]; then
    echo "noprotect mode"
else
    touch /boot/noprotect
    echo "noprotect mode"
fi
mount -o ro,remount /boot


9) モード切替スクリプト作成(protect)
$ sudo vi /usr/local/bin/noprotec

#!/bin/sh
mount -o rw,remount /boot
cd /boot
if [ -e "noprotect" ]; then
    rm /boot/noprotect
fi
if [ -e "protect" ]; then
    echo "protect mode"
else
    touch /boot/protect
    echo "protect mode"
fi
mount -o ro,remount /boot


10) 権限付与

$ sudo chmod a+x /usr/local/bin/noprotect   
$ sudo chmod a+x /usr/local/bin/protect

11) Read Only モードに切り替え、再起動

$ sudo protect
$ sudo reboot


※この再起動時に、通常の再起動より明らかに長い期間があった。
※おそらくここで/bootパーテーションがクリアされていると推測される
※この再起動後、/bootパーテーションは全て消去されており
※この状態で再起動したのでそれ以降起動でき無かった。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • mt08

    2017/04/04 17:08

    /bootパーティションのファイルが削除されていたとのことですが、rootfsは正常でしたか? あと、再現性のある手順をかいてもらえれば、確認できそうですが、これだけの情報だと、アドバイスもちょっと難しいかと。

    キャンセル

  • ProgPi

    2017/04/04 18:21

    追記しました。もっとここを見てほしいとか、ここはどうなってる?とかあればすぐ調べます。

    キャンセル

  • ProgPi

    2017/04/04 18:26

    上記手順で、2回実行して2回とも同じ結果になりました。

    キャンセル

回答 3

checkベストアンサー

+4

ProgPiさん、

https://github.com/josepsanzcamp/root-ro
というのを見つけて、試してみました。
かかれた手順通りにおこなうことで、簡単にリードオンリーにできました。

こんな感じに構成されます。

pi@raspberrypi:~ $ mount | grep /mnt/root
/dev/mmcblk0p2 on /mnt/root-ro type ext4 (ro,relatime,data=ordered)
tmpfs on /mnt/root-rw type tmpfs (rw,relatime)
overlay on / type overlay (rw,relatime,lowerdir=/mnt/root-ro,upperdir=/mnt/root-rw/upper,workdir=/mnt/root-rw/work)
pi@raspberrypi:~ $ 

2017-03-02-raspbian-jessie.imgで、Chromiumなどの起動でできました。
再起動すると、設定などすべて戻ります。

rwに戻すのも、/boot/config.txtに追加されたinitramfs initrd.gzをコメントアウトして、再起動だけです。

sudo mount -o remount,rw /dev/mmcblk0p1
sudo vi /mnt/boot-ro/config.txt #編集して、
sudo reboot # 再起動

心配な点としては、overlayfsでの書き込まれる部分(upperdir=/mnt/root-rw/upper)が、tmpfsなので、
ログなど増えていく場合は、たまにお掃除しないといけないかな、ってとこですね。(再起動で解決できますが)

↓のようなテストをしましたが、時間が経つと、少しずつ使える領域が減ってます。

pi@raspberrypi:~ $ cat /dev/zero > aa
cat: write error: No space left on device
pi@raspberrypi:~ $ ls -l ./aa
-rw-r--r-- 1 pi pi 471199744 Apr  5 17:46 ./aa
pi@raspberrypi:~ $ rm -v aa
removed ‘aa’
pi@raspberrypi:~ $ cat /dev/zero > aa
cat: write error: No space left on device
pi@raspberrypi:~ $ ls -l ./aa
-rw-r--r-- 1 pi pi 471052288 Apr  5 17:49 aa

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/07 19:24

    出来ました。
    この方法が一番楽ですね。
    出来れば再起動はしたくないので、ログを取らない設定に変更するか
    もしくは、常設しているUSBメモリに出力先を変更できるか試してみます。

    ちなみにaufs+fsprotectでのリードオンリー化はうまくいきました。
    ただ、カーネルのクロスコンパイル環境(Ubuntu)そろえたり、
    カーネルコンパイルに数時間かかったりとかなり大変でした。
    mt08様のご紹介して頂いた方法は数分でできるし、こちらのほうがいいですね。
    ありがとうございました。

    これからラズベリーパイを使用する方の為に、まとめておきます。

    まとめ
    Raspberry Pi 3でリードオンリー化する方法
    1)UnionFSを使用したリードオンリー化はうまくいかない。
    2)aufs+fsprotectを使用したリードオンリー化はうまくいった。
      参考サイト:
       http://blue-black.ink/?page_id=2442
       http://blue-black.ink/?page_id=2476
    3)mt08様ご紹介の方法(Read-only Root-FS)を使用したリードオンリー化はうまくいった。
       https://github.com/josepsanzcamp/root-ro

    キャンセル

  • 2017/04/07 20:01

    2)の備忘録
     git clone --depth=1 git://github.com/raspberrypi/tools.gitは何故かタイムアウトになりました
     git clone --depth=1 https://github.com/raspberrypi/tools.gitであればうまくいきました。
     あと、クロスコンパイル時に
     tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihtf-raspbian/bin
     にパスを通しておくこと

    キャンセル

0

ProgPiさん、再現させて、確認してみました。

が、結局、この方法での設定はうまくできませんでした。

どういったアプリケーションが動いていて、どのデータを保存しないといけないかわからないので、どうか分かりませんが、別の方法として、基本ro(Read only)で、マウントしてしまって、必要なとこだけ、symlinkをはったりして、rwで扱う、というのはどうでしょうか。
Protect your Raspberry PI SD card, use Read-Only filesystem この辺が参考になるかと思います。


一応、確認したことを書いておきます。

  • /etc/fstabを変更して、mmcblk0p1を ro にしたところ、/bootのファイルは消えなくなりました。
  • が、pivot_root でエラー、/ の変更ができないので、期待通りにunionfsを使用できていません。 
  • pivot_rootをいじってみましたが、Invalid argumentがでて、結局、うまく動作させられませんでした。
  • (pivot_rootのエラー): pivot_root: failed to change root from '.' to 'oldroot': Invalid argument
pi@raspberrypi:~$ sudo systemctl status a-unionfs-fuse-live-cd -l
● a-unionfs-fuse-live-cd.service - LSB: UnionFS mode
   Loaded: loaded (/etc/init.d/a-unionfs-fuse-live-cd)
   Active: active (running) since Tue 2017-04-04 21:19:12 UTC; 3min 3s ago
  Process: 111 ExecStart=/etc/init.d/a-unionfs-fuse-live-cd start (code=exited, status=0/SUCCESS)
   CGroup: /system.slice/a-unionfs-fuse-live-cd.service
           mq130 /usr/bin/unionfs-fuse -o allow_other,use_ino,suid,dev,nonempty -ocow,chroot=/tmp/unionfs,max_files=32768 /rw=RW:/root=RO /tmp/union

Apr 04 21:19:13 raspberrypi a-unionfs-fuse-live-cd[111]: proc is already mounted on /proc
Apr 04 21:19:13 raspberrypi a-unionfs-fuse-live-cd[111]: pivot_root: failed to change root from `.' to `oldroot': Invalid argument
Apr 04 21:19:13 raspberrypi a-unionfs-fuse-live-cd[111]: mount: mount point /oldroot does not exist
Apr 04 21:19:13 raspberrypi a-unionfs-fuse-live-cd[111]: mount: special device /oldroot/dev does not exist
Apr 04 21:19:13 raspberrypi a-unionfs-fuse-live-cd[111]: mount: special device /oldroot/run does not exist
Apr 04 21:19:13 raspberrypi a-unionfs-fuse-live-cd[111]: mount: special device /oldroot/run/lock does not exist
Apr 04 21:19:13 raspberrypi a-unionfs-fuse-live-cd[111]: mount: special device /oldroot/sys does not exist
Apr 04 21:19:13 raspberrypi a-unionfs-fuse-live-cd[111]: mount: mount point /run/shm does not exist
Apr 04 21:19:13 raspberrypi a-unionfs-fuse-live-cd[111]: mount: special device /oldroot/dev/pts does not exist
Apr 04 21:19:13 raspberrypi a-unionfs-fuse-live-cd[111]: mount: special device /oldroot/boot does not exist
pi@raspberrypi:~$

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/05 10:09

    ご確認、及び、ご回答ありがとうございます。
    unionfsでの方法は、net上の記事の日付を見る限りraspberry pi 2での
    記事と推測されるので、raspberry pi 3ではだめなのかもしれませんね。
    現在、aufs(AnotherUnionFS)+fsprotecの方法を試すため、
    raspberry pi 3でカーネルコンパイル中(8時間位かかるらしい)なので、
    そちらの確認が取れ次第、mt08様に教えていただいたURLの方法も
    確認してみたいと思います。

    追伸)
    今回のシステムでは、書き込みが必要なデータ類は全て
    raspberry pi 3にさしたUSBメモリに記憶させる予定ですので、
    SDカードは全面ReadOnlyで問題ありません。

    キャンセル

  • 2017/04/05 15:30 編集

    aufs+fsprotectでの方法は、手順をどこかで間違えたらしく失敗しました。
    (コンパイルに8時間と書きましたが、raspberry pi 3では4時間でコンパイルできました)
    こちらに関しては再チャレンジしてみるつもりです。

    その前に、ご提示頂いたページを、これから確認するところですが、
    Using a read-only file system is mostly used for Pi working 24H/7 a day and with console mode only, so if you’re using X11 or graphic interface, I won’t recommend this method because it won’t work.
    とあり、GUIを使用する場合には動作しない旨の記載がありました。

    キャンセル

  • 2017/04/05 17:02

    ああ、すみません。
    このページを参考に、全体RO、必要な部分をRWにしてってことですね><
    結局のところ、aufsやunionfsなどのROMとRAMを重ね合わせるオーバーレイ機能は不要で
    全体をROにして、書込みが必要なところはRW, ログはRAMディスクへという対応を
    fstabに記載すれば問題ないってことなのでしょうか?

    キャンセル

  • 2017/04/06 02:22

    > このページを参考に、全体RO、必要な部分をRWにしてってことですね><
    > ...

    はい。基本的にそうなります。
    が、GUIアプリケーションなどで、どこに何を書き込まれるか調べるのが面倒...ですね.

    キャンセル

0

要件(電源ブチ切り)に合うか分かりませんが、以下の方法も参考になるかと思います。
How to build a web kiosk with Raspberry Pi and make the SD read-only.
最近までコメントのやりとりもあるので最新のRaspbian(Lite)でも動作しそうですし、わりとシンプルそうな手順です。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/04/05 16:54

    can110さん、ご回答ありがとうございます。試してみます。

    キャンセル

  • 2017/04/05 19:25

    mmcblk0p1、mmcblk0p2をroにしてしまうと、
    電源起動時のX立上りタイミングあたり(起動時のログが流れ終わって
    Xが起動するために画面が更新されるタイミングあたり)で、画面左上に
    点滅する"_"が表示されてそれ以降そこで停止する状態になってしまいました

    キャンセル

  • 2017/04/05 20:01

    回答にあげたリンク先での2日前のコメントと同じ状況でしょうか?
    Try to create a symlink of /home/pi/.local/share/xorg to /tmp とあるので
    試してみてはいかがでしょうか。

    キャンセル

関連した質問

同じタグがついた質問を見る

  • Linux

    3907questions

    Linuxは、Unixをベースにして開発されたオペレーティングシステムです。日本では「リナックス」と呼ばれています。 主にWebサーバやDNSサーバ、イントラネットなどのサーバ用OSとして利用されています。 上位500のスーパーコンピュータの90%以上はLinuxを使用しています。 携帯端末用のプラットフォームAndroidは、Linuxカーネル上に構築されています。

  • Raspberry Pi

    848questions

    Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。