Archives

/ 和 //

看下面这个的例子:

[wangcong@cr0 ~]$ cd /

[wangcong@cr0 /]$ pwd

/

[wangcong@cr0 /]$ cd //

[wangcong@cr0 //]$ pwd

//

[wangcong@cr0 //]$ cd ///

[wangcong@cr0 /]$ pwd

/

[wangcong@cr0 /]$ cd ////

[wangcong@cr0 /]$ pwd

/

其实 POSIX 规范里有讲到,Pathname Resolution

A pathname consisting of a single slash shall resolve to the root directory of the process. A null pathname shall not be successfully resolved. A pathname that begins with two successive slashes may be interpreted in an implementation-defined manner, although more than two leading slashes shall be treated as a single slash.
大多数实现,包括 bash,都是把 // 当 / 来处理,但是仍然显示 //。但 zsh 不是,zsh 把 // 当 / 处理并显示。

ping 的 mdev 值

在运行 ping 命令的时候,里面有一项输出叫 mdev,如下所示:

~% ping www.google.pt

PING www.l.google.com (72.14.203.103) 56(84) bytes of data.

64 bytes from tx-in-f103.1e100.net (72.14.203.103): icmp_req=1 ttl=50 time=84.1 ms

64 bytes from tx-in-f103.1e100.net (72.14.203.103): icmp_req=2 ttl=50 time=83.0 ms

64 bytes from tx-in-f103.1e100.net (72.14.203.103): icmp_req=3 ttl=50 time=85.5 ms

^C

—- www.l.google.com ping statistics —-

3 packets transmitted, 3 received, 0% packet loss, time 2001ms

rtt min/avg/max/mdev = 83.019/84.227/85.506/1.016 ms

它是什么意思呢? ping 的手册中并没有提到。我们不妨看一下 ping 的源代码,见 ping_common.c:

tsum += triptime;
tsum2 += (long long)triptime * (long long)triptime

以及

tsum /= nreceived + nrepeats;
tsum2 /= nreceived + nrepeats;
tmdev = llsqrt(tsum2 - tsum * tsum);

所以我们可以得出:

mdev = SQRT(SUM(RTT*RTT) / N - (SUM(RTT)/N)^2)

也就是这个平均偏差的公式:

所以 mdev 就是 Mean Deviation 的缩写,它表示这些 ICMP 包的 RTT 偏离平均值的程度,这个值越大说明你的网速越不稳定。

布拉格之行

因为开会的原因去了一趟捷克,顺便在那里玩了一圈。阔别三年,终于回到欧洲了,最遗憾的是这次因为签证的原因没机会到葡萄牙看望以前的同事了。:-( 不过,在布拉格开会期间遇到了 Fengguang Wu 和 Ying Han,就约着一起出去玩。

布拉格绝对一个是典型的欧洲城市,有很多欧式风格的教堂、城堡,当然啦,还有大名鼎鼎的布拉格广场和查理大桥。

到了你会发现,这几个景点每天都是游客如织,即便秋天已经不是去捷克的最佳季节。所以,那首歌里唱的“布拉格黄昏的无人的广场”都是骗人的!黄昏的时候布拉格广场人山人海!

虽然说夏天是来捷克旅游的最佳季节,但我认为秋天的布拉格也很不错,可以看到各种各样的颜色。

离开布拉格,在捷克南波西米亚地区,靠近奥地利的地方,有一个非常出名的小镇,叫克鲁姆洛夫(Český Krumlov)。这里被称为“捷克的丽江”,确实和丽江风格类似,不过它比丽江要小得多,人也相对不多。那里除了那个闻名的城堡,还有一个非常好看的地方,就是瓦尔塔瓦河拐弯处。整个小镇美妙绝伦,天一放晴,感觉像是步入了童话世界。

在克鲁姆洛夫的时候住青旅,遇到一个日本姑娘,第二天和她一起逛了逛小镇,海阔天空地聊了很多,发现日本人真心爽,去世界上好多地方都不需要签证,包括中国!我就不好意思对比中国的了。

在捷克西部,也有一个知名的小镇,叫 Karlovy Vary。这个小镇以温泉而出名,所以那里有很多慕名而来泡温泉的人,但景色一般。我去那儿的时候还尝了尝免费的温泉,真的很难喝,还不如白开水呢。

这里一个有意思的插曲是,中午吃饭的时候我无意间着走到一家小店,老板是一位非常和蔼可亲的捷克大叔。他会汉语哦,而且还能说不少呢!和他聊了聊才知道,原来他之前是在捷克驻北京大使馆工作!说完,还一直用汉语说“建国门、建国门……”。临走之前,大叔给我要几个人民币硬币,我索性掏出一把零钱来都给他了。大叔问我今晚要不是住这,我说可惜我要回布拉格了。

下面这个就是他的店的广告,如果你有机会去 Karlovy Vary 的话,记得去这个大叔店里面坐坐哦!

住宿推荐:

Český Krumlov, Hostel99, http://www.hostel99.cz
Prague, Hostel ELF, http://www.hostelelf.com

关于 bash -c

我们知道 -c 的意思是 command,所以 bash -c 后面应该跟一个 command。连 bash 的 man page 中都这么说:

-c string If the -c option is present, then commands are read from string.
If there are arguments after the string, they are assigned to the positional parameters, starting with $0.
而实际上不对。我们看下面的例子:

% bash -c “echo a b c”
a b c
% bash -c echo a b c

% bash -cx “echo a”

  • echo a
    a

如果 -c 后面跟一个参数 string的话,那么第三个例子中的 -cx 应该会报错,找不到x这个命令,而实际上没有报错,也就是说,-c 和 -x 一样,后面不跟任何参数。

再看上面第二个例子中,为什么只有换行输出?手册中说,如果后面还有参数的话,那么它们被赋值给$0,$1,$2等等,也就是说,bash -c echo a b c,实际上只执行了 bash -c echo,所以只输出了换行!我们可以看更好的例子:

% bash -c ‘echo “$0 is $0, $1 is $1, $2 is $2”‘ foo bar biz
$0 is foo, $1 is bar, $2 is biz

% echo ‘echo “$0 is $0, $1 is $1, $2 is $2”‘ > /tmp/args
% chmod +x /tmp/args
% bash -c /tmp/args foo bar biz
$0 is /tmp/args, $1 is , $2 is

% bash -c ‘/tmp/args; echo $0 is $0, $1 is $1, $2 is $2’ foo bar biz
$0 is /tmp/args, $1 is , $2 is
$0 is foo, $1 is bar, $2 is biz

推荐两本并行编程的书

1. 入门的,《The Little Book of Semaphores》

The Little Book of Semaphores is a free textbook that introduces the principles of synchronization for concurrent programming.

The approach of this book is to identify patterns that are useful for a variety of synchronization problems and then show how they can be assembled into solutions. After each problem, the book offers a hint before showing a solution, giving students a better chance of discovering solutions on their own.

The book covers the classical problems, including “Readers-writers,” “Producer-consumer”, and “Dining Philosophers.” In addition, it collects a number of not-so-classical problems, some written by the author and some by other teachers and textbook writers.
可以在它的官方网站下载:http://greenteapress.com/semaphores/

2. RCU 的作者,大牛 Paul E. McKenney 写的书,《Is Parallel Programming Hard, And, If So, What Can You Do About It?》。这个比较猛,我还没时间看。它也是免费的,英文版可以在这里下载:

git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/perfbook.git

现在已经被翻译成中文了,叫《深入理解并行编程》:

http://download.csdn.net/detail/xiebaoyou/3552357

我在南京和布拉格的时候见过 Paul E. McKenney,他是一个非常和蔼、热心的人,没有一点儿牛人的架子。:-)

忽然很想跟自己说声对不起

忽然很想跟自己说声对不起,对不起总是让自己不开心

忽然很想跟自己说声对不起,对不起总是莫名其妙的忧伤

忽然很想跟自己说声对不起,对不起总是给自己太多的压力

忽然很想跟自己说声对不起,对不起总是忘了提醒自己好好照顾自己

忽然很想跟自己说声对不起,对不起总是不能为所欲为的做自己喜欢的事儿

忽然很想跟自己说声对不起,对不起总是和别人说对不起而忘了自己

忽然很想跟自己说声对不起,对不起因为悲观让自己不再相信生活

忽然很想跟自己说声对不起,对不起因为倔强让自己受了很多伤

忽然很想跟自己说声对不起,对不起因为伪装让自己活的很辛苦

忽然很想跟自己说声对不起,对不起因为年轻让自己疲惫了太久

忽然很想跟自己说声对不起,对不起因为悲伤麻烦了一些爱我的人

忽然很想跟自己说声对不起,对不起很久没有好好的照顾自己

忽然很想跟自己说声对不起,对不起很久没有好好的利用时间享受生活

忽然很想跟自己说声对不起,对不起很久没有给自己挑一份喜欢的礼物

忽然很想跟自己说声对不起,对不起曾经为了别人而难为自己

忽然很想跟自己说声对不起,对不起难过的时候只能让自己硬撑着

忽然很想跟自己说声对不起,对不起含泪微笑的时候我没有倾诉

忽然很想跟自己说声对不起,对不起心那么的疼还要假装着不在乎

忽然很想跟自己说声对不起,对不起让自己装了这么多年的无所谓

忽然很想跟自己说声对不起,对不起很多东西我没有学会好好珍惜

忽然很想跟自己说声对不起,对不起忘记了要搁浅

忽然很想跟自己说声对不起,对不起再也找不回原来的自己了

我弄丢了太多的东西、忘记了太多的事情、舍弃了太多的责任……

对不起,对不起,对不起,真的对不起……

不敢乞求自己的原谅,只有让自己活得更好才能对过去的生活有所补偿

忘记所有,重新开始

抬头仰望夜空,眼泪都已倒流,嘴角轻轻上扬

告诉自己

明天太阳依旧灿烂,生活却要华丽转身

(转自:http://www.douban.com/note/124817865/

shell 重定向的一处妙用

偶然在 dracut 的代码中发现一个使用重定向很巧妙的地方。见 modules.d/90kernel-modules/module-setup.sh 文件。

之前的老代码是这样的:

[bash]

#

         local _f
         while read _f; do case "$_f" in
             *.ko)    [[ $(<         $_f) =~ $_blockfuncs ]] && echo "$_f" ;;
             *.ko.gz) [[ $(gzip -dc <$_f) =~ $_blockfuncs ]] && echo "$_f" ;;
             esac
         done

[/bash]

意思很清楚吧?就是在内核模块(注意是二进制格式)中匹配一些函数(字符串)。这样会很慢,因为 bash 要在庞大的二进制文件流中匹配一些指定字符串。

于是,就有人想了一个方法加速这个处理过程,把原来的单个数据流分成两个并行的数据流,同时进行匹配!很巧妙!

[bash]

#

         function bmf1() {
             local _f
             while read _f; do case "$_f" in
                 *.ko)    [[ $(<         $_f) =~ $_blockfuncs ]] && echo "$_f" ;;
                 *.ko.gz) [[ $(gzip -dc &${side2}; fi
             done 
             | bmf1     1>&${merge}    ) {side2}>&1 
             | bmf1  )      {merge}>&1

[/bash]

经过 refactor 之后的或许更好理解一些:

[bash]

        # subfunctions inherit following FDs
        local _merge=8 _side2=9
        function bmf1() {
            local _f
            while read _f; do case "$_f" in
                *.ko)    [[ $(<         $_f) =~ $_blockfuncs ]] && echo "$_f" ;;
                *.ko.gz) [[ $(gzip -dc &${_side2}
                fi
            done | bmf1 1>&${_merge}
        }
        # Use two parallel streams to filter alternating modules.
        eval "( ( rotor ) ${_side2}>&1 | bmf1 ) ${_merge}>&1"

[/bash]

关于配置 vlan 设备名字

以前只知道 vlan 设备的名字都是像 bond0.77 这种格式,前两天拿到一台机器,上面的 vlan 是 vlan77,而且 ifcfg-vlan77 多了一个 PHYSDEV=bond0。这才明白原来 vlan 还可以这么配置。

可是我仍然想测一下之前的 bond0.77 这个格式的配置,因为 kdump 要解释这两个不同的格式。于是我把 ifcfg-vlan77 重命名为 ifcfg-bond0.77,并且把 DEVICE=vlan77 改为 DEVICE=bond0.77,结果重启之后出错。看了半天的 ifup 的代码也没找到问题出在哪里。忽然注意到 /proc/net/vlan 下面仍然是 vlan77,于是开始扒内核的源代码,终于在 net/8021q/vlanproc.c 里发现了问题的所在。

我忘记修改 VLAN_NAME_TYPE=VLAN_PLUS_VID_NO_PAD 这一项!看内核源代码很了然,VLAN_PLUS_VID_NO_PAD 就是说名字格式是 “vlan” + VLANID,而且没有填充0,也就是 “vlan77” 这种格式。VLAN_NAME_TYPE=DEV_PLUS_VID_NO_PAD 才是我想要的设备名+VLANID,比如 bond0.77。如果不加“NO_PAD”的话,VLAN_NAME_TYPE=DEV_PLUS_VID 就会把设备命名成 bond0.0077了。

最最幸福的文字

去新疆之前路过成都的时候,杜姑娘推荐我看一下这本书。上火车之前,正好在成都的一家书店买到了它。

过多的评价用不着,我只想说一句,这本书是我读过的最最幸福的文字!一个在阿勒泰的角落里生活的裁缝,怎么能写出这么幸福这么朴实得打动人心的文字呢!:-) 这让我想起了《万物有灵且美》这本书,作者是一个英国的乡村兽医,同样是不怎么起眼的职业,他们写出的文字一点儿都不华丽,可就是这种朴实、乐观、幸福,足以打动每一个读者!

由此可见,幸福和职业无关,和金钱更是没有关系,“苦和甜来自外界,而体味幸福却来自内心”!这个在阿勒泰当裁缝的李娟足以让每一个生活在大城市还每天矫揉造作的人无地自容了。

我去新疆的时候也去了阿勒泰,去了那个“童话边的小城”布尔津,也去了那个“遍地都是宝石”的可可托海镇。从布尔津到可可托海真费了我不少功夫,先是坐车到阿勒泰市(后来才知道其实可以在北屯镇转车的),再转车到富蕴县,再转车到可可托海镇,要去景区的话还得转车……到了可可托海镇才发现,这么一个小地方就是李娟所谓的“算得上真正的城市”!天呐,她到底生活在阿勒泰的哪个小小小小角落里!

阿勒泰有很多哈萨克族人,他们应该是为数不多的现在还在过游牧生活的民族。我在去阿勒泰市的路上看到不少赶着骆驼、骑着马、放着羊的哈萨克人,而骆驼上驼着各种各种的东西,有桌子,帐篷,家具……要我说,他们才是真正的四海为家的人!

我们在禾木碰到过两个哈萨克小伙儿,都很幽默。其中一个小伙儿骑着马,主动上来跟我们当中的姑娘搭讪,用他那不太流利的汉语介绍说,“我——叫——哈——哈”。哈哈哈哈,我们一听就笑了!另一个小伙儿是住的客栈碰到的,叫克里木,他硬是从我这儿蹭走了一个打火机!我怎么觉得哈萨克族的小伙儿都是这么“脸皮厚”呢,哈哈!

打住,继续说这本书。书上还留了她的博客地址,看到下面的一句“进城不易,更新缓慢”,我又笑了!再看看她的微博上,“不见网友。不见读者。不签名”,看来还是李娟懂得什么是幸福!

红帽正在招人

受同事之托,发一下 Kernel QE 的招聘信息:

Senior Quality Engineer - Kernel(General)

Senior Quality Engineer - Kernel(Network)

Quality Engineer - Kernel(General)

Intern - Kernel QE

有兴趣的可以把简历发到我的邮箱:xiyou dot wangcong at gmail dot com,我会转发到负责招聘的人那里。

关于在红帽工作,我最喜欢的是上下班时间自由、假期可任意调换、允许在家上班。:-D 我好久不在办公室上班了,时常想念公司里的阿姨和零食。。。想了解更多更新内容可参考其他同事的博客:

akong:http://amosk.info/blog/

caspar:http://www.casparant.com/

erguan:http://guaneryu.com/blog/

adam8157:http://www.adam8157.info/