Копирование glibc из initrd в мою корневую файловую систему

732
user3900460

Я пытаюсь установить glibc 2.20 (недавно собранный) в Debian, используя это руководство из FAQ, на которое есть ссылки на этой странице (вопрос в FAQ: Как установить все библиотеки проектов библиотеки GNU C, которые я только что создал? ):

Единственный педантично правильный способ установки этих библиотек - выполнить make install INSTALLDIR = / tmp / glibc, которая установит библиотеки в / tmp / glibc, после чего вы скопируете этот каталог в исходный корневой диск, загрузите исходный корневой диск, и скопируйте результаты в корневую файловую систему, а затем выполните поворот в корневую файловую систему в качестве последнего шага загрузки. Это единственный безопасный способ установки glibc на сегодняшний день.

Мне удалось скопировать этот свежий каталог glibc (который содержит продукт make install) в распакованную копию initrd (которая загружается по умолчанию), сжать ее обратно и успешно загрузиться после указания этого нового initrd в GRUB путем редактирования командной строки.

Может кто-нибудь сказать мне, как и где я должен скопировать этот glibc в мою корневую файловую систему (чтобы сделать его основной библиотекой C в системе вместо текущей (по умолчанию))?

0

1 ответ на вопрос

1
Damiano Verzulli

Your question ("how and where should I copy this glibc to my root filesystem") admits several answers, with the one mentioned in the FAQ being the one with minimum requirements (although not the simplest at all, IMHO).

What they are suggesting, once you've booted your kernel root-mounting your new initrd (and, hence, ending in a prompt like '(initramfs)' is to mount your real system somewhere below your filesystem. Supposing your real root-filesystem resides in /dev/sda1, something like:

 (initramfs) mkdir /new_root (initramfs) mount /dev/sda1 /new_root 

After this, you will have:

  • /lib => contains the new libraries you've compiled yourself and packed within the INITRD you've used to boot and root-mount;
  • /new_root/lib => contains the old libraries still present on your hard drive, within your (not-running) real system;

(BTW: you could also have a lib64 structure aside the mentioned /lib, depending on your architecture. Please apply some common sense and sanity checks before applying what I'm writing)

At this stage, you already have all it's needed to copy the content from /lib to /new_root/lib and then simply umount /new_root and reboot.

So why they're suggesting such "magic" with pivot_root and the like?

IMHO, what they're assuming, in the FAQ, is that you want to limit the number of reboot to the minimum. One reboot is unavoidable (to boot from INITRD). Then you can mount the root-partition, copy the libraries and.... tell the system to continue booting as normal, pointing to the (new) root-file-system that you just mounted from your hard-drive. Here, the key-point is that the "root mount point" (the "/" folder, in other words) need to be replaced from the one related to the INITRD image, to the one related to your real system (/dev/sda1 partition mounted to /new_root under the INITRD filesystem).

There are several tools being able to "change root", with pivot_root being referenced in the FAQ. Here you can find a discussion about using pivot_root to switch among two linux installations. It's perfectly suitable to your case, as the two systems are the INITRD initial one and the real system on your disk.

Here you can find some information (and links) comparing pivot_root to switch_root.

Before posting this answer, I've run through some pivot_root test: unfortunatly I have been UNABLE to pivot_root, ending in various errors (BTW: it seems I'm not alone here).

Due to problems above, I've got to the conclusion that a "second reboot" is not a problem and easy the whole process.

As for other approaches, it's also possible (...and even much easier) to simply boot your linux-box with a Live-CD (like SystemRescueCD) and:

  • manually extract the (new) libraries from the INITRD;
  • replace the (old) ones in your system with aboves.

Obviously, to get access to your INITRD as well as your real system, you need to "mount" your partitions somewhere within the file-system of the live-cd (in the same way as discussed above).

As for the extraction process, let's assume your initrd is /mnt/initrd.img-3.2.0-58-generic. Let's check it's compressed:

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 

