zygote孵化器在android系统中有着及其中要的位置. android系统中的进程都是有zygote孵化出来的, 所有应用进程都是zygote的子进程. 在init进程中的服务都是由命令启动起来的, zygote服务也不例外, 所以在分析zygote之前要分析一下init.rc中命令是如何执行的.
在分析init进程时知道在init.cpp中的main函数循环执行命令
while (true) {
if (!waiting_for_exec) {
am.ExecuteOneCommand(); //循环执行命令
restart_processes(); //重启死掉的进程
}
int timeout = -1;
if (process_needs_restart) {
timeout = (process_needs_restart - gettime()) * 1000;
if (timeout < 0)
timeout = 0;
}
if (am.HasMoreCommands()) {
timeout = 0;
}
bootchart_sample(&timeout);
epoll_event ev;
int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
if (nr == -1) {
ERROR("epoll_wait failed: %s\n", strerror(errno));
} else if (nr == 1) {
((void (*)()) ev.data.ptr)();
}
}
return 0;
void ActionManager::ExecuteOneCommand() {
// Loop through the trigger queue until we have an action to execute
while (current_executing_actions_.empty() && !trigger_queue_.empty()) { //当前的可执行action队列为空, trigger_queue_队列不为空
for (const auto& action : actions_) { //循环遍历action_队列,包含了所有需要执行的命令,解析init.rc获得
if (trigger_queue_.front()->CheckTriggers(*action)) { //获取队头的trigger, 检查actions_列表中的action的trigger,对比是否相同
current_executing_actions_.emplace(action.get()); //将所有具有同一trigger的action加入当前可执行action队列
}
}
trigger_queue_.pop(); //将队头trigger出栈
}
if (current_executing_actions_.empty()) {//当前可执行的actions队列为空就返回
return;
}
auto action = current_executing_actions_.front(); //获取当前可执行actions队列的首个action
if (current_command_ == 0) {
std::string trigger_name = action->BuildTriggersString();
INFO("processing action (%s)\n", trigger_name.c_str());
}
action->ExecuteOneCommand(current_command_); //执行当前的命令
// If this was the last command in the current action, then remove
// the action from the executing list.
// If this action was oneshot, then also remove it from actions_.
++current_command_; //不断叠加,将action_中的所有命令取出
if (current_command_ == action->NumCommands()) {
current_executing_actions_.pop();
current_command_ = 0;
if (action->oneshot()) {
auto eraser = [&action] (std::unique_ptr& a) {
return a.get() == action;
};
actions_.erase(std::remove_if(actions_.begin(), actions_.end(), eraser));
}
}
}
由于所有的命令执行顺序都是根据trigger的顺序执行的, 所以在获取现在需要执行的action就需要检查一下这个action的trigger.
不同的trigger对应这不同的CheckTriggers. 之前讲android7.0 init进程时知道
early-init等的trigger为EventTrigger
wait_for_coldboot_done_action等的trigger就为BuiltinTrigger
在init.rc可以看到类似与on property:sys.powerctl=*这样的trigger为PropertyTrigger
下面具体看一下这几个trigger的CheckTriggers函数
class EventTrigger : public Trigger {
public:
EventTrigger(const std::string& trigger) : trigger_(trigger) {
}
bool CheckTriggers(const Action& action) const override {
return action.CheckEventTrigger(trigger_);
}
private:
const std::string trigger_;
};
class PropertyTrigger : public Trigger {
public:
PropertyTrigger(const std::string& name, const std::string& value)
: name_(name), value_(value) {
}
bool CheckTriggers(const Action& action) const override {
return action.CheckPropertyTrigger(name_, value_);
}
private:
const std::string name_;
const std::string value_;
};
class BuiltinTrigger : public Trigger {
public:
BuiltinTrigger(Action* action) : action_(action) {
}
bool CheckTriggers(const Action& action) const override {
return action_ == &action; //如果action相等就返回true执行
}
private:
const Action* action_;
};
EventTrigger
bool Action::CheckEventTrigger(const std::string& trigger) const {
return !event_trigger_.empty() && //event_trigger_不为空, 在addCommand时InitTriggers添加数据
trigger == event_trigger_ && //event_trigger_与当前的trigger相同
CheckPropertyTriggers(); //不是property trigger
}
PropertyTrigger
bool Action::CheckPropertyTrigger(const std::string& name,
const std::string& value) const {
return event_trigger_.empty() && CheckPropertyTriggers(name, value);
}
bool Action::CheckPropertyTriggers(const std::string& name,
const std::string& value) const {
if (property_triggers_.empty()) { //property triggers为空返回true
return true;
}
bool found = name.empty();
for (const auto& t : property_triggers_) {
const auto& trigger_name = t.first;
const auto& trigger_value = t.second;
if (trigger_name == name) {
if (trigger_value != "*" && trigger_value != value) {
return false; //是property trigger 返回false
} else {
found = true;
}
} else {
std::string prop_val = property_get(trigger_name.c_str());
if (prop_val.empty() || (trigger_value != "*" &&
trigger_value != prop_val)) {
return false;
}
}
}
return found;
}
根据trigger找到对应的action就开始执行了
void Action::ExecuteOneCommand(std::size_t command) const {
ExecuteCommand(commands_[command]); //从commands_队列取出命令对应的函数
}
void Action::ExecuteCommand(const Command& command) const {
Timer t; //使用timer计时
int result = command.InvokeFunc();
if (klog_get_level() >= KLOG_INFO_LEVEL) {
std::string trigger_name = BuildTriggersString();
std::string cmd_str = command.BuildCommandString();
std::string source = command.BuildSourceString();
INFO("Command '%s' action=%s%s returned %d took %.2fs\n",
cmd_str.c_str(), trigger_name.c_str(), source.c_str(),
result, t.duration()); //可以将该log级别改为NOTICE,可以输出当前执行命令的信息以及执行时间输出, 定位开机问题
}
}
int Command::InvokeFunc() const {
std::vector expanded_args;
expanded_args.resize(args_.size());
expanded_args[0] = args_[0];
for (std::size_t i = 1; i < args_.size(); ++i) {
if (!expand_props(args_[i], &expanded_args[i])) {
ERROR("%s: cannot expand '%s'\n", args_[0].c_str(), args_[i].c_str());
return -EINVAL;
}
}
return func_(expanded_args); //执行获得的函数
}
由于根据android7.0 init进程可以知道第一个触发的动作为early-init
在init.rc中early-init的命令如下:
on early-init //触发器为early-init, 首先执行
# Set init and its forked children's oom_adj.
write /proc/1/oom_score_adj -1000 //调用do_write函数
# Disable sysrq from keyboard
write /proc/sys/kernel/sysrq 0
# Set the security context of /adb_keys if present.
restorecon /adb_keys //调用do_restorecon函数
# Shouldn't be necessary, but sdcard won't start without it. http://b/22568628.
mkdir /mnt 0775 root system //调用do_mkdir函数
# Set the security context of /postinstall if present.
restorecon /postinstall
start ueventd //调用do_start函数启动ueventd服务
service ueventd /sbin/ueventd
class core //class name为core
critical //重要服务
seclabel u:r:ueventd:s0
之后会相继触发init, late-init等.
on late-init
trigger early-fs //触发early-fs
trigger fs //触发fs
trigger post-fs //触发post-fs
# Load properties from /system/ + /factory after fs mount. Place
# this in another action so that the load will be scheduled after the prior
# issued fs triggers have completed.
trigger load_system_props_action
# Now we can mount /data. File encryption requires keymaster to decrypt
# /data, which in turn can only be loaded when system properties are present
trigger post-fs-data
trigger load_persist_props_action
# Remove a file to wake up anything waiting for firmware.
trigger firmware_mounts_complete
trigger early-boot
trigger boot
on fs //触发fs就会执行如下命令
ubiattach 0 ubipac
exec /sbin/resize2fs -ef /fstab.${ro.hardware}
mount_all /fstab.${ro.hardware} //执行do_mount_all函数
mount pstore pstore /sys/fs/pstore
setprop ro.crypto.fuse_sdcard true
symlink /system/res /res
symlink /system/bin /bin
在system/core/init/builtins.cpp中实现了do_mount_all函数
static int do_mount_all(const std::vector& args) {
pid_t pid;
int ret = -1;
int child_ret = -1;
int status;
struct fstab *fstab;
const char* fstabfile = args[1].c_str();
/*
* Call fs_mgr_mount_all() to mount all filesystems. We fork(2) and
* do the call in the child to provide protection to the main init
* process if anything goes wrong (crash or memory leak), and wait for
* the child to finish in the parent.
*/
pid = fork();
..............
if (ret == FS_MGR_MNTALL_DEV_NEEDS_ENCRYPTION) {
ActionManager::GetInstance().QueueEventTrigger("encrypt");
} else if (ret == FS_MGR_MNTALL_DEV_MIGHT_BE_ENCRYPTED) {
property_set("ro.crypto.state", "encrypted");
property_set("ro.crypto.type", "block");
ActionManager::GetInstance().QueueEventTrigger("defaultcrypto");
} else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTED) {
property_set("ro.crypto.state", "unencrypted");
ActionManager::GetInstance().QueueEventTrigger("nonencrypted"); //将nonencrypted加入trigger_queue_
} else if (ret == FS_MGR_MNTALL_DEV_NOT_ENCRYPTABLE) {
property_set("ro.crypto.state", "unsupported");
ActionManager::GetInstance().QueueEventTrigger("nonencrypted"); //将nonencrypted加入trigger_queue_
} else if (ret == FS_MGR_MNTALL_DEV_NEEDS_RECOVERY) {
/* Setup a wipe via recovery, and reboot into recovery */
ERROR("fs_mgr_mount_all suggested recovery, so wiping data via recovery.\n");
ret = wipe_data_via_recovery("wipe_data_via_recovery");
/* If reboot worked, there is no return. */
} else if (ret == FS_MGR_MNTALL_DEV_FILE_ENCRYPTED) {
if (e4crypt_install_keyring()) {
return -1;
}
property_set("ro.crypto.state", "encrypted");
property_set("ro.crypto.type", "file");
// Although encrypted, we have device key, so we do not need to
// do anything different from the nonencrypted case.
ActionManager::GetInstance().QueueEventTrigger("nonencrypted");
} else if (ret > 0) {
ERROR("fs_mgr_mount_all returned unexpected error %d\n", ret);
}
/* else ... < 0: error */
return ret;
}
on nonencrypted //触发action
# A/B update verifier that marks a successful boot.
exec - root -- /system/bin/update_verifier nonencrypted
class_start main //调用do_class_start函数将class name为main的services启动起来
class_start late_start
在system/core/rootdir/init.zygote64.rc文件中可以看出zygote的class name就为main
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main //class name为main
socket zygote stream 660 root system
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart audioserver
onrestart restart cameraserver
onrestart restart media
onrestart restart netd
writepid /dev/cpuset/foreground/tasks /dev/stune/foreground/tasks
还是在system/core/init/builtins.cpp中实现了do_class_start函数
static int do_class_start(const std::vector& args) {
/* Starting a class does not start services
* which are explicitly disabled. They must
* be started individually.
*/
ServiceManager::GetInstance().
ForEachServiceInClass(args[1], [] (Service* s) { s->StartIfNotDisabled(); });
return 0;
}
bool Service::StartIfNotDisabled() {
if (!(flags_ & SVC_DISABLED)) {
return Start(); //如果services不是disable,就将start()函数返回
} else {
flags_ |= SVC_DISABLED_START; //否则,标记services为disable
}
return true;
}
void ServiceManager::ForEachServiceInClass(const std::string& classname,
void (*func)(Service* svc)) const {
for (const auto& s : services_) { //遍历services_寻找所有name为main的servies
if (classname == s->classname()) {
func(s.get()); //如果找到就调用Start()函数
}
}
}
bool Service::Start() {
// Starting a service removes it from the disabled or reset state and
// immediately takes it out of the restarting state if it was in there.
flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
time_started_ = 0;
// Running processes require no additional work --- if they're in the
// process of exiting, we've ensured that they will immediately restart
// on exit, unless they are ONESHOT.
if (flags_ & SVC_RUNNING) {
return false;
}
bool needs_console = (flags_ & SVC_CONSOLE);
if (needs_console && !have_console) {
ERROR("service '%s' requires console\n", name_.c_str());
flags_ |= SVC_DISABLED;
return false;
}
struct stat sb;
if (stat(args_[0].c_str(), &sb) == -1) {
ERROR("cannot find '%s' (%s), disabling '%s'\n",
args_[0].c_str(), strerror(errno), name_.c_str());
flags_ |= SVC_DISABLED;
return false;
}
std::string bootmode = property_get("ro.bootmode");
if(((!strncmp(name_.c_str(),"healthd",7))||(!strncmp(name_.c_str(),"bootanim",8))||(!strncmp(name_.c_str(),"zygote",6))||(!strncmp(name_.c_str(),"surfaceflinger",14)))&&(bootmode == "charger")){
ERROR("stopping '%s'\n",name_.c_str());
flags_ |= SVC_DISABLED;
return false;
}
std::string scon;
if (!seclabel_.empty()) {
scon = seclabel_;
} else {
char* mycon = nullptr;
char* fcon = nullptr;
INFO("computing context for service '%s'\n", args_[0].c_str());
int rc = getcon(&mycon);
if (rc < 0) {
ERROR("could not get context while starting '%s'\n", name_.c_str());
return false;
}
rc = getfilecon(args_[0].c_str(), &fcon);
if (rc < 0) {
ERROR("could not get context while starting '%s'\n", name_.c_str());
free(mycon);
return false;
}
char* ret_scon = nullptr;
rc = security_compute_create(mycon, fcon, string_to_security_class("process"),
&ret_scon);
if (rc == 0) {
scon = ret_scon;
free(ret_scon);
}
if (rc == 0 && scon == mycon) {
ERROR("Service %s does not have a SELinux domain defined.\n", name_.c_str());
free(mycon);
free(fcon);
return false;
}
free(mycon);
free(fcon);
if (rc < 0) {
ERROR("could not get context while starting '%s'\n", name_.c_str());
return false;
}
}
//上面都是对services进行判断,设置flags, 下面才是重点
NOTICE("Starting service '%s'...\n", name_.c_str()); //在kernel log中可以看打印信息
pid_t pid = fork(); //孵化进程
if (pid == 0) {
umask(077);
for (const auto& ei : envvars_) {
add_environment(ei.name.c_str(), ei.value.c_str());
}
for (const auto& si : sockets_) {
int socket_type = ((si.type == "stream" ? SOCK_STREAM :
(si.type == "dgram" ? SOCK_DGRAM :
SOCK_SEQPACKET)));
const char* socketcon =
!si.socketcon.empty() ? si.socketcon.c_str() : scon.c_str();
int s = create_socket(si.name.c_str(), socket_type, si.perm,
si.uid, si.gid, socketcon);
if (s >= 0) {
PublishSocket(si.name, s);
}
}
std::string pid_str = StringPrintf("%d", getpid());
for (const auto& file : writepid_files_) {
if (!WriteStringToFile(pid_str, file)) {
ERROR("couldn't write %s to %s: %s\n",
pid_str.c_str(), file.c_str(), strerror(errno));
}
}
if (ioprio_class_ != IoSchedClass_NONE) {
if (android_set_ioprio(getpid(), ioprio_class_, ioprio_pri_)) {
ERROR("Failed to set pid %d ioprio = %d,%d: %s\n",
getpid(), ioprio_class_, ioprio_pri_, strerror(errno));
}
}
if (needs_console) {
setsid();
OpenConsole();
} else {
ZapStdio();
}
setpgid(0, getpid());
// As requested, set our gid, supplemental gids, and uid.
if (gid_) {
if (setgid(gid_) != 0) {
ERROR("setgid failed: %s\n", strerror(errno));
_exit(127);
}
}
if (!supp_gids_.empty()) {
if (setgroups(supp_gids_.size(), &supp_gids_[0]) != 0) {
ERROR("setgroups failed: %s\n", strerror(errno));
_exit(127);
}
}
if (uid_) {
if (setuid(uid_) != 0) {
ERROR("setuid failed: %s\n", strerror(errno));
_exit(127);
}
}
if (!seclabel_.empty()) {
if (setexeccon(seclabel_.c_str()) < 0) {
ERROR("cannot setexeccon('%s'): %s\n",
seclabel_.c_str(), strerror(errno));
_exit(127);
}
}
std::vector strs;
for (const auto& s : args_) {
strs.push_back(const_cast(s.c_str()));
}
strs.push_back(nullptr);
if (execve(args_[0].c_str(), (char**) &strs[0], (char**) ENV) < 0) { //执行system/bin/process程序,进入framework层
ERROR("cannot execve('%s'): %s\n", args_[0].c_str(), strerror(errno));
}
_exit(127);
}
if (pid < 0) {
ERROR("failed to start '%s'\n", name_.c_str());
pid_ = 0;
return false;
}
time_started_ = gettime();
pid_ = pid;
flags_ |= SVC_RUNNING; //将services标记为running
if ((flags_ & SVC_EXEC) != 0) {
INFO("SVC_EXEC pid %d (uid %d gid %d+%zu context %s) started; waiting...\n",
pid_, uid_, gid_, supp_gids_.size(),
!seclabel_.empty() ? seclabel_.c_str() : "default");
}
NotifyStateChange("running");
return true;
}
调用execve执行system/bin/app_process程序, 就会进入framework/cmds/app_process/app_main.cpp的main函数.
正式进入framework层. 后文将详细分析.