Почему я не могу указать свой root fs с UUID?

29

Моя система загружается нормально с этим в моей конфигурации GRUB 2:

linux   /bzImage root=/dev/sda2 init=/usr/lib/systemd/systemd ro

Но если я заменю /dev/sda2на соответствующий UUID:

linux   /bzImage root=UUID=666c2eee-193d-42db-a490-4c444342bd4e init=/usr/lib/systemd/systemd ro

тогда это терпит неудачу во время загрузки:

kernel panic - not syncing: VFS: unable to mount root fs on unknown-block(0,0)

UUID кажется правильным:

# blkid
/dev/sda1: UUID="97ac3744-39de-4d6d-9a81-e3a3ea08a8bb" TYPE="ext2" 
/dev/sda2: UUID="666c2eee-193d-42db-a490-4c444342bd4e" TYPE="ext4" 

Почему это не работает? Это потому, что я не использую initramfs?

Это x86_64 Gentoo Linux с ядром 3.10.7. Я использую таблицу разделов MBR и таблицу sdaразделов GUID sdb.

CJM
источник
unknown-block(0,0)выглядит как устройство GRUB для меня. я предполагаю, что GRUB по какой-то причине не может использовать этот UUID.
Струджи
@strugee, я не думаю, что GRUB вообще пытается интерпретировать командную строку ядра. (GRUB загружает ядро ​​из sda1. Я не показывал эту часть конфига.)
cjm
Я склонен согласиться. странно, однако, что устройство выглядит как устройство GRUB вместо устройства UNIX.
Струджи
@ Жиль, вопрос не в GRUB. Это просто тот загрузчик, который я использую. Это вопрос ядра Linux.
CJM
Это не вопрос о ядре - это вопрос init.
mikeserv

Ответы:

22

Просто чтобы уточнить UUIDs - единственный надежный способ для ядра идентифицировать жесткие диски. Существует два типа: UUID, который хранится в файловой системе и недоступен ядру во время загрузки, и PARTUUID, который хранится в таблице разделов и доступен во время загрузки. Так что вы должны использовать

root=PARTUUID=SSSSSSSS-PP

как /dev/sd??может измениться с устройствами, подключенными / отключенными.

Не забудьте извлечь выгоду шестнадцатеричного числа SSSSSSSS-PPвы получаете от blkid!

Чем проще в использовании

root=LABEL=
root=UUID=

работать только с тем, initramfsкоторый выбирает эти идентификаторы.

Так что, если вы используете непустой initramfs, вы можете иметь все три! С пустым у initramfsвас только есть PARTUUID.

ineiti
источник
Не могли бы вы объяснить, кто использует аргумент boot =? Я просто использовал эту строку для установки Archlinuxarm, в которой нет initrd, и где я не могу использовать ни boot = LABEL, ни boot = UUID.
ineiti
1
Вы правы - я поправил загрузчик в root, извините! Надеюсь, теперь это имеет больше смысла.
ineiti
1
Насколько я понимаю (после одного дня на форумах archlinuxarm), в Archlinuxarm нет initrd (или initramfs, но kernel.org/doc/Documentation/kernel-parameters.txt называет его initrd). На Ubuntu и тому подобном я даю указатель на initrd, но (насколько я понимаю) не на Archlinuxarm.
ineiti
1
Archlinuxarm обсуждение NO initrd: archlinuxarm.org/forum/viewtopic.php?f=23&t=6652
ineiti
1
Попробуйте эту ссылку. И этот . И, возможно, этот . initramfs не является образом initramfs - обычно это сжатый архив, содержащий cpioархив, который распаковывается ядром /при загрузке. initramfs - это файловая система - она ​​всегда /монтируется первой и откуда ядро ​​вызывает init. Вы можете скомпилировать содержимое в ядро ​​или распаковать его при загрузке - это два варианта.
mikeserv
16

Параметр , который вы должны перейти к загрузке с UUID это PARTUUID. Так и должно быть root=PARTUUID=666c2eee-193d-42db-a490-4c444342bd4e.

Документация объясняет, почему он возвращается с unknown-block(0,0):

kernel-parameters.txt :

    root = [KNL] Root файловая система
            Смотрите name_to_dev_t комментарий в init / do_mounts.c.

