raspbianのbtrfsルートファイルシステム


11

ルートパーティションとしてbtrfsを使用して、停電時にファイルの破損がどのように処理されるかを確認すると思います。しかし、起動できません。

私がしたこと:

  1. 切り替える前のPI:

    apt-get install btrfs-tools 2. Linuxコンピューターから:

    btrfs-convert / dev / sda2

  2. /etc/fstab変更ext4してbtrfs

  3. /cmdline.txt変更ext4してbtrfs

ブートしようとすると、カーネルパニックが発生します。他に何かすべきですか?

回答:


7

btrfsがカーネルモジュールとしてコンパイルされている場合は、起動時にモジュールをロードするinitramfsを作成する必要があります。Raspian(および他のdebian派生物)では、これupdate-initramfsが最も簡単な方法です。

initramfs-toolsがインストールされている場合apt-get、新しいカーネルをインストールすると、update-initramfs自動的にトリガーされます。

sudo apt-get update
sudo apt-get install initramfs-tools

ただし、を使用rpi-updateして新しいカーネルをインストールする場合は、新しいカーネルでupdate-initramfs再起動する前に手動で実行する必要があります。

sudo update-initramfs -u -k <kernel-version>

これにより、initramfsが作成または更新され/boot/initrd.img-<kernel-version>ます。

最後のステップは、それをブート構成に追加することです。次の行をに追加します/boot/config.txt

initramfs initrd.img-<kernel-version> followkernel

initrd-<kernel-version>のファイル名と正確に一致する必要があります/boot

を実行するたびに、これらの手順を繰り返す必要がありますrpi-update


2

私の簡単なテストでは、btrfsサポートがraspbianの外部モジュールとして構築されており、カーネルに直接リンクされていないことが示されています。

つまり、カーネルは、ルートファイルシステムのマウント方法を認識する前に、そのモジュール(ルートファイルシステムに格納されている)をロードできる必要があります。明らかに、これは機能しません。

アプローチ1:

独自のカーネルをビルドし、ビルド構成を調整してbtrfsを事前にリンクします。独自のカーネルを構築してロードする方法を理解していれば、設定の調整は簡単です。

アプローチ2:

カーネルとモジュールがext4ファイルシステムにあり、最も圧縮したいデータがbtrfsパーティションにあるように、再調整してください。

アプローチ2A:

ルートパーティションをext4のままにして、btrfsベースの新しいパーティションを作成しますが、それがOSインストールの縮小に役立ちません(それが目的の場合)。

アプローチ2B:

小さなブートパーティションを作成し、カーネルとモジュールを保持し、その他はすべてbtrfsに残します。私はこれをPiのブートローダーでどのように行うのか、またはこれに関する制限は何なのかわかりません。


btrfsモジュールをブートパーティションにコピーし、事前にそこからロードするのはどうですか?
GuySoft 2013

3
initrd.imgから始めることもできませんか?
アンデルス2013

はい、initrd.imgはそれを解決する最も簡単な方法のように見えます!私はそれを使用したことがありません。「mkinitrd」でドキュメントを探してください。
DonGar 2013

最新のRaspbianではCONFIG_BLK_DEV_INITRDが有効になっていないようです。つまり、initdサポートを有効にするには、カーネルを再コンパイルする必要があります。
GuySoft 2013

1
paxswill.com/blog/2013/11/04/encrypted-raspberry-piを参照してください-暗号化されたルートを許可するためにinitramfsが使用されています。同様に、rootが利用可能になる前に、cryptsetup(ここではbtrfs)のサポートが必要です。
Rbjz 2014

1

外部BTRFSルートパーティションを見つけるために、ブートパーティションのルートパーティションのUUIDを明示的に指定する必要がありましたcmdline.txt。例えば:

dwc_otg.lpm_enable = 0 console = tty1 root = PARTUUID = 123e4567-e89b-12d3-a456-426655440000 rootfstype = btrfsエレベーター=デッドラインrootwait静かなスプラッシュ

