前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android Installd 分析

Android Installd 分析

原创
作者头像
用户5189678
修改2019-04-16 09:47:11
1K0
修改2019-04-16 09:47:11
举报
文章被收录于专栏:Android 源码

一、Installd 有哪些功能

1. 功能集如下:

代码语言:txt
复制
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 },
};

二、框架结构

Installd架构.png
Installd架构.png

三、程序如何启动

  1. 启动文件 system/etc/init/installd.rc 启动service installd 守护程序 service installd /system/bin/installd class main socket installd stream 600 system system
  2. 在mount_all fstab.qcom 之后会启动installd.rc 脚本 参考system/core/init/init.cpp代码int main(int argc, char** argv) { .................
代码语言:txt
复制
const BuiltinFunctionMap function\_map;
代码语言:txt
复制
Action::set\_function\_map(&function\_map);
代码语言:txt
复制
Parser& parser = Parser::GetInstance();
代码语言:txt
复制
parser.AddSectionParser("service",std::make\_unique<ServiceParser>());
代码语言:txt
复制
parser.AddSectionParser("on", std::make\_unique<ActionParser>());
代码语言:txt
复制
parser.AddSectionParser("import", std::make\_unique<ImportParser>());
代码语言:txt
复制
parser.ParseConfig("/init.rc");
代码语言:txt
复制
ActionManager& am = ActionManager::GetInstance();
代码语言:txt
复制
am.QueueEventTrigger("early-init");

..........................

代码语言:txt
复制
// Trigger all the boot actions to get us started.
代码语言:txt
复制
am.QueueEventTrigger("init");

.........................

代码语言:txt
复制
std::string bootmode = property\_get("ro.bootmode");
代码语言:txt
复制
if (bootmode == "charger") {
代码语言:txt
复制
    am.QueueEventTrigger("charger");
代码语言:txt
复制
} else if (strncmp(bootmode.c\_str(), "ffbm", 4) == 0) {
代码语言:txt
复制
    NOTICE("Booting into ffbm mode\n");
代码语言:txt
复制
    am.QueueEventTrigger("ffbm");
代码语言:txt
复制
} else {
代码语言:txt
复制
    am.QueueEventTrigger("late-init");
代码语言:txt
复制
}
代码语言:txt
复制
// Run all property triggers based on current state of the properties.
代码语言:txt
复制
am.QueueBuiltinAction(queue\_property\_triggers\_action, "queue\_property\_triggers");

...............................

}

*.rc 中如何解析相关脚本,参看如下方法定义:

system/core/init/builtins.cpp

BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {

代码语言:txt
复制
constexpr std::size\_t kMax = std::numeric\_limits<std::size\_t>::max();
代码语言:txt
复制
static const Map builtin\_functions = {
代码语言:txt
复制
    {"bootchart\_init",          {0,     0,    do\_bootchart\_init}},
代码语言:txt
复制
    {"chmod",                   {2,     4,    do\_chmod}},
代码语言:txt
复制
    {"chown",                   {2,     5,    do\_chown}},
代码语言:txt
复制
    {"class\_reset",             {1,     1,    do\_class\_reset}},
代码语言:txt
复制
    {"class\_start",             {1,     1,    do\_class\_start}},
代码语言:txt
复制
    {"class\_stop",              {1,     1,    do\_class\_stop}},
代码语言:txt
复制
    {"copy",                    {2,     2,    do\_copy}},
代码语言:txt
复制
    {"domainname",              {1,     1,    do\_domainname}},
代码语言:txt
复制
    {"enable",                  {1,     1,    do\_enable}},
代码语言:txt
复制
    {"exec",                    {1,     kMax, do\_exec}},
代码语言:txt
复制
    {"export",                  {2,     2,    do\_export}},
代码语言:txt
复制
    {"hostname",                {1,     1,    do\_hostname}},
代码语言:txt
复制
    {"ifup",                    {1,     1,    do\_ifup}},
代码语言:txt
复制
    {"init\_user0",              {0,     0,    do\_init\_user0}},
代码语言:txt
复制
    {"insmod",                  {1,     kMax, do\_insmod}},
代码语言:txt
复制
    {"installkey",              {1,     1,    do\_installkey}},
代码语言:txt
复制
    {"load\_persist\_props",      {0,     0,    do\_load\_persist\_props}},
代码语言:txt
复制
    {"load\_system\_props",       {0,     0,    do\_load\_system\_props}},
代码语言:txt
复制
    {"loglevel",                {1,     1,    do\_loglevel}},
代码语言:txt
复制
    {"mkdir",                   {1,     4,    do\_mkdir}},
代码语言:txt
复制
    {"mount\_all",               {1,     kMax, do\_mount\_all}},
代码语言:txt
复制
    {"mount",                   {3,     kMax, do\_mount}},
代码语言:txt
复制
    {"umount",                  {1,     1,    do\_umount}},
代码语言:txt
复制
    {"powerctl",                {1,     1,    do\_powerctl}},
代码语言:txt
复制
    {"restart",                 {1,     1,    do\_restart}},
代码语言:txt
复制
    {"restorecon",              {1,     kMax, do\_restorecon}},
代码语言:txt
复制
    {"restorecon\_recursive",    {1,     kMax, do\_restorecon\_recursive}},
代码语言:txt
复制
    {"rm",                      {1,     1,    do\_rm}},
代码语言:txt
复制
    {"rmdir",                   {1,     1,    do\_rmdir}},
代码语言:txt
复制
    {"setprop",                 {2,     2,    do\_setprop}},
代码语言:txt
复制
    {"setrlimit",               {3,     3,    do\_setrlimit}},
代码语言:txt
复制
    {"start",                   {1,     1,    do\_start}},
代码语言:txt
复制
    {"stop",                    {1,     1,    do\_stop}},
代码语言:txt
复制
    {"swapon\_all",              {1,     1,    do\_swapon\_all}},
代码语言:txt
复制
    {"symlink",                 {2,     2,    do\_symlink}},
代码语言:txt
复制
    {"sysclktz",                {1,     1,    do\_sysclktz}},
代码语言:txt
复制
    {"trigger",                 {1,     1,    do\_trigger}},
代码语言:txt
复制
    {"verity\_load\_state",       {0,     0,    do\_verity\_load\_state}},
代码语言:txt
复制
    {"verity\_update\_state",     {0,     0,    do\_verity\_update\_state}},
代码语言:txt
复制
    {"wait",                    {1,     2,    do\_wait}},
代码语言:txt
复制
    {"write",                   {2,     4,    do\_write}},
代码语言:txt
复制
};
代码语言:txt
复制
return builtin\_functions;

}

static int do_mount_all(const std::vector<std::string>& args) {

代码语言:txt
复制
std::size\_t na = 0;
代码语言:txt
复制
bool import\_rc = true;
代码语言:txt
复制
bool queue\_event = true;
代码语言:txt
复制
int mount\_mode = MOUNT\_MODE\_DEFAULT;
代码语言:txt
复制
const char\* fstabfile = args[1].c\_str();
代码语言:txt
复制
std::size\_t path\_arg\_end = args.size();

.................

代码语言:txt
复制
int ret =  mount\_fstab(fstabfile, mount\_mode);

................

代码语言:txt
复制
if (import\_rc) {
代码语言:txt
复制
    /\* Paths of .rc files are specified at the 2nd argument and beyond \*/
代码语言:txt
复制
    import\_late(args, 2, path\_arg\_end);
代码语言:txt
复制
}

......................

}

static void import_late(const std::vector<std::string>& args, size_t start_index, size_t end_index) {

代码语言:txt
复制
Parser& parser = Parser::GetInstance();
代码语言:txt
复制
if (end\_index <= start\_index) {
代码语言:txt
复制
    // Use the default set if no path is given
代码语言:txt
复制
    static const std::vector<std::string> init\_directories = {

   //执行到该目录,读取*.rc 解析

代码语言:txt
复制
        "/system/etc/init",
代码语言:txt
复制
        "/vendor/etc/init",
代码语言:txt
复制
        "/odm/etc/init"
代码语言:txt
复制
    };
代码语言:txt
复制
    for (const auto& dir : init\_directories) {
代码语言:txt
复制
        parser.ParseConfig(dir);
代码语言:txt
复制
    }
代码语言:txt
复制
} else {
代码语言:txt
复制
    for (size\_t i = start\_index; i < end\_index; ++i) {
代码语言:txt
复制
        parser.ParseConfig(args[i]);
代码语言:txt
复制
    }
代码语言:txt
复制
}

}

  1. installd 程序运行 程序入口 int main(const int argc, char *argv[]) { return android::installd::installd_main(argc, argv); }

