Kopieren von glibc von initrd in mein Root-Dateisystem

0

Ich versuche, glibc 2.20 (vor kurzem erstellt) unter Verwendung dieser Anleitung aus den auf dieser Seite genannten FAQ auf Debian zu installieren (die Frage in den FAQ lautet: Wie installiere ich alle GNU C Library-Projektbibliotheken, die ich gerade erstellt habe? ):

Die einzige pedantisch korrekte Möglichkeit, diese Bibliotheken zu installieren, besteht darin, eine make install INSTALLDIR = / tmp / glibc auszuführen, mit der die Bibliotheken in / tmp / glibc installiert werden. Anschließend kopieren Sie dieses Verzeichnis auf einen ursprünglichen Root-Datenträger und starten den ursprünglichen Root-Datenträger. Kopieren Sie die Ergebnisse in Ihr Root-Dateisystem und drehen Sie sie anschließend als letzten Schritt des Bootvorgangs in das Root-Dateisystem. Das ist der einzig sichere Weg, glibc heute zu installieren.

Ich habe es geschafft, dieses frische glibc-Verzeichnis (das das Produkt von enthält make install) in eine dekomprimierte Kopie von initrd (die standardmäßig geladen wird) zu kopieren, es zurück zu komprimieren und erfolgreich zu booten, nachdem diese neue initrd in GRUB durch Bearbeiten der Befehlszeile angegeben wurde.

Kann mir jemand sagen, wie und wo ich diese glibc in mein Root-Dateisystem kopieren soll (um sie anstelle der aktuellen (Standard-) Bibliothek zur primären C-Bibliothek im System zu machen)?

user3900460
quelle

Antworten:

2

Ihre Frage (" Wie und wo soll ich diese glibc in mein Root-Dateisystem kopieren? ") Lässt mehrere Antworten zu, wobei die in den FAQ genannte die mit den Mindestanforderungen ist (wenn auch nicht die einfachste überhaupt, IMHO).

Nach dem Booten des Kernels als Root- Mount wird die neue initrd vorgeschlagen (und endet daher mit einer Eingabeaufforderung wie " (initramfs) " , wenn Sie Ihr reales System irgendwo unterhalb Ihres Dateisystems mounten. Angenommen, Sie haben Ihr reales Root-Dateisystem residiert in / dev / sda1, so etwas wie:

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

Danach haben Sie:

  • / lib => enthält die neuen Bibliotheken, die Sie selbst kompiliert und in das INITRD gepackt haben, mit dem Sie gebootet und als Root gemountet haben.
  • / new_root / lib => enthält die alten Bibliotheken, die noch auf Ihrer Festplatte in Ihrem (nicht laufenden) realen System vorhanden sind.

(Übrigens: Abhängig von Ihrer Architektur können Sie neben der erwähnten / lib- Struktur auch eine lib64- Struktur haben. Wenden Sie vor dem Anwenden des, was ich schreibe, einige Überprüfungen auf gesunden Menschenverstand und Vernunft an.)

Zu diesem Zeitpunkt haben Sie bereits alle Voraussetzungen, um den Inhalt von / lib nach / new_root / lib zu kopieren und dann einfach / new_root zu laden und neu zu starten.

Also, warum schlagen sie eine solche "Magie" mit pivot_root und dergleichen vor?

IMHO gehen sie in den FAQ davon aus, dass Sie die Anzahl der Neustarts auf ein Minimum beschränken möchten. Ein Neustart ist unvermeidlich (um von INITRD zu starten). Dann können Sie die Root-Partition mounten, die Bibliotheken kopieren und ... das System anweisen, wie gewohnt weiter zu booten und auf das (neue) Root-Dateisystem zu verweisen, das Sie gerade von Ihrer Festplatte gemountet haben. Der entscheidende Punkt hierbei ist, dass der "Root-Mount-Punkt" (mit anderen Worten der Ordner "/") von dem zum INITRD-Image gehörenden zu dem zu Ihrem realen System gehörenden ersetzt werden muss (/ dev / sda1-Partition in / new_root unter dem Dateisystem INITRD eingehängt).

Es gibt mehrere Tools, die "root" ändern können, wobei pivot_root in den FAQ referenziert wird. Hier finden Sie eine Diskussion über die Verwendung von pivot_root, um zwischen zwei Linux-Installationen zu wechseln. Es ist perfekt für Ihren Fall geeignet, da es sich bei den beiden Systemen um das ursprüngliche INITRD-System und das reale System auf Ihrer Festplatte handelt.

Hier finden Sie einige Informationen (und Links), die pivot_root mit switch_root vergleichen.

Bevor ich diese Antwort poste, habe ich einige pivot_root-Tests durchlaufen: Leider konnte ich pivot_root nicht ausführen, was zu verschiedenen Fehlern führte (Übrigens: Ich bin anscheinend nicht allein hier).

Aufgrund der oben genannten Probleme bin ich zu dem Schluss gekommen, dass ein "zweiter Neustart" kein Problem ist und den gesamten Vorgang vereinfacht.

Wie bei anderen Ansätzen ist es auch möglich (... und noch viel einfacher), Ihre Linux-Box einfach mit einer Live-CD (wie SystemRescueCD ) zu booten und:

  • Manuelles Extrahieren der (neuen) Bibliotheken aus dem INITRD.
  • Ersetzen Sie die (alten) in Ihrem System durch die obigen.

Um auf Ihr INITRD und Ihr reales System zugreifen zu können, müssen Sie Ihre Partitionen natürlich irgendwo im Dateisystem der Live-CD "mounten" (wie oben beschrieben).

Nehmen wir für den Extraktionsprozess an, dass Ihre initrd /mnt/initrd.img-3.2.0-58-generic ist. Lassen Sie uns überprüfen, ob es komprimiert ist:

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

Dekomprimieren wir es nicht, um seinen Inhalt besser zu überprüfen (wir arbeiten im Verzeichnis / 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$

Lassen Sie uns nun überprüfen, was in der unkomprimierten Datei enthalten ist:

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

Okay. Jetzt haben wir also ein cpio-Archiv . Das Extrahieren des Inhalts ist so einfach wie:

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

Jetzt haben wir endlich alles extrahiert, einschließlich Ihrer Bibliotheken:

 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

Zu diesem Zeitpunkt können Sie einfach den Ordner lib (und lib64) von / tmp / libs nach / mnt kopieren (vorausgesetzt, Ihre Root-Partitionen - / dev / sda1 - sind unter / mnt gemountet) und anschließend neu starten.


Ein letzter (sehr persönlicher) Hinweis: Nachdem ich alles oben Genannte gesagt habe, möchte ich hinzufügen, dass ... obwohl die FAQ eindeutig besagt, dass es gefährlich ist , sich auf Paketmanager zu verlassen, um Systembibliotheken zu aktualisieren , ich persönlich glaube, dass der manuelle Umgang mit Systembibliotheken Bibliotheken alleine ... es ist sicher gefährlicher :-)

Also, bitte, beschuldigen Sie mich nicht, wenn Sie in einem nicht bootfähigen System laufen ;-)


