Копирование glibc из initrd в мою корневую файловую систему
Я пытаюсь установить glibc 2.20 (собранный недавно) в Debian, используя это руководство из FAQ, на которое есть ссылки на этой странице (вопрос в FAQ: Как установить все библиотеки проекта библиотеки GNU C, которые я только что создал?):
Единственный педантично правильный способ установки этих библиотек - выполнить make install INSTALLDIR=/tmp/glibc, которая установит библиотеки в / tmp / glibc, после чего вы скопируете этот каталог в исходный корневой диск, загрузите исходный корневой диск, и скопируйте результаты в корневую файловую систему, а затем выполните поворот в корневую файловую систему в качестве последнего шага загрузки. Это единственный безопасный способ установки glibc на сегодняшний день.
Мне удалось скопировать этот свежий каталог glibc (который содержит продукт make install
) в распакованную копию initrd (которая загружается по умолчанию), сожмите ее обратно и успешно загрузитесь после указания этого нового initrd в GRUB путем редактирования командной строки.
Может кто-нибудь сказать мне, как и где я должен скопировать этот glibc в мою корневую файловую систему (чтобы сделать его основной библиотекой C в системе вместо текущей (по умолчанию))?
1 ответ
Ваш вопрос ("как и где я должен скопировать этот glibc в мою корневую файловую систему") допускает несколько ответов, причем тот, который упоминается в FAQ, является вопросом с минимальными требованиями (хотя и не самым простым, IMHO).
То, что они предлагают, после того, как вы загрузили ядро с монтированием root для вашего нового initrd (и, следовательно, заканчиваете приглашением типа '(initramfs)'), это монтирование вашей реальной системы где-то ниже вашей файловой системы. Предположим, ваша настоящая root-файловая система находится в /dev/sda1, что-то вроде:
(initramfs) mkdir /new_root
(initramfs) mount /dev/sda1 /new_root
После этого у вас будет:
- /lib => содержитновые библиотеки, которые вы сами скомпилировали и упаковали в INITRD, который вы использовали для загрузки и монтирования root;
- /new_root/lib => содержитстарые библиотеки, все еще присутствующие на вашем жестком диске, в вашей (не запущенной) реальной системе;
(Кстати: вы могли бы также иметь структуру lib64 помимо упомянутой/lib, в зависимости от вашей архитектуры. Пожалуйста, примените некоторые проверки здравого смысла и здравомыслия перед применением того, что я пишу)
На этом этапе у вас уже есть все, что нужно для копирования содержимого из /lib в /new_root/lib, а затем просто отключите / new_root и перезагрузите компьютер.
Так почему же они предлагают такую "магию" с pivot_root и тому подобным?
ИМХО, они предполагают в FAQ, что вы хотите ограничить количество перезагрузок до минимума. Одна перезагрузка неизбежна (для загрузки из INITRD). Затем вы можете смонтировать корневой раздел, скопировать библиотеки и... сказать системе продолжить загрузку в обычном режиме, указывая на (новую) корневую файловую систему, которую вы только что смонтировали со своего жесткого диска. Здесь ключевым моментом является то, что "корневая точка монтирования" (другими словами, папка "/") должна быть заменена на ту, что относится к образу INITRD, на ту, что относится к вашей реальной системе (/dev/ раздел sda1, смонтированный в / new_root в файловой системе INITRD).
Есть несколько инструментов, способных "сменить root", на pivot_root есть ссылки в FAQ. Здесь вы можете найти обсуждение использования pivot_root для переключения между двумя установками Linux. Это идеально подходит для вашего случая, так как две системы - начальная INITRD и реальная система на вашем диске.
Здесь вы можете найти некоторую информацию (и ссылки), сравнивающую pivot_root с switch_root.
Прежде чем опубликовать этот ответ, я прошел некоторый тест pivot_root: к сожалению, я был неспособен pivot_root, заканчиваясь различными ошибками (кстати, я здесь не один).
Из-за вышеперечисленных проблем я пришел к выводу, что "вторая перезагрузка" не является проблемой и облегчает весь процесс.
Что касается других подходов, также возможно (... и даже намного проще) просто загрузить linux-box с Live-CD (например, SystemRescueCD) и:
- вручную извлекать (новые) библиотеки из INITRD;
- замените (старые) в вашей системе вышеупомянутыми.
Очевидно, чтобы получить доступ к вашему INITRD, а также к вашей реальной системе, вам необходимо "смонтировать" ваши разделы где-нибудь в файловой системе live-cd (так же, как описано выше).
Что касается процесса извлечения, давайте предположим, что ваш initrd является /mnt/initrd.img-3.2.0-58-generic. Давайте проверим, что это сжато:
damiano@tablet:/$ file /mnt/initrd.img-3.2.0-58-generic
/mnt/initrd.img-3.2.0-58-generic: gzip compressed data, from Unix, last modified: Wed Jan 8 11:54:03 2014
Не будем его распаковывать, чтобы лучше проверить его содержимое (мы будем работать в каталоге /tmp/libs):
damiano@tablet:/$ mkdir /tmp/libs
damiano@tablet:/$ cd /tmp/libs
damiano@tablet:/tmp/libs$ gzip -dc /mnt/initrd.img-3.2.0-58-generic > init_uncompressed
damiano@tablet:/tmp/libs$
Теперь давайте проверим, что находится в несжатом файле:
damiano@tablet:/tmp/libs$ file init_uncompressed
init_uncompressed: ASCII cpio archive (SVR4 with no CRC)
Хорошо. Итак, теперь у нас есть архив cpio. Извлечь его содержание так же просто, как:
damiano@tablet:/tmp/libs$ cpio -i < init_uncompressed
109835 blocchi
Теперь, наконец, у нас есть все, включая ваши библиотеки:
damiano@tablet:/tmp/libs$ ls -l
totale 54968
drwxr-xr-x 2 verzulli verzulli 4096 dic 31 14:42 bin
drwxr-xr-x 3 verzulli verzulli 4096 dic 31 14:42 conf
drwxr-xr-x 8 verzulli verzulli 4096 dic 31 14:42 etc
-rwxr-xr-x 1 verzulli verzulli 7230 dic 31 14:42 init
-rw-rw-r-- 1 verzulli verzulli 56235520 dic 31 14:38 init_uncompressed
drwxr-xr-x 9 verzulli verzulli 4096 dic 31 14:42 lib
drwxr-xr-x 2 verzulli verzulli 4096 dic 31 14:42 lib64
drwxr-xr-x 2 verzulli verzulli 4096 dic 31 14:42 run
drwxr-xr-x 2 verzulli verzulli 4096 dic 31 14:42 sbin
drwxr-xr-x 10 verzulli verzulli 4096 dic 31 14:42 scripts
drwxr-xr-x 4 verzulli verzulli 4096 dic 31 14:42 usr
На этом этапе вы можете просто скопировать папку lib (и lib64) из /tmp/libs в /mnt (при условии, что ваши корневые разделы -/dev/sda1-- смонтированы в /mnt) и затем перезагрузиться.
Последнее (очень личное) замечание: сказав все вышесказанное, позвольте мне добавить, что... хотя в FAQ четко сказано, что полагаться на менеджеры пакетов при обновлении системных библиотек опасно, я лично считаю, что вручную иметь дело с системными библиотеки сами по себе... это, безусловно, более опасно:-)
Так что, пожалуйста, не вините меня, если вы работаете в не загружаемой системе;-)
Обновление 1:
Что касается "кактолько вы загрузили ядро, монтируя новый initrd", вы можете выполнить следующее:
- В меню grub выберите запись, которую вы обычно запускаете, и нажмите "E" ("Правка"). (Кстати: если у вас нет меню grub, то этот вопрос и / или другие онлайн-поиски могут помочь). Вы попадете на экран, похожий на этот:
Обратите внимание на строку, относящуюся к ядру. На такой строке вы найдете:
- ссылка на ядро (в моем примере vmlinux-3.8.0-19-generic);
- ссылка на устройство, используемое для монтирования корневой файловой системы (root=/dev/mapper/kubuntu- vg-root в моем примере);
другие параметры загрузки ( ro quiet splace $vt_handoff)
- так как вы хотите смонтировать root initrd файл, который вы подготовили (... содержащий ваш обновленный glibc; не общее устройство /hard_drive/partition), вам нужно отредактировать строку выше, заменив ссылку на параметр "root=", как в:
Обратите внимание, что я использовал root=/initrd.img-3.8.0-19-generic, в то время как вы должны ссылаться на ваш конкретный файл initrd
- После того, как вы правильно определили параметр "root=", просто нажмите F10. Через несколько секунд вы должны получить приглашение (initramfs), как в:
Теперь у вашего "/" есть папка /lib с библиотеками, которые вы скомпилировали... и упаковали в INITRD.