init / do_mounts.c :

/ *
 * Преобразование имени в номер устройства. Мы принимаем следующие варианты:
 *
 * 1) номер устройства в шестнадцатеричном формате представляет себя
 * 2) / dev / nfs представляет Root_NFS (0xff)
 * 3) / dev / <имя_диска> представляет номер устройства диска
 * 4) / dev / <имя_диска> <десятичное число> представляет номер устройства
 * of partition - номер устройства диска плюс номер раздела
 * 5) / dev / <имя_диска> p <десятичное число> - то же, что и выше, эта форма
 * используется, когда имя диска с разделенным диском заканчивается цифрой.
 * 6) PARTUUID = 00112233-4455-6677-8899-AABBCCDDEEFF, представляющий
 * уникальный идентификатор раздела, если таблица разделов предоставляет его.
 * UUID может быть либо EFI / GPT UUID, либо относиться к MSDOS
 * раздел с использованием формата SSSSSSSS-PP, где SSSSSSSS - это ноль
 * заполнено шестнадцатеричное представление 32-битной «NT подписи диска» и PP
 * - заполненное нулями шестнадцатеричное представление номера раздела на основе 1.
 * 7) PARTUUID = <UUID> / PARTNROFF = <int>, чтобы выбрать раздел по отношению к
 * раздел с известным уникальным идентификатором.
 *
 * Если имя не попало в вышеприведенные категории, мы возвращаем (0,0).
 * block_class используется, чтобы проверить, является ли что-то имя диска. Если диск
 * имя содержит косые черты, имя устройства заменено на
 * челка.
 * /

Последний бит в конце говорит, что если он не может понять значение, он возвращает (0,0), следовательно, ваша ошибка.

Патрик
источник
1
Это только частично правильно. UUID раздела полностью отличается от UUID файловой системы, поэтому PARTUUID=666c2eee-193d-42db-a490-4c444342bd4eне работает. Однако я смог использовать PARTUUID=SSSSSSSS-02(где SSSSSSSS - это подпись диска NT, отображаемая непосредственно перед сообщением об ошибке).
CJM
6
Поэтому я думаю, что реальный ответ заключается в том, что ядро ​​не поддерживает root=UUIDтолько root=PARTUUID. Если вы хотите использовать UUID файловой системы, я думаю, вам нужен initramfs, который может обрабатывать монтирование файловых систем с помощью UUID.
CJM
@ CJM мои grubботинки вполне довольны root=UUID.
Тердон
3
@terdon, держу пари, у тебя есть initramfs или initrd. (Он может быть связан с вашим ядром, а не отдельным файлом.)
cjm
4

Это 5-летняя тема. Но все-таки имхо не до конца ответили. Там отсутствует маленький пример. Вот:

В этом примере:

/dev/sda3 = /
/dev/sda2 = swap

... используя раздел GPT. С MBR (дос раздел) партуиды короче, но процедура такая же ...

получить ПАРТЮУИД с помощью blkid:

blkid -s PARTUUID -o value /dev/sda3 # root
77fd7830-faa2-4e99-a48b-337ad9eded28
blkid -s PARTUUID -o value /dev/sda2 # swap
5b63167a-6fd2-4e72-948c-90832372956c

/boot/grub/grub.cfg:

search --no-floppy --part-uuid --set=root 77fd7830-faa2-4e99-a48b-337ad9eded28

menuentry "GNU/Linux, KERNEL 4.12.7-lfs-8.1" {
  linux /boot/vmlinuz-4.12.7-lfs-8.1 root=PARTUUID=77fd7830-faa2-4e99-a48b-337ad9eded28 net.ifnames=0 ipv6.disable=1 ro rootwait rootfstype=ext4
}

/ И т.д. / Fstab /:

PARTUUID=77fd7830-faa2-4e99-a48b-337ad9eded28 / ext4 noatime,nodiratime,errors=remount-ro 0 1
PARTUUID=5b63167a-6fd2-4e72-948c-90832372956c swap swap pri=1 0 0

Известно, что это работает с lfs8.1 (ядро 4.12.7), но я думаю, что оно должно работать и с большинством других ядер (старые и новые ...)

Майкл Х.Г. Шмидт
источник