Update 1:

Was " Sobald Sie Ihren Kernel als Root gebootet haben und Ihre neue initrd gemountet haben " betrifft , können Sie folgendermaßen vorgehen:

  1. Wählen Sie im Menü grub den Eintrag aus, den Sie normalerweise ausführen, und drücken Sie "E" (Bearbeiten). (Übrigens: Wenn Sie kein Menü haben, können diese Frage und / oder andere Online-Suchanfragen hilfreich sein.) Sie gelangen zu einem Bildschirm ähnlich dem folgenden:

Bildbeschreibung hier eingeben

Bitte beachten Sie die Zeile zum Kernel. In einer solchen Zeile finden Sie:

  • Verweis auf den Kernel (vmlinux-3.8.0-19-generic in meinem Beispiel);
  • Referenz auf das Gerät, das zum Mounten des Root-Dateisystems verwendet werden soll (root = / dev / mapper / kubuntu - vg-root in meinem Beispiel);
  • andere Bootparameter (ro quiet splace $ vt_handoff)

    1. Wenn Sie die von Ihnen vorbereitete initrd-Datei (... mit Ihrer aktualisierten glibc und nicht der gemeinsamen device / hard_drive / partition) als Root-Mount ausführen möchten, müssen Sie die obige Zeile bearbeiten und den Verweis auf den Parameter "root =" als ersetzen im:

Bildbeschreibung hier eingeben

Bitte beachten Sie, dass ich root = / initrd.img-3.8.0-19-generic verwendet habe, während Sie auf Ihre spezifische initrd-Datei verlinken sollten

  1. Wenn Sie den Parameter "root =" richtig definiert haben, drücken Sie einfach die Taste F10. Nach einigen Sekunden sollten Sie zur Eingabeaufforderung (initramfs) gelangen, wie in:

Bildbeschreibung hier eingeben

Jetzt hat Ihr "/" einen / lib-Ordner mit den Bibliotheken, die Sie kompiliert und in das INITRD gepackt haben.


Damiano Verzulli
quelle
Vielen Dank für diese Antwort. Sie schreiben: "Sie haben Ihren Kernel-Root gebootet, indem Sie Ihre neue initrd gemountet haben (und daher mit einer Eingabeaufforderung wie '(initramfs)' enden). Können Sie mir bitte sagen, was ich tun soll, um eine Eingabeaufforderung wie (initramfs) zu erhalten?
user3900460
Sollte ich eine Art Minimal-Initrd anstelle meiner Kopie der Standard-Initrd verwenden, um frisches Glibc zu transportieren? Oder kann eine (initramfs) Eingabeaufforderung nach dem Bearbeiten der Befehlszeile im GRUB-Menü beim Booten erreichbar sein?
user3900460
Ich habe gerade meine Antwort aktualisiert, um zu erklären, wie man die initrd als Root bootet.
Damiano Verzulli
Erstens schätze ich Ihre Bemühungen sehr. Sie haben mich wirklich inspiriert, obwohl ich nach dem Kopieren dieser Verzeichnisse kein bootfähiges System bekommen konnte. Übrigens make installgeneriert in meinem Fall kein libVerzeichnis. Die Verzeichnisse sind etc, lib64, sbin, usrund var. Das Beste , was ich bisher erreicht bootet Debian leben (Rettungs-) Bild, dann Root - Shell bekommen, mein Ziel - Dateisystem Montage, Durchführung pivot_root, chroot . bashund dann make installin das Build - Verzeichnis. Das Problem hier ist die Nichtübereinstimmung der Kernel-Version, da ich glibc für einen neueren Kernel als im Live-Image erstelle.
user3900460
Es kehrt schließlich mit zurück FATAL: kernel too old, aber glibc selbst wird erfolgreich aktualisiert (überprüft von ldd --version). Obwohl getconf -anicht funktioniert ...
user3900460