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

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

新規登録して質問してみよう
ただいま回答率
85.37%
Linux

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

Raspberry Pi

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

Q&A

解決済

3回答

26167閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

Linux

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

Raspberry Pi

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

3グッド

3クリップ

投稿2017/04/04 06:30

編集2017/04/05 06:17

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
  1. テンポラリファイル生成抑制

/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
  1. 一旦再起動してdf -hでtmpfsができていることを確認

  2. unionfs-fuseパッケージインストール

$ sudo apt-get install unionfs-fuse
  1. スクリプトのコピー
$ 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
  1. /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
  1. initスクリプト有効化
$ sudo update-rc.d a-unionfs-fuse-live-cd defaults
  1. モード切替スクリプト作成(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
  1. モード切替スクリプト作成(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
  1. 権限付与
$ sudo chmod a+x /usr/local/bin/noprotect $ sudo chmod a+x /usr/local/bin/protect
  1. Read Only モードに切り替え、再起動
$ sudo protect $ sudo reboot

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

tanat, nullbot, tokkun01👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mt08

2017/04/04 08:08

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

退会済みユーザー

2017/04/04 09:21

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

退会済みユーザー

2017/04/04 09:26

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

回答3

0

ベストアンサー

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/05 17:53

mt08

総合スコア1825

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/04/07 10: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 11: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  にパスを通しておくこと
guest

0

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

投稿2017/04/05 06:50

編集2017/04/05 06:52
can110

総合スコア38339

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/04/05 07:54

can110さん、ご回答ありがとうございます。試してみます。
退会済みユーザー

退会済みユーザー

2017/04/05 10:25

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

2017/04/05 11:01

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

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/04 23:08

mt08

総合スコア1825

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/04/05 01: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 08:13 編集

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 08:02

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

2017/04/05 17:22

> このページを参考に、全体RO、必要な部分をRWにしてってことですね>< > ... はい。基本的にそうなります。 が、GUIアプリケーションなどで、どこに何を書き込まれるか調べるのが面倒...ですね.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問