Not let's decompress it, to better check its content (we'll work in /tmp/libs directory):

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$ 

Now let's check what's in the uncompressed file:

damiano@tablet:/tmp/libs$ file init_uncompressed init_uncompressed: ASCII cpio archive (SVR4 with no CRC) 

Ok. So now we have a cpio archive. Extracting its content is as simple as:

damiano@tablet:/tmp/libs$ cpio -i < init_uncompressed 109835 blocchi 

Now, finally, we have everything extracted, included your libs:

 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 

At this point, you can simply copy the lib (and lib64) folder from /tmp/libs to /mnt (assuming your root partitions --/dev/sda1-- is mounted under /mnt) and then reboot.


A final (very personal) note: Having said all the above, let me add that... even though the FAQ clearly states that relying on package-managers to update system-libraries is dangerous, I personally believe that manually dealing with system-libraries on my own... it's surely more dangerous :-)

So, please, don't blame me should you run in an unbootable system ;-)


Update 1:

As for "once you've booted your kernel root-mounting your new initrd", you can proceed this way:

  1. At grub menu, select the entry you usually run and press "E" (Edit). (BTW: if you don't have a grub-menu, than this question and/or other on-line searches can help). You'll get to a screen similar to this:

enter image description here

Please note the line related to the kernel. On such line you find:

  • reference to to kernel (vmlinux-3.8.0-19-generic in my example);
  • reference to device to use to mount the root-filesystem (root=/dev/mapper/kubuntu--vg-root in my example);
  • other boot parameters ( ro quiet splace $vt_handoff )

    1. as you want to root-mount the initrd file you preparared (...containing your updated glibc; and not the common device/hard_drive/partition) you need to edit above line, replacing the reference to the "root=" parameter, as in:

enter image description here

Please note that I used root=/initrd.img-3.8.0-19-generic while you should link to your specific initrd file

  1. once you have properly defined your "root=" parameter, than simply press F10. After few seconds, you should get to the (initramfs) prompt, as in:

enter image description here

Now your "/" has a /lib folder with the libraries you compiled... and packed within the INITRD.


Большое спасибо за этот ответ. Вы пишете: «Вы загрузили ядро, монтируя root на свой новый initrd (и, следовательно, заканчивая приглашением типа« (initramfs) »). Не могли бы вы сказать, что мне следует сделать, чтобы получить приглашение типа (initramfs)? user3900460 9 лет назад 0
Должен ли я использовать какой-то минимальный initrd вместо моей копии initrd по умолчанию для переноса свежего glibc? Или может быть (initramfs) приглашение доступно после редактирования командной строки в меню GRUB при загрузке? user3900460 9 лет назад 0
Я только обновил свой ответ, чтобы объяснить, как загрузить root-mount для вашего initrd. Damiano Verzulli 9 лет назад 0
Во-первых, я высоко ценю ваши усилия. Они действительно вдохновили меня, хотя я не мог получить загрузочную систему после копирования этих каталогов. Кстати, в моем случае `make install` не генерирует каталог` lib`. Каталогами являются `etc`,` lib64`, `sbin`,` usr` и `var`. Лучшее, чего я достиг на данный момент, - это загрузка живого (спасительного) образа Debian, затем получение корневой оболочки, монтирование моей целевой файловой системы, выполнение `pivot_root`,` chroot. bash`, а затем `make install` в каталоге сборки. Проблема здесь в несоответствии версий ядра, так как я собираю glibc для более нового ядра, чем в живом образе. user3900460 9 лет назад 0
Наконец, он возвращается с `FATAL: ядро ​​слишком старое`, но сам glibc успешно обновляется (проверено` ldd --version`). Хотя `getconf -a` не работает ... user3900460 9 лет назад 0
Возможно, последним вызовом на этом пути является обновление ядра в этом живом (спасательном) образе Debian, чтобы позволить `make install` работать как надо ... user3900460 9 лет назад 0

Похожие вопросы