Linux系统源代码升级glibc到最新版本2.25.90(正在开发的版本)

时间:2023-02-06 20:03:20

网上关于升级glibc的文章不少,但没有一篇能成功的,本人被坑过无数次,以至后来能避就避,今天自己在虚拟机上实验,终于成功,我把升级过程记录下来,为网友提供完整的升级方法。


升级是在ubuntu下进行的,但是其他系统升级也类似,我的系统版本:

Linux ubuntu 3.19.0-25-generic #26~14.04.1-Ubuntu SMP Fri Jul 24 21:16:20 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux


准备两个Linux系统, 一个是你要升级glibc的系统B, 另一个A用于glibc升级失败之后恢复,
它能挂载升级失败的系统的根文件系统, 恢复失败的系统.

首先配置系统B,
安装 nfs 服务
配置成 A能以root身份访问B

做法:
服务器B安装 nfs服务
sudo apt-get install nfs-kernel-server

然后启动nfs服务:
sudo /etc/init.d/nfs-kernel-server start

编辑/etc/exports,加入:
/ A_ip(rw,sync,no_root_squash)

然后重启动nfs服务:
sudo /etc/init.d/nfs-kernel-server restart

配好之后 登录系统A
挂载系统B的根文件系统

mkdir /mnt/glibc-upgrade
sudo mount -t nfs B_ip:/ /mnt/glibc-upgrade


1. 登录系统B
下载最新版本的glibc
git clone git://sourceware.org/git/glibc.git
cd glibc
git checkout --track -b local_glibc-2.25 origin/release/2.25/master

2.
mkdir build-glibc
cd build-glibc
../glibc/configure --prefix=/usr
make
make install install_root=~/share/src-glibc-2.25/system_fake_root

ll ~/share/src-glibc-2.25/system_fake_root
查看glibc安装时会修改哪些文件,
将这些文件进行备份(安全起见, 以便升级失败恢复原来的系统, 一定要备份)

我的glibc安装会修改以下文件
xxx@ubuntu:~/share/git-glibc-src/system_fake_root$ ll
total 28
drwxrwxr-x 7 liuwb  liuwb  4096 Apr  7 00:26 ./
drwxrwxr-x 5 liuwb  liuwb  4096 Apr  7 00:20 ../
drwxr-xr-x 2 root root 4096 Apr  7 00:26 etc/
drwxr-xr-x 2 root root 4096 Apr  7 00:26 lib64/
drwxr-xr-x 2 root root 4096 Apr  7 00:26 sbin/
drwxr-xr-x 8 root root 4096 Apr  7 00:22 usr/
drwxr-xr-x 3 root root 4096 Apr  7 00:23 var/

以上是glibc源代码 make install 会修改的目录

