Gentoo: Probleme nach Hardware-Architekturdowngrade

Nach einem Architekturdowngrade, was es durchaus in virtuellen Umgebungen mal geben kann, steht man mit Gentoo hin und wieder vor dem Problem, dass das System nur noch recht instabil läuft und GCC jeden Kompillierversuch mit einem “internal compiler error: Illegal instruction”, “internal compiler error: Segmentation fault” oder “error: Building GCC requires GMP 4.2+, MPFR 2.3.1+ and MPC 0.8.0+” quittiert.

Hinweis: Die nachfolgend dokumentierte Vorgehensweise funktioniert nur, solange die Architektur und der Hersteller der verwendeten Prozessoren identisch ist! Ein Architektur- (z.B. x86 -> x86_64 oder x86_64 -> ia64) oder Herstellerwechsel (z.B. AMD -> Intel)  erfordert fast immer eine Neuinstallation.

Das Quellsystem ist ein HP ProLiant DL180 G6 mit Intel(R) Xeon(R) CPU E5504 Prozessoren , das Zielsystem ist ein HP ProLiant DL160 G5 mit Intel(R) Xeon(R) CPU E5405 Prozessoren, auf beiden Systemen läuft VMWare ESXi 4.1, die Virtuelle Maschine (VM) wurde 1:1 geklont, im Zielsystem wurden nach dem Klonen die Netzwerkeinstellungen, der SSH-Hostkey und die Macadresse der Netzwerkkarte angepasst.

Auf dem Quellsystem wurde mit -march=native kompilliert, welches auf den jeweiligen Systemen zu folgenden GCC-Flags aufgelöst wird:

E5504:
-quiet -D_FORTIFY_SOURCE=2 -march=core2 -mcx16 -msahf -mpopcnt \
-msse4.2 --param l1-cache-size=32 --param l1-cache-line-size=64
--param l2-cache-size=256 -mtune=core2

E5405:
-quiet -D_FORTIFY_SOURCE=2 -march=core2 -mcx16 -msahf \
-msse4.1 --param l1-cache-size=32 --param l1-cache-line-size=64 \
--param l2-cache-size=6144 -mtune=core2

Jede Software, für welche also die Flags -mpopcnt, -msse4.2 relevant sind, oder auf eine bestimmte Grösse an L2-Cache angewiesen ist,  wird auf dem Zeilsystem nicht laufen.

Nach dem Klonen bricht ein Kompilliervorgang auf der VM im Zielsystem mit folgender Meldung ab:

>>> Emerging (1 of 1) sys-libs/glibc-2.14.1-r3
>>> Failed to emerge sys-libs/glibc-2.14.1-r3, Log file:
>>>  '/var/tmp/portage/sys-libs/glibc-2.14.1-r3/temp/build.log'
>>> Jobs: 0 of 39 complete, 1 failed                Load avg: 1.04, 0.88, 0.56
 * Package:    sys-libs/glibc-2.14.1-r3
 * Repository: gentoo
 * Maintainer: toolchain@gentoo.org
 * USE:        amd64 elibc_glibc kernel_linux multilib userland_GNU
 * FEATURES:   sandbox
glibc-test.c: In function 'main':
glibc-test.c:2: internal compiler error: Illegal instruction
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugs.gentoo.org/> for instructions.
make: *** [glibc-test] Error 1
emake failed
 * Simple build failed ... assuming this is desired #324685
glibc-test.c: In function 'main':
glibc-test.c:3: internal compiler error: Illegal instruction
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://bugs.gentoo.org/> for instructions.
make: *** [glibc-test] Error 1
emake failed
 * Simple build failed ... assuming this is desired #324685
 * Auto adding -march=x86_64 to CFLAGS_x86 #185404
 * Checking gcc for __thread support ...
 [ !! ]

 * Could not find a gcc that supports the __thread directive!
 * Please update your binutils/gcc and try again.
 * ERROR: sys-libs/glibc-2.14.1-r3 failed (unpack phase):
 *   No __thread support in gcc!
 *
 * Call stack:
 *          ebuild.sh, line   85:  Called src_unpack
 *        environment, line 3185:  Called eblit-run 'src_unpack'
 *        environment, line  728:  Called eblit-glibc-src_unpack
 *   src_unpack.eblit, line  168:  Called toolchain-glibc_src_unpack
 *   src_unpack.eblit, line   82:  Called check_nptl_support
 *   src_unpack.eblit, line   38:  Called die
 * The specific snippet of code:
 *           die "No __thread support in gcc!"
 *
 * If you need support, post the output of 'emerge --info =sys-libs/glibc-2.14.1-r3',
 * the complete build log and the output of 'emerge -pqv =sys-libs/glibc-2.14.1-r3'.
 * The complete build log is located at '/var/tmp/portage/sys-libs/glibc-2.14.1-r3/temp/build.log'.
 * The ebuild environment file is located at '/var/tmp/portage/sys-libs/glibc-2.14.1-r3/temp/environment'.
 * S: '/var/tmp/portage/sys-libs/glibc-2.14.1-r3/work/glibc-2.14.1'

Die Lösung dieses Problems ist recht einfach:

