[转帖]Linux平台软件管理系统设计与规划_VMware, Unix及操作系统讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  VMware, Unix及操作系统讨论区 »
总帖数
7
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3979 | 回复: 6   主题: [转帖]Linux平台软件管理系统设计与规划        下一篇 
ganxinge
注册用户
等级:少校
经验:893
发帖:66
精华:0
注册:2013-2-22
状态:离线
发送短消息息给ganxinge 加好友    发送短消息息给ganxinge 发消息
发表于: IP:您无权察看 2013-2-27 11:13:21 | [全部帖] [楼主帖] 楼主

本篇涉及的内容有:
(1): RPM 在 linux系统上如何运行浅解与要点总结
(2): YUM 服务出现和要素分析
(3): 怎样搭建和使用 yum 服务
(4): createrepo 和 RPM 的索引文件分析
(5): yum 本地cache
(6): yum clean 源码浅析
(7): yum 配置文件详解
(北京联动北方科技有限公司: yum插件剖析与开发

========================================
在写完 “ RPM认知” 和 ” RPM制作与SPEC文件“ 两篇后,本来计划再整理学习下一篇 ” RPM如何在linux系统上工作“的,但是考虑了下,因为我对 RPM 的源码还没有阅读,只能说出
大概的动作/流程等,细节言不明,难以从开发人员的角度来分析,只好就粗糙点从运维人员的角度来总结下。
关于 ”RPM如何在linux系统上工作“的内容,就简单总结了几点常用的知识,在本篇开头来讲下。
很庆幸有这个空闲的周末,蜗居西溪旁,小雨漫天下,卧室微冷,聆听听着《夜的钢琴曲》,慢慢总结一下这篇,废话不多,开始。 北京联动北方科技有限公司



赞(0)    操作        顶端 
ganxinge
注册用户
等级:少校
经验:893
发帖:66
精华:0
注册:2013-2-22
状态:离线
发送短消息息给ganxinge 加好友    发送短消息息给ganxinge 发消息
发表于: IP:您无权察看 2013-2-27 11:17:55 | [全部帖] [楼主帖] 2  楼

从宏观上来说,linux操作系统(只看OS层面,不谈硬件)就是由静态的文件系统和动态的进程组成的(不知道这样说合适不合适)。文件系统记录了 ”我是什么样的,我有什么“,而进程则能够用文件系统的这些功能动态的改变OS的状态或者对外提供服务。
其实这样的OS也就能够运行了,为什么还要出现软件包呢?大概是人们为了方便的管理操作系统吧,就跟一个国家都是零散的百姓而没有组织机构一样,那样会很难于管理,为此才把地方划为郡县,省市,县,乡,村,甚至大队~~。理想状况下,这样任意一个人需要服务,都可以直接找自己归属的组织去寻求帮助。工作起来效率提高。
操作系统当然不能够只是零散的文件组成,也需要对这些文件/程序进行管理,因此,就有了软件包的概念。某些文件属于某个软件包,某个软件包有某些文件。这样的有序性
是提供了管理效率,但是也是有付出的,那就是存储,需要有额外的空间来记录文件和包的对应关系。当然,在一个包内部,这是不需要的,因为任何咚咚都属于所在的这个包,当环境转移到OS层面之后,多个软件包要在OS上共存,有序管理,我们不仅要记录文件到包的关系,有时也要记录包和包之间的关系。
逐渐的,当这些信息被梳理并且记录时,就形成了软件包数据库的概念。对 RPM 而言就是 RPM数据库。

以前没有包的概念时,是人类直接通过工具操作文件,现在介入了数据库的操作。简单画了个图,表达此改变,如下:

北京联动北方科技有限公司 2012-12-29 14:03 上传 下载附件 (20.19 KB)

自然而然,我们大概也就猜到了 RPM 是如何在OS上工作的: 用户通过工具(rpm命令)管理软件包,也就是对文件系统进行增删查改,在增删查改的同时(也可能先于或者晚于),也对RPM的数据库进行了增删查改操作,总之,RPM数据库是为了方便用户通过工具来管理系统上的文件系统或者说软件包。

下面我们列举下比较重要的几个方面,都是跟RPM在OS上的管理相关的。


赞(0)    操作        顶端 
ganxinge
注册用户
等级:少校
经验:893
发帖:66
精华:0
注册:2013-2-22
状态:离线
发送短消息息给ganxinge 加好友    发送短消息息给ganxinge 发消息
发表于: IP:您无权察看 2013-2-27 11:20:00 | [全部帖] [楼主帖] 3  楼

(1)关于 linux 主机上的 RPM 数据库

RPM 在 linux 机器上工作原来是比较明确的,首先有实际的rpm解压缩并且安装后的文件;另外有Rpm 的DB文件,
存储这些安装了的 rpm 的信息,这些库中信息在 RPM进行安装,升级和卸载时进行更新。

RPM命令对两者的操作有: (1):对DB库进行增删查该 (2):对文件系统进行增加和删除和读取。
结合起来看:

(1): RPM的安装/升级,写入DB库,写文件系统,生成安装列表和服务,配置等,执行安装时脚本。
(2): RPM卸载,删除DB库,删除文件系统中归属于该软件包的文件,执行卸载时脚本。
(3): RPM查询, 读取DB库/文件并且显示。

RPM 的在主机上的数据库有好多个,根据不同的应用类型,采用不同的访问方法,可以看下: file /var/lib/rpm/* | grep Berkeley

/var/lib/rpm/Basenames: Berkeley DB (Hash, version 8, native byte-order)
/var/lib/rpm/Conflictname: Berkeley DB (Hash, version 8, native byte-order)
/var/lib/rpm/Dirnames: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Filemd5s: Berkeley DB (Hash, version 8, native byte-order)
/var/lib/rpm/Group: Berkeley DB (Hash, version 8, native byte-order)
/var/lib/rpm/Installtid: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Name: Berkeley DB (Hash, version 8, native byte-order)
/var/lib/rpm/Packages: Berkeley DB (Hash, version 8, native byte-order)
/var/lib/rpm/Providename: Berkeley DB (Hash, version 8, native byte-order)
/var/lib/rpm/Provideversion: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Pubkeys: Berkeley DB (Hash, version 8, native byte-order)
/var/lib/rpm/Requirename: Berkeley DB (Hash, version 8, native byte-order)
/var/lib/rpm/Requireversion: Berkeley DB (Btree, version 9, native byte-order)
/var/lib/rpm/Sha1header: Berkeley DB (Hash, version 8, native byte-order)
/var/lib/rpm/Sigmd5: Berkeley DB (Hash, version 8, native byte-order)
/var/lib/rpm/Triggername: Berkeley DB (Hash, version 8, native byte-order)


复制代码能够看到,主要是 HASH 和 BTREE 这两种访问方式。(很奇怪,version 8 的是 HASH, version 9的是BTREE ?是应用相关,还纯粹是作者爱好呢?)

RPM 的所有DB,都是从 /var/lib/rpm/Packages 生成的。可以做个实验,把除了 Packages 以外的其它文件全部删掉。
然后重新 rpm --rebuilddb -vv
这些文件都会一一生成,因为构成这几个新的db文件的信息都在Packages中包含了。(如果你把这个文件干掉了,那就悲催了,
曾经遇到有人把这个文件给删掉了,只好从同组配置接近的机器给他拷贝了一个os和arch一样的机器的Packages,重新生成了下db,还好,能继续用,呵呵)。因为这个文件中记录了你的机器安装的所有RPM和文件列表,一旦这个文件丢失了,rpm就不知道你的机器上有哪些rpm了,当你通过
rpm -qf path 查询某个二进制文件属于哪个rpm时,也不会有结果输出。

关于 /var/lib/rpm/Packages 这个 DB 文件的最初来源,我分析(结合猜测)是这样的:

首先,在安装(或者OS安装时)每一个 rpm 文件的时候,rpm 命令都会把要安装的 rpm 包的信息分析出来,包括我们在第一篇看到的所有TAG还有文件列表等信息;
然后会把这些信息写入 /var/lib/rpm/Packages 文件中,如果这个文件不存在,就创建;当删除包时,就会从 /var/lib/rpm/Packages 中
删除与该包相关的所有信息。该文件中记录了所有 rpm 的全量信息,因此,我们通过 rpm 命令查询时,才能够看到那么多灿烂和丰富的信息。

以rpm -qf 和 rpm -ql 为例:
比如,为了能从 xshell 拷贝文件到windows机器,我经常会用 sz/rz命令,但是有些机器上就是没这个命令,
要安装,又不知道它在哪个包,怎么办,这时就需要用 rpm -qf 来查询了:

找一台安装了 sz/rz 命令的机器: # which sz

/usr/bin/sz
# rpm -qf /usr/bin/sz
lrzsz-0.12.20-22.1


复制代码喔,我们发现sz和rz是在 lrzsz 这个包中的,然后在需要的机器上 rpm/yum 安装 lrzsz 包即可。

那么,rpm -qf 命令路径 就能查到这个命令属于那个包,这是怎么做到的呢?

首先我们知道安装 lrzsz 时 rpm 会把 这个包的所有信息写入 /var/lib/rpm/Packages 文件,这个包包含的文件列表也会写入
到 这个文件中,然后才会更新生成 /var/lib/rpm 中的其它DB文件(个人理解,其它DB文件就是为了查询加速而用生成的cache.)

然后,当执行 rpm -qf /usr/bin/sz
复制代码时,rpm 就会去 /var/lib/rpm/Packages 中(或者其它cache文件中)查询包含 /usr/bin/sz 这个路径的
包,当然就查到了是 lrzsz.

有人说,可能查到多个包么?这个是不可能的,因为 rpm 在安装 rpm 文件的时候,也就是往 /var/lib/rpm/Packages
中写数据的时候,会检查这个rpm 中包含的文件列表是否已经在本机安装的其它包中出现了,如果找到了,就会警告: 这个文件和其它某个包中的
某某文件冲突了的错误信息,这个现象做SA的同学应该都见过。

实验: ls -alt /var/lib/rpm/Packages

-rw-r--r-- 1 rpm rpm 19234816 Dec 27 09:30 /var/lib/rpm/Packages


复制代码我们能够看到,这个文件只对root 可以写,我们尝试改下它的属性: chattr +i /var/lib/rpm/Packages
复制代码设置不可改变属性,然后尝试安装包: rpm -ivh RPMS/i386/test-baby-1.1-1.i386.rpm

error: cannot open Packages index using db3 - Permission denied (13)
error: cannot open Packages database in /var/lib/rpm


复制代码因为rpm 没有权限去写 Packages 这个数据库文件。 # chattr -i /var/lib/rpm/Packages

rpm -ivh RPMS/i386/test-baby-1.1-1.i386.rpm
Preparing... ########################################### [100%]
1:test-baby ########################################### [100%]


复制代码这下就成功了,再次验证了 rpm 在包安装时对 /var/lib/rpm/Packages 的写操作确实是存在的。
同样,你也可以同样方法测试下卸载包时对 /var/lib/rpm/Packages 文件的写操作是否存



赞(0)    操作        顶端 
ganxinge
注册用户
等级:少校
经验:893
发帖:66
精华:0
注册:2013-2-22
状态:离线
发送短消息息给ganxinge 加好友    发送短消息息给ganxinge 发消息
发表于: IP:您无权察看 2013-2-27 11:20:54 | [全部帖] [楼主帖] 4  楼

(2)关于 /var/log/rpmpkgs 和 /etc/cron.daily/rpm

在linux系统上能够看到

# rpm -qf /etc/cron.daily/rpm
rpm-4.4.2-37.el5


复制代码/etc/cron.daily/rpm 是 rpm 这个包带的一个每日执行的crontab任务。
/etc/crontab 中配置每天4:02执行 cron.daily 里面的计划任务。
看下这个脚本的内容: cat /etc/cron.daily/rpm

#!/bin/sh
/bin/rpm -qa --qf '%{name}-%{version}-%{release}.%{arch}.rpm\n' 2>&1 \
| /bin/sort > /var/log/rpmpkgs


复制代码就是把 系统上所有 rpm 的列表导出下,排序存储在 /var/log/rpmpkgs 这个文件中。
这个文件有什么作用呢?个人分析应该有以下两个作用:

(1): 可以作为rpm -qa 的 cache文件,如果这个文件在很短时间内刚更新,rpm -qa 直接打印该文件内容即可。
(2): 有人可能已经想到了,它可以帮助恢复你的rpm 数据库文件,如果你不小心把 /var/lib/rpm/Packages 弄坏或者丢了,
但是很幸运,var/log/rpmpkgs 这个文件还在,而且是比较新的,然后你就可以如下恢复你的rpm 数据库了。

第一: 找到 系统的安装镜像包,也就是包含了所有OS的RPM列表。
第二:写个脚本,读取 var/log/rpmpkgs 文件,每行是一个rpm 文件,进行安装,这里的安装可不是实际安装。而是
要采用一个特殊的功能,看下 rpm 的 man 手册: --justdb

Update only the database, not the filesystem.


复制代码只是更新rpm 的数据库,并不更新系统文件(好像这个安装过程也是 --noscripts的,如果你真的走到这一步,可以检验下,然后告诉我,呵呵)。



赞(0)    操作        顶端 
ganxinge
注册用户
等级:少校
经验:893
发帖:66
精华:0
注册:2013-2-22
状态:离线
发送短消息息给ganxinge 加好友    发送短消息息给ganxinge 发消息
发表于: IP:您无权察看 2013-2-27 11:21:32 | [全部帖] [楼主帖] 5  楼

(3) rpm/rpmq/yum/rpmDB hang 住,死锁的情况

在实际工作中,有时会碰到执行rpm/yum 等命令时,没有任何反应,进程 hang 住的现象,用 strace -p pid 会发现进程 hang 在对 对futex 的操作上,
据有些文章说这个是berkeley db 支持多进程操作不好导致DB死锁的结果。曾经尝试寻找原因,但是未能跟踪到,只总结了下解决办法,希望对碰到的同学
有帮助。

首先查看是哪些进程,一般无非是 rpm rpmq yum 这三个其中的若干个,直接 sudo killall -9 yum rpm rpmq;
复制代码然后清除临时库文件: sudo rm -fr /var/lib/rpm/__db.00*
复制代码这样就可以了。我一般给同事提供的三板斧就是: (1): sudo killall -9 rpm rpmq yum

(2): sudo rm -fr /var/lib/rpm/__db.00*

(3): sudo yum clean all
复制代码当然,别的原因导致的 hang 住情况,就要另当别论了。视具体情况处理。


赞(0)    操作        顶端 
ganxinge
注册用户
等级:少校
经验:893
发帖:66
精华:0
注册:2013-2-22
状态:离线
发送短消息息给ganxinge 加好友    发送短消息息给ganxinge 发消息
发表于: IP:您无权察看 2013-2-27 11:22:03 | [全部帖] [楼主帖] 6  楼

开始 yum 的介绍
用 yum 服务 对 RPM 进行管理

类似于 RPM 的出现一样,yum 的出现也是为了方便管理而生,对于软件包的管理,采用 rpm 文件来做载体; 安装,部署等操作时,用 rpm 命令,基本上也够了。
好多人现在可能还处于这个状态,我一年之前也是如此:只知道 rpm 能够查看 rpm 包信息,安装,卸载等操作,小日子得过且过也就够了。后来,接触的环境稍微大点,就遇到一些问题了,大概总结了下,面临的问题已以下几点最为典型:

(1):作为开发人员,我只在32位的 rhel5.4 系统上开发,测试。每次修改代码后都会重新 rpmbuild包, 然后把rpm 交给同事去安装,而且同事的操作步骤大概会是:先卸载原来的rpm, 清空安装目录,然后安装新的rpm,这期间,他还可能还要备份自己的配置文件。忽然有一天,同事报告:这台机器不能安装你的rpm,仔细一看,是x86_64平台的系统,或者是4u8的系统,也可能是6u3的系统。显然,这种不同 arch 和 os release version 的环境,是单用 rpm 面临一类问题.

(2):某人开发的 XXOO.rpm 使用了接近十个第三方库,运行时依赖于这些库的so,因此安装时,也就需要依赖于包含这些库的rpm包, 严格按照规范,他在编写 spec 文件时,写了N 个 require 依赖,结果每次部署时,只要运行命令: rpm -ivh XXOO.rpm
复制代码,就会报告找不到依赖的若干个包,面对这样的问题,有的聪明一点的部署人员就会把依赖的包安装的语句写在一个脚本中,先执行这个脚本安装依赖包,然后再安装 XXOO 这个包,这样做即便能够解决问题,还是很麻烦,因为我们拿到rpm后还要分析它的require list, 人为的标明,然后先替他安装。有木有一种机制能够自动检测XXOO 依赖的 rpm 并且尝试进行安装呢?

(3):我开发的软件生成的 RPM 已经有很多版本了,每次为了升级到最新版,都需要记住最新的 RPM 文件的名字,而且是完整的名字,比如:test-daddy-1.1-1.x86_64.rpm,然后再执行 rpm -Uvh http://URL路径/test-daddy-1.1-1.x86_64.rpm
复制代码才能够安装成功,有没有一种机制,能够用很简单的方式:我只给它 RPM 的名字,就能够自动安装对应包的最新版 rpm 文件呢,而且还能安装指定版本的 rpm 呢?

(4):几台机器需要安装或者管理 rpm 时,直接 rpm -i 安装对应OS的包即可,如果成千上万台机器都需要部署该软件,而且有不同 os 版本,平台不一样,那该怎么办?有同学可能会自己写个脚本拷贝到目标机器去执行,自己检查os和arch,然后安装对应的rpm,这也是一种办法,但是有木有更简洁的方式呢,通用而且灵活,简易操作?

(5):有时候我们并不确定要装哪个版本的包,只想看看已经有哪些 rpm 了,然后再选择安装哪个。。你会怎么做?登录rpm服务器去 find,ls ? 还是高级点,安装个lynx,用 lynx --dump http://URL地址
复制代码浏览文件列表,然后grep选择,再 RPM 安装? 这样岂不是有些太费事?


对于上面列出的五个问题(也可能更多),yum 给提供了很好的解决方案,或者说功能接口。我想 yum 的出现也是由于最早的rpm使用者遇到了不止上面的五个问题等诸多难题后,总结问题特征,归纳,才设计开发出来的。

下面我们会以庖丁解牛的方式来给您阐述 yum 的强大功能和涉及到的知识点,或者详细或者粗糙,由于我个人能力有限,就只就自己知道和能够搜索到的范围的来说吧,有不对的地方请尽管指出。


赞(0)    操作        顶端 
ganxinge
注册用户
等级:少校
经验:893
发帖:66
精华:0
注册:2013-2-22
状态:离线
发送短消息息给ganxinge 加好友    发送短消息息给ganxinge 发消息
发表于: IP:您无权察看 2013-2-27 11:22:55 | [全部帖] [楼主帖] 7  楼

yum 服务构成的要素

构成一个完整的 yum 服务,需要以下及部分:

(1): yum 服务器上的服务仓库 (存储rpm文件和索引文件)
(2): 提供rpm和索引下载的网络服务(http或者ftp服务)
(3): 安装客户端的 yum 命令集 (接收用户输入,从服务器检索/下载文件)
(4): 客户端配置文件以及扩展功能模块。

用架构师大会的PPT <<2012系统架构师大会-Linux平台软件管理系统设计与规划.pptx>> 中的一幅图,来表示下这四个要素的部署关系图:


北京联动北方科技有限公司 2012-12-30 12:13 上传 下载附件 (719.82 KB)

简单描述一下一个 rpm 从发布进 yum, 到客户端可用的过程:

yum 中 rpm 从发布到可用的过程

1. 开发完成,RPM 已经通过 rpmbuild 或者其它工具制作好,把 rpm 放到 yum 服务器的 rpm 仓库目录下 。
2. 在 yum服务器的 仓库目录 (具体目录位置后面会讲)执行 createrepo 命令,该命令会扫描当前目录(包括子目录)里面的rpm 文件,记录rpm 文件的信息,写入repodata 目录中的索引文件中。这样 yum 中就有了新发布的 rpm 的信息了。
3. 使用者在客户端安装了 yum 命令,通过配置 yum 的客户端配置文件,指定了一个或者若干个安装源, yum 安装/检索包时会去这些安装源上检索索引文件。
4. 使用者在客户端使用 yum install pkgname 方式安装包,yum命令 会把配文件中配置的 yum服务器的地址(安装源)作为目标服务器,通过http/ftp/file服务去 yum 服务器上下载索引文件,然后在索引文件中查找有无指定的rpm(适合在本系统安装),找到的话,就按照配置中的路径组成url地址,下载rpm, 并且在本地安装。
5. 安装后,索引文件和rpm包会cache到本地的cache目录,方便下次使用,而且把安装rpm 的信息记录进本地 rpm 的数据库文件中。

为了读者能够实际操作一把,我们给出一个实际的例子:



赞(0)    操作        顶端 
总帖数
7
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论