analyse yum
Yum 工作原理
Yum Compotents
Yum 服务器(repository仓库)
- 数据:rpm包
- 元数据:rpm包的属性,包括大小,版本,依赖关系,通过createrepo命令生成,保存在repodata中
所有要发行的rpm包都放在yum服务器以供下载,rpm包根据kernel版本号,cpu版本号分别编译发布,yum服务器只要提供简单的下载。Yum服务器最重要的环节就是整理出每个rpm包的基本信息即元数据metadata,yum服务器上提供了createrepo工具用于把rpm包的基本概要信息做成一张清单—-元数据1
2
3
4
5$ createrepo -o /var/www/yum/centos/5/i386/ /var/www/yum/centos/5/i386
3/3 - rpm_test-0.0.1-3.noarch.rpm
Saving Primary metadata
Saving file lists metadata
Saving other metadata
在createrepo之后会在/var/www/yum/centos/5/i386/生成下面的目录和文件1
2
3
4
5
6$ tree repodata/
repodata/
|-- filelists.xml.gz
|-- other.xml.gz
|-- primary.xml.gz
`-- repomd.xml
Filelists.xml记录了rpm包列表,版本号,配置信息
Primary.xml记录了rpm包的依赖信息
Yum客户端
Client每次调用yum install或search都去解析/etc/yum.repo.d下面所有以.repo结尾的配置文件,这些文件指定了yum服务器的地址。Yum定期更新yum服务器上rpm包的清单,把清单保存到yum的本地cache里面,默认在/var/cache/yum。根据清单信息描述,来确定安装包的名字版本号,所需要的依赖包,再去下载rpm包。
本地yum cache /var/cache/yum,每个repo记录的cache1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27/var/cache/yum/
|-- base
| |-- cachecookie
| |-- mirrorlist.txt
| |-- packages
| |-- primary.xml.gz
| |-- primary.xml.gz.sqlite
| `-- repomd.xml
|-- epel
| |-- 76c4dcbfaf075e55d5876839eb11c4f33b3a2495-primary.sqlite
| |-- cachecookie
| |-- mirrorlist.txt
| |-- packages
| `-- repomd.xml
|-- firefoxbug
| |-- cachecookie
| |-- packages
| |-- primary.xml.gz
| |-- primary.xml.gz.sqlite
| `-- repomd.xml
|-- timedhosts.txt
|-- updates
| |-- cachecookie
| |-- mirrorlist.txt
| |-- packages
| |-- primary.sqlite
| `-- repomd.xml
我的本地机器的cache1
2
3
4
5
6
7
8
9[root@mthz3mpi001 qa_os_centos6.5_x86_64]# pwd
/var/cache/yum/x86_64/6/qa_os_centos6.5_x86_64
[root@mthz3mpi001 qa_os_centos6.5_x86_64]# ll
total 15728
-rw------- 1 root root 0 Jan 8 01:34 cachecookie
drwx------ 2 root root 4096 Jan 7 03:06 packages
-rw------- 1 root root 1470397 Oct 25 15:01 primary.xml.gz
-rw------- 1 root root 14625792 Jan 6 03:19 primary.xml.gz.sqlite
-rw------- 1 root root 1214 Oct 25 15:01 repomd.xml
primary.xml.gz就是yum服务器上的”清单”,但是这里以sqlite方式存储了,可以查看sqlite的db
每次安装yum包都会来查询这个sqlite的DB
timedhosts.txt这个文件记录着所有源地址访问所需要的时间,可以查到哪些源的地址比较慢
YUM Client process
- 获取仓库元数据
Yum会先将仓库的元数据缓存于本地的/var/cache/yum- 安装程序包
Yum 分析本地的元数据文件,结合本地系统环境(已经安装的包)做出要安装的程序决策- 获取程序包
根据决策联系yum仓库,下载各程序包缓存于本地后,一并安装
Client code analysis
before code
RPM package names are made up of 5 parts: the package name, epoch, version, release, architecture. This format is commonly referred to as the acronym NEVRA. And the format for the whole string is n-e:v-r.a (i.e foo-0:1.2.3-el5)
In a word, yum compare just compare E.V.R
e.g a sample using labelCompare:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20import rpm
# t1 and t2 are tuples of (version, release)
# return 1: a is newer than b
# 0: a and b are the same version
# -1: b is newer than a
def compare(t1, t2):
v1, r1 = t1
v2, r2 = t2
return rpm.labelCompare(('1', v1, r1), ('1', v2, r2))
t1 = ['foo','1.2.5']
t2 = ['foo','1.2.1']
t3 = ['foo','1.2.1']
print compare(t1,t2)
print compare(t2,t3)
print compare(t2,t1)
result:
1 | [root@hugwang3 yumtest]# python cmp.py |
最后贴上rpm版本比较的源码
appendix (rpm/lib/rpmvercmp.c)
1 | include "system.h" |