Sunday, March 7, 2010

what's good about conary

试图总结一下 conary 到底有什么独特之处... 不过我对其他的包管理不是很熟悉,所以不太好总结。

这样,以下内容基本上是这篇文章的意译。

包管理,也就是管理系统上所有其他软件的一个软件。但 conary 不只是一个包管理软件,更是一个强大的对软件系统的版本管理系统。

===========
第一个问题,如何组织软件源(repository)

在 deb/rpm 系统上,一个 repository 无非是某个服务器上的一个目录,其中存放着软件包(一些文件)。文件的命名无非就是"软件名",加上"软件版本"(当然一般还有其他部分,稍后再提)。

问题来自于文件的命名是任意的,手动的。比如有两个软件源,都提供了firefox-3.0 这个包,那么包管理就会搜索到两个"相同"的包,可能产生冲突。

而 conary 不这样处理软件源,conary 的 repository 并不是一个静态的目录,而是一个有版本的动态的分支。整个软件源都是处在版本控制下的,随着其中软件的更新,不断的向前发展,而不是像磁盘文件系统上的一个目录,新版本的文件会覆盖旧文件。

当然,conary 里面的包名字也必须有好几个部分,比如名字加版本。但这些都是由 conary 自动管理,没有手动的过程,conary 能保证两个不同的包,用户能识别出它们确实是不一样的。比如有两个 deb 的源,apt.joeschmoe.com 和 apt.joesmith.com,它们有同一个版本的 liferea,那包名可能是一样的,就会有问题,而 conary 不会遇到这个矛盾,因为,软件源的域名其实也是包名字的一部分。

如果 deb 要以域名来辨别不同的包,那只能把域名写到文件名里面,结果必然是,软件包的名字变得特别长。正因为 conary 下的“包”并不是以文件形式存在的,才能做到上边这一点。

而问题没有到此为止,一般发行版会支持多个硬件平台 (至少有 32 位或 64 位之分吧)。deb/rpm 的做法是什么?只能把 arch 写进文件名里面。结果就是这样的,liferea-1.2.2-2.el5.rf.x86_64.rpm。能看出跟 liferea-1.2.2-2.el5.rf.x86-64.rpm 的区别吗?

conary 也需要支持不用的 arch,包名字也会包含 x86, x86_64 等等。但由于 conary 的“自动管理”,默认情况下这些额外信息是被隐藏的。有时候一个简单的"liferea"就能识别一个包,有时候需要 "liferea=1.0"才能识别, 有时候需要 "liferea=foresight.rpath.org@fl:2-devel" (以区别 "liferea=foresight.rpath.org@fl:2-qa", 或者 "liferea=jesse.rpath.org@fl:2-devel"),有时候甚至需要"liferea=foresight.rpath.org@fl:2-devel/1.7.3-0.1-2",而这就是 conary 里面包的 full-name 的样子。

===========
正由于以上这些,conary 不需要复杂的 sources.list。如果你想从我的个人软件源安装 liferea,在 deb 世界里需要把我的源添加到 sources.list 里边,这样 apt 才能自动从那里查找更新。

而对于 conay, 只需要安装 liferea=jesse.rpath.org@fl:2-devel,conary 会记住这个源,以后只会从这里查找更新,即使 foresight 的官方源里面有更新的版本,也不会影响你的系统。

===========
细粒度的依赖关系

解决依赖是包管理的另一个基本作用,对于 deb/rpm 来说,依赖是定义在包的层面的,带来的一个问题是,有时候要安装某个包,需要先安装一系列的依赖,它们的体积加起来可能很大。另一个问题是,更新的时候,整个包都要重新下载,而好多时候这是不需要的,比如 man page 和一些图片,可能并没有任何变化。

conary 是在文件层次上解决依赖的,所以,一个包并不依赖于另"一个包",而是依赖某个文件的存在。conary 把包划分成几个部分,比如 :runtime, :doc, 或者 :devel,安装依赖包、更新包都是基于这个子部分的,用不到或没有变化的部分就不用下载。好处是可以节省带宽,节省硬盘空间,节省电力,节省能源...

而且这带来了另一个可能:系统可以定制得很小,能够把不需要的都删掉。比如最近我们在裁减 GNOME Developer Kit 的大小,在脚本里有这一句:

        r.removeComponents(['doc', 'supdoc', 'build-tree', 'devellib', 'devel'],
            'group-gnome-dist')

这样就把所有的文档、开发相关的文件移除了。

当然,deb 和 rpm 也能把一个包划分开 (也就是那些 -devel 包的由来)。问题是,手动。打包的开发者必须在 spec 文件里手动指明哪些文件是 liferea-doc 的,哪些是 liferea-devel 包的。但 conary 能自动完成这些,安装到 /etc 的,一般就是 :config 部分的;在 /user/share/man/ 下的,应该就是 :doc。conary 能识别出 general case 来,开发者只需要做剩下的那一点。

===========
回滚。由于整个系统都是在 conary 的版本管理之下,所以 conary 支持包管理操作的回滚。这个特性是最容易记住的,所以不细说了。

===========
给 conary 打包非常容易,所有的打包过程,都由简短的 python 脚本定义。在我看来,比 rpm 的 spec 文件清晰的多。而且像前面提到的,一般来说,开发者只处理特殊情况就行了,负担会大大减小。