static int installd_main(const int argc ATTRIBUTE_UNUSED, char *argv[]) {

代码语言:txt
复制
char buf[BUFFER_MAX];
代码语言:txt
复制
struct sockaddr addr;
代码语言:txt
复制
socklen_t alen;
代码语言:txt
复制
int lsocket, s;
代码语言:txt
复制
int selinux_enabled = (is_selinux_enabled() > 0);
代码语言:txt
复制
setenv("ANDROID_LOG_TAGS", "*:v", 1);
代码语言:txt
复制
android::base::InitLogging(argv);
代码语言:txt
复制
ALOGI("installd firing up\n");
代码语言:txt
复制
union selinux_callback cb;
代码语言:txt
复制
cb.func_log = log_callback;
代码语言:txt
复制
selinux_set_callback(SELINUX_CB_LOG, cb);
代码语言:txt
复制
if (!initialize_globals()) {
代码语言:txt
复制
    ALOGE("Could not initialize globals; exiting.\n");
代码语言:txt
复制
    exit(1);
代码语言:txt
复制
}
代码语言:txt
复制
if (initialize_directories() < 0) {
代码语言:txt
复制
    ALOGE("Could not create directories; exiting.\n");
代码语言:txt
复制
    exit(1);
代码语言:txt
复制
}
代码语言:txt
复制
if (selinux_enabled && selinux_status_open(true) < 0) {
代码语言:txt
复制
    ALOGE("Could not open selinux status; exiting.\n");
代码语言:txt
复制
    exit(1);
代码语言:txt
复制
}

 //创建服务端socket

代码语言:txt
复制
lsocket = android_get_control_socket(SOCKET_PATH); //#define SOCKET_PATH "installd"
代码语言:txt
复制
if (lsocket < 0) {
代码语言:txt
复制
    ALOGE("Failed to get socket from environment: %s\n", strerror(errno));
代码语言:txt
复制
    exit(1);
代码语言:txt
复制
}
代码语言:txt
复制
if (listen(lsocket, 5)) {
代码语言:txt
复制
    ALOGE("Listen on socket failed: %s\n", strerror(errno));
代码语言:txt
复制
    exit(1);
代码语言:txt
复制
}
代码语言:txt
复制
fcntl(lsocket, F_SETFD, FD_CLOEXEC);
代码语言:txt
复制
for (;;) {
代码语言:txt
复制
    alen = sizeof(addr);
代码语言:txt
复制
    s = accept(lsocket, &addr, &alen);
代码语言:txt
复制
    if (s < 0) {
代码语言:txt
复制
        ALOGE("Accept failed: %s\n", strerror(errno));
代码语言:txt
复制
        continue;
代码语言:txt
复制
    }
代码语言:txt
复制
    fcntl(s, F_SETFD, FD_CLOEXEC);
代码语言:txt
复制
    ALOGI("new connection\n");
代码语言:txt
复制
    for (;;) {
代码语言:txt
复制
        unsigned short count;
代码语言:txt
复制
        if (readx(s, &count, sizeof(count))) {
代码语言:txt
复制
            ALOGE("failed to read size\n");
代码语言:txt
复制
            break;
代码语言:txt
复制
        }
代码语言:txt
复制
        if ((count < 1) || (count >= BUFFER_MAX)) {
代码语言:txt
复制
            ALOGE("invalid size %d\n", count);
代码语言:txt
复制
            break;
代码语言:txt
复制
        }
代码语言:txt
复制
        if (readx(s, buf, count)) {
代码语言:txt
复制
            ALOGE("failed to read command\n");
代码语言:txt
复制
            break;
代码语言:txt
复制
        }
代码语言:txt
复制
        buf[count] = 0;
代码语言:txt
复制
        if (selinux_enabled && selinux_status_updated() > 0) {
代码语言:txt
复制
            selinux_android_seapp_context_reload();
代码语言:txt
复制
        }
代码语言:txt
复制
        if (execute(s, buf)) break;
代码语言:txt
复制
    }
代码语言:txt
复制
    ALOGI("closing connection\n");
代码语言:txt
复制
    close(s);
代码语言:txt
复制
}
代码语言:txt
复制
return 0;

}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Installd 有哪些功能
    • 1. 功能集如下:
    • 二、框架结构
    • 三、程序如何启动
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档