RPM升級(jí)篇
升級(jí)做什么
RPM的升級(jí)功能是它受到用戶好評(píng)的原因之一。因?yàn)橛脩糇约簩⒁粋€(gè)軟件包從舊版本升級(jí)到新版本,特別是大型軟件,需要有經(jīng)驗(yàn)的支持和技術(shù)的積累,比較復(fù)雜,而用RPM升級(jí)軟件,只需一個(gè)rpm
-U命令就可以了,極大方便了用戶。
軟件升級(jí)基本做兩項(xiàng)工作,一是安裝新版本,二是卸載舊版本。RPM還有一項(xiàng)重要的工作要做,這就是妥善處理配置文件(CONFIG FILE)。若直接采用安裝方式,則用戶已配置好的配置文件就會(huì)被覆蓋,不符合用戶要求。
配置文件處理
RPM對(duì)某個(gè)配置文件,通過(guò)比較三種不同的MD5檢查和(checksum)來(lái)決定如何處理它。這三種不同的MD5檢查和是:
1. 原檢查和。它是舊版本軟件包安裝時(shí)配置文件的MD5檢查和。
2. 當(dāng)前檢查和。它是升級(jí)時(shí)舊版本配置文件的MD5檢查和。
3. 新檢查和。它是新版本軟件包中配置文件的MD5檢查和。
RPM針對(duì)以下幾種情況分別處理:
1. 當(dāng)原檢查和=X,當(dāng)前檢查和=X,新檢查和=X時(shí):
這表明配置文件未曾修改過(guò)。此時(shí),RPM會(huì)將新的配置文件覆蓋掉原文件,而不是對(duì)原文件不作處理,原因在于: 雖然文件名和文件內(nèi)容都沒有變化,但文件別的方面的屬性(如文件的屬主,屬組,權(quán)限等)卻可能改變,所以有必要覆蓋一下。
2. 當(dāng)原檢查和=X,當(dāng)前檢查和=X,新檢查和=Y時(shí):
這表明原配置文件沒有改動(dòng)過(guò),但是它與新軟件包中的配置文件卻有所不同。這種情況下,RPM將用新文件覆蓋掉舊文件,并且舊文件不作保存(因?yàn)樗辉膭?dòng)過(guò),沒有必要保存)。
3. 當(dāng)原檢查和=X,當(dāng)前檢查和=Y,新檢查和=X時(shí):
這表明新文件與舊文件內(nèi)容相同,但當(dāng)前文件已經(jīng)作過(guò)修改,這些修改對(duì)于新版本來(lái)說(shuō)應(yīng)該是合法的,可以使用的。因此,RPM對(duì)當(dāng)前文件予以保留。
4. 當(dāng)原檢查和=X,當(dāng)前檢查和=Y,新檢查和=Y時(shí):
這表明原文件經(jīng)過(guò)修改,現(xiàn)在已與新文件相同,這或許是用戶用來(lái)修補(bǔ)安全上的漏洞,新版本也作了同樣的修改。這種情況下,RPM將新文件覆蓋當(dāng)前文件,避免文件屬性方面的不同。
5. 當(dāng)原檢查和=X,當(dāng)前檢查和=Y,新檢查和=Z時(shí):
這表明用戶已修改了原文件,并且當(dāng)前內(nèi)容與新文件內(nèi)容不同。這種情況下,RPM無(wú)法保證新版本軟件能正常使用當(dāng)前的配置文件,所以采用了一個(gè)比較明智的辦法,既能保護(hù)用戶的配置數(shù)據(jù),又能保證新版本軟件正常。這種作法就是將當(dāng)前文件換名保存(給原文件名加個(gè).rpmsave的后綴,如原文件名為ABC,則換名后為ABC.rpmsave),同時(shí)安裝新文件,并給出警告信息,如:
warning: /etc/.funkey saved as /etc/.funkey.rpmsave
6. 當(dāng)沒有原檢查和時(shí):
此種情況下,當(dāng)前檢查和與新檢查和已無(wú)關(guān)緊要,這表明沒有安裝過(guò)此配置文件。因?yàn)闆]有安裝過(guò)此配置文件,所以RPM無(wú)法判斷當(dāng)前文件是否被用戶修改過(guò)。這種情況下,RPM會(huì)將當(dāng)前文件換名保存(原文件名后綴不是加個(gè).rpmsave,而是.rpmorig),同時(shí)安裝新文件,并給出警告信息,如:
warning: /etc/.inputdef saved as /etc/.inputdef.rpmsave
升級(jí)命令格式
升級(jí)RPM包時(shí),請(qǐng)用以下命令格式:
rpm -U [升級(jí)選項(xiàng)1 升級(jí)選項(xiàng)2...] [軟件包標(biāo)識(shí)1 軟件包標(biāo)識(shí)2...]
其中: 也可使用--upgrade代替-U,效果相同。
軟件包標(biāo)識(shí)
有關(guān)軟件包標(biāo)識(shí)的定義,請(qǐng)參見<<精通RPM之三--卸載篇>>。
選項(xiàng)列表
選項(xiàng)說(shuō)明
因?yàn)樯?jí)也是一種安裝,所以升級(jí)的選項(xiàng)列表與安裝選項(xiàng)列表基本相同,只是升級(jí)的選項(xiàng)列表增加了一項(xiàng)--oldpackage?,F(xiàn)著重說(shuō)明一下這個(gè)選項(xiàng),其它選項(xiàng)說(shuō)明見<<精通RPM之二--安裝篇>>,在此恕不贅述。
--oldpackage選項(xiàng): 從名字上就可以看出來(lái)是老版本軟件包的意思。為什么要將軟件"升級(jí)"到老版本?(這里的升級(jí)其實(shí)是降級(jí))這里面有個(gè)原因。用戶一直好好地用著老版本的軟件,當(dāng)有一天發(fā)現(xiàn)有新版本發(fā)布時(shí),馬上用rpm
-U命令升級(jí)到系統(tǒng)中,但因?yàn)樾掳姹居?臭蟲",所以這個(gè)軟件暫時(shí)不能正常工作。而這時(shí),直接用rpm -U命令是升級(jí)不到老版本的,因?yàn)橐话闱闆r的升級(jí)是將老版本升級(jí)到新版本,RPM默認(rèn)這一點(diǎn)。若想升級(jí)到老版本,則必須用這個(gè)特殊的選項(xiàng)。下面舉個(gè)例子:
# rpm -U -v lze-6.0-1.i386.rpm
package lze-7.0-1 (which is newer then lze-6.0-1) is already installed
#
注: 本例在升級(jí)過(guò)程中出現(xiàn)錯(cuò)誤,RPM提示lze軟件包已安裝,并且現(xiàn)存版本號(hào)7.0,高于準(zhǔn)備升級(jí)的版本號(hào)6.0,升級(jí)無(wú)法繼續(xù)。
若在命令行使用--oldpackage,結(jié)果會(huì)怎么樣呢?
# rpm -U -v --oldpackage lze-6.0-1.i386.rpm
lze-6.0-1
#
注: 命令執(zhí)行后輸出了軟件包標(biāo)識(shí)lze-6.0-1,表明升級(jí)到老版本成功了。
下面通過(guò)輸出調(diào)試信息來(lái)觀察一下升級(jí)軟件包時(shí)RPM做的主要工作:
# rpm -U -vv --oldpackage foo-3.0-2.i386.rpm 2>&1 | nl
1 D: counting packages to install
2 D: found 1 packages
3 D: looking for packages to download
4 D: retrieved 0 packages
5 D: New Header signature
6 D: Signature size: 68
7 D: Signature pad : 4
8 D: sigsize : 72
9 D: Header + Archive: 1577
10 D: expected size : 1577
11 D: opening database mode 0x42 in //var/lib/rpm/
12 D: found 0 source and 1 binary packages
13 D: requires: /bin/sh satisfied by db file lists.
14 D: installing binary packages
15 D: getting list of mounted filesystems
16 D: New Header signature
17 D: Signature size: 68
18 D: Signature pad : 4
19 D: sigsize : 72
20 D: Header + Archive: 1577
21 D: expected size : 1577
22 D: package: foo-3.0-2 files test = 0
23 D:file: /etc/foo.conf action: create
24 D:file: /usr/bin/foo action: create
25 D: running preinstall script (if any)
26 + echo preinstall
27 preinstall
28 foo-3.0-2
29 D: running postinstall scripts (if any)
30 + echo postinstall
31 postinstall
32 + echo triggerinstall
33 triggerinstall
34 + echo triggeruninstall
35 triggeruninstall
36 + echo preuninstall
37 preuninstall
38 D: will remove files test = 0
39 D:file: /usr/bin/foo action: skip
40 D:file: /etc/foo.conf action: skip
41 D: running postuninstall script (if any)
42 + echo postuninstall
43 postuninstall
44 D: removing database entry
45 D: removing name index
46 D: removing group index
47 D: removing requiredby index for /bin/sh
48 D: removing trigger index for file
49 D: removing trigger index for file
50 D: removing trigger index for file
51 D: removing file index for foo.conf
52 D: removing file index for foo
注: 第1-4行: 計(jì)算命令行上要升級(jí)的包數(shù),并且下載那些需要下載的包裹文件;
第5-10行: 根據(jù)包裹文件頭部信息,確定軟件占用空間;
第11,12行: 打開RPM數(shù)據(jù)庫(kù)及包裹文件;
第13行: 檢查依賴是否滿足,本例滿足;
第14行: 安裝執(zhí)行程序包;
第15行: 取當(dāng)前已安裝文件系統(tǒng)列表;
第16-21行: 再度檢查包裹頭信息,確定占用系統(tǒng)空間;
第22-24行: 確定包中各個(gè)文件的執(zhí)行操作(action),均為建立(create);
第25行: 執(zhí)行安裝前腳本程序(如果有的話);
第26-27行: 以+開頭的為腳本程序執(zhí)行的命令,其后為其輸出結(jié)果;
第28行: 安裝foo-3.0-2包;
第29行: 執(zhí)行安裝后腳本程序(如果有的話);
第30-31行: 以+開頭的為腳本程序執(zhí)行的命令,其它為執(zhí)行結(jié)果;
第32-33行: 執(zhí)行安裝時(shí)觸發(fā)腳本程序;
第34-35行: 執(zhí)行卸載前觸發(fā)腳本程序,自此開始卸載原軟件包;
第36-37行: 執(zhí)行卸載前腳本程序;
第38-40行: 確定原包中各文件的執(zhí)行操作,本例均為跳過(guò)(skip),即不作處理;
第41-43行: 執(zhí)行卸載后腳本程序;
第44-52行: 刪除原包在RPM數(shù)據(jù)庫(kù)中的所有信息(數(shù)據(jù)及索引)。
評(píng)論
查看更多