- 論壇徽章:
- 0
|
![]()
![]()
![]()
使用源代碼將 Glibc 升級(jí)到 2.6
本
文介紹了一種使用源代碼的方式升級(jí)系統(tǒng)標(biāo)準(zhǔn)動(dòng)態(tài)庫到 Glibc2.6
的方法。該方法是安全的,即使遇到升級(jí)失敗,也能把系統(tǒng)恢復(fù)為原來的狀態(tài)。系統(tǒng)環(huán)境不同,源代碼的編譯和安裝方法會(huì)有很大的差異,因此本文也只能針對(duì)一種
特定的平臺(tái)(Mandriva Linux release 2006.0)的 Glibc 進(jìn)行升級(jí)。撰寫本文的目的,是為了給出一個(gè)升級(jí)
Glibc 的例子,讀者可以參考本文介紹的方法升級(jí) Glibc,但是一定要根據(jù)系統(tǒng)的實(shí)際情況作相應(yīng)的調(diào)整。
簡(jiǎn)介
有些軟件可能要求系統(tǒng)的 Glibc 高于某個(gè)版本才可以正常運(yùn)行。如果您的 Glibc 低于要求的版本,為了運(yùn)行這些軟件,您就不得不升級(jí)您的 Glibc 了 。您可以尋找已經(jīng)編譯好的 rpm 包或者使用源代碼的方式升級(jí) Glibc。
使
用源代碼方式升級(jí) Glibc 是需要小心考慮的事情,因?yàn)檎麄(gè)系統(tǒng)幾乎所有應(yīng)用程序都依賴于原有的動(dòng)態(tài)庫,升級(jí)的時(shí)候,執(zhí)行"make
install"命令會(huì)打斷舊的動(dòng)態(tài)庫鏈接,改為指向新的庫文件。在這個(gè)過程中,不同的鏈接指向新舊不同版本的庫文件,很容易導(dǎo)致系統(tǒng)崩潰,崩潰后,一般
是無法重新啟動(dòng)的。
筆者使用的Linux發(fā)行版本是Mandriva Linux release
2006.0,其Glibc版本是2.3.5,內(nèi)核版本是2.6.12-12mdk。由于某些需要,筆者必須升級(jí)原來的Glibc到更高的版本。經(jīng)過實(shí)
踐,成功使用源代碼的方式安全地把Glibc從2.3.5升級(jí)到2.6。使用相同的方法,也能成功升級(jí)到Glibc2.4或Glibc2.5。成功升級(jí)
后,還可以在新舊不同版本的Glibc之間自由切換。
如果您需要閱讀有關(guān)升級(jí)Glibc的文檔,可以閱讀
Glibc 2
HOWTO文檔,該文論述了如何從libc5升級(jí)到libc6,但是現(xiàn)在的Linux發(fā)行版的Glibc都已經(jīng)使用libc6,更多的需要是在libc6
的范圍內(nèi),從低版本升級(jí)到更高的版本。另外您可以閱讀Linux From
Scratch項(xiàng)目有關(guān)如何安裝Glibc的文檔。筆者認(rèn)為最有必要閱讀的是Glibc源程序目錄樹下的INSTALL和FAQ文檔,INSTALL詳細(xì)
描述了有關(guān)各編譯選項(xiàng)的具體作用,F(xiàn)AQ回答了很多具體的問題。
![]()
![]()
![]()
![]()
升級(jí)Glibc的流程
為
了安全升級(jí)Glibc,在升級(jí)前必須做好詳細(xì)的部署和備份,即使是升級(jí)失敗,系統(tǒng)也要能夠還原為原來的狀態(tài)。升級(jí)Glibc失敗后,一般是無法重新啟動(dòng)系
統(tǒng)的,必須使用另外一個(gè)可以啟動(dòng)計(jì)算機(jī)的Linux系統(tǒng)啟動(dòng),掛載升級(jí)失敗的根文件系統(tǒng),恢復(fù)系統(tǒng)的Glibc為原來的狀態(tài)。因此,準(zhǔn)備另外一個(gè)可以啟動(dòng)
的Linux系統(tǒng),是必需的。
準(zhǔn)備好另外一個(gè)可以啟動(dòng)的Linux系統(tǒng)后,接下來的工作是編譯Glibc。編
譯前要執(zhí)行"configure"命令,用戶可以根據(jù)自己的需要,加入不同的編譯選項(xiàng),編譯選項(xiàng)在INSTLL文件里有詳細(xì)的說明。如果是升級(jí)當(dāng)前的
Glibc,必須使用--prefix=/usr選項(xiàng),該選項(xiàng)指定當(dāng)前即將編譯的Glibc作為系統(tǒng)的標(biāo)準(zhǔn)動(dòng)態(tài)庫,安裝的時(shí)候,Glibc會(huì)修改
/lib,/usr等目錄下的文件和鏈接。如果--prefix不是指向/usr,譬如--prefix=/glibc,
安裝的時(shí)候,Glibc只會(huì)在/glibc目錄下生成目錄,文件以及鏈接,安裝后的Glibc不會(huì)成為系統(tǒng)的標(biāo)準(zhǔn)動(dòng)態(tài)庫。如果不指定
--prefix,Glibc缺省認(rèn)為--prefix=/usr/local,安裝后的Glibc也不會(huì)成為系統(tǒng)的標(biāo)準(zhǔn)動(dòng)態(tài)庫。編譯Glibc的時(shí)候需
要使用Linux內(nèi)核的頭文件,如果內(nèi)核的頭文件太舊,執(zhí)行"make"的時(shí)候,可能會(huì)失敗,這時(shí)可以在configure的時(shí)候,使用--with-
headers選項(xiàng)指定新內(nèi)核的頭文件的所在目錄。筆者的Mandriva Linux release
2006.0的內(nèi)核頭文件就不能令Glibc2.6成功編譯,但是卻能令Glibc2.4和Glibc2.5成功編譯,使用--with-headers
指向新內(nèi)核的頭文件后,Glibc2.6也能成功編譯,下文將會(huì)有詳細(xì)敘述。
Glibc安裝的時(shí)候,會(huì)直接修改/lib,/usr/lib等目錄下的文件和鏈接,為了在升級(jí)失敗的情況下能夠恢復(fù)系統(tǒng)的Glibc為原來狀態(tài),在安裝新版本的Glibc之前必須對(duì)一些重要目錄進(jìn)行備份,至于哪些目錄需要做備份,下文將會(huì)有敘述。
備
份好重要目錄后就可以安裝Glibc了,必須由root用戶執(zhí)行make
install命令,不同的Linux發(fā)行版,可能會(huì)有不同的結(jié)果。筆者使用的Mandriva Linux release
2006.0在這個(gè)過程中會(huì)出現(xiàn)錯(cuò)誤,并且輸入任何命令都無效,重新啟動(dòng)也無法再次進(jìn)入Linux系統(tǒng)。出現(xiàn)的這樣的錯(cuò)誤是由于Coreutils的命令
都是依賴于/usr/tls/目錄下的鏈接文件,這些鏈接文件都指向原來的Glibc動(dòng)態(tài)庫文件,而/lib/ld-linux.so.2已經(jīng)被改為指向
新版本的Glibc動(dòng)態(tài)庫文件了,這些重要鏈接分別指向新舊不同版本的庫文件,導(dǎo)致了執(zhí)行Coreutils的命令無效。這個(gè)時(shí)候,就要用另外一個(gè)
Linux系統(tǒng)啟動(dòng),把/usr/tls/目錄下的鏈接修改為指向新版本的Glibc的庫文件。
經(jīng)過上述修
改,重新啟動(dòng)計(jì)算機(jī),如果能重新進(jìn)入原Linux系統(tǒng),表明到目前為止升級(jí)過程都是正確的。這個(gè)時(shí)候,要再執(zhí)行一次"make
install"重新安裝Glibc,正常情況下,這次不會(huì)出現(xiàn)任何錯(cuò)誤,安裝結(jié)束的時(shí)候,Glibc會(huì)給出安裝成功的消息。如果修改/lib/tls
/下的鏈接后重新啟動(dòng)計(jì)算機(jī)仍然不能進(jìn)入原Linux系統(tǒng),表明這次升級(jí)失敗,只能再次使用另外一個(gè)Linux系統(tǒng)啟動(dòng),掛載升級(jí)失敗的根文件系統(tǒng),把先
前備份好的重要目錄恢復(fù)為原來的名字,經(jīng)過這樣的恢復(fù),一般是可以重新啟動(dòng)升級(jí)失敗的Linux系統(tǒng)的。
升級(jí)的最后一步是執(zhí)行"make localedata/install-locales"命令安裝時(shí)區(qū)和地區(qū)數(shù)據(jù)庫。
圖一:升級(jí)Glibc的流程圖
![]()
![]()
![]()
![]()
注意
本
文介紹的方法在升級(jí)過程中會(huì)出現(xiàn)一次鏈接錯(cuò)誤,系統(tǒng)無法輸入命令,重新啟動(dòng)也無法進(jìn)入Linux,必須使用另外一個(gè)Linux系統(tǒng)啟動(dòng),并掛載原根文件系
統(tǒng),修正在升級(jí)過程中產(chǎn)生的錯(cuò)誤鏈接,然后才能繼續(xù)升級(jí)。因此在升級(jí)之前,一定要先確保擁有另外一個(gè)可啟動(dòng)的Linux系統(tǒng)。此外,還要備份下文將會(huì)論述
的一些重要目錄,如果最終升級(jí)失敗,需要用另外一個(gè)Linux系統(tǒng)啟動(dòng),恢復(fù)原Linux系統(tǒng)的Glibc為原來的版本。
建議在升級(jí)之前,詳細(xì)閱讀Glibc源代碼包內(nèi)的INSTALL和FAQ文件。
![]()
![]()
![]()
升級(jí)過程
本
文假設(shè)進(jìn)行編譯的用戶名字是xyz,用戶目錄是/home/xyz/,所有源代碼都在/home/xyz/build/目錄下編譯。所有源代碼壓縮包都已
經(jīng)拷貝到/home/xyz/build/目錄下。升級(jí)Glibc的Linux系統(tǒng)的根文件系統(tǒng)使用hda5分區(qū),其文件系統(tǒng)格式為xfs。
1 準(zhǔn)備另外一個(gè)可啟動(dòng)的Linux系統(tǒng)
準(zhǔn)
備另外一個(gè)可啟動(dòng)的Linux系統(tǒng)的方法有很多,可以在硬盤上安裝另外一個(gè)Linux發(fā)行版,可以在DOS環(huán)境下使用loadlin.exe啟動(dòng)一個(gè)
Linux系統(tǒng),最簡(jiǎn)單的方式是使用Live CD,從光驅(qū)啟動(dòng)。無論使用什么形式,它都必須能掛載需要升級(jí)Glibc的根文件系統(tǒng)。
如
果選擇Live
CD啟動(dòng),Knoppix是一個(gè)很好的選擇。您可以從Knoppix的網(wǎng)站下載iso文件,燒制成啟動(dòng)CD,也可以把Knoppix的系統(tǒng)文件拷貝到硬盤
上,在DOS環(huán)境下,執(zhí)行l(wèi)oadlin.exe啟動(dòng)。筆者使用了Knoppix 5.0.1,制作成Live CD啟動(dòng)。參考資料有介紹如何使用
Knoppix 進(jìn)行系統(tǒng)恢復(fù)。
2 編譯
Glibc的編譯安裝與一般的軟件很類似,都是要經(jīng)過configure,make和make install三個(gè)階段。Glibc不能在源代碼目錄下編譯,必須在一個(gè)空目錄下編譯。
編
譯Glibc是需要內(nèi)核頭文件的,筆者的Mandriva Linux release
2006.0的內(nèi)核版本是2.6.12-12mdk,可以直接使用該版本內(nèi)核的頭文件升級(jí)到Glibc2.4
和Glibc2.5。如果升級(jí)到Glibc2.6,在make過程中,會(huì)出現(xiàn)以下錯(cuò)誤:
libc_pic.os: In function `sync_file_range':
: undefined reference to `.Lpseudo_end'
collect2: ld returned 1 exit status
這是由于2.6.12-12mdk的內(nèi)核頭文件太舊,為了順利編譯Glibc2.6,必須使用新的內(nèi)核頭文件。
2.1 編譯Glibc2.4或Glibc2.5
如果要升級(jí)Glibc到2.4或2.5,configure的時(shí)候只需要--prefix=/usr一個(gè)選項(xiàng),意思是該Glibc將會(huì)作為系統(tǒng)的標(biāo)準(zhǔn)動(dòng)態(tài)庫。
以升級(jí)到Glibc2.5為例,執(zhí)行以下命令進(jìn)行編譯:
$ cd ~/build
$ tar xjf glibc-2.5.tar.bz2
$ mkdir glibc-2.5-build
$ cd glibc-2.5-build
$ ../glibc-2.5/configure --prefix=/usr
$ make
glibc-2.5.tar.bz2是
Glibc2.5的源代碼壓縮包,執(zhí)行"tar xjf
glibc-2.5.tar.bz2"命令后,在~/build/目錄下產(chǎn)生了glibc-2.5目錄樹,Glibc2.5的源代碼就在這個(gè)目錄里面。
Glibc不能在源代碼目錄下編譯,因此執(zhí)行了"mkdir
glibc-2.5-build"命令,生成glibc-2.5-build目錄,編譯Glibc2.5時(shí)產(chǎn)生的文件,保存在這個(gè)目錄下。如果順利,將會(huì)
成功編譯,不會(huì)出現(xiàn)錯(cuò)誤信息。
2.2 編譯Glibc2.6
如
果您打算升級(jí)到Glibc2.6,使用版本為2.6.12-12mdk的內(nèi)核頭文件是不能成功編譯的,必須使用新的內(nèi)核頭文件。configure的時(shí)候
使用--with-headers選項(xiàng)指向新的內(nèi)核頭文件的目錄。Glibc的FAQ文檔明確指出最好使用最新版本的內(nèi)核頭文件,而且編譯時(shí)需要的內(nèi)核頭
文件的版本不需要與當(dāng)前正在運(yùn)行的內(nèi)核版本一致。筆者試驗(yàn)了版本為linux-2.6.20.7和linux-2.6.18兩個(gè)版本的內(nèi)核頭文件,編譯時(shí)
系統(tǒng)運(yùn)行的內(nèi)核版本是2.6.12-12mdk,都可以成功編譯Glibc2.6。
為了使用新版本的內(nèi)核頭文件,解開新版本的內(nèi)核壓縮包后,在源代碼目錄下執(zhí)行"make menuconfig",這將會(huì)進(jìn)入內(nèi)核的設(shè)置頁面,不需要作任何處理,直接退出并保存。然后執(zhí)行"make",不需要等待make完畢,一開始看到
SYMLINK include/asm -> include/asm-i386
就可以按下ctrl+c停止編譯內(nèi)核。執(zhí)行"make"的目的是在內(nèi)核源代碼目錄樹內(nèi)生成一些重要的文件和軟鏈接,其中在include/目錄下產(chǎn)生一個(gè)名為asm的軟鏈接指向asm-i386目錄,沒有這個(gè)鏈接,Glibc2.6是無法編譯的。
假設(shè)使用linux-2.6.20.7的內(nèi)核頭文件,執(zhí)行以下命令:
$ cd ~/build
$ tar xjf linux-2.6.20.7.tar.bz2
$ cd linux-2.6.20.7
$ make menuconfig
$ make
linux-
2.6.20.7.tar.bz2是2.6.20.7版本的Linux內(nèi)核源代碼壓縮包,執(zhí)行"tar xjf
linux-2.6.20.7.tar.bz2"命令后,將會(huì)產(chǎn)生linux-2.6.20.7目錄,Linux內(nèi)核的源代碼都在這個(gè)目錄下,其中內(nèi)核頭
文件在linux-2.6.20.7/include/下。確保linux-2.6.20.7/include/asm已經(jīng)產(chǎn)生后,就可以停止內(nèi)核的編
譯,然后進(jìn)行Glibc2.6的編譯:
$ cd ~/build
$ tar xjf glibc-2.6.tar.bz2
$ mkdir glibc-2.6-build
$ cd glibc-2.6-build
$ ../glibc-2.6/configure --prefix=/usr --with-headers=~/build/linux-2.6.20.7/include
$ make
glibc-2.6.tar.bz2是Glibc2.6的源代碼壓縮包,執(zhí)行"tar xjf glibc-2.6.tar.bz2"命令后,在~/build/目錄下產(chǎn)生了glibc-2.6目錄樹。
如
果您的系統(tǒng)當(dāng)前運(yùn)行的內(nèi)核已經(jīng)升級(jí)到比較新的版本,例如2.6.20.7,configure的時(shí)候,就不需要--with-headers選項(xiàng)了,與
Glibc2.4或Glibc2.5的configure命令一樣,只需要--prefix=/usr選項(xiàng)就可以了,但是前提條件是/lib
/modules/`uname -r`/source指向內(nèi)核的源程序目錄,您可以用以下命令查看它指向哪里:
$ ls -l /lib/modules/`uname -r`/
3.make install前的準(zhǔn)備工作
3.1 哪些目錄需要備份?
安裝Glibc前必須備份好原來的系統(tǒng)動(dòng)態(tài)庫,一旦安裝失敗,使用另外一個(gè)Linux系統(tǒng)啟動(dòng),掛載升級(jí)失敗的根文件系統(tǒng),還原Glibc為原來的狀態(tài)。可是哪些目錄需要備份?Glibc在安裝的時(shí)候,將會(huì)修改哪個(gè)目錄下的文件?
Glibc
在安裝時(shí)可以指定install_root選項(xiàng),命令Glibc把該選項(xiàng)指向的目錄作為根,文件都安裝到這個(gè)目錄下,通過觀察Glibc在這個(gè)目錄里生成
了什么目錄和文件,我們就可以知道Glibc在安裝的時(shí)候到底會(huì)修改哪些目錄了。假設(shè)安裝到~/build/system_fake_root上:
$ cd ~/build
$ cd glibc-2.6-build
$ make install install_root=~/build/system_fake_root
安裝后:
$ ls ~/build/system_fake_root
etc/ lib/ sbin/ usr/
可以看出,Glibc的make
install命令會(huì)修改/etc,/lib,/sbin和/usr目錄下的文件。這里最重要的是/lib和/usr。一般來說/usr目錄下有很多文
件,占用硬盤空間很大,實(shí)際也不需要對(duì)整個(gè)/usr目錄備份,使用以下命令查看Glibc會(huì)修改/usr/下的哪些目錄:
$ ls ~/build/system_fake_root/usr
bin/ include/ info/ lib/ libexec/ sbin/ share/
經(jīng)分析,筆者選擇了備份/lib,/usr/lib,/usr/include,/usr/sbin和/usr/bin。您當(dāng)然可以備份更多的目錄,不過筆者發(fā)現(xiàn)備份上述5個(gè)目錄已經(jīng)可以恢復(fù)系統(tǒng)的Glibc為原來的版本了。
3.2 備份目錄
使用su命令切換為root。執(zhí)行:
# cp -a /lib /lib.2.3.5
# cd /usr
# cp -a lib lib.2.3.5
# cp -a bin bin.2.3.5
# cp -a sbin sbin.2.3.5
# cp -a include include.2.3.5
經(jīng)過以上步驟,就備份了以后還原用的目錄。備份的目錄名字使用原目錄名后加上.2.3.5后綴,目的是區(qū)分不同的Glibc版本目錄。
3.3 如何還原系統(tǒng)的Glibc
如
果升級(jí)最終失敗,導(dǎo)致系統(tǒng)無法啟動(dòng),就必須使用另外一個(gè)Linux系統(tǒng)啟動(dòng),還原上述備份的目錄為原來的名字。以筆者的系統(tǒng)為例,升級(jí)失敗的根文件系統(tǒng)使
用hda5分區(qū),其文件系統(tǒng)格式為xfs,將被掛載到/mnt/m1目錄。使用Knoppix 5.0.1 Live
CD啟動(dòng)后,打開一個(gè)控制臺(tái),執(zhí)行"su"命令切換為root用戶,執(zhí)行以下命令
# cd /mnt
# mkdir m1
# mount -t xfs /dev/hda5 /mnt/m1
# cd /mnt/m1
# rm -fr lib
# mv lib.2.3.5 lib
# cd usr
# rm -fr lib bin sbin include
# mv lib.2.3.5 lib
# mv bin.2.3.5 bin
# mv sbin.2.3.5 sbin
# mv include.2.3.5 include
執(zhí)行上述命令后,Glibc已經(jīng)被恢復(fù)為原來的版本,系統(tǒng)應(yīng)該可以正常啟動(dòng)。
3.4 如何知道當(dāng)前的Glibc版本
Mandriva Linux release 2006.0的動(dòng)態(tài)庫是Glibc2.3.5。執(zhí)行"/lib/libc.so.6"可以知道當(dāng)前的Glibc是什么版本:
$ /lib/libc.so.6
GNU C Library stable release version 2.3.5, by Roland McGrath et al.
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.0.1 (4.0.1-2mdk for Mandriva Linux release 2006.0).
Compiled on a Linux 2.6.12 system on 2005-08-30.
Available extensions:
GNU libio by Per Bothner
crypt add-on version 2.1 by Michael Glad and others
linuxthreads-0.10 by Xavier Leroy
BIND-8.2.3-T5B
NIS(YP)/NIS+ NSS modules 0.19 by Thorsten Kukuk
Glibc-2.0 compatibility add-on by Cristian Gafton
libthread_db work sponsored by Alpha Processor Inc
Thread-local storage support included.
For bug reporting instructions, please see:
.
從以上輸出可以看到,當(dāng)前系統(tǒng)的Glibc版本是2.3.5,使用Gcc4.0.1編譯,編譯時(shí)運(yùn)行的Linux內(nèi)核版本是2.6.12。
Glibc的FAQ文檔給出以下程序用于查看當(dāng)前的Glibc的版本:
#include
#include
int main (void) { puts (gnu_get_libc_version ()); return 0; }
把上述程序?qū)懙絚hk_lib_v.c文件,執(zhí)行以下命令編譯:
gcc -o chk_lib_v chk_lib_v.c
執(zhí)行chk_lib_v后有以下輸出:
$ ./chk_lib_v
2.3.5
3.5 注意Coreutils依賴的動(dòng)態(tài)庫情況
Mandriva Linux release 2006.0系統(tǒng)的/lib/目錄下有個(gè)tls目錄。該目錄下的文件是能否成功升級(jí)Glibc到2.6的關(guān)鍵。使用ldd命令查看Coreutils的應(yīng)用程序依賴的動(dòng)態(tài)庫情況可以發(fā)現(xiàn):
$ ldd /bin/ls
linux-gate.so.1 => (0xffffe000)
librt.so.1 => /lib/tls/librt.so.1 (0xb7f60000)
libtermcap.so.2 => /lib/libtermcap.so.2 (0xb7f5b000)
libacl.so.1 => /lib/libacl.so.1 (0xb7f54000)
libc.so.6 => /lib/tls/libc.so.6 (0xb7e26000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0xb7e14000)
/lib/ld-linux.so.2 (0xb7f89000)
libattr.so.1 => /lib/libattr.so.1 (0xb7e10000)
請(qǐng)
注意上述的librt.so.1,libc.so.6和libpthread.so.0,它們都是位于/lib/tls/,而不是/lib/。換言
之,ls的執(zhí)行,依賴于/lib/tls目錄下的某些動(dòng)態(tài)鏈接庫文件。tls是thread-local
storage,當(dāng)不同的線程使用同一個(gè)全局變量的時(shí)候,各線程將會(huì)在本地保留該變量的備份,查閱參考資料可以了解更多有關(guān)tls的信息。
Glibc2.4,Glibc2.5和Glibc2.6都支持tls。
/lib/tls/下有以下文件:
$ ls -l /lib/tls
總用量 1488
-rw-r--r-- 1 root root 1229976 8月 30 2005 libc-2.3.5.so
lrwxrwxrwx 1 root root 13 5月 12 21:25 libc.so.6 -> libc-2.3.5.so
-rw-r--r-- 1 root root 145176 8月 30 2005 libm-2.3.5.so
lrwxrwxrwx 1 root root 13 5月 12 21:25 libm.so.6 -> libm-2.3.5.so
-rw-r--r-- 1 root root 84987 8月 30 2005 libpthread-0.10.so
lrwxrwxrwx 1 root root 18 5月 12 21:25 libpthread.so.0 -> libpthread-0.10.so
-rw-r--r-- 1 root root 30620 8月 30 2005 librt-2.3.5.so
lrwxrwxrwx 1 root root 14 5月 12 21:25 librt.so.1 -> librt-2.3.5.so
-rw-r--r-- 1 root root 22108 8月 30 2005 libthread_db-1.0.so
lrwxrwxrwx 1 root root 19 5月 12 21:25 libthread_db.so.1 -> libthread_db-1.0.so
/lib/tls目錄下的文件是一些很重要的動(dòng)態(tài)庫及軟連接,其中包括libc.so.6,它們都是指向2.3.5版本的動(dòng)態(tài)庫文件。
4. 安裝Glibc2.6
4.1 第一次make install
切換到root用戶,執(zhí)行make install就開始安裝Glibc了:
$ cd ~/build
$ cd glibc-2.6-build
$ su
# make install
在安裝過程中,將會(huì)出現(xiàn)如下錯(cuò)誤:
/home/xyz/build/glibc-2.6-build/elf/sln
/home/xyz/build/glibc-2.6-build/elf/symlink.list
rm -f /home/xyz/build/glibc-2.6-build/elf/symlink.list
rm: relocation error: /lib/tls/libc.so.6: symbol _dl_out_of_memory, \
version GLIBC_PRIVATE not defined in file ld-linux.so.2 with link time reference
make[1]: *** [install-symbolic-link] Error 127
make[1]: Leaving directory `/home/xyz/build/glibc-2.6'
make: *** [install] Error 2
安裝失敗后,輸入任何命令都是無效的,系
統(tǒng)只會(huì)重復(fù)"relocation error: /lib/tls/libc.so.6: symbol _dl_out_of_memory,
version GLIBC_PRIVATE not defined in file ld-linux.so.2 with link time
reference"的錯(cuò)誤信息,重新啟動(dòng)計(jì)算機(jī)在啟動(dòng)中就會(huì)失敗,根本無法進(jìn)入原Linux系統(tǒng)。
出現(xiàn)這樣
的錯(cuò)誤的原因是Coreutils的應(yīng)用程序都依賴于/lib/tls/下的動(dòng)態(tài)庫,在make
install的時(shí)候,/lib/ld-linux.so.2從原來指向ld-2.3.5.so被改為指向ld-2.6.so,但這個(gè)時(shí)候/lib
/tls/libc.so.6指向的仍然是/lib/tls/libc-2.3.5.so。/lib/ld-linux.so.2和/lib/tls
/libc.so.6各自指向不同版本的庫文件導(dǎo)致了Coreutils的命令執(zhí)行失敗,從而make install也失敗。
這
個(gè)時(shí)候,就要用另外一個(gè)Linux系統(tǒng)啟動(dòng),掛載升級(jí)失敗的根文件系統(tǒng),把原根文件系統(tǒng)的/lib/tls/下的鏈接全部改為指向2.6版本的庫文件,具
體就是/lib/tls/libc.so.6,/lib/tls/libm.so.6,
/lib/tls/libpthread.so.0和/lib/tls/librt.so.1這4個(gè)軟鏈接分別指向libc-2.6.so,
libm-2.6.so,libpthread-2.6.so和librt-2.6.so。libthread_db.so.1仍然是指向
libthread_db-1.0.so,但這個(gè)時(shí)候/lib/libthread_db-1.0.so已經(jīng)是Glibc2.6版本的了,原/lib
/tls/libthread_db-1.0.so必須被替換為Glibc2.6版本的libthread_db-1.0.so。
筆者使用Knoppix 5.0.1 Live CD啟動(dòng)計(jì)算機(jī),啟動(dòng)后,打開一個(gè)控制臺(tái),執(zhí)行"su"命令切換為root,執(zhí)行以下命令:
# cd /mnt
# mkdir m1
# mount -t xfs /dev/hda5 /mnt/m1
# cd /mnt/m1/lib/tls
# cp -f ../libthread_db-1.0.so .
# cp ../libc-2.6.so .
# cp ../libm-2.6.so .
# cp ../libpthread-2.6.so .
# cp ../librt-2.6.so .
# ln -sf libc-2.6.so libc.so.6
# ln -sf libm-2.6.so libm.so.6
# ln -sf libpthread-2.6.so libpthread.so.0
# ln -sf librt-2.6.so librt.so.1
上述命令就是把原根文件系統(tǒng)/lib/下
的libc-2.6.so,
libm-2.6.so,libpthread-2.6.so和librt-2.6.so拷貝到/lib/tls/下,并把/lib/tls
/libc.so.6,/lib/tls/libm.so.6,/lib/tls/libpthread.so.0和/lib/tls
/librt.so.1這4個(gè)軟鏈接從原來指向2.3.5版本的庫文件改為指向最新的2.6版本的庫文件。原/lib/tls
/libthread_db-1.0.so下的文件被/lib/libthread_db-1.0.so替換。
4.2 第二次make install
修
改了/lib/tls/下的鏈接和文件后,就可以重新啟動(dòng)計(jì)算機(jī),進(jìn)入原Linux系統(tǒng),這次將會(huì)正常啟動(dòng),登陸后,執(zhí)行Coreutils的命令,例如
ls,已經(jīng)不會(huì)出現(xiàn)"relocation error: /lib/tls/libc.so.6: symbol
_dl_out_of_memory, version GLIBC_PRIVATE not defined in file
ld-linux.so.2 with link time
reference"的錯(cuò)誤信息。由于Glibc2.6沒有徹底安裝完畢,我們還要重新執(zhí)行一次make install:
$ cd ~/build
$ cd glibc-2.6-build
$ su
# make install
這次make install將不會(huì)出現(xiàn)錯(cuò)誤,如果安裝成功,到最后會(huì)有以下信息提示:
Your new glibc installation seems to be ok.
make[1]: Leaving directory `/home/xyz/build/glibc-2.6'
執(zhí)行/lib/libc.so.6查看Glibc的版本:
$ /lib/libc.so.6
GNU C Library stable release version 2.6, by Roland McGrath et al.
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
Compiled by GNU CC version 4.0.1 (4.0.1-5mdk for Mandriva Linux release 2006.0).
Compiled on a Linux >>2.6.12-12mdk.
執(zhí)行chk_lib_v:
$ ./chk_lib_v
2.6
這都表明當(dāng)前系統(tǒng)的動(dòng)態(tài)庫已經(jīng)使用了Glibc2.6。
如果把/lib/tls/下的鏈接改為指向2.6版本的庫文件后,重新啟動(dòng)計(jì)算機(jī)仍然無法進(jìn)入原Linux系統(tǒng),就說明升級(jí)Glibc失敗,只能再次使用另外一個(gè)Linux系統(tǒng)啟動(dòng),恢復(fù)原系統(tǒng)的Glibc為原來的版本,請(qǐng)參考3.3節(jié)。
4.3 安裝時(shí)區(qū)和地區(qū)數(shù)據(jù)庫
雖然現(xiàn)在系統(tǒng)已經(jīng)使用Glibc2.6,但是在X Window下,使用fcitx中文輸入法的用戶會(huì)發(fā)現(xiàn)按下ctrl+space不會(huì)彈出中文輸入框。這是因?yàn)樾碌腉libc2.6還沒安裝時(shí)區(qū)和地區(qū)數(shù)據(jù)庫。執(zhí)行以下命令:
$ cd ~/build
$ cd glibc-2.6-build
$ su
# make localedata/install-locales
上述命令將會(huì)在/usr/lib/locale/下生成一個(gè)名為"locale-archive"的文件。重新啟動(dòng)X Window, 按下ctrl+space就可以調(diào)出中文輸入框并輸入中文了。
至
此,升級(jí)Glibc完畢。筆者在升級(jí)到了Glibc2.6的Linux系統(tǒng)上使用了
VMware,Openoffice,Mplayer,Skype,F(xiàn)irefox,Thunderbird,Vim,F(xiàn)citx等一系列軟件一段時(shí)間,
未發(fā)現(xiàn)由于升級(jí)了Glibc而導(dǎo)致的錯(cuò)誤出現(xiàn)。
回到Glibc2.3.5
成功升級(jí)后,想在Glibc2.6和原來的Glibc2.3.5之間切換是很容易的。因?yàn)榘惭b前對(duì)Glibc2.3.5的重要目錄進(jìn)行了備份,只需使用另
外一個(gè)Linux啟動(dòng),掛載原Linux的根文件系統(tǒng),把升級(jí)前備份好的/lib.2.3.5等目錄的名字改為/lib等原來的名字即可。
使用Knoppix 5.0.1 Live CD啟動(dòng),打開一個(gè)控制臺(tái),執(zhí)行"su"命令切換為root,執(zhí)行以下命令:
# cd /mnt
# mkdir m1
# mount -t xfs /dev/hda5 /mnt/m1
# cd /mnt/m1
# mv lib lib.2.6
# mv lib.2.3.5 lib
# cd usr
# mv lib lib.2.6
# mv bin bin.2.6
# mv sbin sbin.2.6
# mv include include.2.6
# mv lib.2.3.5 lib
# mv bin.2.3.5 bin
# mv sbin.2.3.5 sbin
# mv include.2.3.5 include
重新啟動(dòng),系統(tǒng)將會(huì)使用原來的Glibc2.3.5,Glibc2.6的目錄備份為原目錄名后加.2.6后綴。
總結(jié)
使
用源代碼升級(jí)Glibc,做好升級(jí)前的準(zhǔn)備是最重要的。首先要準(zhǔn)備好另外一個(gè)可以啟動(dòng)的,能掛載原根文件系統(tǒng)的Linux系統(tǒng)。其次是對(duì)/lib,
/usr/lib,/usr/include,/usr/sbin,/usr/bin等目錄進(jìn)行備份。成功升級(jí)后,可以在高低兩個(gè)版本的Glibc之間自
由切換。
升級(jí)前只要做好上述兩個(gè)準(zhǔn)備,升級(jí)系統(tǒng)的Glibc是安全的。
由于不同的Linux發(fā)行版的系統(tǒng)環(huán)境不一樣,因此使用源代碼升級(jí)Glibc的過程可能會(huì)有差異,為了成功升級(jí),讀者必須在升級(jí)過程中根據(jù)自己的系統(tǒng)的實(shí)際情況作相應(yīng)的調(diào)整。
(http://www.ibm.com/developerworks/cn/linux/l-cn-glibc-upd/index.html)
本文來自ChinaUnix博客,如果查看原文請(qǐng)點(diǎn):http://blog.chinaunix.net/u3/104386/showart_2062251.html |
|