===========
所以,无论对用户还是对开发者,conary 都是个不错的选择。

现在对用户存在的一个大问题呢,就是 conary 还缺少一个足够简单、但又能发挥其威力的前端,PackageKit 是当前的选择,但是还有很多的工作要做。

想进一步了解的话,请登陆 #foresight (freenode)。

一个冷笑话

第n题
请描述 /proc 的作用:

答:proc 文件夹 blah blah blah

Saturday, February 20, 2010

纪念小连

两天前惊闻噩耗,才知道连黎明已经在二月十七号去世了。我俩是通过 open source 认识的,open party, blug...讨论这个爱好,从此更少一人。成为朋友还没有两年的时间,小连已经远去了。

两天来,一直想着这回事。一个年轻的生命,就这样逝去了。我本悲观,于此更感觉人生的无常、无奈。鲜活的生命,洋溢着笑容的脸,从此再也没有。小连在病房内都笑口常开,可惜斯人逝矣。

哀痛难已,只希望小连在另一个世界,摆脱凡世,再无烦恼。

Tuesday, February 2, 2010

Reading about a kernel bug

看了这么长时间的 Linux 代码,终于能从 bug report 里读出点大概了。今天这个是关于 ATI 显卡驱动的 regression (咋翻译?)。

事情从这里开始,Radeon KMS regression still present in 2.6.33-rc6 [0],reporter 提到开机的时候总是 kernel panic,只有禁用 KMS (Kernel Mode Setting) [1],也就是需要传一个 radeon.modeset=0 参数给内核,才能启动。

然后有一张 panic 时的照片。里面包含了好多的信息,能帮助找到出问题的代码。

首先能看到出错指令的位置,在照片的倒数第五行:

0.097281] RIP [<0xffffffff811c1592>] radeon_agp_init+0x1d/0x2e7

根据这个,作者用 gdb 得出了出错的代码位置。

(gdb) l *(radeon_agp_init+0x1d)
0xffffffff811c1592 is in radeon_agp_init
(drivers/gpu/drm/radeon/radeon_agp.c:136).

我们能看到出错行是 radeon_agp.c 的第 136 行,但这一行挺长的,不知道到底是那个地方除了错:

if (rdev->ddev->agp->agp_info.aper_size < 32) {

这时看第二封邮件,Linus 把相应的代码编译成了汇编,注意被标出的那个 mov 指令,它的十六进制形式是 4c 8b 60 28,正是上边照片里的那串数字。也就是倒数第六行:

0.097281] Code: 0b 83 78 ... 20 03 00 00 (4c) 8b 60 28 49 83 ...

2f: 位置的那个 cmp $0x1f,%r12 指令对应 if 语句的那个 "> 32" (因为 0x1f == 31),所以 %r12 应该存有 aper_size,(由于 mov 0x28(%rax),%r12) 所以 %rax 应该存有 agp_info。这个 mov 出错,说明 agp_info 为空。rdev->ddev->agp->agp_info,顾名思义 :),是应该由 AGP 模块填好的,所以 Linus 指出问题可能是因为 DRM 初始化的时候 AGP 还没有初始化。

当然,随后的故事有点简单,一个开发者指出这是个已知的问题,而且已经被修复了。然后就是测试、提交代码。故事到此结束。但是可以看到,问题最终是在 AGP 模块里解决的,而不是引发 panic 的 DRM 模块。并且这个修复也挺有意思,牵扯到 agp_amd64 模块的初始化逻辑,值得一看。AGP 根本没有被初始化,才导致了整个的问题。

在我看来,整个故事中有关汇编、gdb 的部分是精彩之处。

[0] 其实在此五天之前作者就提出过这个问题,但没人回复...; 这提示我们要锲而不舍,问题没解决就要一直纠缠他们 :)
[1] KMS,大体上,指的是让内核来管理显卡,而之前是 X server (具体是 X server 的驱动,即 Device Dependent X / DDX,比如 xf86-video-ati 这个包) 来管理设备的,称作 UMS / User Mode Setting。Kernel 指 kernel space, user 指 user space。

Sunday, January 31, 2010

Reading Dilbert

Practicing Programming 的时候,又看到 Dilbert,查了查维基百科,他中文名叫呆伯特 :D 维基百科的这个页面极度搞笑,于是终于决定订阅来看看。

看了几篇的感觉是,得多看几遍才能找到笑点。文化差异和语言水平啊...

不过确实很搞笑,比如今天的这篇:

同事A: 华利,能帮我个忙吗?
华利:没问题。谁叫咱们是朋友嘛。
华利:毕竟,我如果求你帮忙,你肯定会帮我的,对吧?
同事A:呃... 肯定的。
华利:对啊,你一定会帮我的。
华利:那就请帮我个忙,别让我帮你忙。
同事A:...

同事B: 你真是个高手啊,能把人际交往的法则运用成魔法一样。
同事B: 你是个光头哈利!
华利:别跟秃顶魔说啊。
(尖发老板从背后经过...)

关于这个漫画,刚开始看,还不认识那两个同事。

"What are friends for?" 一开始没明白,想到老友记那去了。

精华在 Hairless Potter 跟 Baldemort。分别是哈利波特(Harry Potter)跟伏地魔(Voldemort)的谐音,看了漫画下面的评论才明白。网站有评论,这点不错。

看大写还不习惯 :)