2013年3月14日星期四

如何延时GNOME的自动启动程序

环境是Ubuntu 12.04 GNOME 3.2。GNOME可以通过Startup Applications这个应用来设置自动启动的程序。Dropbox就是通过这里自动启动的。我发现每次刚刚进入桌面系统负载都很高,用top查看与Dropbox有关系。
从右上角的菜单打开
我想让Dropbox延迟两分钟再启动,这样可以让GNOME启动的速度加快,体验会好一点。我试图在Dropbox的启动命令前面加上sleep 120来延时,但这样后Dropbox根本就不自动启动了。
更改自动启动程序的对话框
我打算探个究竟,搞定我的问题。先通过ps找到启动这个程序的命令是gnome-session-properties,通过dpkg -S /usr/bin/gnome-session-properties找到对应的包名,然后下载源代码包gnome-session,在Eclipse里面创建项目。

不知道相关的文件是哪个?竟然是从翻译文件po/zh_CN.po里面看出来的,在capplet目录下。在gsm-app-dialog.c里面有这样的代码:
if (gsm_util_text_is_blank (exec)) {
        error_msg = _("The startup command cannot be empty");
} else {
        if (!g_shell_parse_argv (exec, &argc, &argv, &error)) {
                if (error != NULL) {
                        error_msg = error->message;
                } else {
                        error_msg = _("The startup command is not valid");
                }
        }
}
看起来这是判断启动命令的代码。安装好相关的开发包之后,在Eclipse里面可以看到g_shell_parse_argvglib.h里面声明的。文档里面说了,这个函数不支持Shell的很多特性。看来我的命令行'sleep 120; dropbox start -i'被解析成了不能执行的命令。写了如下一个测试程序test_gshell.c
#include <glib.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
    const char *exec = argv[1];
    GError     *error;
    const char *error_msg;
    char      **myargv;
    int         myargc;
    if (!g_shell_parse_argv (exec, &myargc, &myargv, &error)) {
        if (error != NULL) {
            error_msg = error->message;
        } else {
            error_msg = "The startup command is not valid";
        }
    }
    printf("%d\n", myargc);
    for(int i = 0; i < myargc; i++) {
        printf("%s\n", myargv[i]);
    }
}
用如下的命令编译出执行文件:
gcc -o test_gshell test_gshell.c \
    -I/usr/include/glib-2.0/ \
    -I/usr/lib/x86_64-linux-gnu/glib-2.0/include/ \
    -L/lib/x86_64-linux-gnu/ \
    -L/usr/lib/x86_64-linux-gnu/ \
    -L/lib64/ -lglib-2.0 -std=c99
然后测试我的命令:
$ ./test_gshell "sleep 120; dropbox start -i"
5
sleep
120;
dropbox
start
-i
看到GLib把我本来期望的两条命令的List解析成了sleep命令后面跟4个参数,相当于执行了如下Shell命令:
sleep "120;" "dropbox" "start" "-"
这个命令显然不能达到我的目的。

我翻墙的脚本也是通过GNOME来自启动的,有时候网络还没好,就希望能够延时执行,那个脚本可以带命令行的延时参数。现在要让Dropbox延时启动,我也只能用一个脚本把延时和Dropbox的命令封装起来,然后再让GNOME自动运行这个脚本。主要要在Dropbox的设置里把自动启动去掉。

2013年3月6日星期三

Ubuntu在Mac下的网络故障

Ubuntu(Macbook Pro 8,2)在一次例行升级后,以太网开始失效,ping办公室的网关时候就出现Destination Host Unreachable的错误。检查路由没有异常,抓包看不到任何ICMP包,怀疑是系统bug。

办公室的Wifi很差劲,为了工作只好切换到OSX下。OSX下工作环境没有配置完整,而且安装相关的开发环境很不方便,回头还是切回Ubuntu,但Ubuntu网络还是不能用,Wifi很卡。这两周来来回回切换,影响工作效率。

