udevフックなしで最小initramfsを使用してルートbtrfsファイルシステムから起動するにはどうすればよいですか?

udevフックなしで最小initramfsを使用してルートbtrfsファイルシステムから起動するにはどうすればよいですか?

Arch Linuxは、GPTと3つのパーティションを備えたUSBフラッシュドライブからUEFIブートが可能です。

  1. EFI (vfat ファイルシステム)
  2. root(btrfsファイルシステム、ext4から変換)
  3. ホーム(btrfsファイルシステム、ext4から変換)

btrfsパーティションにはサブボリュームはなく、単一のディスク(USBフラッシュドライブ)にあります。ここではLVMは使用されません。

仕事

作成しようとしています最小initramfsudevと他のいくつかのフックを削除します。mkinitcpioを使用した起動の最適化インスピレーションとしても使用されます。
有効なmkinitcpioフックは次のとおりです。~によると自動検出そして構成ファイルの変更

BTRFSフック

btrfs フックが有効になっていません。mkinitcpioフック文書化btrfsフックリスト:

単一のデバイスでBtrfsを使用している場合は、このフックは必要ありません。

返品

  1. udev - >起動エラーを削除してみました。
  2. btrfsモジュールを追加しようとしています - >起動エラー
  3. btrfsフックを追加しました - >起動エラー
  4. root = PARTUUID = root = UUID =シンボルに変更 - >開始エラー
  5. パラメータrootfstype = btrfs追加 - >起動エラー
  6. rootdelay=0 -> 起動エラー
  7. rootdelay=10 -> 起動エラー
  8. 緊急シェルで/dev/sda2を使用してマウント - >チェック

間違い

udevまたはsystemdフックを挿入した後にのみ、システムルートがbtrfsルートパーティションに接続されます。それ以外の場合は、次のエラーが発生します。

ERROR: device 'PARTUUID=c2...c13' not found. Skipping fsck.
:: mounting 'PARTUUID=c2...c13' on real root 
mount: can't find 'PARTUUID=c2...c13'
You are now being dropped into an emergency shell.

ランタイム初期化デバッグ/ロギング出力

起動パラメータを有効にし、rd.debugrd.logプレマウント」呼び出しを表示します。分析装置関数を実行し、空の検索を返します。

resolve_device PARTUUID=c2...c13
local major minor dev tag device=PARTUUID=c2...c13
blkid -lt PARTUUID=c2...c13 -o device
dev=

最後の空の開発でデバイスが見つかりませんでしたエラーが発生しました。

initramfs マウントコマンド

mount_handler=default_mount_handler
...
# Mount root at /new_root
"$mount_handler" /new_root

源泉:https://git.archlinux.org/mkinitcpio.git/tree/init

default_mount_handler() {
    msg ":: mounting '$root' on real root"
    mount ${rootfstype:+-t $rootfstype} -o ${rwopt:-ro}${rootflags:+,$rootflags} "$root" "$1"

源泉:https://git.archlinux.org/mkinitcpio.git/tree/init_functions#n375

initramfsマウントバージョン

[rootfs ]# mount -V
mount from util-linux 2.29.2 (libmount 2.29.2: btrfs, assert, debug)

initramfsの内容

$ lsinitcpio -a /boot/initramfs-linux-tiny.img
==> Image: /boot/initramfs-linux-tiny.img
==> Created with mkinitcpio 23
==> Kernel: 4.10.3-1-ARCH
==> Size: 3.53 MiB
==> Compressed with: lz4 -l
  -> Uncompressed size: 8.32 MiB (.424 ratio)
  -> Estimated extraction time: 0.028s

==> Included modules:
  ahci [explicit]         hid-generic [explicit]      raid6_pq            usbcore
  atkbd [explicit]        i8042 [explicit]        scsi_mod            usbhid [explicit]
  btrfs [explicit]        libahci             sd_mod [explicit]       xhci-hcd
  crc32c-intel [explicit]     libata              serio               xhci-pci [explicit]
  crc32c_generic          libcrc32c           serio_raw [explicit]        xor
  ehci-hcd            libps2              uas [explicit]
  ehci-pci [explicit]         ohci-hcd            usb-common
  hid                 ohci-pci [explicit]         usb-storage

==> Included binaries:
  blkid       busybox     dosfsck     fsck        fsck.vfat   kmod        mount       switch_root

緊急シェルのblkidコマンドは、正しい(部分的な)UUID値をリストします。 (PART)UUIDがないため、インストールは失敗しますか/dev/disk/

質問

udevなしでUSBフラッシュドライブ上の非RAID非サブボリュームシングルドライブルートbtrfsパーティションから起動するには何が必要ですか?


initramfs/initPSこのエラーは、コマンドの実行時にUUID / PARTUUIDをまだ使用できないRACE条件が原因で発生する可能性がありますmount ... UUID=...

ベストアンサー1

理由

バージョン23ではmkinitcpioresolve_device() 関数一度だけ呼び出されました。実行時にまだドライブラベルを読み取っていない場合blkid/dev/...要求されたラベルのカーネルドライバ()名が見つかりません。

解決策

「without-udev」フック(下に示す)を追加すると、solve_device機能は変更されていません。利用可能な標準 mkinitcpio 関数はmount_handler をオーバーライドできますが、 run_hookを追加blkid値が返されるまで、または(タイムアウト)10秒が経過するまでポーリングに使用されます。したがって、mkinitcpio設定から「udev」フックを削除できます。

ノート

  • このソリューションは、次の助けを借りて作成されました。ファルコニンディ
  • fsckに関連するエラーメッセージは、初期ブート段階で表示されます。そのメッセージを削除するためにudevなしでフックをrun_hook代わりに使用するように書き直しましたmount_handler。新しいコードははるかに短いです。

$ cat /usr/lib/initcpio/hooks/without-udev
#!/bin/ash
# Minimal initramfs files are created without udev.
# This hooks provides a polling disk mount replacement for udev.
# Udev hook can be removed, resulting in smaller initramfs files.

run_hook () {
    local dev timeout sleepval device=$root
    # if udev is running then exit
    [ "$udevd_running" -eq 1 ] && return
    # try for (timeout * sleepval =) 10 seconds to handle slow (USB) devices
    timeout=1000
    sleepval=0.01

    case $device in
        # label to resolve, when resolved the kernel block device also exists
        UUID=*|LABEL=*|PARTUUID=*|PARTLABEL=*)
            while [ $timeout -gt 0 ]; do
                timeout=$((timeout - 1))
                dev=$(blkid -lt "$device" -o device)
                [ -n "$dev" ] && timeout=0 || sleep $sleepval
            done
            ;;
        # kernel named block device, poll for existence
        /dev/*)
            while [ $timeout -gt 0 ]; do
                timeout=$((timeout -1))
                if [ -b "$device" ]; then
                    dev=$device
                    timeout=0
                else
                    sleep $sleepval
                fi
            done
            ;;
    esac
}

# vim:set syntax=sh:

$ cat /usr/lib/initcpio/install/without-udev
#!/bin/bash

build() {
    add_runscript
}

help() {
    cat <<HELPEOF
This hook provides support for booting without the "udev" hook,
including support for UUID, LABEL, PARTUUID, PARTLABEL.
HELPEOF
}

# vim: set ft=sh ts=4 sw=4 et:

おすすめ記事