先看service是如何啟動的。
1.啟動zygote
init.rc中有這樣一句話:
~~~
#class_start是一個COMMAND,對應的函數為do_class_start,很重要,切記。
class_startdefault
~~~
class_start標示一個COMMAND,對應的處理函數為do_class_start,它位于boot section的范圍內。為什么說它很重要呢?
還記得init進程中的四個執行階段嗎?當init進程執行到下面幾句話時,do_class_start就會被執行了。
~~~
//將bootsection節的command加入到執行隊列
action_for_each_trigger("boot",action_add_queue_tail);
//執行隊列里的命令,class可是一個COMMAND,所以它對應的do_class_start會被執行。
drain_action_queue();
~~~
下面來看do_class_start函數:
**builtins.c**
~~~
int do_class_start(int nargs, char **args)
{
/*
args為do_class_start的參數,init.rc中只有一個參數,就是default。
下面這個函數將從service_list中尋找classname為”default”的service,然后
調用service_start_if_not_disabled函數。現在讀者明白了service結構體中
classname的作用了嗎?
*/
service_for_each_class(args[1],service_start_if_not_disabled);
return 0;
}
~~~
我們已經知道,zygote這個service的classname的值就是“default”,所以會針對這個service調用service_start_if_not_disabled,這個函數的代碼是:
**parser.c**
~~~
static void service_start_if_not_disabled(structservice *svc)
{
if (!(svc->flags & SVC_DISABLED)) {
service_start(svc,NULL); //zygote可沒有設置SVC_DISABLED
}
}
~~~
service_start函數的代碼如下所示:
**init.c**
~~~
void service_start(struct service *svc, constchar *dynamic_args)
{
structstat s;
pid_tpid;
intneeds_console;
int n;
svc->flags &= (~(SVC_DISABLED|SVC_RESTARTING));
svc->time_started = 0;
if(svc->flags & SVC_RUNNING) {
return;//如果這個service已在運行,則不用處理
}
/*
service一般運行于另外一個進程中,這個進程也是init的子進程,所以啟動service前需要判斷
對應的可執行文件是否存在,zygote對應的可執行文件是/system/bin/app_process
*/
if(stat(svc->args[0], &s) != 0) {
svc->flags |= SVC_DISABLED;
return;
}
......
pid =fork(); //調用fork創建子進程
if(pid == 0) {
//pid為零,我們在子進程中
struct socketinfo *si;
struct svcenvinfo *ei;
char tmp[32];
int fd, sz;
//得到屬性存儲空間的信息并加到環境變量中,后面在屬性服務一節中會碰到使用它的地方。
get_property_workspace(&fd, &sz);
add_environment("ANDROID_PROPERTY_WORKSPACE", tmp);
//添加環境變量信息
for (ei = svc->envvars; ei; ei = ei->next)
add_environment(ei->name, ei->value);
//根據socketinfo創建socket
for (si = svc->sockets; si; si = si->next) {
int s = create_socket(si->name,
!strcmp(si->type,"dgram") ?
SOCK_DGRAM :SOCK_STREAM,
si->perm,si->uid, si->gid);
if (s >= 0) {
//在環境變量中添加socket信息。
publish_socket(si->name, s);
}
}
......//設置uid,gid等
setpgid(0, getpid());
if(!dynamic_args) {
/*
執行/system/bin/app_process,這樣就進入到app_process的main函數中了。
fork、execve這兩個函數都是Linux系統上常用的系統調用。
*/
if (execve(svc->args[0], (char**)svc->args, (char**) ENV) < 0) {
......
}
}else {
......
}
......//父進程init的處理,設置service的信息,如啟動時間、進程號,以及狀態等。
svc->time_started = gettime();
svc->pid = pid;
svc->flags |= SVC_RUNNING;
//每一個service都有一個屬性,zygote的屬性為init.svc.zygote,現在設置它的值為running
notify_service_state(svc->name, "running");
}
~~~
原來,zygote是通過fork和execv共同創建的!但service結構中的那個onrestart好像沒有派上用場,原因何在?
2. 重啟zygote
根據名字,就可猜到onrestart應該是在zygote重啟時用的。下面先看在zygote死后,它的父進程init會有什么動作:
**init.c**
~~~
static void sigchld_handler(int s)
{ //當子進程退出時,init的這個信號處理函數會被調用
write(signal_fd, &s, 1); //往signal_fd write數據
}
~~~
signal_fd,就是在init中通過socketpair創建的兩個socket中的一個,既然會往這個signal_fd中發送數據,那么另外一個socket就一定能接收到,這樣就會導致init從poll函數中返回:
**init.rc::main函數代碼片斷**
~~~
nr =poll(ufds, fd_count, timeout);
......
if(ufds[2].revents == POLLIN) {
read(signal_recv_fd, tmp, sizeof(tmp));
while (!wait_for_one_process(0))//調用wait_for_one_process函數處理
;
continue;
}
......
//直接看這個wait_for_one_process函數:
static int wait_for_one_process(int block)
{
pid_tpid;
intstatus;
structservice *svc;
structsocketinfo *si;
time_tnow;
structlistnode *node;
structcommand *cmd;
while( (pid = waitpid(-1, &status, block ? 0 : WNOHANG)) == -1 &&
errno == EINTR );
if(pid <= 0) return -1;
//找到死掉的那個service,現在應該找到了代表zygote的那個service。
svc = service_find_by_pid(pid);
......
if(!(svc->flags & SVC_ONESHOT)) {
//殺掉zygote創建的所有子進程,這就是zygote死后,Java世界崩潰的原因。
kill(-pid, SIGKILL);
}
//清理socket信息,不清楚的讀者可以通過命令man 7 AF_UNIX查詢一下相關知識。
for(si = svc->sockets; si; si = si->next) {
char tmp[128];
snprintf(tmp, sizeof(tmp), ANDROID_SOCKET_DIR"/%s",si->name);
unlink(tmp);
}
svc->pid = 0;
svc->flags &= (~SVC_RUNNING);
if(svc->flags & SVC_ONESHOT) {
svc->flags |= SVC_DISABLED;
}
......
now= gettime();
/*
如果設置了SVC_CRITICAL標示,則4分鐘內該服務重啟次數不能超過4次,否則
機器會重啟進入recovery模式。根據init.rc的配置,只有servicemanager進程
享有此種待遇。
*/
if(svc->flags & SVC_CRITICAL) {
if(svc->time_crashed + CRITICAL_CRASH_WINDOW >= now) {
if (++svc->nr_crashed > CRITICAL_CRASH_THRESHOLD) {
......
sync();
__reboot(LINUX_REBOOT_MAGIC1,LINUX_REBOOT_MAGIC2,
LINUX_REBOOT_CMD_RESTART2, "recovery");
return 0;
}
}else {
svc->time_crashed = now;
svc->nr_crashed = 1;
}
}
svc->flags |= SVC_RESTARTING;
//設置標示為SVC_RESTARTING,然后執行該service onrestart中的COMMAND,這些內容就
//非常簡單了,讀者可以自行學習。
list_for_each(node, &svc->onrestart.commands) {
cmd = node_to_item(node, struct command, clist);
cmd->func(cmd->nargs, cmd->args);
}
//設置init.svc.zygote的值為restarting。
notify_service_state(svc->name, "restarting");
return0;
}
~~~
通過上面的代碼,可知道onrestart的作用了,但zygote本身又在哪里重啟的呢?答案就在下面的代碼中:
**init.c::main函數代碼片斷**
~~~
for(;;) {
int nr, i, timeout = -1;
for (i = 0; i < fd_count; i++)
ufds[i].revents = 0;
drain_action_queue(); //poll函數返回后,會進入下一輪的循環
restart_processes(); //這里會重啟所有flag標志為SVC_RESTARTING的service。
......
}
~~~
這樣,zygote又回來了!
- 前言
- 第1章 閱讀前的準備工作
- 1.1 系統架構
- 1.1.1 Android系統架構
- 1.1.2 本書的架構
- 1.2 搭建開發環境
- 1.2.1 下載源碼
- 1.2.2 編譯源碼
- 1.3 工具介紹
- 1.3.1 Source Insight介紹
- 1.3.2 Busybox的使用
- 1.4 本章小結
- 第2章 深入理解JNI
- 2.1 JNI概述
- 2.2 學習JNI的實例:MediaScanner
- 2.3 Java層的MediaScanner分析
- 2.3.1 加載JNI庫
- 2.3.2 Java的native函數和總結
- 2.4 JNI層MediaScanner的分析
- 2.4.1 注冊JNI函數
- 2.4.2 數據類型轉換
- 2.4.3 JNIEnv介紹
- 2.4.4 通過JNIEnv操作jobject
- 2.4.5 jstring介紹
- 2.4.6 JNI類型簽名介紹
- 2.4.7 垃圾回收
- 2.4.8 JNI中的異常處理
- 2.5 本章小結
- 第3章 深入理解init
- 3.1 概述
- 3.2 init分析
- 3.2.1 解析配置文件
- 3.2.2 解析service
- 3.2.3 init控制service
- 3.2.4 屬性服務
- 3.3 本章小結
- 第4章 深入理解zygote
- 4.1 概述
- 4.2 zygote分析
- 4.2.1 AppRuntime分析
- 4.2.2 Welcome to Java World
- 4.2.3 關于zygote的總結
- 4.3 SystemServer分析
- 4.3.1 SystemServer的誕生
- 4.3.2 SystemServer的重要使命
- 4.3.3 關于 SystemServer的總結
- 4.4 zygote的分裂
- 4.4.1 ActivityManagerService發送請求
- 4.4.2 有求必應之響應請求
- 4.4.3 關于zygote分裂的總結
- 4.5 拓展思考
- 4.5.1 虛擬機heapsize的限制
- 4.5.2 開機速度優化
- 4.5.3 Watchdog分析
- 4.6 本章小結
- 第5章 深入理解常見類
- 5.1 概述
- 5.2 以“三板斧”揭秘RefBase、sp和wp
- 5.2.1 第一板斧--初識影子對象
- 5.2.2 第二板斧--由弱生強
- 5.2.3 第三板斧--破解生死魔咒
- 5.2.4 輕量級的引用計數控制類LightRefBase
- 5.2.5 題外話-三板斧的來歷
- 5.3 Thread類及常用同步類分析
- 5.3.1 一個變量引發的思考
- 5.3.2 常用同步類
- 5.4 Looper和Handler類分析
- 5.4.1 Looper類分析
- 5.4.2 Handler分析
- 5.4.3 Looper和Handler的同步關系
- 5.4.4 HandlerThread介紹
- 5.5 本章小結
- 第6章 深入理解Binder
- 6.1 概述
- 6.2 庖丁解MediaServer
- 6.2.1 MediaServer的入口函數
- 6.2.2 獨一無二的ProcessState
- 6.2.3 時空穿越魔術-defaultServiceManager
- 6.2.4 注冊MediaPlayerService
- 6.2.5 秋風掃落葉-StartThread Pool和join Thread Pool分析
- 6.2.6 你徹底明白了嗎
- 6.3 服務總管ServiceManager
- 6.3.1 ServiceManager的原理
- 6.3.2 服務的注冊
- 6.3.3 ServiceManager存在的意義
- 6.4 MediaPlayerService和它的Client
- 6.4.1 查詢ServiceManager
- 6.4.2 子承父業
- 6.5 拓展思考
- 6.5.1 Binder和線程的關系
- 6.5.2 有人情味的訃告
- 6.5.3 匿名Service
- 6.6 學以致用
- 6.6.1 純Native的Service
- 6.6.2 扶得起的“阿斗”(aidl)
- 6.7 本章小結
- 第7章 深入理解Audio系統
- 7.1 概述
- 7.2 AudioTrack的破解
- 7.2.1 用例介紹
- 7.2.2 AudioTrack(Java空間)分析
- 7.2.3 AudioTrack(Native空間)分析
- 7.2.4 關于AudioTrack的總結
- 7.3 AudioFlinger的破解
- 7.3.1 AudioFlinger的誕生
- 7.3.2 通過流程分析AudioFlinger
- 7.3.3 audio_track_cblk_t分析
- 7.3.4 關于AudioFlinger的總結
- 7.4 AudioPolicyService的破解
- 7.4.1 AudioPolicyService的創建
- 7.4.2 重回AudioTrack
- 7.4.3 聲音路由切換實例分析
- 7.4.4 關于AudioPolicy的總結
- 7.5 拓展思考
- 7.5.1 DuplicatingThread破解
- 7.5.2 題外話
- 7.6 本章小結
- 第8章 深入理解Surface系統
- 8.1 概述
- 8.2 一個Activity的顯示
- 8.2.1 Activity的創建
- 8.2.2 Activity的UI繪制
- 8.2.3 關于Activity的總結
- 8.3 初識Surface
- 8.3.1 和Surface有關的流程總結
- 8.3.2 Surface之乾坤大挪移
- 8.3.3 乾坤大挪移的JNI層分析
- 8.3.4 Surface和畫圖
- 8.3.5 初識Surface小結
- 8.4 深入分析Surface
- 8.4.1 與Surface相關的基礎知識介紹
- 8.4.2 SurfaceComposerClient分析
- 8.4.3 SurfaceControl分析
- 8.4.4 writeToParcel和Surface對象的創建
- 8.4.5 lockCanvas和unlockCanvasAndPost分析
- 8.4.6 GraphicBuffer介紹
- 8.4.7 深入分析Surface的總結
- 8.5 SurfaceFlinger分析
- 8.5.1 SurfaceFlinger的誕生
- 8.5.2 SF工作線程分析
- 8.5.3 Transaction分析
- 8.5.4 關于SurfaceFlinger的總結
- 8.6 拓展思考
- 8.6.1 Surface系統的CB對象分析
- 8.6.2 ViewRoot的你問我答
- 8.6.3 LayerBuffer分析
- 8.7 本章小結
- 第9章 深入理解Vold和Rild
- 9.1 概述
- 9.2 Vold的原理與機制分析
- 9.2.1 Netlink和Uevent介紹
- 9.2.2 初識Vold
- 9.2.3 NetlinkManager模塊分析
- 9.2.4 VolumeManager模塊分析
- 9.2.5 CommandListener模塊分析
- 9.2.6 Vold實例分析
- 9.2.7 關于Vold的總結
- 9.3 Rild的原理與機制分析
- 9.3.1 初識Rild
- 9.3.2 RIL_startEventLoop分析
- 9.3.3 RIL_Init分析
- 9.3.4 RIL_register分析
- 9.3.5 關于Rild main函數的總結
- 9.3.6 Rild實例分析
- 9.3.7 關于Rild的總結
- 9.4 拓展思考
- 9.4.1 嵌入式系統的存儲知識介紹
- 9.4.2 Rild和Phone的改進探討
- 9.5 本章小結
- 第10章 深入理解MediaScanner
- 10.1 概述
- 10.2 android.process.media分析
- 10.2.1 MSR模塊分析
- 10.2.2 MSS模塊分析
- 10.2.3 android.process.media媒體掃描工作的流程總結
- 10.3 MediaScanner分析
- 10.3.1 Java層分析
- 10.3.2 JNI層分析
- 10.3.3 PVMediaScanner分析
- 10.3.4 關于MediaScanner的總結
- 10.4 拓展思考
- 10.4.1 MediaScannerConnection介紹
- 10.4.2 我問你答
- 10.5 本章小結