Schritt 1
Auf dem Zielsystem wird eine neue virtuelle Maschine mit den identischen Parametern erstellt, oder die bestehende Maschine dupliziert – ich nenne diese Maschine nachgehend “buildhost”.

Im Folgenden werde ich für die VM auf dem Quellsystem den Namen “sourcehost” und für den Klon desselben auf dem Zielsystem den Namen “targethost” verwenden.

Schritt 2
Auf dem buildhost wird nun ein möglichst minimalistischen Gentoo-System frisch aufgesetzt. Dabei ist zu beachten, dass tunlichst ein Portage-Snapshot ab einem Mirror verwendet wird (portage-latest.tar.xz beispielsweise). Die Konfigurationsdatei /etc/make.conf so angepasst, dass die CFLAGS und CXXFLAGS dem Zielsystem angepasst wird, und alle anderen Varablen gleich wie auf dem Quellsystem gesetzt sind.

Schritt 3
Nun werden die Pakete gcc, glibc, gmp, mpfr, mpc als Binärpakete kompilliert:

buildhost ~ # emerge -B gcc glibc gmp mpfr mpc

Damit werden die Pakete kompilliert und als Binärpakete zur weiteren Verwendung in /usr/portage/packages/ abgelegt, aber nicht installiert.

Schritt 4
Die gerade eben erstellten Pakete werden nun auf den targethost kopiert. Falls das Netzwerk noch funktioniert, kann das per SSH erledigt werden:

buildhost ~ # ssh root@targethost 'mkdir /usr/portage/packages/
Password:
buildhost ~ # scp -r /usr/portage/packages/* root@targethost:/usr/portage/packages/
Password:
Packages                   100% 9067     8.9KB/s   8.9KB/s   00:00    
mpc-0.8.2.tbz2             100%   89KB  88.6KB/s  88.6KB/s   00:00    
gmp-5.0.2_p1.tbz2          100%  624KB 624.4KB/s 624.4KB/s   00:00    
mpfr-3.0.1_p4.tbz2         100%  602KB 601.8KB/s 624.4KB/s   00:00    
gcc-4.5.3-r2.tbz2          100%   24MB  24.4MB/s  24.4MB/s   00:01    
glibc-2.14.1-r3.tbz2       100%   16MB  15.8MB/s  24.4MB/s   00:01

Schritt 5
Auf dem targethost wird nun der identische Portage-Snapshot wie auf dem buildhost installiert – damit stellen wir sicher, dass die Binärpakete auch installiert werden können.

Nun können auf dem targethost die Binärpakete installiert werden:

targethost ~ # emerge --usepkg --oneshot gcc glibc gmp mpfr mpc

 * IMPORTANT: 5 news items need reading for repository 'gentoo'.
 * Use eselect news to read news items.

>>> Starting parallel fetch
>>> Emerging binary (1 of 5) dev-libs/gmp-5.0.2_p1
>>> Installing (1 of 5) dev-libs/gmp-5.0.2_p1
>>> Emerging binary (2 of 5) dev-libs/mpfr-3.0.1_p4
>>> Installing (2 of 5) dev-libs/mpfr-3.0.1_p4
>>> Emerging binary (3 of 5) sys-libs/glibc-2.14.1-r3
>>> Installing (3 of 5) sys-libs/glibc-2.14.1-r3
>>> Emerging binary (4 of 5) dev-libs/mpc-0.8.2
>>> Installing (4 of 5) dev-libs/mpc-0.8.2
>>> Emerging binary (5 of 5) sys-devel/gcc-4.5.3-r2
>>> Installing (5 of 5) sys-devel/gcc-4.5.3-r2

 * Messages for package sys-devel/gcc-4.5.3-r2:

 * If you have issues with packages unable to locate libstdc++.la,
 * then try running 'fix_libtool_files.sh' on the old gcc versions.
 * You might want to review the GCC upgrade guide when moving between
 * major versions (like 4.2 to 4.3):
 * http://www.gentoo.org/doc/en/gcc-upgrading.xml

 * IMPORTANT: 5 news items need reading for repository 'gentoo'.
 * Use eselect news to read news items.

Der Parameter –oneshot muss unbedingt gesetzt werden, weil ansonsten die Pakete ins World-File aufgenommen werden, wo sie garantiert nicht hingehören.

Es empfiehlt sich ebenfalls, mit gcc-config die eben installierte gcc-Version ausgeählt wird:

targethost ~ # gcc-config -l
 [1] x86_64-pc-linux-gnu-4.4.5
 [2] x86_64-pc-linux-gnu-4.5.3 *
targethost ~ # gcc-config 2
 * Switching native-compiler to x86_64-pc-linux-gnu-4.5.3 ...
>>> Regenerating /etc/ld.so.cache...                         [ ok ]

 * If you intend to use the gcc from the new profile in an already
 * running shell, please remember to do:

 *   . /etc/profile

targethost ~ # . /etc/profile

Auch wenn schon die richtige Version gesetzt ist – falls man das nicht macht, kann es zu sehr merkwürdigen Problemen führen.

Schritt 6
Nun kann man das System komplett neu durchkompilieren:

targethost ~ # emerge -e world

Oder, wenn weiss was man tut und so faul wie ich ist, baut man nur die Pakete neu, welche dies auch tatsächlich nötig haben.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.