一个偶然的原因,在研究git使用时,发现有个自动启动的git-daemon进程:
wellbye@AY130622174524343529Z:~$ ps aux|grep git root 912 0.0 0.0 164 4 ? Ss 16:47 0:00 runsv git-daemon gitlog 923 0.0 0.0 184 4 ? S 16:47 0:00 svlogd -tt /var/log/git-daemon 113 2254 0.0 0.0 11448 816 ? S 23:31 0:00 /usr/lib/git-core/git-daemon --verbose --reuseaddr --base-path=/home/git/repositories --syslog wellbye 2257 0.0 0.0 8100 924 pts/0 S+ 23:31 0:00 grep git
于是便想知道这个进程是怎么启动的,怎么调整其启动参数。因为最初的命令行参数里--base-path指向/var/cache/git,当然不是我想要的,为了能将其改为自己的仓库路径,自然就要了解其启动过程。
man了大半天,又bg了半天,基本知道了这是由runit包提供的一个进程监控机制,对指定的进程(一般是后台服务)进行监控,发现其挂了就会自动重启。同时它也提供了对外操作接口,可以通过管道与其通讯,默认提供了一个sv命令行程序来控制(被监控)进程的启停。
首先,在/etc/service/下面,有一堆子目录,这里每一个目录代表了一个要监控的服务,目录里面要放一些脚本文件如run/finish/down等等,分别会在各种时机被调用。对git-daemon来说,只有一个run脚本:
root@AY130622174524343529Z:/home/wellbye# ls -al /etc/service/git-daemon/ total 16 drwxr-xr-x 3 root root 4096 Jul 1 09:22 . drwxr-xr-x 4 root root 4096 Jun 25 14:29 .. drwxr-xr-x 2 root root 4096 Jun 25 14:24 log -rwxr-xr-x 1 root root 180 Jun 25 15:28 run lrwxrwxrwx 1 root root 29 Jun 25 14:24 supervise -> /var/lib/supervise/git-daemon
其内容很简单,就是真正启动目标进程:
root@AY130622174524343529Z:/home/wellbye# cat /etc/service/git-daemon/run #!/bin/sh exec 2>&1 echo 'git-daemon starting.' exec chpst -ugitdaemon "$(git --exec-path)"/git-daemon --verbose --reuseaddr --base-path=/home/git/repositories --syslog
chpst是改变进程属性的指令,-u意指修改所属用户,因为runsv都是由root启动的吧所以这里把用户改为专用于git的gitdaemon。要改变的进程则是后半句里启动的git-daemon进程。整个句子颇有点宾语从句的味道。。那么,要修改启动参数的话,就是在这里改了。
整个机制的总控进程是runsvdir,它会读取相应目录下的各个“服务配置”,为每一个“服务”分配启动一个runsv进程去监控执行,一个svlogd进程去写log。
runsvdir自身则是在系初始化时启动的,对ubuntu来说,它本身又是更高层级服务upstart里的一个条目:
root@AY130622174524343529Z:/home/wellbye# ls -l /etc/init/|grep runsv -rw-r--r-- 1 root root 103 Mar 15 03:42 runsvdir.conf
其内容就是在系统启动时,运行runsvdir-start进程,也就相当于 runsvdir /etc/service,即把/etc/service下面列出的服务启动并监控起来:
root@AY130622174524343529Z:/home/wellbye# cat /etc/init/runsvdir.conf start on runlevel [2345] stop on runlevel [016] respawn kill signal HUP exec /usr/sbin/runsvdir-start
对于这些服务,可用“sv 命令 服务名”来控制查询其状态:
root@AY130622174524343529Z:/home/wellbye# sv d git-daemon root@AY130622174524343529Z:/home/wellbye# sv s git-daemon down: git-daemon: 4s, normally up; run: log: (pid 923) 64894s root@AY130622174524343529Z:/home/wellbye# sv u git-daemon root@AY130622174524343529Z:/home/wellbye# sv s git-daemon run: git-daemon: (pid 3427) 5s; run: log: (pid 923) 64915s
概念大致就如此了。一个奇怪的问题是,之前我想用“sv d git-daemon”去停止git服务,以便测试客户端clone还能否运行,但结果怎么都杀不掉git-daemon进程,还以为是用法有问题搜索了很久也没答案,倒是也见到不少帖子说有类似现象的,说是的svlogd进程未能及时退出,导致后续响应失常,被杀的git-daemon进程又被重启了。直到我重启系统后,发现这个问题没了,每次u/d都正常有效,也许这确实是个bug吧。