今天试了试Ubuntu的恢复模式,发现在单用户下网络是可以用的。遂把故障定位到GNOME桌面,认为是GNOME下网络有问题。就在单用户模式下装了个KDE,进去后结果还是有问题。后来想到试试内核模块,这个网卡用的模块是tg3,我rmmod之后再modprode,结果网络就好了。

折腾了这么久,其实重新加载内核模块的方法我早就用过了。还是这台Mac这个Ubuntu,以前Wifi用着用着就断了,我就用重新加载内核模块的方法了,出问题时候执行一个叫reset-wifi的脚本:
#! /bin/bash
# Reload Wifi module
sudo rmmod b43
sudo rmmod bcma
sudo modprobe bcma
可是这次有线网络出问题,我竟然折腾了这么久才找到个解决办法。

Git仓库的体积问题

我用git-filter-branch(1)手册中的方法:
git filter-branch --subdirectory-filter foodir -- --all
把Git仓库中的一个目录独立成一个新的Git项目。发现项目的.git目录没变小太多。原项目:
$ du -sk .git
55332 .git
新项目:
$ du -sk .git
49792 .git
新项目其实代码和历史都不多。我做过一次相同的事情,新项目会显著变小。我猜测是不是推到Git服务器上后会自动压缩,去掉历史里面无关的内容。于是我把内容推到GitLab(3.1版,后台是Gitolite管理),再clone下来,果然变小了很多:
$ du -sh .git
268K .git
我到服务器上检查,服务器上的仓库目录也压缩了。
所以git-filter-branch之后不用担心体积大小,放到服务器上会自动压缩的。

2013年3月1日星期五

Gitlab:缺乏工程性的项目

GitLab是一款界面类似GitHub的Git管理软件。虽然很强大,但是在工程性上欠佳。

GitLab的开发很快,也很流行。到官方博客去看,差不多一个月一个小版本,几个月就出一个大版本。3.0还是去年10月发布的,现在master分支已经是针对5.0的了,应该很快就要发布了。这些大版本都有重大的不兼容引入。

4.0前,仓库是在一个名字空间内。4.0开始,仓库是按用户名来区分的,类似GitHub的user/repo的命名方式。这和之前版本的用法是不兼容的。如果用户不想用这种用户名区分的仓库命名方式,想安装去年11月发布的3.1,就不能按照官方给出的文档地址来安装。因为这个是stable分支,现在指向的是4-1-stable,我们需要切换到3.1分支的文档来参考安装。

仅仅3月多月前的稳定版都没有一个正确的安装文档。这个文档里面init script和Nginx配置文件的地址分别是:https://raw.github.com/gitlabhq/gitlab-recipes/master/init.d/gitlab和https://raw.github.com/gitlabhq/gitlab-recipes/master/nginx/gitlab。master分支已经针对5.0了,和3-1-stable不兼容。gitlab-recipes这个项目没有针对3.1的分支。怎么办呢?我只好按照GitLab 3.1的发布日期2012年11月22日,去找到gitlab-recipes最接近那天的版本,下载这个版本的配置文件。

从4.1版本开始,GitLab的作者已经全职开发GitLab。充足的时间让这款软件的演进速度很快,但由于作者更专注于新功能的开发,而忽略了维护工作,导致文档缺乏,没有一个长期支持的稳定版本,缺乏对发行版本生命周期的管理。

GitLab一直依赖他们fork的Gitolite。5.0开始,将不依赖Gitolite,而用他们自己开发的GitLab Shell来管理仓库。有用户提出,之前GitLab宕了Git仓库还能访问(Gitolite是独立的);这样改动后,GitLab如果宕了整个Git仓库就不能访问了。

此外,GitLab安装过程繁琐,容易出错,而目前没有打包好的安装包。我觉得这对推广软件是很重要的,但貌似作者并不重视发行渠道。

根据我安装GitLab的经历,我觉得目前的GitLab还不太适合企业里面全面推广和长期部署。