BTRFSパーティションのUUIDは、を使用して確認できlsblk -fます。


1

Raspbianカーネルにはbtrfsデフォルトでサポートが含まれていません。最初の起動段階は正常に実行されますが、カーネルが読み込まれると、マウントできるファイルシステムが表示されず、パニックが発生します。解決策があります:initramfsで、カーネルモジュールとしてbtrfsを追加します。主に3つの 異なる 記事のおかげで、次のように設定しました。

  • 必要なパッケージをインストールします-カーネルモジュールとそれでinitramfsを更新するツール: sudo apt install btrfs-tools initramfs-tools
  • initramfsにbtrfsモジュールをロードするように指示します(何らかの理由でRPi1では機能しなかったため、自動的に発生するはずです)-必要なモジュールのリストに「btrfs」の行を追加します。 echo 'btrfs' | sudo tee -a /etc/initramfs-tools/modules
  • btrfsのinitramfsフック(イメージの構築用)とスクリプト(起動用)を作成します-デフォルトが提供されていますが、私のテストでは、自動的に使用されず、/ etcにコピーする必要がありました。 sudo mkdir -p /etc/initramfs-tools/hooks ; sudo mkdir -p /etc/initramfs-tools/scripts/local-premount ; sudo cp /usr/share/initramfs-tools/hooks/btrfs /etc/initramfs-tools/hooks ; sudo cp /usr/share/initramfs-tools/scripts/local-premount/btrfs /etc/initramfs-tools/scripts/local-premount; sudo chmod +x /etc/initramfs-tools/hooks/btrfs /etc/initramfs-tools/scripts/local-premount/btrfs
  • -c現在のカーネルバージョン(uname -r)の新しいinitramfsを作成()します-既存のものを更新する場合は、-u代わりにupdate()を使用する必要があります。これにより、/ boot / initrd.img- *のような名前のファイルが作成されます。*は現在のカーネルバージョンです。生成された名前に注意してください(スクリプトが出力します)。次のステップで使用します。update-initramfs -c -k $(uname -r)
  • /boot/config.txtこのinitramfsを使用するように編集し、追加しinitramfs initrd.img-3.11.0+ followkernelます。ファイル名はパスなしで、前のステップで生成されたものです。「followkernel」はメモリ内の場所を制御します(config.txtドキュメント)。
  • これで現在のカーネルは解決されますが、@ Ingoが指摘したように、カーネルをアップグレードするとシステムが壊れます。これを修正するために、私は彼のカーネルインストールフックスクリプトを使用しました

    • / etc / default / raspberrypi-kernelを編集してコメントを外します INITRD=Yes
    • 削除する /etc/kernel/postinst.d/initramfs-tools
    • 追加RPI-initramfs-toolsで /etc/kernel/postinst.d/にし、chmod +xそれ
    • オプションで、initramfsのより簡単な手動更新のためにupdate-rpi-initramfsをダウンロードします。
  • この時点で、ルートデバイスとしてbtrfsを使用できるシステムがあります。再起動してテストします。システムは引き続きext4パーティション(または/boot/cmdline.txtにあるもの)から起動しますが、dmesg | grep -i btrfs「Btrfsが読み込まれた」という行が表示されるはずです。次に、実際にbtrfsパーティションを作成して使用する必要があります。

  • /(ext4)パーティションのバックアップを作成します-これが/ dev / mmcblk0p2であると仮定します-通常:RPiをシャットダウンし、SDカードを取り出し、別の場所(この例sudo mount /dev/mmcblk0p2 /mntではLinuxコンピューター)にマウントして、内容をアーカイブします。所有権とパーミッションを保持するツール、たとえばtar:を使用する必要があることに注意してくださいcd /mnt; sudo tar -czvf ~/rpi-rootfs-backup.tgz *(その後、SDカードを再度マウント解除します)

  • btrfsパーティションをどこかに作成します-SDカードを再利用し、ext4パーティション(/ dev / mmcblk0p2)を置き換えました。btrfs-raid配列を作成しようとしている場合、これはこれを行うときです(これはmkfs.btrfsの引数の1つであり、この回答の範囲を超えています):mkfs.btrfs /dev/mmcblk0p2
  • btrfsパーティションをマウントし、それにバックアップを復元します。 sudo partprobe; sudo mount /dev/mmcblk0p2 /mnt; cd /mnt; tar -xzvf ~/rpi-rootfs-backup.tgz
  • btrfsパーティションの fstab 編集します。sudo nano /mnt/etc/fstab

