一個偶然的原因,在研究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吧。