Wednesday June 15, 2005 |
在Sun两年,一个很有趣的发现就是每个项目的内部项目代码,颇是有些美国创新精神的体现。说是内部代码,因为在Solaris发布后,往往每个特性会有另外一个更加"道貌岸然"的市场推广名称,好比某人的大名、小名一样。只是对于我们工程师来说,还是小名叫来更亲切一些。 这些项目代码,有的精炼直白,例如ZFS(Zettabyte File System);有的概括功能,zones(现在的市场名字叫Containers-"容器",中文名字有点傻);有的取其寓意,FireEngine(取其高性能之意,特指Solaris 10中焕然一新的的TCP/IP协议栈);有的又似随手拈来,Nemo(恐怕项目启动时"Finding Nemo"正在热映 今天是Solaris开源 的日子,对你这意味着什么?意味着你不但可以享有我们曾经独有的特权 (还有什么比源代码更神秘的?),同时也可以访问到Solaris中更多的小秘密-看到那几个新的项目代码了?Yosemite(UDP性能增强项目。Yosemite,美国Yosemite国家公园);Surya(路由转发性能增强项目。Surya,印度教太阳神);Crossbow(网络协议栈的虚拟和资源管理。Crossbow,强弩);还有......Clearview! Clearview,作为项目组1/5的我来说,当然具有特别的意义。说来惭愧,作为自己的项目,除了隐约知道项目取其清楚、简单、统一之意外,并不清楚这个名字后面具体的故事。而且正如项目介绍中所说,Clearview包含5个相对独立的部分,三两句话竟然归纳不清。不过作为OpenSolaris的合作项目机会之一,敬请研读项目需求文档,并欢迎提问。 另外我知道,从今天起,我对自己的代码得格外小心了-就在你们中间,一定有某些人正在摩拳擦掌,准备着在对我的代码品头论足呢! 这些天在整理湘西一游的照片,许多以为已经洇没的回忆扑面而来。旅行总是这样,在路上时或者很疲累,或者有怨言,回忆起来就只剩下美好和想念。 由于"湘行散记",我是带着些许期待走进湘西的-那窄急的险滩,河面的木筏,那快乐多情的水手和吊脚楼的灯光,还能寻得多少影子?那直爽的野话,动听的山歌,还能听到几许?不能不承认,最初走进凤凰,看到满街的商铺,虽然已有所准备,还是有些淡淡的失望的。 但湘西以它特有的悠闲平和和鲜活动人,很快就让我喜欢上了它-凤凰城的闲适和美味的小吃;都罗寨热情纯真的小导游和极度疲惫后柳暗花明的峡谷风景;山江喧闹有趣的苗家集市;甚至当时恼人的每天早上7点定时响起的沱江上的苗鼓,现在也都很想念 P.S. 此行没有到沈从文先生墓前一访(当时觉得像古人凭吊,酸气十足),但确是遗憾。看"湘行散记"中沈张的温柔多情,再读张兆和在"沈从文全集-后记"中的"斯人可贵""悔之晚矣",长叹! Jun 12 2005, 09:33:17 PM GMT+08:00 Permalink相信多数在Solaris内核上工作的工程师都象我一样,工作中很大的乐趣来自修改Bug。尤其对于我来说,追根溯源找到导致问题的原因是其中最有满足感的部分(对我,后面的修改,测试验证过程的确相对平淡很多)。尤其是某些Bug,当你最初看到它的描述,第一印象就是"这绝不可能!",然后就是试图重现,将描述中的片断拼凑成真正的问题,最后通过某种手段找到元凶--其中的精彩有时真的可以和侦探探案相比--而且,的确如此,好的工程师与精明的侦探有一样灵敏的嗅觉。或许某一天,我应该谈一谈将我带到Solaris内核世界的第一个bug,讲讲当时我是如何地束手无策,同事的一个资深工程师又是如何地与我坐在一起帮助我,我是如何惊叹于他的思维模式和mdb工具的强大,从毫无头绪中抽丝拨茧,找到问题的根本原因。 不过今天,我要讲的是这个星期我正在解决的bug 6272300。问题其实很简单,新引入的Gldv3(Generic Lan Driver v3)构架中就应该确保如果在一个接口(例如bge1)上已经创建了链路聚合(aggregation),那么后续ifconfig再尝试 plumb该接口,应该返回设备忙,并显示操作失败 (exclusive active原则). 现在你们所能看到bug的问题描述已经被重新编辑过,简化了很多。最初的描述里,提到测试版本是Solaris snv-14,但同时打印出来的栈信息却显示了根本在snv-14中不存在的函数e1000g_m_resources(存在这个函数,说明e1000g 网卡驱动已经移植到Gldv3,但事实e1000g当前仍然是最传统的DLPI驱动),这是之一;之二,按照其中描述的步骤,在我的实验机器上却无法重现(当然只能基于已经基于GLDv3的BGE网卡)。所以,我最初的反应就是,这应该是网卡驱动组自己编译的Solaris版本,问题也可能出自那个项目的代码中。 (当我刚到Sun时,我的Sunvisor就告诉我,永远不要相信bug report里的描述,那里表面描述的可能不够准确,有时甚至根本不是问题,但往往真正的问题确实存在,只是隐藏在后面,需要我们去挖掘 -至理名言 这个bug被搁置了几天后,终于又被转发过来,还同时传递了几个信息-1). 此问题只能在特定机器上重现;2) 已经确认此问题在Snv14的BGE网卡上也能重现。第二条信息说明当前的Solaris版本的确存在问题,第一个信息则比较奇怪了,为什么只能在特定机器上重现(发现问题的两台机器都是x64系统,而我的实验机器则是Sparc,但相关的代码不应该也不可能与机器的体系结构有关。- 哈哈,有趣的东西来了。 痛苦的是,bug的提交者反复强调这个问题很可能在即使是相同的体系结构其他机器上也不能重现,但调试这个问题需要使用kmdb,而这两台机器都没有console连接,但是让我坐在实验室里瑟瑟发抖(实验室的温度简直变态),而且通过主机调试,手边又不再有别的机器可以参照代码,简直再没有比这更"完美"的调试环境了。 还是没有勇气坐在实验室里忍受冰山一样的寒冷,我要了问题机器的IP地址,回到了自己的座位上。先碰碰运气吧尝试复现吧。比较幸运,很快我就在我们自己的实验室里找到了有console接口,具有bge接口,同时又是相同体系结构的机器,更幸运的是,它已经装了snv-14,我甚至不需要重装系统或者bfu;最最幸运的是,它上面的snv-14是非调试版本的内核!(你们很快就会知道为什么这一点这么重要。) 重现意想不到地顺利,说实话,对那段代码的自信(虽然不直接是我本人的代码,但是相关代码的review, 修改,让我对那段代码我太熟悉了,绝对不可能有这么简单的逻辑问题!)使我对能够复现问题颇为吃惊。接下来的工作就比较简单了,创建链路聚合,在处理DLPI 消息的函数(处理IP plumb的主要函数)入口设置断点,plumb接口,单步跟踪... 相关的代码在函数dld_proto中:
/*
* If this primitive causes the data-link channel used by this
* object to become active, then we need to notify dls. Note that
* if we're already passive by having succesfully processed a
* DL_PASSIVE_REQ, then active primitives do not cause us to become
* active.
*/
if (prip->pri_active && dsp->ds_passivestate == DLD_UNINITIALIZED) {
if (!dls_active_set(dsp->ds_dc)) {
dlerrorack(dsp->ds_wq, mp, prim, DL_SYSERR, EBUSY);
return;
}
}
当处理DL_BIND_REQ DLPI消息时,prip->pri_active为TRUE,表示该DLPI请求是一个activation请求,此时的dsp刚刚被初始化,其 ds_passivestate为UNINITIALIZED状态,dls_active_set函数调用mac_active_set,发现相应的 mac(bge1接口)已经处于active状态(其mi_activelink在创建aggregation时设置为1),返回失败,回应EBUSY DL_ERROR_ACK消息,通知上层应用程序该操作失败。- 一切看上去都很完美。 可kmdb的结果却出人意料 但不要忘了这是非调试版本的内核,创建对象时直接使用缓冲的实例,str_constructor函数并没有被调用,所以此时的 ds_passivestate继承了上个实例释放时的数值(DLD_ACTIVE);而调试版本的内核,总是删除缓冲对象,每次创建对象时重新构造,所以不能重现相同的问题。 哈,对应的修改只需一行,在dld_str_destroy函数中重新初始化ds_passivestate为DLD_UNINITIALIZED。 就这么简单。 启动一个blog是需要不少勇气的,因为不想像曾经风行一时的个人网站一样,许诺着经常更新,但最后一次的更新时间却是3年以前;但又有多少人会对我在这里的所思所写感兴趣,或者(按官方说法)受益于此呢?如何在这个blog中平衡我的生活,工作?...无论如何,但愿我不是在这里自言自语 :-) 其实能够在Sun的网站上blog也不错,blog本来就应该是一件令人愉快的事情,也应该记录一些有趣的事情,可天知道对于我这样一个比较无趣的人来说,在Sun的工作可能多数时候就是我生活中最有意思的部分了,这个Blog总算给了我一个官方的借口叙述一下这些比较"闷"却让我着迷的事情. :-) 每个工作,最有趣的部分都是共事的同事们,尤其当你逐渐熟悉他们,发现他们隐藏在职务面孔背后的绝然不同的个性-有人像耐心的长者,有人非常挑剔(但对自己尤其格外挑剔),有完美主义者,有的人则总是能考虑的面面俱全.说来有趣,有时候,从他们的代码风格里,或者bug report的分析里,你甚至能够看到他们个性的影子.(举个要求完美到极端的例子,谁会要求自己C代码中包含的头文件都按照字母顺序排序?!)我是一个比较容易个人崇拜的人(虽然并不盲目:-),但如果你见到一个对Sparc, x86, Opeton各个体系结构的细节信守拈来的工程师,或者虽然忙碌,你却总能信任能够在第一时间得到他不厌其烦的回复在他看来或者幼稚,或者愚蠢的问题的架构工程师,你怎么能够不尊敬他们? Solaris本身,也是我热爱这份工作的很大一个原因.(不像某些Solaris的guru们,我从来不认为Solaris有多么完美,天知道我多么希望某一天我可以在Solaris上使用Source insight!)但Solaris内核中的代码有时候真的让我着迷,无论是它精密的一面还是愚蠢的一面.说它精密,经常是一个小小的似乎无关的改动,导致系统Crash;说它愚蠢,某些似乎显而易见的bug,竟然在那里存在了超过10年!但是还有什么事情比揪出这些隐藏或深或浅的bug更让人开心的事情呢. 能够工作在Solaris内核,说老实话,比较幸运.不仅仅是因为这是一个比较有挑战性,很有意思的领域,而且,Solaris的前辈们,包括现在的那些牛人们,提供了我们很多有用的工具,让我们的生活简单了很多.Crash dump文件,mdb + kmdb,还有dtrace(kmdb和dtrace都是Solaris 10的新特性,如果你在Solaris平台下工作,或者曾经对原有的kadb失望过,尝试一下这些新的功能,你会得到意外的惊喜.),尝试一下使用这些工具,解决你在开发中遇见的问题,你就能够理解为什么这里的很多工程师最喜欢看到的就是Panic,哈,又一个使用这些有效工具,找到问题,获得满足感的机会! Sun还有很多让我觉得工作在这里比较自在的地方-Sun中国还在不断发展,只要我们自己清楚想要什么,总能获得足够的支持;不需要早9晚5的打卡(很重要!:-),随时可以work_from_home(随时随地登陆到自己的桌面系统或者试验机器,与坐在办公室没有任何区别!) 所以,我的blog会围绕这些让我兴奋的人或者事情,某个我尊敬的工程师,某个我喜欢的工具,某个我解决的bug,我的项目...但愿不会变得无趣. 对了,作为开场白,少不了自我介绍,周昀,软件工程师,所在的部门-OperationPlatform Group的core technologies Group(这个部门是内核组和网络组重组合并的结果,现在的名字有些奇怪,好像感觉是包含了太多领域,不知道该怎样概括它的功能,干脆就叫核心科技得了:-),工作的主要方向是网络方面的内核开发,现在从事的项目嘛,一个很有意思的项目,会在某次的blog中再作详细介绍.:-) May 30 2005, 09:34:17 PM GMT+08:00 Permalink |
Calendar
LinksReferersToday's Page Hits: 3 |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
......当然,更多的时候,我无法知道每个项目代码背后的故事,但可以想象每个项目的启动初期,都会为自己"宝贝"的名字颇费一些心思。