四. 故障排除和清理
本章介绍的内容不仅仅是故障排除和清理,还将有些关于Arch及Linux系统的说明。
如果仅仅是升级,不必看本章内容,除非:
升级过程中,发生了错误;
想要个所谓的“纯净”的系统。
1. 清理工作
有人有洁癖,喜欢一个“纯净”的64位系统,很遗憾的告诉你,用Arch的方式做到这点几乎是不可能的,至少,它的内核是支持32位程序运行的。
能做的只尽量不使用32位的程序。
到了现在,我们的系统已经是完整的64位环境了,可以去掉32位的glibc兼容性支持了:
代码:
pacman -Rcsn lib32-glibc
至此,一个“纯净”的64位ArchLinux系统就完成了。
可以用下面的命令检查一下是否还有残留的32位包:
代码:
LC_ALL=C pacman -Qi|egrep "Name|^$|Arch" | grep i686 -B 1 | grep Name | awk '{print $3}'
如果有,可以用pacman删除。
2. 故障排除
故障排除是个复杂的工作,在升级过程中,一旦换掉了glibc,出现故障的可能性就很大,因为此时系统的运行,用了不少`trick',比如在运行时删除替换文件,使用32位兼容的glibc来运行程序。下面来分解介绍:
i. 关于内核与libc和程序之间
内核是系统的基础的基础,64位的内核+64位的libc和64位的程序可以运行,64位内核+32位的libc和32位的程序也可以运行,还可以直接在64位内核上直接运行静态的32位或64位的程序;而32位的内核则不能运行64位的libc和64位的程序。认识了到这一点,那么第一次重启的原因就可以理解了,这也是我们可以升级的基础。
实际上,除了依赖libc,很多程序还依赖其它库。
ii. 动态链接程序与lib之间的关系
动态链接的程序需要各种动态链接库的支持,我们可以用ldd来查看,比如:
代码:
$ ldd `which pacman`
linux-vdso.so.1 => (0x00007fff015be000)
libalpm.so.4 => /usr/lib/libalpm.so.4 (0x00007f19f4097000)
libc.so.6 => /lib/libc.so.6 (0x00007f19f3d44000)
libfetch.so => /usr/lib/libfetch.so (0x00007f19f3b35000)
libarchive.so.2 => /usr/lib/libarchive.so.2 (0x00007f19f38ff000)
/lib/ld-linux-x86-64.so.2 (0x00007f19f42b8000)
libssl.so.0.9.8 => /usr/lib/libssl.so.0.9.8 (0x00007f19f36b0000)
libcrypto.so.0.9.8 => /usr/lib/libcrypto.so.0.9.8 (0x00007f19f3322000)
libacl.so.1 => /lib/libacl.so.1 (0x00007f19f311b000)
libattr.so.1 => /lib/libattr.so.1 (0x00007f19f2f17000)
liblzma.so.0 => /usr/lib/liblzma.so.0 (0x00007f19f2cf7000)
libbz2.so.1.0 => /lib/libbz2.so.1.0 (0x00007f19f2ae7000)
libz.so.1 => /usr/lib/libz.so.1 (0x00007f19f28d2000)
libdl.so.2 => /lib/libdl.so.2 (0x00007f19f26ce000)
libpthread.so.0 => /lib/libpthread.so.0 (0x00007f19f24b3000)
通过这个,加上一些脚本处理,就可以得到`隐含‘的依赖关系:
代码:
[kangkang@kangkang ~]$ pacman -Qo $(ldd `which pacman`|awk '{print $3}'|grep "^/"|sort |uniq )
/lib/libacl.so.1 属于 acl 2.2.47-2
/lib/libattr.so.1 属于 attr 2.4.43-1
/lib/libbz2.so.1.0 属于 bzip2 1.0.5-4
/lib/libc.so.6 属于 glibc 2.10.1-4
/lib/libdl.so.2 属于 glibc 2.10.1-4
/lib/libpthread.so.0 属于 glibc 2.10.1-4
/usr/lib/libalpm.so.4 属于 pacman 3.3.2-1
/usr/lib/libarchive.so.2 属于 libarchive 2.7.1-1
/usr/lib/libcrypto.so.0.9.8 属于 openssl 0.9.8k-4
/usr/lib/libfetch.so 属于 libfetch 2.25-1
/usr/lib/liblzma.so.0 属于 xz-utils 4.999.9beta-1
/usr/lib/libssl.so.0.9.8 属于 openssl 0.9.8k-4
/usr/lib/libz.so.1 属于 zlib 1.2.3.3-3
依据这个结果,加上pacman -Qi的结果,我们就可以做出一个完整的依赖关系,这就是前面所见的。
iii. 动态程序与静态程序
之前的过程中,有若干次提到动态链接的程序和静态链接的程序,我们使用的大多数程序使用的都是动态的。使用 file命令可看出来这些信息:
代码:
[kangkang@kangkang /]$ file /usr/bin/qemu
/usr/bin/qemu: ELF [color=#FF0000]32-bit[/color] LSB executable, Intel 80386, version 1 (SYSV), [color=#FF4000]dynamically [/color]linked (uses shared libs), for GNU/Linux 2.6.18, stripped
[kangkang@kangkang /]$ file /bin/busybox
/bin/busybox: ELF [color=#FF0000]64-bit [/color]LSB executable, x86-64, version 1 (SYSV), [color=#FF4000]statically[/color] linked, for GNU/Linux 2.6.18, stripped
不仅可以看出来是动态还是静态的,还能知道是32位还是 64位的。
动态链接程序不但可以节省磁盘的空间,还可以节省内存的使用。然后还是有少量程序却是静态的,它们有个好处:在库被破坏时仍然可以运行,比如busybox,它包含了大量的程序,可以通过做所需命令的符号链接或运行 busybox 命令的方式来执行:
代码:
$ ln -s /bin/busybox ls
$ ./ls
bin dev ...
$ busybox ls
bin dev ...
对于动态链接程序,动态调用库的过程是由ld-linux来完成的,装有32位运行库时,会有/lib/ld-linux-x86-32.so.2:
代码:
[kangkang@kangkang /]$ ls /lib/ld-* -lh
-rwxr-xr-x 1 root root 138K 8月 23 22:24 /lib/ld-2.10.1.so
lrwxrwxrwx 1 root root 20 10月 17 19:31 /lib/ld-linux.so.2 -> ld-linux-x86-32.so.2
lrwxrwxrwx 1 root root 28 8月 25 03:11 /lib/ld-linux-x86-32.so.2 -> /opt/lib32/lib/ld-linux.so.2
lrwxrwxrwx 1 root root 12 8月 23 22:24 /lib/ld-linux-x86-64.so.2 -> ld-2.10.1.so
对于ELF格式的动态链接程序,程序本身会有默认的请求的解释器:
代码:
[kangkang@kangkang /]$ readelf -a /bin/bash|grep /lib
[Requesting program interpreter: /lib/ld-linux-x86-64.so.2]
[kangkang@kangkang /]$ readelf -a /usr/bin/qemu|grep /lib
[Requesting program interpreter: /lib/ld-linux.so.2]
可以看到32位程序请求的解释器和我们期待的不一样,所以上面的程序可能会需要指定解释器来运行,就好比脚本语言,对于shell程序可以用 bash cmd,对于python可以使用 python -c 这样的样式来运行一样。
注意:这样运行程序需要使用绝对或相对路径,解释器不会去识别PATH参数。
iv. ArchLinux的包
ArchLinux使用的是tar.gz来做包,这就给我们提供了很大便利,在pacman坏掉的时候,可以用gzip和tar来安装软件,举例来说,如果pacman这个包坏了,可以使用下面的命令来重新安装它:
代码:
[kangkang@kangkang shm]$ busybox cp /var/cache/pacman/pkg/pacman-3.3.2-1-i686.pkg.tar.gz .
[kangkang@kangkang shm]$ busybox gzip -d pacman-3.3.2-1-i686.pkg.tar.gz
[kangkang@kangkang shm]$ busybox tar xf pacman-3.3.2-1-i686.pkg.tar -C /
用这种方法,将前述的pacman依赖的包都重安装一下,可以至少修复出一个可用的pacman来。
v. ArchLinux的命脉
对于ArchLinux本身来说,什么才是最关键的地方呢?答案是:
代码:
/var/lib/pacman/local/
这里保存了系统中所有已安装包的信息。具体的,有兴趣的可以去看看,都是以目录和文本的方式储存的。
后记
拥有了这些知识,Linux,至少是ArchLinux,对于你来说,就成了不死鸟,无论怎样,都可以恢复,所以说,没有修理不好的Linux系统。
PS:这篇文还有个姊妹篇,即把ArchLinux从64位降级到32位。