次のような行があるはずです。

/dev/mmcblk0p2  / ext4 foo,bar,baz 0 1

これを次のように変更します(新しいFSタイプはbtrfsで、デフォルトのオプションを使用します):

/dev/mmcblk0p2  / btrfs defaults 0 1
  • パーティションをアンマウントしますが、SDカードはまだ取り外さないでください。 sudo umount /mnt
  • RPiにbtrfsから起動することを伝える必要があります
  • 新しいbtrfsパーティションのUUIDを見つけます。/dev/mmcblk0p2の行を見つけて、UUID =の部分を(UUID_SUBではなく、PARTUUIDではなく)コピーします。これにより、ブートローダーのバグがトリガーされ、カーネルが起動しません。。):sudo blkid

    / dev / mmcblk0p2:UUID = "cafebeef-0000-1234-aaaa-12346589" UUID_SUB = "ababccdd-2345-cafe-beee-587989991110" TYPE = "btrfs" PARTUUID = "beef0bee-02"

  • ブート(FAT32)パーティションをマウントします。 sudo mount /dev/mmcblk0p1 /mnt

  • cmdline.txtを編集します。 sudo nano /mnt/cmdline.txt

これら2つのパラメーターを見つける

 root=PARTUUID=1234-5678 rootfstype=ext4

と置き換えます

 root=UUID=cafebeef-0000-1234-aaaa-12346589 rootfstype=btrfs

UUIDは引用符なしで先ほどコピーしたものであることに注意してください。

  • RPiブートパーティションをアンマウントします。 sudo umount /mnt
  • SDカードをRPiに交換し、起動します。
  • RPiで、実際にbtrfsルートマウントから実行していることを確認します。 mount

    / dev / mmcblk0p2 /タイプbtrfs(rw、space_cache、subvol = /)

  • エボラ!ポイントアンドクリックではありませんが、巨人の肩の上に立つことで、それを機能させることができました。(これもレポにしました。)


1
最初のsudo apt upgrade場合、カーネルもアップグレードすると、新しいカーネルは古いinitramfsをロードしようとして失敗し、カーネルがbtrfsドライバーをロードできないため、このセットアップは起動時に劇的に失敗します。そして、少なくともchrootarmhfシステムでは、簡単に修正することはできません。
インゴ

カーネルのアップグレード時にupdate-initramfsが呼び出されませんか?
Piskvorが建物を去る

1
いいえ、デフォルトのRaspbianは新しいinitramfsの生成に失敗します。このために構成されていません。apt upgrade新しいカーネルを起動する前に、何をしているのかを常に監視し、必要に応じて手動でinitramfsを生成する必要があります。失敗することは劇的であるため、初心者にとって実行可能なタスクではありません。Raspberry Piの起動時にinit ramdisk(initramfs)を使用するに
インゴ

1
私が見つけた小さなバグがありますが、今のところ修正されていません。カーネルは、4.14.98+となどの2つのモデルをサポートしています4.14.98-v7+。カーネルの更新によってupdate-initramfsがトリガーされると、モデルごとに1つずつ、合計2つのinitrd.img *が生成されます。これは/bootパーティションに適合せず(エラー-スペース不足)、生成は完了しません。
インゴ

1
使用を検討していますMODULES=list
インゴ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.