liuwb@ubuntu:~/share/git-glibc-src/system_fake_root$ ll lib64/
total 18768
drwxr-xr-x 2 root root     4096 Apr  7 00:26 ./
drwxrwxr-x 7 liuwb  liuwb      4096 Apr  7 00:26 ../
-rwxr-xr-x 1 root root   863537 Apr  7 00:26 ld-2.25.90.so*
lrwxrwxrwx 1 root root       13 Apr  7 00:26 ld-linux-x86-64.so.2 -> ld-2.25.90.so*
-rwxr-xr-x 1 root root    75101 Apr  7 00:26 libanl-2.25.90.so*
lrwxrwxrwx 1 root root       17 Apr  7 00:26 libanl.so.1 -> libanl-2.25.90.so*
-rwxr-xr-x 1 root root    19640 Apr  7 00:25 libBrokenLocale-2.25.90.so*
lrwxrwxrwx 1 root root       26 Apr  7 00:26 libBrokenLocale.so.1 -> libBrokenLocale-2.25.90.so*
-rwxr-xr-x 1 root root 10177656 Apr  7 00:26 libc-2.25.90.so*
-rwxr-xr-x 1 root root   275419 Apr  7 00:26 libcidn-2.25.90.so*
lrwxrwxrwx 1 root root       18 Apr  7 00:26 libcidn.so.1 -> libcidn-2.25.90.so*
-rwxr-xr-x 1 root root   136272 Apr  7 00:26 libcrypt-2.25.90.so*
lrwxrwxrwx 1 root root       19 Apr  7 00:26 libcrypt.so.1 -> libcrypt-2.25.90.so*
lrwxrwxrwx 1 root root       15 Apr  7 00:26 libc.so.6 -> libc-2.25.90.so*
-rwxr-xr-x 1 root root    97704 Apr  7 00:26 libdl-2.25.90.so*
lrwxrwxrwx 1 root root       16 Apr  7 00:26 libdl.so.2 -> libdl-2.25.90.so*
-rwxr-xr-x 1 root root  4219769 Apr  7 00:26 libm-2.25.90.so*
-rwxr-xr-x 1 root root    46984 Apr  7 00:26 libmemusage.so*
lrwxrwxrwx 1 root root       15 Apr  7 00:26 libm.so.6 -> libm-2.25.90.so*
-rwxr-xr-x 1 root root   194650 Apr  7 00:26 libmvec-2.25.90.so*
lrwxrwxrwx 1 root root       18 Apr  7 00:26 libmvec.so.1 -> libmvec-2.25.90.so*
-rwxr-xr-x 1 root root   575386 Apr  7 00:26 libnsl-2.25.90.so*
lrwxrwxrwx 1 root root       17 Apr  7 00:26 libnsl.so.1 -> libnsl-2.25.90.so*
-rwxr-xr-x 1 root root   158298 Apr  7 00:26 libnss_db-2.25.90.so*
lrwxrwxrwx 1 root root       20 Apr  7 00:26 libnss_db.so.2 -> libnss_db-2.25.90.so*
-rwxr-xr-x 1 root root    94107 Apr  7 00:26 libnss_dns-2.25.90.so*
lrwxrwxrwx 1 root root       21 Apr  7 00:26 libnss_dns.so.2 -> libnss_dns-2.25.90.so*
-rwxr-xr-x 1 root root   249089 Apr  7 00:26 libnss_files-2.25.90.so*
lrwxrwxrwx 1 root root       23 Apr  7 00:26 libnss_files.so.2 -> libnss_files-2.25.90.so*
-rwxr-xr-x 1 root root    87402 Apr  7 00:26 libnss_hesiod-2.25.90.so*
lrwxrwxrwx 1 root root       24 Apr  7 00:26 libnss_hesiod.so.2 -> libnss_hesiod-2.25.90.so*
-rwxr-xr-x 1 root root    12334 Apr  7 00:26 libpcprofile.so*
-rwxr-xr-x 1 root root   970407 Apr  7 00:26 libpthread-2.25.90.so*
lrwxrwxrwx 1 root root       21 Apr  7 00:26 libpthread.so.0 -> libpthread-2.25.90.so*
-rwxr-xr-x 1 root root   370842 Apr  7 00:26 libresolv-2.25.90.so*
lrwxrwxrwx 1 root root       20 Apr  7 00:26 libresolv.so.2 -> libresolv-2.25.90.so*
-rwxr-xr-x 1 root root   200745 Apr  7 00:26 librt-2.25.90.so*
lrwxrwxrwx 1 root root       16 Apr  7 00:26 librt.so.1 -> librt-2.25.90.so*
-rwxr-xr-x 1 root root    70685 Apr  7 00:26 libSegFault.so*
-rwxr-xr-x 1 root root   238153 Apr  7 00:26 libthread_db-1.0.so*
lrwxrwxrwx 1 root root       19 Apr  7 00:26 libthread_db.so.1 -> libthread_db-1.0.so*
-rwxr-xr-x 1 root root    32122 Apr  7 00:26 libutil-2.25.90.so*
lrwxrwxrwx 1 root root       18 Apr  7 00:26 libutil.so.1 -> libutil-2.25.90.so*


虽然glibc安装时不会修改/lib 下的文件, 也要将 /lib 目录备份, 因为/lib下的lib依赖
的还是旧版本的glibc, 而系统A就是在这里起关键作用, 系统A负责把 /lib 依赖旧版本的lib
改为依赖新版本的lib

