Arch Linuxは、GPTと3つのパーティションを備えたUSBフラッシュドライブからブートされたUEFIです。
Btrfsパーティションにはサブボリュームがなく、単一のディスク(USBフラッシュメモリドライブ)にあります。
Udevや他の多くのフックを削除して、 minimal initramfs を作成しようとしています。 mkinitcpioを使用したブートアップの最適化 もインスピレーションとして使用されました。
有効なmkinitcpio
フックは次のとおりです: base 、 autodetect および modconf 。
mkinitcpio
hooks documentation btrfsフックのリストであるため、btrfsフックは有効になっていません:
このフックは、単一のデバイスでBtrfsを使用する場合には必要ありません。
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.debug
およびrd.log
を有効にすると、「premount」が resolve_device 関数を呼び出し、空のルックアップを返すことが示されます。
resolve_device PARTUUID=c2...c13
local major minor dev tag device=PARTUUID=c2...c13
blkid -lt PARTUUID=c2...c13 -o device
dev=
最後の空の開発により、デバイスが見つかりませんというエラーが発生しています。
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
[rootfs ]# mount -V
mount from util-linux 2.29.2 (libmount 2.29.2: btrfs, assert, debug)
$ 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
コマンドは、正しい(PART)UUID値をリストします。 /dev/disk/
がないため、(PART)UUIDを使用したマウントが失敗する可能性がありますか?
UdevなしでUSBフラッシュドライブにある非RAIDの非サブボリュームのシングルドライブルートbtrfsパーティションを起動するには何が必要ですか?
PSこのエラーは、initramfs/init
がmount ... UUID=...
コマンドを実行したときにUUID/PARTUUIDがまだ使用できないというRACE状態が原因である可能性があります。
バージョン23では、 mkinitcpio resolve_device()関数 は1回だけ呼び出されます。実行時にドライブラベルがまだ読み取られていない場合、 blkid
は、要求されたラベルのカーネルドライブ(/dev/...
)名を検索できません。
以下に示すように、「without-udev」フックを追加することにより、resolve_device関数は変更されません。標準で利用可能なmkinitcpio機能が mount_handlerをオーバーライドするadd run_hookを使用して、blkid
が値を返すか、(タイムアウト)10秒が経過するまでポーリングします。したがって、「udev」フックはmkinitcpioconfigから削除できます。
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: