Friday, December 12, 2008

和平、友爱与火箭! (HP首席技术专家的基于ARM板的开源飞行高度记录软件开发实记) (From: OLS2008论文集)

Subject: 和平、友爱与火箭! (HP首席技术专家的基于ARM板的开源飞行高度记录软件开发实记) (From: OLS2008论文集)

http://ols.fedoraproject.org/OLS/Reprints-2008/

Bdale Garbee Peace, Love, and Rockets!

http://ols.fedoraproject.org/OLS/Reprints-2008/garbee-reprint.pdf

作者 Bdale Garbee 是 HP 的开源和Linux首席技术专家,同时是一位模型火箭飞行爱好者,

他和他的儿子很喜欢制作和飞行各种各样的模型火箭,但是当他们想要一款电子高度计用于探测火箭实飞高度时,却发现市面上现有的产品都是功能很有限,且依赖于专有的软件来配置和解析出数据,这个令人很不爽!

这篇论文描述了他们如何制作开放的硬件和软件来满足自己对于高度的好奇心,现场演示文件中包含有更详细的更强动力的火箭设计计划,并包含了照片和视频材料。

这些材料应该是任何对开放的小型嵌入式设备好奇的人们都感兴趣的。
硬件是基于ARM的,以 "TAPR Open Hardware" 协议开放,
并且完全是基于开源的设计工具实现的。
软件是以GNU工具链和很多开源库在 FreeRTOS 上实现的。

有兴趣的同学们可以读这篇论文。

Thursday, November 13, 2008

你知道 Intrepid Ibex (勇敢的巨角羊) 操作系统 (Ubuntu 8.10) 吗?




"勇敢的巨角羊"这个名字很有意思,看一下最近一系列Ubuntu发行用过的名字:
  1. Intrepid Ibex (勇敢的巨角羊) (Ubuntu 8.10)
  2. Hardy Heron (坚忍的苍鹭) (Ubuntu 8.04)
  3. Gusty Gibbon (强风中的长臂猿) (Ubuntu 7.10)
  4. Feisty Fawn (精神饱满的幼鹿) (Ubuntu 7.04)
  5. Edgy Eft (急躁不安的小蜥蜴) (Ubuntu 6.10)
  6. Dapper Drake (衣冠楚楚的公鸭) (Ubuntu 6.06)
  7. Breezy Badger (微风下的獾) (Ubuntu 5.10)
  8. Hoary HedgeHog (灰白的刺猬) (Ubuntu 5.04)
  9. Warty Warthog (长疣的非洲野猪) (Ubuntu 4.10)
再看下一个半年的发行名称
  1. Jaunty Jackalope (轻松愉悦的狐狼?) (Ubuntu 9.04?)
注意这些名字都有一个"形容词定语+动物名词" (Adjective Animal) 的定式;这个命名模式起源于Mark与 Robert Collins 在关于 Sydney 的一个名为 Funky Ferry (渡口) 的一个 joke 时的对话,"那么,我们要多久才发行第一个版本呢?还有点晕,最多六个月吧。六个月?那不足以做出一个精良的系统啊。那我们先做一个"长疣猪"的发行吧。"

所有发行代号(CodeName)都可以在这个wiki页面查到:

https://wiki.ubuntu.com/DevelopmentCodeNames

另外,有个神秘的版本 Grumpy Groundhog (性情暴躁的土拨鼠) 一直存在于Ubuntu开发人员的心中,其实它本来很有可能作为第一个发行的命名,但它在第一次投票中落选了;并由此带来了更为长久的生命力,因为 Grumpy Groundhog 被作为了永远的 unstable (类似于debian的sid)

另外, Ubuntu 9.10 发行的 CodeName 也正在征集中,从这个帖子来看,很有可能的结果是 Killer Komodo (杀手级巨蜥) 因为这个名字符合命名模式中的下一个起始字母K,现在很受欢迎

http://ubuntuforums.org/showthread.php?t=915595

当然,你永远都可以从 Ubuntu 创意集 (http://brainstorm.ubuntu.com) 提出自己的想法或者为你支持的想法投票, Ubuntu 开发者会从这里寻找最受欢迎的创意并去努力实现它。

Saturday, October 25, 2008

Talk some more about working efficiency on Terminal

Do you know how long compiling a kernel on different hardware with different configs will take?

$ time make -C /usr/src/linux-2.6.27/ -j5

1. that would take 25 minutes on my personal PC with 1 2.9GHz P4 and 512M RAM, 5400rpm IDE disk, a moderate configuration for desktop peripherals;
2. that would take 10 minutes on a Dell 2950 Server, which has dual core 3.0Gx2, 2GB RAM, 7200rpm SATA disk, a minimal config for this type of hardware;
3. that would take 5 minutes if distcc configured on 2 Dell 2950 machines, and compiled with "-j13";

Do you know how long compiling a software package will take on different hardware?

$ time { ./configure --prefix=/usr && make; }

and then:

$ make install DESTDIR=$PWD/dest

from LFS book, you could know the time in unit of SBU,



Use "time" to time it, anywhere the command will last longer than 1 second.

Saturday, October 18, 2008

记录EndUserSummit上的三次全场爆笑

1、在开篇JimZemlin的 Welcome to the Summit 演讲中

Jim说到现在全球有很多企业在使用和关注Linux的发展,其中碰到很多问题,其实是EndUser与Developers之间缺乏足够的互相了解:对EndUser方面是不了解已经有了什么功能;对Developers方面的介绍是说:"$700 billion lines of code every year" (每年产生7千亿行代码),但不是每行都有效的,或者不知道哪一种是最好的,EndUser常常对此感到无所适从;

七千亿啊,全场爆笑;

2、在RicWheeler主持的FileSystem的Track中


他们在讲述Ext4和Btrfs(发音BetterFS),但在这两个具体的文件系统之前,Ted谈到KernelPeople为Filesystem遇到的挑战的应对是设计了NGFS(NextGernerationFileSystem)的概念,针对块设备的变化,(SSD的出现,多设备应用等),在NGFS中都有相应针对的设计,而ext4是当前NGFS的一个snapshot,BtrFS是最接近NGFS设计的一个;

此时,我向ChirsMason(BtrFS的主要开发者也是维护者)提了一个问题,“Ted说ext4可以用在他的Laptop上,不知BtrFS是否可以用在Laptop上?”全场爆笑。Chirs回复说:“当然可以。在我的Laptop已经用了很久了;其实你提得对,我应该也这么宣布一下,这是一个很好的Marketing机会。”回头想想,我提的这个问题好弱的呀。

3、在Cocktail上

其实就是上面第一天的内容,看James和Jonathan还有两位银行界人士共四人的照片,后来我也加入进去谈话了,我问了James一些块设备方面的问题,后来James发现我不像是EndUser更像是Developer,问我知不知道LinuxPlumbersConference,我说我知道,我本来想参加那个会议的,但美国大使馆(USEmbassy)给签证的速度太慢了,导致我错过了那个会议,我的一个朋友(当时一个Google的人为我感到惋惜时说的)说它是"Such an enept bureaucracy",James说“它从来都是 Such an enept bureaucracy”;

"Such an enept bureaucracy"(一个无能的官僚机构),全场爆笑啊。


实际上西方人士大都很幽默,全场爆笑的次数当然也不只这三次,这里只将印象最深刻的三次记录下来。

Wednesday, October 15, 2008

十月,纽约的EndUserSummit(第二天)

第二天的内容更多,首先是主题演讲,Jonathan还是再一次给大家讲述内核社区的工作原理,

这是会议现场,


接下来都是同时进行的很多个Track,这部分我没有拍很多照片,因为我也在里面发言,忙着交流去了,大家直接看主办方的安排就知道有什么内容了,

https://www.linuxfoundation.org/events/enduser/program

这次问过主办方LinuxFoundation,会后会把相关的Presentation文件,和主办方的专业级相机拍的一些照片发布出来,请大家关注主办方的网站吧,

http://www.linuxfoundation.org/

在机场时间不多了,马上要去登机,其它有趣的照片回去再整理吧.

Monday, October 13, 2008

十月,纽约的EndUserSummit


九点,会议在DesmondTutuCenter如期举行,地点是在一个Refectory(餐厅),说是餐厅,我觉得更像一间教堂,

第一个主题演讲的是LinuxFoundation的执行主席Zemlin讲述在Linux平台上,Developers与EndUsers缺少沟通,以至于开发者对用户需求不够了解,或者用户不了解最新开发的功能等,有必要举办一个开发者与EndUser沟通的会议,

第二个主题演讲是Wikinomics的作者,讲述大规模协作如何改变了世界,

接下来是一个Panel讨论,参与Panel的有FifthThird银行的CIO,美国航空的首席架师,纽约股票交易所的ChiefArchitect,还有AIG副总等人物一起来谈应用Linux的开始,以及应用过程所碰到的各种问题,希望Linux做到的哪些功能,等等,台下有一些Subsystem的维护者(也就是开发者)分别给出了回复;

片刻休息之后,是三个主要Vendor(发行商)的总裁或副总来讨论作为Vendor如何协调Developers与EndUsers之间的关系,有Novell,Redhat,和Ubuntu,

午餐后,另一个Panel讨论EndUser观点如何参与进Developers的开发流程,

再一场是Ted讲述了你所不知道的ext3和最新的ext4的特性,ChirsMason讲述BtrFS,这个是最接近NGFS(NextGeneartionFS)概念的了,特性非常多,cool,预计在2.6.29进入mainline;

接下来分为五个Track同时进行,我穿插去听了两个,FileSystem方面还是讨论各文件系统,有一个Administrator(作为EndUser)就说为什么现在的内核用dd将一个块设备上的ext3写到另一个块设备上就挂载不了了,他说记得以前的内核是可以的,Ted和Crhis和James一起回复了关于UUID的问题,

PerformanceTuning的Track中讨论了UDP的延迟,内存资源的合理使用,内存管理的改进,等等,

一小段总结之后到了5点,准时结束,到达附近一个公园举行露天的Cocktail酒会,大家一边喝点饮料吃点东西,一边在谈着Business或者Troubleshooting;我下午看了Rosedt的RT-linux的演示,太cool了,晚上继续听了一些关于RT-patches的改进,我问有什么Benefits,回复很简单,就是
"Better User Experience",除了timer之外的每个IRQ都有单独的内核线程执行,实时的内核用起来就是非常流畅,桌面开上数百个应用程序也不会互相影响导致有停顿的现象,只要内存足够给这些应用程序;

JamesBottomley和JonathanCorbet与两位来自银行的人士在交流,你认出来了吗?


不过太困了,不到7点结束,我就返回了.

Tuesday, September 30, 2008

再说find action,提高终端下的工作效率

再说find的action,是个很有用的工具,

对于查看目录下的所有文件,普通人常用的是ls,不带任何参数的ls,碰到有子目录的情况,就cd到子目录里面,进去只为敲个ls,再又cd回来,因为当前还是主要工作目录,需要查看哪个目录时就cd到哪儿去;进阶一点的人会用ls后接目录参数,可是ls还是只能列出一个目录,对于需要同时查看多个目录的情况可以用"ls -R",可是它只列出了文件名,没有全路径,对于下一步的最大可能是cat或调用编辑器,有了全路径才是最有用的;

试试这个: "find -ls"

一次将目录下所有文件都以ls方式列表出来,可以是递归的方式看到所有文件的"ls -l"方式的结果,并且有了全路径,可以用鼠标双击全选中,再敲中键(就是鼠标滚轮)便会粘贴出来,C-A定位光标到达行首,加上个cat或者vim,阅读或者是编辑,一切操作都是连贯的;

在Shell应用中,对/proc/sys/或/sys/下的查看常常既有列表还需要阅读变量内容,以前的做法是:

find /proc/sys/vm -type f -ls -exec cat {} \;

或者需要监视这个变量值的变化情况,加上个watch,每隔1s重读一次:

watch -n1 'find /proc/sys/vm -type f -printf "%p\t" -exec cat {} \;'

find是一个简单而强大的工具,绝不只是如名称一般只有"查找"文件的功用,它的参数有两个基本类型:


  1. test是一个条件判断,如查按文件名查找使用"-name ...";

  2. action是对找到的文件的一个动作,如缺省的-print是打印全路径名,-ls是模拟ls方式列表;



缺省的action只有ls,printf等,(printf另有强大的功能),而-exec扩展方式可以后接程序执行,如上面的-exec cat读出文件内容,

但是-exec cat实在太常用了,今日作了一个patch,在find-4.5.2上面加上-cat这个action,这样上面的监视命令就可以简化为:

find /proc/sys/vm -cat



Download as text

  1
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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
---
find/defs.h | 1 +
find/parser.c | 22 ++++++++++++++++++++++
find/pred.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
find/tree.c | 1 +
4 files changed, 76 insertions(+)

Index: findutils-4.5.2/find/defs.h
===================================================================
--- findutils-4.5.2.orig/find/defs.h
+++ findutils-4.5.2/find/defs.h
@@ -411,6 +411,7 @@ PREDICATEFUNCTION pred_cnewer;
PREDICATEFUNCTION pred_comma;
PREDICATEFUNCTION pred_ctime;
PREDICATEFUNCTION pred_delete;
+PREDICATEFUNCTION pred_cat;
PREDICATEFUNCTION pred_empty;
PREDICATEFUNCTION pred_exec;
PREDICATEFUNCTION pred_execdir;
Index: findutils-4.5.2/find/parser.c
===================================================================
--- findutils-4.5.2.orig/find/parser.c
+++ findutils-4.5.2/find/parser.c
@@ -91,6 +91,7 @@ static boolean parse_cnewer PARAM
static boolean parse_comma PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
static boolean parse_daystart PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
static boolean parse_delete PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
+static boolean parse_cat PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
static boolean parse_d PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
static boolean parse_depth PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
static boolean parse_empty PARAMS((const struct parser_table*, char *argv[], int *arg_ptr));
@@ -253,6 +254,7 @@ static struct parser_table const parse_t
{ARG_TEST, "ctime", parse_time, pred_ctime}, /* POSIX */
PARSE_POSOPT ("daystart", daystart), /* GNU */
PARSE_ACTION ("delete", delete), /* GNU, Mac OS, FreeBSD */
+ PARSE_ACTION ("cat", cat), /* GNU */
PARSE_OPTION ("d", d), /* Mac OS X, FreeBSD, NetBSD, OpenBSD, but deprecated in favour of -depth */
PARSE_OPTION ("depth", depth), /* POSIX */
PARSE_TEST ("empty", empty), /* GNU */
@@ -801,6 +803,26 @@ parse_delete (const struct parser_table*
}

static boolean
+parse_cat (const struct parser_table* entry, char *argv[], int *arg_ptr)
+{
+ struct predicate *our_pred;
+ (void) argv;
+ (void) arg_ptr;
+
+ our_pred = insert_primary (entry);
+ our_pred->side_effects = our_pred->no_default_print = true;
+ our_pred->need_stat = our_pred->need_type = false;
+ our_pred->est_success_rate = 1.0f;
+ open_stdout(&our_pred->args.printf_vec);
+
+#ifdef DEBUG
+ fprintf(stderr, "%s(%s:%d) called.\n", __func__, __FILE__, __LINE__);
+#endif
+
+ return true;
+}
+
+static boolean
parse_depth (const struct parser_table* entry, char **argv, int *arg_ptr)
{
(void) entry;
Index: findutils-4.5.2/find/pred.c
===================================================================
--- findutils-4.5.2.orig/find/pred.c
+++ findutils-4.5.2/find/pred.c
@@ -445,6 +445,58 @@ pred_delete (const char *pathname, struc
}

boolean
+pred_cat (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
+{
+ FILE * stream = pred_ptr->args.printf_vec.stream;
+ FILE * input_stream;
+ char buf[BUFSIZ];
+ int fd;
+ size_t read_len;
+
+ (void) pred_ptr;
+ (void) stat_buf;
+
+#ifdef DEBUG
+ fprintf(stderr, "%s(%s:%d) called.\n", __func__, __FILE__, __LINE__);
+#endif
+
+ if ((fd = openat(state.cwd_dir_fd, state.rel_pathname, O_RDONLY
+#if defined O_LARGEFILE
+ |O_LARGEFILE
+#endif
+ )) <>
+ {
+ error (0, errno, "%s", safely_quote_err_filename(0, pathname));
+ state.exit_status = 1;
+ return false;
+ }
+
+ input_stream = fdopen(fd, "r");
+ if (input_stream == NULL)
+ {
+ error (0, errno, "%s", safely_quote_err_filename(0, pathname));
+ state.exit_status = 1;
+ return false;
+ }
+
+ while ((read_len = fread(buf, 1, sizeof buf, input_stream)) > 0)
+ {
+#ifdef DEBUG
+ fprintf(stderr, "%s(%s:%d): read_len = %d, stream = %p\n",
+ __func__, __FILE__, __LINE__, read_len, stream);
+#endif
+ fwrite(buf, 1, read_len, stream);
+
+ if (read_len <>
+ break;
+ }
+
+ fclose(input_stream);
+
+ return true;
+}
+
+boolean
pred_empty (const char *pathname, struct stat *stat_buf, struct predicate *pred_ptr)
{
(void) pathname;
Index: findutils-4.5.2/find/tree.c
===================================================================
--- findutils-4.5.2.orig/find/tree.c
+++ findutils-4.5.2/find/tree.c
@@ -906,6 +906,7 @@ static struct pred_cost_lookup costlooku
{ pred_comma , NeedsNothing, },
{ pred_ctime , NeedsStatInfo, },
{ pred_delete , NeedsSyncDiskHit },
+ { pred_cat , NeedsNothing },
{ pred_empty , NeedsStatInfo },
{ pred_exec , NeedsEventualExec },
{ pred_execdir , NeedsEventualExec },



Download as text


参看这个帖子来个实用的:查看文件链接,回复find命令的人是我:有人需要一些shell功能,想到了用python去写,想法不错,却没想到的是,那一段的python代码只对应了一行find命令。

Monday, September 22, 2008

KS2008与LPC2008刚结束

著名黑客GregKroahHartman在这个会上对Ubuntu幕后的Canonical公司的不贡献进行了猛烈的批评:

Canonical的内核开发者在过去三年,从2.6.19到2.6.27-rc5之间,只向内核提交了约100个补丁!(与我在过去两年内做的差不多~)

作为对比,Greg也同样列出了各大Distro的数据:

RedHat排名第二,Novell排名第五,Mandriva是第45,Canonical是第81,

而社区发行版中,Debian和Gentoo分别排名第41和第49,

其实,早在上半年JonathonCorbet就以LWN文章提出了对Canonical的批评,但这次Greg的这次更猛烈的批评则是第一次将问题的严重性推向聚光灯下:

  1. Kernel Log: The second day of Kernel Summit 2008; criticism of Ubuntu at the opening of the Linux Plumbers Conference
  2. Linux Plumbers Conference 2008 Keynote

说到这个排名,可能有人对更为神秘的第一名感兴趣,那么,这个神秘的能够超越RedHat的第一名究竟是谁呢?

那就是我们伟大的Amateurs(业余爱好者)!Kernel的发展自始至现在仍然保持着平民化的Amateurs为主导的发展!

Tuesday, September 02, 2008

manually upgrade x11-drivers/nvidia-drivers

Upgrade kernel to v2.6.27-rc5, x11-drivers/nvidia-drivers have not support so late kernel,

So let's upgrade it manually:

http://paste.ubuntu.com/42782/

Index: NVIDIA-Linux-x86-173.14.12-pkg0/usr/src/nv/nv-linux.h
===================================================================
--- NVIDIA-Linux-x86-173.14.12-pkg0.orig/usr/src/nv/nv-linux.h
+++ NVIDIA-Linux-x86-173.14.12-pkg0/usr/src/nv/nv-linux.h
@@ -77,6 +77,7 @@


#if !defined(KERNEL_2_4)
#include <linux/sched.h> /* suser(), capable() replacement */
+#include <linux/pid.h> /* for find_pid */
#include <linux/moduleparam.h> /* module_param() */
#include <linux/smp_lock.h> /* kernel_locked */
#include <asm/tlbflush.h> /* flush_tlb(), flush_tlb_all() */

@@ -104,7 +105,7 @@
#endif

#include <linux/spinlock.h>
-#include <asm/semaphore.h>
+#include <linux/semaphore.h>
#include <linux/completion.h>
#include <linux/highmem.h>


Index: NVIDIA-Linux-x86-173.14.12-pkg0/usr/src/nv/os-interface.c
===================================================================
--- NVIDIA-Linux-x86-173.14.12-pkg0.orig/usr/src/nv/os-interface.c
+++ NVIDIA-Linux-x86-173.14.12-pkg0/usr/src/nv/os-interface.c
@@ -704,7 +704,7 @@ RM_STATUS NV_API_CALL os_kill_process(
U032 sig
)
{
- return kill_proc(pid, sig, 1) ? RM_ERR_OPERATING_SYSTEM : RM_OK;
+ return kill_pid(find_vpid(pid), sig, 1) ? RM_ERR_OPERATING_SYSTEM : RM_OK;

}

/*******************************************************************************/


this patch also reflects some changes in 2.6.27:
1. asm/semaphore.h => linux/semaphore.h stands a common implementation in all arch;
2. kill_proc => kill_pid

But there's still a problem haven't been resolved, it reports license issues in modpost phase:
1. kill_pid is exported with EXPORT_SYMBOL_GPL, can be used only by GPL code;
2. nvidia.ko is licensed with "NVIDIA", not GPL;

# cd /var/tmp/portage/x11-drivers/nvidia-drivers-173.14.12/work/NVIDIA-Linux-x86-173.14.12-pkg0/usr/src/nv/

# make -C /usr/src/linux-2.6.27-rc5/ M=$PWD modules

the core functionality of nvidia.ko is hidden in nv-kernel.o, that's completely binary, there's no corespoding nv-kernel.c, results of `strings` told that the license is declared in this binary file;

the last killer approach is hexeditor! use it to hexedit the string to "GPL\0", compiling well, insmod well, all runs OK!

Hexediting is an ugly hack, hope my next machine can run toally under free operating system, no hidden binary anymore!

Friday, August 29, 2008

monitor the system totally with dstat

You must have ever monitored the system with different tools:
  1. "vmstat 2" to get a total system "proc,mem,swap,io,sys,cpu" load;
  2. "iostat 2" to get all block devices with seperated I/O bandwidth data;
  3. "ifstat 2" to get different network interfaces network activity;
  4. "top" to get the most CPU-consuming processes;
Now you can do all these things within dstat:
gektop@tux ~ 0 $ dstat -M proc,cpu,mem,sys,page,net,disk,topcpu,topmem,topio,topbio 5
---procs--- ----total-cpu-usage---- ------memory-usage----- ---system-- ---paging-- -net/total- -dsk/total- -most-expensive- -most-expensive- ----most-expensive---- ----most-expensive----
run blk new|usr sys idl wai hiq siq| used buff cach free| int csw | in out | recv send| read writ| cpu process | memory process | i/o process | block i/o process
0 0 6| 39 9 37 14 0 1| 272M 25M 193M 12M| 760 2178 | 0 21B| 0 0 |5577k 1645k|firefox 10|firefox 125M|mount.ntfs- 10M:8223k|mount.ntfs-2699k: 736k
3 0 8| 93 6 0 0 0 1| 252M 25M 189M 37M| 546 980 | 0 0 |3197B 564B| 109k 675k|firefox 15|firefox 125M|mount.ntfs- 771k:3056B|pdflush 0 : 82k
3 0 71| 77 16 0 7 0 1| 257M 26M 191M 29M| 548 1247 | 0 0 |5445B 689B| 230k 544k|firefox 13|firefox 125M|mount.ntfs- 771k:3056B|pdflush 0 : 94k
2 0 24| 85 14 0 1 0 0| 251M 26M 192M 33M| 550 1046 | 0 0 |1173B 418B| 50k 344k|firefox 12|firefox 125M|mount.ntfs- 771k:3056B|pdflush 0 : 85k
2 0 25| 85 12 0 2 0 0| 275M 26M 194M 8044k| 517 1024 | 0 0 |1206B 448B| 104k 642k|cc1 22|firefox 125M|mount.ntfs- 771k:3056B|pdflush 0 : 47k
2 0 9| 88 9 0 2 0 1| 278M 26M 193M 5568k| 558 1056 | 0 0 |1383B 615B| 110k 451k|cc1 26|firefox 125M|mount.ntfs- 771k:3056B|pdflush 0 : 51k
The meanings of "proc,cpu,mem,sys,page,net,disk,topcpu,topmem,topio,topbio" is obvious, it speaks for itself, the design of dstat is all modular, you can use many other modules than this:
$ (cd /usr/share/dstat/; ls *.py)
dstat_battery.py dstat_gpfs.py dstat_mysql5_com.py dstat_mysql_keys.py dstat_postfix.py dstat_thermal.py dstat_topoom.py dstat_vzcpu.py
dstat_cpufreq.py dstat_helloworld.py dstat_mysql5_conn.py dstat_nfs3op.py dstat.py dstat_topbio.py dstat_utmp.py dstat_vzubc.py
dstat_dbus.py dstat_innodb_buffer.py dstat_mysql5_io.py dstat_nfs3.py dstat_rpcd.py dstat_topcpu.py dstat_vmkhba.py dstat_wifi.py
dstat_freespace.py dstat_innodb_io.py dstat_mysql5_keys.py dstat_nfsd3op.py dstat_rpc.py dstat_topio.py dstat_vmkint.py
dstat_gpfsop.py dstat_innodb_ops.py dstat_mysql_io.py dstat_nfsd3.py dstat_sendmail.py dstat_topmem.py dstat_vmknic.py
So with "dstat -M battery 5", you can get the most battery consuming components when hardware supports ACPI.

Its module is just a simple py file with a simple class derived from dstat, so if there's no one fit for you, you can write your own dstat module.

Note: only CLI-based utils discussed here, I know there are many GUI-based or graph-generating tools can do better graphics, but on ther server side, "
Simple is better than complex.
"

Saturday, August 09, 2008

(setq cscope-do-not-update-database t)

if you use the kernel kbuild system `make mrproper cscope` with its cscope databases index files, use this to tell cscope not to update every time:

(setq cscope-do-not-update-database t)

Sunday, July 13, 2008

some most useful bash features

edit-and-execute-command (C-xC-e)
Invoke an editor on the current command line, and execute the result as shell com‐
mands. Bash attempts to invoke $FCEDIT, $EDITOR, and emacs as the editor, in that
order.

insert-completions (M-*)
Insert all completions of the text before point that would have been generated by pos‐
sible-completions.

complete-into-braces (M-{)
Perform filename completion and insert the list of possible completions enclosed
within braces so the list is available to the shell (see Brace Expansion above).

insert-comment (M-#)
Without a numeric argument, the value of the readline comment-begin variable is
inserted at the beginning of the current line. If a numeric argument is supplied,
this command acts as a toggle: if the characters at the beginning of the line do not
match the value of comment-begin, the value is inserted, otherwise the characters in
comment-begin are deleted from the beginning of the line. In either case, the line is
accepted as if a newline had been typed. The default value of comment-begin causes
this command to make the current line a shell comment. If a numeric argument causes
the comment character to be removed, the line will be executed by the shell.

Keyboard Macros
start-kbd-macro (C-x ()
Begin saving the characters typed into the current keyboard macro.
end-kbd-macro (C-x ))
Stop saving the characters typed into the current keyboard macro and store the defini‐
tion.
call-last-kbd-macro (C-x e)
Re-execute the last keyboard macro defined, by making the characters in the macro
appear as if typed at the keyboard.

display-shell-version (C-x C-v)
Display version information about the current instance of bash.

Friday, July 11, 2008

HOWTO ptrace a multi-process programs?

HOWTO-ptrace-multi-process-programs?



References:

  • Playing with ptrace, Part I (LinuxJournal)

  • Playing with ptrace, Part II (LinuxJournal)

  • 以 ptrace 系統呼叫來追蹤/修改行程 (JservBlog)

  • one line curl paste

    Recently an utility named wgetpaste run into my field, but after coming across it, I found it was really a shell script, it just organizes arguments and transfer to wget, in use of post mode of wget,



    $ head -n1 /usr/bin/wgetpaste
    #!/bin/sh


    In fact, I found that curl is better at this job, when I post some code to a paste service, just one curl command is enough:



    $ curl -d poster=chengrq -d syntax=c --data-urlencoded content@file.c \
    http://paste.ubuntu.com


    And, if you would like to read from a pipe other than a file, you could use '-' to replace the filename, it always did like what you think of that!



    BTW, ubuntu did a good job on the paste service, supporting many syntax highting.

    undocumented getopt

    首先说说getopt的规则用法,查看相关手册:



    $ man 3 getopt:

    #include <unistd.h>

    int getopt(int argc, char * const argv[],
    const char *optstring);

    extern char *optarg;
    extern int optind, opterr, optopt;

    #define _GNU_SOURCE
    #include <getopt.h>

    int getopt_long(int argc, char * const argv[],
    const char *optstring,
    const struct option *longopts, int *longindex);

    int getopt_long_only(int argc, char * const argv[],
    const char *optstring,
    const struct option *longopts, int *longindex);



    这一段是说只需要包含了unistd.h头文件就可以使用getopt了,它的函数原型使用argc,argv,optstring这三个参数;而如果需要使用GNU的扩展函数getopt_long,则还需要包含头文件getopt.h,并且在头文件之前定义_GNU_SOURCE宏,可以在C源文件中包含getopt.h之前直接define,而我一般是在Makefile里面写在CFLAGS上直接传参数给gcc;



    于是具体的编译命令是

    gcc -Wall -D_GNU_SOURCE filename.c
    这样如果大型项目使用了多个C文件则不必在每一个C文件中都写上define _GNU_SOURCE,只在Makefile写一次,减少了总体字节数。



    将其中的例子取出来测试:




    Download as text

     1
    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
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    #include <unistd.h>
    #include <stdlib.h>
    #include <stdio.h>

    int main(int argc, char *argv[])
    {
    int flags, opt;
    int nsecs, tfnd;

    nsecs = 0;
    tfnd = 0;
    flags = 0;
    while ((opt = getopt(argc, argv, "nt:")) != -1) {
    switch (opt) {
    case 'n':
    flags = 1;
    break;
    case 't':
    nsecs = atoi(optarg);
    tfnd = 1;
    break;
    default: /* ? */
    fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n",
    argv[0]);
    exit(EXIT_FAILURE);
    }
    }

    printf("flags=%d; tfnd=%d; optind=%d, nsecs=%d\n",
    flags, tfnd, optind, nsecs);

    if (optind >= argc) {
    fprintf(stderr, "Expected argument after options\n");
    exit(EXIT_FAILURE);
    }

    while (optind < argc)
    printf("name argument = %s\n", argv[optind++]);

    /* Other code omitted */

    exit(EXIT_SUCCESS);
    }



    Download as text


    编译和运行:



    $ gcc -Wall opt1.c
    $ ./a.out -t 3 -n arg1 -t 4 arg2
    flags=1; tfnd=1; optind=6, nsecs=4
    name argument = arg1
    name argument = arg2


    可见:




    1. 同一个参数指定多项时以最后一项指定生效,(-t4覆盖了-t3选项值);

    2. 最后多作的参数可以使用optind索引开始访问,getopt在调用过程中对argv字符串数组进行了permute,把所有非option的argument都移到最后去了;



    那么如果需要一个非option的argument参数并且是以"-"开头的,怎么输入?



    manual附带提到了一点,可以使用"--"来关闭option扫描:



    $ ./a.out -t 3 -n arg1 -t 4 arg2 -- -t 6 --new null
    flags=1; tfnd=1; optind=7, nsecs=4
    name argument = arg1
    name argument = arg2
    name argument = -t
    name argument = 6
    name argument = --new
    name argument = null



    在这次运行中,"-t 6"已经不被看作是option,而是作为多余的argument交给了程序。




    然后来说说optarg,optind,optopt,opterr的用途:





    1. optarg作为后接":"字符的option对应所需要的参数;

    2. optind是getopt处理完成(返回EOF表示完成)之后argument的位置,罽getopt只对argv数组重排序,不改变argc的大小,因此从optind到argc循环便可得所有非option参数;

    3. optopt和opterr都是用于处理用户输入未定义的option字符的情况,此时getopt返回'?'字符,将用户输入的真实的option放在optopt,并且自动向stderr打印一条错误消息,如"invalid option -- h",如果不想要这个错误提示可以预先设置opterr为0可关闭这个错误提示;



    手册中还详细介绍了optstring的用法:



    1. 单个的字符是开关量;

    2. 单个字符后接":"则意味着需要参数,在getopt调用后这个参数会被放入optarg这个全局量中;
    3. 如果接上两个冒号"::",则意味着参数是可选的,如"f::"对应输入"-ffoo"时,optarg获得"foo",而"-f foo"则optarg获得NULL,"foo"被计入argument部分;

    4. 如果optstring以"+"开头,则getopt停止于第一个非option处,如"-t 3 -n arg1 -t 4 arg2"会停止于"arg1"处将从它开始的"arg1 -t 4 arg2"都自动作为argument;

    5. 如果optstring以"-"开头,则getopt会将所有非option项(即argument)都以optiont为1处理(注意是数字1不是字符'1'),将其argument作为optarg;

    6. optstring中在前缀"+"或"-"后的第一个字符如果是':'冒号,则对未识别的option字符返回':'冒号而不是'?',参见optopt和opterr描述;



    以上部分都是手册里面提到过的正常的使用getopt,下面是一段在实用过程中发现的getopt的undocumented特性:


    有一个程序需要对getopt作多次循环调用:

    一般的getopt对argc,argv调用返回了所有参数后,在最后一次返回EOF表示argv数组已处理完,这里我将它称为一轮getopt循环调用;

    多次循环调用指的定在一次循环调用之后如何在程序里继续使用getopt处理其它的argc,argv?


    可能有人说,对新的argc,argv直接调用getopt就是了,~~~,其实不然:

    getopt能够循环调用的原理是它在内部使用了静态变量,保存了对argc,argv操作的状态,当第一轮getopt处理完时,这些内部的静态变量已记录处理到argc,argv到最后;因此如果直接使用getopt对新的argc,argv组进入调用时,会发现其根本不工作,直接返回EOF;


    于是有必要对getopt的内部原理作一番研究,已知它是标准C库提供的函数,于是找到glibc:

    apt-get source glibc
    或者
    ebuild /usr/portage/sys-libs/glibc/glibc-x.x.ebuild unpack
    取得源代码,找到实现这个库函数的posix/getopt.c文件,这里将它上传到了paste,分析其中初始化这些静态变量可以发现规律是:

    它会根据optind的值进行初始化(406行,1133行);

    调用顺序及相关数据结构是:



    static struct _getopt_data getopt_data;


    getopt (int argc, char *const *argv, const char *optstring)


    _getopt_internal (int argc, char *const *argv, const char *optstring,


      getopt_data.optind = optind;


     _getopt_internal_r (int argc, char *const *argv, const char *optstring,


      if (d->optind == 0 || !d->__initialized)


          optstring = _getopt_initialize (argc, argv, optstring, d);


    至此可知在d->optind为0或者d->__initialized为假的情况下会调用_getopt_initialize重新初始化;而调用_getopt_internal_r传入的d指针参数始终是&getopt_data,这是一个模块级全局变量(即static全局变量),在C库的此文件之外不可见,因此无法以直接的getopt_data.optind方式设置它;但从前面的调用路径可知d->optind每次都从全局变量optind初始化;因此我们可以设置optind为0然后再调用getopt让传入的d->optind为0使_getopt_initialize再一次被调用,让它从新初始化getopt所使用的内部静态变量(即getopt_data),达到可以重新一轮调用getopt的目的;



    于是程序中,需要新一轮调用getopt之前作一次

    optind=0;
    的设置,于是getopt继续工作!



    总结起来:


    1. getopt(3)手册中中提到了optarg,optind,optopt的输出(out类型参数)作用,即对用户程序是只读的,在getopt调用之后从它们可以读到一些信息;而opterr是只写(in类型参数)的,须在getopt调用之前进行设置为0或1,getopt函数实现中不改变opterr,而只根据opterr值有一些不同的行为;

    2. 通过对C库中的getopt函数实现的阅读可以了解到:optind还可以作为输入(in类型)参数,在getopt调用之前将optind置0可以使得getopt函数内部重新初始化;

    3. getopt.c:114行对optind的注释中提到"zero means the first call",而手册(manual)中未提到optind的in参数功能。


    Saturday, March 29, 2008

    I'm back again.