struct cmdinfo cmds[] = {
{ "ping", 0, do_ping },
{ "create_app_data", 7, do_create_app_data },
{ "restorecon_app_data", 6, do_restorecon_app_data },
{ "migrate_app_data", 4, do_migrate_app_data },
{ "clear_app_data", 5, do_clear_app_data },
{ "destroy_app_data", 5, do_destroy_app_data },
{ "move_complete_app", 7, do_move_complete_app },
{ "get_app_size", 6, do_get_app_size },
{ "get_app_data_inode", 4, do_get_app_data_inode },
{ "create_user_data", 4, do_create_user_data },
{ "destroy_user_data", 3, do_destroy_user_data },
//odex 优化
{ "dexopt", 10, do_dexopt },
{ "markbootcomplete", 1, do_mark_boot_complete },
{ "rmdex", 2, do_rm_dex },
{ "freecache", 2, do_free_cache },
{ "linklib", 4, do_linklib },
{ "idmap", 3, do_idmap },
{ "createoatdir", 2, do_create_oat_dir },
{ "rmpackagedir", 1, do_rm_package_dir },
{ "clear_app_profiles", 1, do_clear_app_profiles },
{ "destroy_app_profiles", 1, do_destroy_app_profiles },
{ "linkfile", 3, do_link_file },
{ "move_ab", 3, do_move_ab },
{ "merge_profiles", 2, do_merge_profiles },
{ "dump_profiles", 3, do_dump_profiles },
{ "delete_odex", 3, do_delete_odex },
};
const BuiltinFunctionMap function\_map;Action::set\_function\_map(&function\_map);Parser& parser = Parser::GetInstance();parser.AddSectionParser("service",std::make\_unique<ServiceParser>());parser.AddSectionParser("on", std::make\_unique<ActionParser>());parser.AddSectionParser("import", std::make\_unique<ImportParser>());parser.ParseConfig("/init.rc");ActionManager& am = ActionManager::GetInstance();am.QueueEventTrigger("early-init");..........................
// Trigger all the boot actions to get us started.am.QueueEventTrigger("init");.........................
std::string bootmode = property\_get("ro.bootmode");if (bootmode == "charger") { am.QueueEventTrigger("charger");} else if (strncmp(bootmode.c\_str(), "ffbm", 4) == 0) { NOTICE("Booting into ffbm mode\n"); am.QueueEventTrigger("ffbm");} else { am.QueueEventTrigger("late-init");}// Run all property triggers based on current state of the properties.am.QueueBuiltinAction(queue\_property\_triggers\_action, "queue\_property\_triggers");...............................
}
*.rc 中如何解析相关脚本,参看如下方法定义:
system/core/init/builtins.cpp
BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
constexpr std::size\_t kMax = std::numeric\_limits<std::size\_t>::max();static const Map builtin\_functions = { {"bootchart\_init", {0, 0, do\_bootchart\_init}}, {"chmod", {2, 4, do\_chmod}}, {"chown", {2, 5, do\_chown}}, {"class\_reset", {1, 1, do\_class\_reset}}, {"class\_start", {1, 1, do\_class\_start}}, {"class\_stop", {1, 1, do\_class\_stop}}, {"copy", {2, 2, do\_copy}}, {"domainname", {1, 1, do\_domainname}}, {"enable", {1, 1, do\_enable}}, {"exec", {1, kMax, do\_exec}}, {"export", {2, 2, do\_export}}, {"hostname", {1, 1, do\_hostname}}, {"ifup", {1, 1, do\_ifup}}, {"init\_user0", {0, 0, do\_init\_user0}}, {"insmod", {1, kMax, do\_insmod}}, {"installkey", {1, 1, do\_installkey}}, {"load\_persist\_props", {0, 0, do\_load\_persist\_props}}, {"load\_system\_props", {0, 0, do\_load\_system\_props}}, {"loglevel", {1, 1, do\_loglevel}}, {"mkdir", {1, 4, do\_mkdir}}, {"mount\_all", {1, kMax, do\_mount\_all}}, {"mount", {3, kMax, do\_mount}}, {"umount", {1, 1, do\_umount}}, {"powerctl", {1, 1, do\_powerctl}}, {"restart", {1, 1, do\_restart}}, {"restorecon", {1, kMax, do\_restorecon}}, {"restorecon\_recursive", {1, kMax, do\_restorecon\_recursive}}, {"rm", {1, 1, do\_rm}}, {"rmdir", {1, 1, do\_rmdir}}, {"setprop", {2, 2, do\_setprop}}, {"setrlimit", {3, 3, do\_setrlimit}}, {"start", {1, 1, do\_start}}, {"stop", {1, 1, do\_stop}}, {"swapon\_all", {1, 1, do\_swapon\_all}}, {"symlink", {2, 2, do\_symlink}}, {"sysclktz", {1, 1, do\_sysclktz}}, {"trigger", {1, 1, do\_trigger}}, {"verity\_load\_state", {0, 0, do\_verity\_load\_state}}, {"verity\_update\_state", {0, 0, do\_verity\_update\_state}}, {"wait", {1, 2, do\_wait}}, {"write", {2, 4, do\_write}},};return builtin\_functions;}
static int do_mount_all(const std::vector<std::string>& args) {
std::size\_t na = 0;bool import\_rc = true;bool queue\_event = true;int mount\_mode = MOUNT\_MODE\_DEFAULT;const char\* fstabfile = args[1].c\_str();std::size\_t path\_arg\_end = args.size();.................
int ret = mount\_fstab(fstabfile, mount\_mode);................
if (import\_rc) { /\* Paths of .rc files are specified at the 2nd argument and beyond \*/ import\_late(args, 2, path\_arg\_end);}......................
}
static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {
Parser& parser = Parser::GetInstance();if (end\_index <= start\_index) { // Use the default set if no path is given static const std::vector<std::string> init\_directories = {//执行到该目录,读取*.rc 解析
"/system/etc/init", "/vendor/etc/init", "/odm/etc/init" }; for (const auto& dir : init\_directories) { parser.ParseConfig(dir); }} else { for (size\_t i = start\_index; i < end\_index; ++i) { parser.ParseConfig(args[i]); }}}
static int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) {
char buf[BUFFER_MAX];struct sockaddr addr;socklen_t alen;int lsocket, s;int selinux_enabled = (is_selinux_enabled() > 0);setenv("ANDROID_LOG_TAGS", "*:v", 1);android::base::InitLogging(argv);ALOGI("installd firing up\n");union selinux_callback cb;cb.func_log = log_callback;selinux_set_callback(SELINUX_CB_LOG, cb);if (!initialize_globals()) { ALOGE("Could not initialize globals; exiting.\n"); exit(1);}if (initialize_directories() < 0) { ALOGE("Could not create directories; exiting.\n"); exit(1);}if (selinux_enabled && selinux_status_open(true) < 0) { ALOGE("Could not open selinux status; exiting.\n"); exit(1);}//创建服务端socket
lsocket = android_get_control_socket(SOCKET_PATH); //#define SOCKET_PATH "installd"if (lsocket < 0) { ALOGE("Failed to get socket from environment: %s\n", strerror(errno)); exit(1);}if (listen(lsocket, 5)) { ALOGE("Listen on socket failed: %s\n", strerror(errno)); exit(1);}fcntl(lsocket, F_SETFD, FD_CLOEXEC);for (;;) { alen = sizeof(addr); s = accept(lsocket, &addr, &alen); if (s < 0) { ALOGE("Accept failed: %s\n", strerror(errno)); continue; } fcntl(s, F_SETFD, FD_CLOEXEC); ALOGI("new connection\n"); for (;;) { unsigned short count; if (readx(s, &count, sizeof(count))) { ALOGE("failed to read size\n"); break; } if ((count < 1) || (count >= BUFFER_MAX)) { ALOGE("invalid size %d\n", count); break; } if (readx(s, buf, count)) { ALOGE("failed to read command\n"); break; } buf[count] = 0; if (selinux_enabled && selinux_status_updated() > 0) { selinux_android_seapp_context_reload(); } if (execute(s, buf)) break; } ALOGI("closing connection\n"); close(s);}return 0;}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。