diff --git a/init/README.md b/init/README.md index c4505fe4c..806bfa7e1 100644 --- a/init/README.md +++ b/init/README.md @@ -414,7 +414,8 @@ Commands `class_start_post_data ` > Like `class_start`, but only considers services that were started - after /data was mounted. Only used for FDE devices. + after /data was mounted, and that were running at the time + `class_reset_post_data` was called. Only used for FDE devices. `class_stop ` > Stop and disable all services of the specified class if they are diff --git a/init/builtins.cpp b/init/builtins.cpp index ba1c94d65..6ce773672 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -104,35 +104,36 @@ static void ForEachServiceInClass(const std::string& classname, F function) { } } -static Result class_start(const std::string& class_name, bool post_data_only) { +static Result do_class_start(const BuiltinArguments& args) { // Do not start a class if it has a property persist.dont_start_class.CLASS set to 1. - if (android::base::GetBoolProperty("persist.init.dont_start_class." + class_name, false)) + if (android::base::GetBoolProperty("persist.init.dont_start_class." + args[1], false)) return Success(); // Starting a class does not start services which are explicitly disabled. // They must be started individually. for (const auto& service : ServiceList::GetInstance()) { - if (service->classnames().count(class_name)) { - if (post_data_only && !service->is_post_data()) { - continue; - } + if (service->classnames().count(args[1])) { if (auto result = service->StartIfNotDisabled(); !result) { LOG(ERROR) << "Could not start service '" << service->name() - << "' as part of class '" << class_name << "': " << result.error(); + << "' as part of class '" << args[1] << "': " << result.error(); } } } return Success(); } -static Result do_class_start(const BuiltinArguments& args) { - return class_start(args[1], false /* post_data_only */); -} - static Result do_class_start_post_data(const BuiltinArguments& args) { if (args.context != kInitContext) { return Error() << "command 'class_start_post_data' only available in init context"; } - return class_start(args[1], true /* post_data_only */); + for (const auto& service : ServiceList::GetInstance()) { + if (service->classnames().count(args[1])) { + if (auto result = service->StartIfPostData(); !result) { + LOG(ERROR) << "Could not start service '" << service->name() + << "' as part of class '" << args[1] << "': " << result.error(); + } + } + } + return Success(); } static Result do_class_stop(const BuiltinArguments& args) { diff --git a/init/service.cpp b/init/service.cpp index 2f9668107..ccc37b70c 100644 --- a/init/service.cpp +++ b/init/service.cpp @@ -1154,10 +1154,23 @@ void Service::Reset() { void Service::ResetIfPostData() { if (post_data_) { + if (flags_ & SVC_RUNNING) { + running_at_post_data_reset_ = true; + } StopOrReset(SVC_RESET); } } +Result Service::StartIfPostData() { + // Start the service, but only if it was started after /data was mounted, + // and it was still running when we reset the post-data services. + if (running_at_post_data_reset_) { + return Start(); + } + + return Success(); +} + void Service::Stop() { StopOrReset(SVC_DISABLED); } diff --git a/init/service.h b/init/service.h index dc2b12883..ae29f28c3 100644 --- a/init/service.h +++ b/init/service.h @@ -79,6 +79,7 @@ class Service { Result ExecStart(); Result Start(); Result StartIfNotDisabled(); + Result StartIfPostData(); Result Enable(); void Reset(); void ResetIfPostData(); @@ -248,6 +249,8 @@ class Service { bool pre_apexd_ = false; bool post_data_ = false; + + bool running_at_post_data_reset_ = false; }; class ServiceList {