3.sudo make install
这个时候通常是失败的, 我的系统提示是
coredump
具体是:
/home/liuwb/share/glibc-2.25-build/elf/sln /home/liuwb/share/glibc-2.25-build/elf/symlink.list
rm -f /home/liuwb/share/glibc-2.25-build/elf/symlink.list
make[1]: *** [install-symbolic-link] Segmentation fault (core dumped)
make[1]: Leaving directory `/home/liuwb/share/glibc'
make: *** [install] Error 2

这是因为/home/liuwb/share/glibc-2.25-build/elf/sln /home/liuwb/share/glibc-2.25-build/elf/symlink.list
修改了 /lib64/ld-linux-x86-64.so.2 它指向了新版本的

#ll /lib64/ld-linux-x86-64.so.2
/lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.25.90.so*

然而
ldd /bin/ls
    linux-vdso.so.1 =>  (0x00007fff474e0000)
    libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007fdceab17000)
    libacl.so.1 => /lib/x86_64-linux-gnu/libacl.so.1 (0x00007fdcea90f000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fdcea54a000)
    libpcre.so.3 => /lib/x86_64-linux-gnu/libpcre.so.3 (0x00007fdcea30c000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fdcea108000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fdcead3a000)
    libattr.so.1 => /lib/x86_64-linux-gnu/libattr.so.1 (0x00007fdce9f03000)
    
ls 依赖的 /lib/x86_64-linux-gnu/libc.so.6
/lib/x86_64-linux-gnu/libc.so.6 -> libc-2.19.so* 这还是旧版本的libc~

rm 也一样的

所以 Segmentation fault (core dumped) 了

那为啥 ld-VERSION.so 和 libc-VERSION.so 版本不一致会core呢?
这是因为:
ldd /lib/x86_64-linux-gnu/libc.so.6
    /lib64/ld-linux-x86-64.so.2 (0x00007f49dc122000)
    linux-vdso.so.1 =>  (0x00007ffd6f531000)
    
libc.so.6 -> libc-VERSION.so  依赖 /lib64/ld-linux-x86-64.so.2
而 /lib64/ld-linux-x86-64.so.2 -> ld-VERSION.so

4. A系统登场
只需要
cd 到B系统的根目录,
ln -sf libc-VERSION-NEW.so  /lib/x86_64-linux-gnu/libc.so.6

我的B系统的glibc安装都安装到了 /lib64/ 目录下

把 /lib64/ 目录下的 libxxx-VERSION-NEW.so 拷贝到 /lib/x86_64-linux-gnu/ 下
把 /lib/x86_64-linux-gnu/libxxx.x.1.so.x => /lib/x86_64-linux-gnu/libxxx-VERSION-OLD.x.1.x.so
/lib/x86_64-linux-gnu/libxxx.x.1.so.x => /lib/x86_64-linux-gnu/libxxx-VERSION-NEW.x.1.x.so

5. 再到 B系统验证一下一些常用的命令是否能用
如果命令都能正确运行, 系统的大多数命令就已经可以用了, 也没必要再make install了(上次的make install 不是没成功嘛)

但是我还是进行了第二次 make install, 结果报下面的错误:
/usr/bin/install -c /home/liuwb/share/git-glibc-src/build/elf/ld.so /lib64/ld-2.25.90.so.new
mv -f /lib64/ld-2.25.90.so.new /lib64/ld-2.25.90.so
/usr/bin/install -c /home/liuwb/share/git-glibc-src/build/libc.so /lib64/libc-2.25.90.so.new
mv -f /lib64/libc-2.25.90.so.new /lib64/libc-2.25.90.so
rm -f /lib64/ld-linux-x86-64.so.2
ln -s `../scripts/rellns-sh -p /lib64/ld-2.25.90.so /lib64/ld-linux-x86-64.so.2` /lib64/ld-linux-x86-64.so.2
make[2]: /bin/sh: Command not found
make[2]: *** [/lib64/ld-linux-x86-64.so.2] Error 127
make[2]: Leaving directory `/home/liuwb/share/git-glibc-src/glibc/elf'
make[1]: *** [elf/ldso_install] Error 2
make[1]: Leaving directory `/home/liuwb/share/git-glibc-src/glibc'
make: *** [install] Error 2

注意:
rm -f /lib64/ld-linux-x86-64.so.2
ln -s `../scripts/rellns-sh -p /lib64/ld-2.25.90.so /lib64/ld-linux-x86-64.so.2` /lib64/ld-linux-x86-64.so.2

第一次 make install 的时候, 会修改/lib64/ld-linux-x86-64.so.2 指向新版本的 ld-VERSION-NEW.so
/lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.25.90.so*
已经是新版本的了

第二次 make install 的话, install还要把/lib64/ld-linux-x86-64.so.2 删掉,
这样就导致了install要执行 ln -s 命令执行不了了,
为啥执行不了呢?
我在A系统上看B系统的/bin/ln
ldd ./bin/ln
    linux-vdso.so.1 =>  (0x00007ffe08b6b000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fb14f0c3000)
    /lib64/ld-linux-x86-64.so.2 (0x00007fb14f488000)
它是依赖 /lib64/ld-linux-x86-64.so.2 的,
/lib64/ld-linux-x86-64.so.2 如果都被删掉了, 自然ln命令执行不了了

于是 我又在A系统手动执行下面这两条命令
cd lib64/
ln -sf ld-2.25.90.so ld-linux-x86-64.so.2

这样B系统又能ls,ln了

总之我觉得第一次make install失败了, 从A系统修改指向旧版本的软连接之后, B系统重新能运行大部分命令
就算升级成功了....
并且用一个小小的输出当前glibc版本的c程序, 也输出新版本了
#include <stdio.h>
#include <gnu/libc-version.h>
int main (void) { puts (gnu_get_libc_version ()); return 0; }

liuwb@ubuntu:~/share/check_glibc_version$ gcc main.c
liuwb@ubuntu:~/share/check_glibc_version$ ./a.out
2.25.90

然后我觉得应该成功了, = = ! 如果以后发现还有问题再来补充吧, 继续完成glibc升级大业

如果在B系统执行命令有这样的错误
Illegal Instruction(coredump)

检查一下是否还有一些库没替换成新版本的

--------------------------------------------------------------
../glibc/configure --prefix=/usr --host=i686-pc-linux-gnu
../glibc/configure --prefix=/usr --host=x86_64-pc-linux-gnu
make CFLAGS+=-mtune=x86_64
make时
make CFLAGS+=-mtune=i686

如果 cc1:all warnings being treated as errors
../glibc/configure --prefix=/usr --host=i686-pc-linux-gnu --disable-werror

#error "glibc cannot be compiled without optimization"',