Loading init/builtins.cpp +82 −0 Original line number Diff line number Diff line Loading @@ -1093,6 +1093,86 @@ static Result<Success> do_parse_apex_configs(const BuiltinArguments& args) { } } static Result<Success> bind_mount_file(const char* source, const char* mount_point, bool remount_private) { if (remount_private && mount(nullptr, mount_point, nullptr, MS_PRIVATE, nullptr) == -1) { return ErrnoError() << "Could not change " << mount_point << " to a private mount point"; } if (mount(source, mount_point, nullptr, MS_BIND, nullptr) == -1) { return ErrnoError() << "Could not bind-mount " << source << " to " << mount_point; } return Success(); } static Result<Success> bind_mount_bionic(const char* linker_source, const char* lib_dir_source, const char* linker_mount_point, const char* lib_mount_dir, bool remount_private) { if (access(linker_source, F_OK) != 0) { return Success(); } if (auto result = bind_mount_file(linker_source, linker_mount_point, remount_private); !result) { return result; } for (auto libname : kBionicLibFileNames) { std::string mount_point = lib_mount_dir + libname; std::string source = lib_dir_source + libname; if (auto result = bind_mount_file(source.c_str(), mount_point.c_str(), remount_private); !result) { return result; } } return Success(); } // The bootstrap bionic libs and the bootstrap linker are bind-mounted to // the mount points for pre-apexd processes. static Result<Success> do_prepare_bootstrap_bionic(const BuiltinArguments& args) { static bool prepare_bootstrap_bionic_done = false; if (prepare_bootstrap_bionic_done) { return Error() << "prepare_bootstrap_bionic was already executed. Cannot be executed again"; } if (auto result = bind_mount_bionic(kBootstrapLinkerPath, kBootstrapBionicLibsDir, kLinkerMountPoint, kBionicLibsMountPointDir, false); !result) { return result; } if (auto result = bind_mount_bionic(kBootstrapLinkerPath64, kBootstrapBionicLibsDir64, kLinkerMountPoint64, kBionicLibsMountPointDir64, false); !result) { return result; } LOG(INFO) << "prepare_bootstrap_bionic done"; prepare_bootstrap_bionic_done = true; return Success(); } // The bionic libs and the dynamic linker from the runtime APEX are bind-mounted // to the mount points. As a result, the previous mounts done by // prepare_bootstrap_bionic become hidden. static Result<Success> do_setup_runtime_bionic(const BuiltinArguments& args) { static bool setup_runtime_bionic_done = false; if (setup_runtime_bionic_done) { return Error() << "setup_runtime_bionic was already executed. Cannot be executed again"; } if (auto result = bind_mount_bionic(kRuntimeLinkerPath, kRuntimeBionicLibsDir, kLinkerMountPoint, kBionicLibsMountPointDir, true); !result) { return result; } if (auto result = bind_mount_bionic(kRuntimeLinkerPath64, kRuntimeBionicLibsDir64, kLinkerMountPoint64, kBionicLibsMountPointDir64, true); !result) { return result; } ServiceList::GetInstance().MarkRuntimeAvailable(); LOG(INFO) << "setup_runtime_bionic done"; setup_runtime_bionic_done = true; return Success(); } // Builtin-function-map start const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max(); Loading Loading @@ -1131,6 +1211,7 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { {"mount_all", {1, kMax, {false, do_mount_all}}}, {"mount", {3, kMax, {false, do_mount}}}, {"parse_apex_configs", {0, 0, {false, do_parse_apex_configs}}}, {"prepare_bootstrap_bionic",{0, 0, {false, do_prepare_bootstrap_bionic}}}, {"umount", {1, 1, {false, do_umount}}}, {"readahead", {1, 2, {true, do_readahead}}}, {"restart", {1, 1, {false, do_restart}}}, Loading @@ -1139,6 +1220,7 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { {"rm", {1, 1, {true, do_rm}}}, {"rmdir", {1, 1, {true, do_rmdir}}}, {"setprop", {2, 2, {true, do_setprop}}}, {"setup_runtime_bionic", {0, 0, {false, do_setup_runtime_bionic}}}, {"setrlimit", {3, 3, {false, do_setrlimit}}}, {"start", {1, 1, {false, do_start}}}, {"stop", {1, 1, {false, do_stop}}}, Loading init/service.cpp +76 −0 Original line number Diff line number Diff line Loading @@ -140,6 +140,43 @@ Result<Success> Service::SetUpMountNamespace() const { return Success(); } Result<Success> Service::SetUpPreApexdMounts() const { // If a pre-apexd service is 're' launched after the runtime APEX is // available, unmount the linker and bionic libs which are currently // bind mounted to the files in the runtime APEX. This will reveal // the hidden mount points (targetting the bootstrap ones in the // system partition) which were setup before the runtime APEX was // started. Note that these unmounts are done in a separate mount namespace // for the process. It does not affect other processes including the init. if (pre_apexd_ && ServiceList::GetInstance().IsRuntimeAvailable()) { if (access(kLinkerMountPoint, F_OK) == 0) { if (umount(kLinkerMountPoint) == -1) { return ErrnoError() << "Could not umount " << kLinkerMountPoint; } for (const auto& libname : kBionicLibFileNames) { std::string mount_point = kBionicLibsMountPointDir + libname; if (umount(mount_point.c_str()) == -1) { return ErrnoError() << "Could not umount " << mount_point; } } } if (access(kLinkerMountPoint64, F_OK) == 0) { if (umount(kLinkerMountPoint64) == -1) { return ErrnoError() << "Could not umount " << kLinkerMountPoint64; } for (const auto& libname : kBionicLibFileNames) { std::string mount_point = kBionicLibsMountPointDir64 + libname; std::string source = kBootstrapBionicLibsDir64 + libname; if (umount(mount_point.c_str()) == -1) { return ErrnoError() << "Could not umount " << mount_point; } } } } return Success(); } Result<Success> Service::SetUpPidNamespace() const { if (prctl(PR_SET_NAME, name_.c_str()) == -1) { return ErrnoError() << "Could not set name"; Loading Loading @@ -929,6 +966,14 @@ Result<Success> Service::Start() { scon = *result; } if (!ServiceList::GetInstance().IsRuntimeAvailable() && !pre_apexd_) { // If this service is started before the runtime APEX gets available, // mark it as pre-apexd one. Note that this marking is permanent. So // for example, if the service is re-launched (e.g., due to crash), // it is still recognized as pre-apexd... for consistency. pre_apexd_ = true; } LOG(INFO) << "starting service '" << name_ << "'..."; pid_t pid = -1; Loading @@ -945,6 +990,26 @@ Result<Success> Service::Start() { LOG(FATAL) << "Service '" << name_ << "' could not enter namespaces: " << result.error(); } if (pre_apexd_) { // pre-apexd process gets a private copy of the mount namespace. // However, this does not mean that mount/unmount events are not // shared across pre-apexd processes and post-apexd processes. // *Most* of the events are still shared because the propagation // type of / is set to 'shared'. (see `mount rootfs rootfs /shared // rec` in init.rc) // // This unsharing is required to not propagate the mount events // under /system/lib/{libc|libdl|libm}.so and /system/bin/linker(64) // whose propagation type is set to private. With this, // bind-mounting the bionic libs and the dynamic linker from the // runtime APEX to the mount points does not affect pre-apexd // processes which should use the bootstrap ones. if (unshare(CLONE_NEWNS) != 0) { LOG(FATAL) << "Creating a new mount namespace for service" << " '" << name_ << "' failed: " << strerror(errno); } } if (namespace_flags_ & CLONE_NEWNS) { if (auto result = SetUpMountNamespace(); !result) { LOG(FATAL) << "Service '" << name_ Loading @@ -952,6 +1017,13 @@ Result<Success> Service::Start() { } } if (pre_apexd_ && ServiceList::GetInstance().IsRuntimeAvailable()) { if (auto result = SetUpPreApexdMounts(); !result) { LOG(FATAL) << "Pre-apexd service '" << name_ << "' could not setup the mount points: " << result.error(); } } if (namespace_flags_ & CLONE_NEWPID) { // This will fork again to run an init process inside the PID // namespace. Loading Loading @@ -1324,6 +1396,10 @@ void ServiceList::MarkServicesUpdate() { delayed_service_names_.clear(); } void ServiceList::MarkRuntimeAvailable() { runtime_available_ = true; } void ServiceList::DelayService(const Service& service) { if (services_update_finished_) { LOG(ERROR) << "Cannot delay the start of service '" << service.name() Loading init/service.h +25 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,24 @@ namespace android { namespace init { static constexpr const char* kLinkerMountPoint = "/system/bin/linker"; static constexpr const char* kBootstrapLinkerPath = "/system/bin/linker"; static constexpr const char* kRuntimeLinkerPath = "/apex/com.android.runtime/bin/linker"; static constexpr const char* kBionicLibsMountPointDir = "/system/lib/"; static constexpr const char* kBootstrapBionicLibsDir = "/system/lib/"; static constexpr const char* kRuntimeBionicLibsDir = "/apex/com.android.runtime/lib/bionic/"; static constexpr const char* kLinkerMountPoint64 = "/system/bin/linker64"; static constexpr const char* kBootstrapLinkerPath64 = "/system/bin/linker64"; static constexpr const char* kRuntimeLinkerPath64 = "/apex/com.android.runtime/bin/linker64"; static constexpr const char* kBionicLibsMountPointDir64 = "/system/lib64/"; static constexpr const char* kBootstrapBionicLibsDir64 = "/system/lib64/"; static constexpr const char* kRuntimeBionicLibsDir64 = "/apex/com.android.runtime/lib64/bionic/"; static const std::vector<std::string> kBionicLibFileNames = {"libc.so", "libm.so", "libdl.so"}; class Service { public: Service(const std::string& name, Subcontext* subcontext_for_restart_commands, Loading Loading @@ -124,6 +142,7 @@ class Service { std::optional<std::chrono::seconds> timeout_period() const { return timeout_period_; } const std::vector<std::string>& args() const { return args_; } bool is_updatable() const { return updatable_; } bool is_pre_apexd() const { return pre_apexd_; } private: using OptionParser = Result<Success> (Service::*)(std::vector<std::string>&& args); Loading @@ -132,6 +151,7 @@ class Service { Result<Success> SetUpMountNamespace() const; Result<Success> SetUpPidNamespace() const; Result<Success> EnterNamespaces() const; Result<Success> SetUpPreApexdMounts() const; void NotifyStateChange(const std::string& new_state) const; void StopOrReset(int how); void ZapStdio() const; Loading Loading @@ -242,6 +262,8 @@ class Service { std::vector<std::string> args_; std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_; bool pre_apexd_ = false; }; class ServiceList { Loading Loading @@ -284,13 +306,16 @@ class ServiceList { const std::vector<Service*> services_in_shutdown_order() const; void MarkServicesUpdate(); void MarkRuntimeAvailable(); bool IsServicesUpdated() const { return services_update_finished_; } bool IsRuntimeAvailable() const { return runtime_available_; } void DelayService(const Service& service); private: std::vector<std::unique_ptr<Service>> services_; bool services_update_finished_ = false; bool runtime_available_ = false; std::vector<std::string> delayed_service_names_; }; Loading rootdir/init.rc +16 −5 Original line number Diff line number Diff line Loading @@ -12,6 +12,12 @@ import /init.usb.configfs.rc import /init.${ro.zygote}.rc on early-init # Mount shared so changes propagate into child namespaces # Do this before other processes are started from init. Otherwise, # processes launched while the propagation type of / is 'private' # won't get mount events from others. mount rootfs rootfs / shared rec # Set init and its forked children's oom_adj. write /proc/1/oom_score_adj -1000 Loading Loading @@ -40,6 +46,8 @@ on early-init # cgroup for system_server and surfaceflinger mkdir /dev/memcg/system 0550 system system prepare_bootstrap_bionic start ueventd on init Loading Loading @@ -350,8 +358,6 @@ on post-fs # Once everything is setup, no need to modify /. # The bind+remount combination allows this to work in containers. mount rootfs rootfs / remount bind ro nodev # Mount shared so changes propagate into child namespaces mount rootfs rootfs / shared rec # Mount default storage into root namespace mount none /mnt/runtime/default /storage bind rec mount none none /storage slave rec Loading Loading @@ -587,6 +593,14 @@ on post-fs-data # Check any timezone data in /data is newer than the copy in the runtime module, delete if not. exec - system system -- /system/bin/tzdatacheck /apex/com.android.runtime/etc/tz /data/misc/zoneinfo # Wait for apexd to finish activating APEXes before starting more processes. # This certainly reduces the parallelism but is required to make as many processes # as possible to use the bionic libs from the runtime APEX. This takes less than 50ms # so the impact on the booting time is not significant. wait_for_prop apexd.status ready setup_runtime_bionic parse_apex_configs # If there is no post-fs-data action in the init.<device>.rc file, you # must uncomment this line, otherwise encrypted filesystems # won't work. Loading Loading @@ -808,6 +822,3 @@ on property:ro.debuggable=1 service flash_recovery /system/bin/install-recovery.sh class main oneshot on property:apexd.status=ready parse_apex_configs Loading
init/builtins.cpp +82 −0 Original line number Diff line number Diff line Loading @@ -1093,6 +1093,86 @@ static Result<Success> do_parse_apex_configs(const BuiltinArguments& args) { } } static Result<Success> bind_mount_file(const char* source, const char* mount_point, bool remount_private) { if (remount_private && mount(nullptr, mount_point, nullptr, MS_PRIVATE, nullptr) == -1) { return ErrnoError() << "Could not change " << mount_point << " to a private mount point"; } if (mount(source, mount_point, nullptr, MS_BIND, nullptr) == -1) { return ErrnoError() << "Could not bind-mount " << source << " to " << mount_point; } return Success(); } static Result<Success> bind_mount_bionic(const char* linker_source, const char* lib_dir_source, const char* linker_mount_point, const char* lib_mount_dir, bool remount_private) { if (access(linker_source, F_OK) != 0) { return Success(); } if (auto result = bind_mount_file(linker_source, linker_mount_point, remount_private); !result) { return result; } for (auto libname : kBionicLibFileNames) { std::string mount_point = lib_mount_dir + libname; std::string source = lib_dir_source + libname; if (auto result = bind_mount_file(source.c_str(), mount_point.c_str(), remount_private); !result) { return result; } } return Success(); } // The bootstrap bionic libs and the bootstrap linker are bind-mounted to // the mount points for pre-apexd processes. static Result<Success> do_prepare_bootstrap_bionic(const BuiltinArguments& args) { static bool prepare_bootstrap_bionic_done = false; if (prepare_bootstrap_bionic_done) { return Error() << "prepare_bootstrap_bionic was already executed. Cannot be executed again"; } if (auto result = bind_mount_bionic(kBootstrapLinkerPath, kBootstrapBionicLibsDir, kLinkerMountPoint, kBionicLibsMountPointDir, false); !result) { return result; } if (auto result = bind_mount_bionic(kBootstrapLinkerPath64, kBootstrapBionicLibsDir64, kLinkerMountPoint64, kBionicLibsMountPointDir64, false); !result) { return result; } LOG(INFO) << "prepare_bootstrap_bionic done"; prepare_bootstrap_bionic_done = true; return Success(); } // The bionic libs and the dynamic linker from the runtime APEX are bind-mounted // to the mount points. As a result, the previous mounts done by // prepare_bootstrap_bionic become hidden. static Result<Success> do_setup_runtime_bionic(const BuiltinArguments& args) { static bool setup_runtime_bionic_done = false; if (setup_runtime_bionic_done) { return Error() << "setup_runtime_bionic was already executed. Cannot be executed again"; } if (auto result = bind_mount_bionic(kRuntimeLinkerPath, kRuntimeBionicLibsDir, kLinkerMountPoint, kBionicLibsMountPointDir, true); !result) { return result; } if (auto result = bind_mount_bionic(kRuntimeLinkerPath64, kRuntimeBionicLibsDir64, kLinkerMountPoint64, kBionicLibsMountPointDir64, true); !result) { return result; } ServiceList::GetInstance().MarkRuntimeAvailable(); LOG(INFO) << "setup_runtime_bionic done"; setup_runtime_bionic_done = true; return Success(); } // Builtin-function-map start const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { constexpr std::size_t kMax = std::numeric_limits<std::size_t>::max(); Loading Loading @@ -1131,6 +1211,7 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { {"mount_all", {1, kMax, {false, do_mount_all}}}, {"mount", {3, kMax, {false, do_mount}}}, {"parse_apex_configs", {0, 0, {false, do_parse_apex_configs}}}, {"prepare_bootstrap_bionic",{0, 0, {false, do_prepare_bootstrap_bionic}}}, {"umount", {1, 1, {false, do_umount}}}, {"readahead", {1, 2, {true, do_readahead}}}, {"restart", {1, 1, {false, do_restart}}}, Loading @@ -1139,6 +1220,7 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { {"rm", {1, 1, {true, do_rm}}}, {"rmdir", {1, 1, {true, do_rmdir}}}, {"setprop", {2, 2, {true, do_setprop}}}, {"setup_runtime_bionic", {0, 0, {false, do_setup_runtime_bionic}}}, {"setrlimit", {3, 3, {false, do_setrlimit}}}, {"start", {1, 1, {false, do_start}}}, {"stop", {1, 1, {false, do_stop}}}, Loading
init/service.cpp +76 −0 Original line number Diff line number Diff line Loading @@ -140,6 +140,43 @@ Result<Success> Service::SetUpMountNamespace() const { return Success(); } Result<Success> Service::SetUpPreApexdMounts() const { // If a pre-apexd service is 're' launched after the runtime APEX is // available, unmount the linker and bionic libs which are currently // bind mounted to the files in the runtime APEX. This will reveal // the hidden mount points (targetting the bootstrap ones in the // system partition) which were setup before the runtime APEX was // started. Note that these unmounts are done in a separate mount namespace // for the process. It does not affect other processes including the init. if (pre_apexd_ && ServiceList::GetInstance().IsRuntimeAvailable()) { if (access(kLinkerMountPoint, F_OK) == 0) { if (umount(kLinkerMountPoint) == -1) { return ErrnoError() << "Could not umount " << kLinkerMountPoint; } for (const auto& libname : kBionicLibFileNames) { std::string mount_point = kBionicLibsMountPointDir + libname; if (umount(mount_point.c_str()) == -1) { return ErrnoError() << "Could not umount " << mount_point; } } } if (access(kLinkerMountPoint64, F_OK) == 0) { if (umount(kLinkerMountPoint64) == -1) { return ErrnoError() << "Could not umount " << kLinkerMountPoint64; } for (const auto& libname : kBionicLibFileNames) { std::string mount_point = kBionicLibsMountPointDir64 + libname; std::string source = kBootstrapBionicLibsDir64 + libname; if (umount(mount_point.c_str()) == -1) { return ErrnoError() << "Could not umount " << mount_point; } } } } return Success(); } Result<Success> Service::SetUpPidNamespace() const { if (prctl(PR_SET_NAME, name_.c_str()) == -1) { return ErrnoError() << "Could not set name"; Loading Loading @@ -929,6 +966,14 @@ Result<Success> Service::Start() { scon = *result; } if (!ServiceList::GetInstance().IsRuntimeAvailable() && !pre_apexd_) { // If this service is started before the runtime APEX gets available, // mark it as pre-apexd one. Note that this marking is permanent. So // for example, if the service is re-launched (e.g., due to crash), // it is still recognized as pre-apexd... for consistency. pre_apexd_ = true; } LOG(INFO) << "starting service '" << name_ << "'..."; pid_t pid = -1; Loading @@ -945,6 +990,26 @@ Result<Success> Service::Start() { LOG(FATAL) << "Service '" << name_ << "' could not enter namespaces: " << result.error(); } if (pre_apexd_) { // pre-apexd process gets a private copy of the mount namespace. // However, this does not mean that mount/unmount events are not // shared across pre-apexd processes and post-apexd processes. // *Most* of the events are still shared because the propagation // type of / is set to 'shared'. (see `mount rootfs rootfs /shared // rec` in init.rc) // // This unsharing is required to not propagate the mount events // under /system/lib/{libc|libdl|libm}.so and /system/bin/linker(64) // whose propagation type is set to private. With this, // bind-mounting the bionic libs and the dynamic linker from the // runtime APEX to the mount points does not affect pre-apexd // processes which should use the bootstrap ones. if (unshare(CLONE_NEWNS) != 0) { LOG(FATAL) << "Creating a new mount namespace for service" << " '" << name_ << "' failed: " << strerror(errno); } } if (namespace_flags_ & CLONE_NEWNS) { if (auto result = SetUpMountNamespace(); !result) { LOG(FATAL) << "Service '" << name_ Loading @@ -952,6 +1017,13 @@ Result<Success> Service::Start() { } } if (pre_apexd_ && ServiceList::GetInstance().IsRuntimeAvailable()) { if (auto result = SetUpPreApexdMounts(); !result) { LOG(FATAL) << "Pre-apexd service '" << name_ << "' could not setup the mount points: " << result.error(); } } if (namespace_flags_ & CLONE_NEWPID) { // This will fork again to run an init process inside the PID // namespace. Loading Loading @@ -1324,6 +1396,10 @@ void ServiceList::MarkServicesUpdate() { delayed_service_names_.clear(); } void ServiceList::MarkRuntimeAvailable() { runtime_available_ = true; } void ServiceList::DelayService(const Service& service) { if (services_update_finished_) { LOG(ERROR) << "Cannot delay the start of service '" << service.name() Loading
init/service.h +25 −0 Original line number Diff line number Diff line Loading @@ -62,6 +62,24 @@ namespace android { namespace init { static constexpr const char* kLinkerMountPoint = "/system/bin/linker"; static constexpr const char* kBootstrapLinkerPath = "/system/bin/linker"; static constexpr const char* kRuntimeLinkerPath = "/apex/com.android.runtime/bin/linker"; static constexpr const char* kBionicLibsMountPointDir = "/system/lib/"; static constexpr const char* kBootstrapBionicLibsDir = "/system/lib/"; static constexpr const char* kRuntimeBionicLibsDir = "/apex/com.android.runtime/lib/bionic/"; static constexpr const char* kLinkerMountPoint64 = "/system/bin/linker64"; static constexpr const char* kBootstrapLinkerPath64 = "/system/bin/linker64"; static constexpr const char* kRuntimeLinkerPath64 = "/apex/com.android.runtime/bin/linker64"; static constexpr const char* kBionicLibsMountPointDir64 = "/system/lib64/"; static constexpr const char* kBootstrapBionicLibsDir64 = "/system/lib64/"; static constexpr const char* kRuntimeBionicLibsDir64 = "/apex/com.android.runtime/lib64/bionic/"; static const std::vector<std::string> kBionicLibFileNames = {"libc.so", "libm.so", "libdl.so"}; class Service { public: Service(const std::string& name, Subcontext* subcontext_for_restart_commands, Loading Loading @@ -124,6 +142,7 @@ class Service { std::optional<std::chrono::seconds> timeout_period() const { return timeout_period_; } const std::vector<std::string>& args() const { return args_; } bool is_updatable() const { return updatable_; } bool is_pre_apexd() const { return pre_apexd_; } private: using OptionParser = Result<Success> (Service::*)(std::vector<std::string>&& args); Loading @@ -132,6 +151,7 @@ class Service { Result<Success> SetUpMountNamespace() const; Result<Success> SetUpPidNamespace() const; Result<Success> EnterNamespaces() const; Result<Success> SetUpPreApexdMounts() const; void NotifyStateChange(const std::string& new_state) const; void StopOrReset(int how); void ZapStdio() const; Loading Loading @@ -242,6 +262,8 @@ class Service { std::vector<std::string> args_; std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_; bool pre_apexd_ = false; }; class ServiceList { Loading Loading @@ -284,13 +306,16 @@ class ServiceList { const std::vector<Service*> services_in_shutdown_order() const; void MarkServicesUpdate(); void MarkRuntimeAvailable(); bool IsServicesUpdated() const { return services_update_finished_; } bool IsRuntimeAvailable() const { return runtime_available_; } void DelayService(const Service& service); private: std::vector<std::unique_ptr<Service>> services_; bool services_update_finished_ = false; bool runtime_available_ = false; std::vector<std::string> delayed_service_names_; }; Loading
rootdir/init.rc +16 −5 Original line number Diff line number Diff line Loading @@ -12,6 +12,12 @@ import /init.usb.configfs.rc import /init.${ro.zygote}.rc on early-init # Mount shared so changes propagate into child namespaces # Do this before other processes are started from init. Otherwise, # processes launched while the propagation type of / is 'private' # won't get mount events from others. mount rootfs rootfs / shared rec # Set init and its forked children's oom_adj. write /proc/1/oom_score_adj -1000 Loading Loading @@ -40,6 +46,8 @@ on early-init # cgroup for system_server and surfaceflinger mkdir /dev/memcg/system 0550 system system prepare_bootstrap_bionic start ueventd on init Loading Loading @@ -350,8 +358,6 @@ on post-fs # Once everything is setup, no need to modify /. # The bind+remount combination allows this to work in containers. mount rootfs rootfs / remount bind ro nodev # Mount shared so changes propagate into child namespaces mount rootfs rootfs / shared rec # Mount default storage into root namespace mount none /mnt/runtime/default /storage bind rec mount none none /storage slave rec Loading Loading @@ -587,6 +593,14 @@ on post-fs-data # Check any timezone data in /data is newer than the copy in the runtime module, delete if not. exec - system system -- /system/bin/tzdatacheck /apex/com.android.runtime/etc/tz /data/misc/zoneinfo # Wait for apexd to finish activating APEXes before starting more processes. # This certainly reduces the parallelism but is required to make as many processes # as possible to use the bionic libs from the runtime APEX. This takes less than 50ms # so the impact on the booting time is not significant. wait_for_prop apexd.status ready setup_runtime_bionic parse_apex_configs # If there is no post-fs-data action in the init.<device>.rc file, you # must uncomment this line, otherwise encrypted filesystems # won't work. Loading Loading @@ -808,6 +822,3 @@ on property:ro.debuggable=1 service flash_recovery /system/bin/install-recovery.sh class main oneshot on property:apexd.status=ready parse_apex_configs