Merge "Support for stopping/starting post-data-mount class subsets."
am: fc78be2935
Change-Id: I3dad9a80217cc2d33576be4d681168566d991c77
This commit is contained in:
commit
741fef7395
5 changed files with 77 additions and 8 deletions
|
@ -412,6 +412,10 @@ Commands
|
|||
not already running. See the start entry for more information on
|
||||
starting services.
|
||||
|
||||
`class_start_post_data <serviceclass>`
|
||||
> Like `class_start`, but only considers services that were started
|
||||
after /data was mounted. Only used for FDE devices.
|
||||
|
||||
`class_stop <serviceclass>`
|
||||
> Stop and disable all services of the specified class if they are
|
||||
currently running.
|
||||
|
@ -421,6 +425,10 @@ Commands
|
|||
currently running, without disabling them. They can be restarted
|
||||
later using `class_start`.
|
||||
|
||||
`class_reset_post_data <serviceclass>`
|
||||
> Like `class_reset`, but only considers services that were started
|
||||
after /data was mounted. Only used for FDE devices.
|
||||
|
||||
`class_restart <serviceclass>`
|
||||
> Restarts all services of the specified class.
|
||||
|
||||
|
@ -494,6 +502,10 @@ Commands
|
|||
`write` command to write to `/proc/sys/kernel/printk` to change that.
|
||||
Properties are expanded within _level_.
|
||||
|
||||
`mark_post_data`
|
||||
> Used to mark the point right after /data is mounted. Used to implement the
|
||||
`class_reset_post_data` and `class_start_post_data` commands.
|
||||
|
||||
`mkdir <path> [mode] [owner] [group]`
|
||||
> Create a directory at _path_, optionally with the given mode, owner, and
|
||||
group. If not provided, the directory is created with permissions 755 and
|
||||
|
|
|
@ -104,23 +104,37 @@ static void ForEachServiceInClass(const std::string& classname, F function) {
|
|||
}
|
||||
}
|
||||
|
||||
static Result<Success> do_class_start(const BuiltinArguments& args) {
|
||||
static Result<Success> class_start(const std::string& class_name, bool post_data_only) {
|
||||
// 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." + args[1], false))
|
||||
if (android::base::GetBoolProperty("persist.init.dont_start_class." + class_name, 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(args[1])) {
|
||||
if (service->classnames().count(class_name)) {
|
||||
if (post_data_only && !service->is_post_data()) {
|
||||
continue;
|
||||
}
|
||||
if (auto result = service->StartIfNotDisabled(); !result) {
|
||||
LOG(ERROR) << "Could not start service '" << service->name()
|
||||
<< "' as part of class '" << args[1] << "': " << result.error();
|
||||
<< "' as part of class '" << class_name << "': " << result.error();
|
||||
}
|
||||
}
|
||||
}
|
||||
return Success();
|
||||
}
|
||||
|
||||
static Result<Success> do_class_start(const BuiltinArguments& args) {
|
||||
return class_start(args[1], false /* post_data_only */);
|
||||
}
|
||||
|
||||
static Result<Success> 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 */);
|
||||
}
|
||||
|
||||
static Result<Success> do_class_stop(const BuiltinArguments& args) {
|
||||
ForEachServiceInClass(args[1], &Service::Stop);
|
||||
return Success();
|
||||
|
@ -131,6 +145,14 @@ static Result<Success> do_class_reset(const BuiltinArguments& args) {
|
|||
return Success();
|
||||
}
|
||||
|
||||
static Result<Success> do_class_reset_post_data(const BuiltinArguments& args) {
|
||||
if (args.context != kInitContext) {
|
||||
return Error() << "command 'class_reset_post_data' only available in init context";
|
||||
}
|
||||
ForEachServiceInClass(args[1], &Service::ResetIfPostData);
|
||||
return Success();
|
||||
}
|
||||
|
||||
static Result<Success> do_class_restart(const BuiltinArguments& args) {
|
||||
// Do not restart a class if it has a property persist.dont_start_class.CLASS set to 1.
|
||||
if (android::base::GetBoolProperty("persist.init.dont_start_class." + args[1], false))
|
||||
|
@ -1042,6 +1064,12 @@ static Result<Success> do_init_user0(const BuiltinArguments& args) {
|
|||
{{"exec", "/system/bin/vdc", "--wait", "cryptfs", "init_user0"}, args.context});
|
||||
}
|
||||
|
||||
static Result<Success> do_mark_post_data(const BuiltinArguments& args) {
|
||||
ServiceList::GetInstance().MarkPostData();
|
||||
|
||||
return Success();
|
||||
}
|
||||
|
||||
static Result<Success> do_parse_apex_configs(const BuiltinArguments& args) {
|
||||
glob_t glob_result;
|
||||
// @ is added to filter out the later paths, which are bind mounts of the places
|
||||
|
@ -1093,8 +1121,10 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
|
|||
{"chmod", {2, 2, {true, do_chmod}}},
|
||||
{"chown", {2, 3, {true, do_chown}}},
|
||||
{"class_reset", {1, 1, {false, do_class_reset}}},
|
||||
{"class_reset_post_data", {1, 1, {false, do_class_reset_post_data}}},
|
||||
{"class_restart", {1, 1, {false, do_class_restart}}},
|
||||
{"class_start", {1, 1, {false, do_class_start}}},
|
||||
{"class_start_post_data", {1, 1, {false, do_class_start_post_data}}},
|
||||
{"class_stop", {1, 1, {false, do_class_stop}}},
|
||||
{"copy", {2, 2, {true, do_copy}}},
|
||||
{"domainname", {1, 1, {true, do_domainname}}},
|
||||
|
@ -1114,6 +1144,7 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
|
|||
{"load_persist_props", {0, 0, {false, do_load_persist_props}}},
|
||||
{"load_system_props", {0, 0, {false, do_load_system_props}}},
|
||||
{"loglevel", {1, 1, {false, do_loglevel}}},
|
||||
{"mark_post_data", {0, 0, {false, do_mark_post_data}}},
|
||||
{"mkdir", {1, 4, {true, do_mkdir}}},
|
||||
// TODO: Do mount operations in vendor_init.
|
||||
// mount_all is currently too complex to run in vendor_init as it queues action triggers,
|
||||
|
|
|
@ -362,7 +362,7 @@ void Service::Reap(const siginfo_t& siginfo) {
|
|||
|
||||
// Oneshot processes go into the disabled state on exit,
|
||||
// except when manually restarted.
|
||||
if ((flags_ & SVC_ONESHOT) && !(flags_ & SVC_RESTART)) {
|
||||
if ((flags_ & SVC_ONESHOT) && !(flags_ & SVC_RESTART) && !(flags_ & SVC_RESET)) {
|
||||
flags_ |= SVC_DISABLED;
|
||||
}
|
||||
|
||||
|
@ -951,6 +951,8 @@ Result<Success> Service::Start() {
|
|||
pre_apexd_ = true;
|
||||
}
|
||||
|
||||
post_data_ = ServiceList::GetInstance().IsPostData();
|
||||
|
||||
LOG(INFO) << "starting service '" << name_ << "'...";
|
||||
|
||||
pid_t pid = -1;
|
||||
|
@ -1150,6 +1152,12 @@ void Service::Reset() {
|
|||
StopOrReset(SVC_RESET);
|
||||
}
|
||||
|
||||
void Service::ResetIfPostData() {
|
||||
if (post_data_) {
|
||||
StopOrReset(SVC_RESET);
|
||||
}
|
||||
}
|
||||
|
||||
void Service::Stop() {
|
||||
StopOrReset(SVC_DISABLED);
|
||||
}
|
||||
|
@ -1343,6 +1351,14 @@ void ServiceList::DumpState() const {
|
|||
}
|
||||
}
|
||||
|
||||
void ServiceList::MarkPostData() {
|
||||
post_data_ = true;
|
||||
}
|
||||
|
||||
bool ServiceList::IsPostData() {
|
||||
return post_data_;
|
||||
}
|
||||
|
||||
void ServiceList::MarkServicesUpdate() {
|
||||
services_update_finished_ = true;
|
||||
|
||||
|
|
|
@ -81,6 +81,7 @@ class Service {
|
|||
Result<Success> StartIfNotDisabled();
|
||||
Result<Success> Enable();
|
||||
void Reset();
|
||||
void ResetIfPostData();
|
||||
void Stop();
|
||||
void Terminate();
|
||||
void Timeout();
|
||||
|
@ -124,6 +125,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_post_data() const { return post_data_; }
|
||||
|
||||
private:
|
||||
using OptionParser = Result<Success> (Service::*)(std::vector<std::string>&& args);
|
||||
|
@ -244,6 +246,8 @@ class Service {
|
|||
std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_;
|
||||
|
||||
bool pre_apexd_ = false;
|
||||
|
||||
bool post_data_ = false;
|
||||
};
|
||||
|
||||
class ServiceList {
|
||||
|
@ -285,6 +289,8 @@ class ServiceList {
|
|||
const std::vector<std::unique_ptr<Service>>& services() const { return services_; }
|
||||
const std::vector<Service*> services_in_shutdown_order() const;
|
||||
|
||||
void MarkPostData();
|
||||
bool IsPostData();
|
||||
void MarkServicesUpdate();
|
||||
bool IsServicesUpdated() const { return services_update_finished_; }
|
||||
void DelayService(const Service& service);
|
||||
|
@ -292,6 +298,7 @@ class ServiceList {
|
|||
private:
|
||||
std::vector<std::unique_ptr<Service>> services_;
|
||||
|
||||
bool post_data_ = false;
|
||||
bool services_update_finished_ = false;
|
||||
std::vector<std::string> delayed_service_names_;
|
||||
};
|
||||
|
|
|
@ -405,6 +405,8 @@ on late-fs
|
|||
class_start early_hal
|
||||
|
||||
on post-fs-data
|
||||
mark_post_data
|
||||
|
||||
# Start checkpoint before we touch data
|
||||
start vold
|
||||
exec - system system -- /system/bin/vdc checkpoint prepareCheckpoint
|
||||
|
@ -747,9 +749,6 @@ on property:sys.init_log_level=*
|
|||
on charger
|
||||
class_start charger
|
||||
|
||||
on property:vold.decrypt=trigger_reset_main
|
||||
class_reset main
|
||||
|
||||
on property:vold.decrypt=trigger_load_persist_props
|
||||
load_persist_props
|
||||
start logd
|
||||
|
@ -767,6 +766,8 @@ on property:vold.decrypt=trigger_restart_min_framework
|
|||
on property:vold.decrypt=trigger_restart_framework
|
||||
# A/B update verifier that marks a successful boot.
|
||||
exec_start update_verifier
|
||||
class_start_post_data hal
|
||||
class_start_post_data core
|
||||
class_start main
|
||||
class_start late_start
|
||||
setprop service.bootanim.exit 0
|
||||
|
@ -775,6 +776,8 @@ on property:vold.decrypt=trigger_restart_framework
|
|||
on property:vold.decrypt=trigger_shutdown_framework
|
||||
class_reset late_start
|
||||
class_reset main
|
||||
class_reset_post_data core
|
||||
class_reset_post_data hal
|
||||
|
||||
on property:sys.boot_completed=1
|
||||
bootchart stop
|
||||
|
|
Loading…
Reference in a new issue