Merge "Support for stopping/starting post-data-mount class subsets." into qt-dev
This commit is contained in:
commit
7a2d54df84
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
|
not already running. See the start entry for more information on
|
||||||
starting services.
|
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>`
|
`class_stop <serviceclass>`
|
||||||
> Stop and disable all services of the specified class if they are
|
> Stop and disable all services of the specified class if they are
|
||||||
currently running.
|
currently running.
|
||||||
|
|
@ -421,6 +425,10 @@ Commands
|
||||||
currently running, without disabling them. They can be restarted
|
currently running, without disabling them. They can be restarted
|
||||||
later using `class_start`.
|
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>`
|
`class_restart <serviceclass>`
|
||||||
> Restarts all services of the specified class.
|
> Restarts all services of the specified class.
|
||||||
|
|
||||||
|
|
@ -490,6 +498,10 @@ Commands
|
||||||
`loglevel <level>`
|
`loglevel <level>`
|
||||||
> Sets the kernel log level to level. Properties are expanded within _level_.
|
> Sets the kernel log level to level. 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]`
|
`mkdir <path> [mode] [owner] [group]`
|
||||||
> Create a directory at _path_, optionally with the given mode, owner, and
|
> Create a directory at _path_, optionally with the given mode, owner, and
|
||||||
group. If not provided, the directory is created with permissions 755 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.
|
// 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();
|
return Success();
|
||||||
// Starting a class does not start services which are explicitly disabled.
|
// Starting a class does not start services which are explicitly disabled.
|
||||||
// They must be started individually.
|
// They must be started individually.
|
||||||
for (const auto& service : ServiceList::GetInstance()) {
|
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) {
|
if (auto result = service->StartIfNotDisabled(); !result) {
|
||||||
LOG(ERROR) << "Could not start service '" << service->name()
|
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();
|
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) {
|
static Result<Success> do_class_stop(const BuiltinArguments& args) {
|
||||||
ForEachServiceInClass(args[1], &Service::Stop);
|
ForEachServiceInClass(args[1], &Service::Stop);
|
||||||
return Success();
|
return Success();
|
||||||
|
|
@ -131,6 +145,14 @@ static Result<Success> do_class_reset(const BuiltinArguments& args) {
|
||||||
return Success();
|
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) {
|
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.
|
// 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))
|
if (android::base::GetBoolProperty("persist.init.dont_start_class." + args[1], false))
|
||||||
|
|
@ -1119,6 +1141,12 @@ static Result<Success> do_init_user0(const BuiltinArguments& args) {
|
||||||
{{"exec", "/system/bin/vdc", "--wait", "cryptfs", "init_user0"}, args.context});
|
{{"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) {
|
static Result<Success> do_parse_apex_configs(const BuiltinArguments& args) {
|
||||||
glob_t glob_result;
|
glob_t glob_result;
|
||||||
// @ is added to filter out the later paths, which are bind mounts of the places
|
// @ is added to filter out the later paths, which are bind mounts of the places
|
||||||
|
|
@ -1170,8 +1198,10 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
|
||||||
{"chmod", {2, 2, {true, do_chmod}}},
|
{"chmod", {2, 2, {true, do_chmod}}},
|
||||||
{"chown", {2, 3, {true, do_chown}}},
|
{"chown", {2, 3, {true, do_chown}}},
|
||||||
{"class_reset", {1, 1, {false, do_class_reset}}},
|
{"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_restart", {1, 1, {false, do_class_restart}}},
|
||||||
{"class_start", {1, 1, {false, do_class_start}}},
|
{"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}}},
|
{"class_stop", {1, 1, {false, do_class_stop}}},
|
||||||
{"copy", {2, 2, {true, do_copy}}},
|
{"copy", {2, 2, {true, do_copy}}},
|
||||||
{"domainname", {1, 1, {true, do_domainname}}},
|
{"domainname", {1, 1, {true, do_domainname}}},
|
||||||
|
|
@ -1191,6 +1221,7 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const {
|
||||||
{"load_persist_props", {0, 0, {false, do_load_persist_props}}},
|
{"load_persist_props", {0, 0, {false, do_load_persist_props}}},
|
||||||
{"load_system_props", {0, 0, {false, do_load_system_props}}},
|
{"load_system_props", {0, 0, {false, do_load_system_props}}},
|
||||||
{"loglevel", {1, 1, {false, do_loglevel}}},
|
{"loglevel", {1, 1, {false, do_loglevel}}},
|
||||||
|
{"mark_post_data", {0, 0, {false, do_mark_post_data}}},
|
||||||
{"mkdir", {1, 4, {true, do_mkdir}}},
|
{"mkdir", {1, 4, {true, do_mkdir}}},
|
||||||
// TODO: Do mount operations in vendor_init.
|
// TODO: Do mount operations in vendor_init.
|
||||||
// mount_all is currently too complex to run in vendor_init as it queues action triggers,
|
// 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,
|
// Oneshot processes go into the disabled state on exit,
|
||||||
// except when manually restarted.
|
// except when manually restarted.
|
||||||
if ((flags_ & SVC_ONESHOT) && !(flags_ & SVC_RESTART)) {
|
if ((flags_ & SVC_ONESHOT) && !(flags_ & SVC_RESTART) && !(flags_ & SVC_RESET)) {
|
||||||
flags_ |= SVC_DISABLED;
|
flags_ |= SVC_DISABLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -951,6 +951,8 @@ Result<Success> Service::Start() {
|
||||||
pre_apexd_ = true;
|
pre_apexd_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
post_data_ = ServiceList::GetInstance().IsPostData();
|
||||||
|
|
||||||
LOG(INFO) << "starting service '" << name_ << "'...";
|
LOG(INFO) << "starting service '" << name_ << "'...";
|
||||||
|
|
||||||
pid_t pid = -1;
|
pid_t pid = -1;
|
||||||
|
|
@ -1150,6 +1152,12 @@ void Service::Reset() {
|
||||||
StopOrReset(SVC_RESET);
|
StopOrReset(SVC_RESET);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Service::ResetIfPostData() {
|
||||||
|
if (post_data_) {
|
||||||
|
StopOrReset(SVC_RESET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Service::Stop() {
|
void Service::Stop() {
|
||||||
StopOrReset(SVC_DISABLED);
|
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() {
|
void ServiceList::MarkServicesUpdate() {
|
||||||
services_update_finished_ = true;
|
services_update_finished_ = true;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -81,6 +81,7 @@ class Service {
|
||||||
Result<Success> StartIfNotDisabled();
|
Result<Success> StartIfNotDisabled();
|
||||||
Result<Success> Enable();
|
Result<Success> Enable();
|
||||||
void Reset();
|
void Reset();
|
||||||
|
void ResetIfPostData();
|
||||||
void Stop();
|
void Stop();
|
||||||
void Terminate();
|
void Terminate();
|
||||||
void Timeout();
|
void Timeout();
|
||||||
|
|
@ -124,6 +125,7 @@ class Service {
|
||||||
std::optional<std::chrono::seconds> timeout_period() const { return timeout_period_; }
|
std::optional<std::chrono::seconds> timeout_period() const { return timeout_period_; }
|
||||||
const std::vector<std::string>& args() const { return args_; }
|
const std::vector<std::string>& args() const { return args_; }
|
||||||
bool is_updatable() const { return updatable_; }
|
bool is_updatable() const { return updatable_; }
|
||||||
|
bool is_post_data() const { return post_data_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using OptionParser = Result<Success> (Service::*)(std::vector<std::string>&& args);
|
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_;
|
std::vector<std::function<void(const siginfo_t& siginfo)>> reap_callbacks_;
|
||||||
|
|
||||||
bool pre_apexd_ = false;
|
bool pre_apexd_ = false;
|
||||||
|
|
||||||
|
bool post_data_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ServiceList {
|
class ServiceList {
|
||||||
|
|
@ -285,6 +289,8 @@ class ServiceList {
|
||||||
const std::vector<std::unique_ptr<Service>>& services() const { return services_; }
|
const std::vector<std::unique_ptr<Service>>& services() const { return services_; }
|
||||||
const std::vector<Service*> services_in_shutdown_order() const;
|
const std::vector<Service*> services_in_shutdown_order() const;
|
||||||
|
|
||||||
|
void MarkPostData();
|
||||||
|
bool IsPostData();
|
||||||
void MarkServicesUpdate();
|
void MarkServicesUpdate();
|
||||||
bool IsServicesUpdated() const { return services_update_finished_; }
|
bool IsServicesUpdated() const { return services_update_finished_; }
|
||||||
void DelayService(const Service& service);
|
void DelayService(const Service& service);
|
||||||
|
|
@ -292,6 +298,7 @@ class ServiceList {
|
||||||
private:
|
private:
|
||||||
std::vector<std::unique_ptr<Service>> services_;
|
std::vector<std::unique_ptr<Service>> services_;
|
||||||
|
|
||||||
|
bool post_data_ = false;
|
||||||
bool services_update_finished_ = false;
|
bool services_update_finished_ = false;
|
||||||
std::vector<std::string> delayed_service_names_;
|
std::vector<std::string> delayed_service_names_;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -405,6 +405,8 @@ on late-fs
|
||||||
class_start early_hal
|
class_start early_hal
|
||||||
|
|
||||||
on post-fs-data
|
on post-fs-data
|
||||||
|
mark_post_data
|
||||||
|
|
||||||
# Start checkpoint before we touch data
|
# Start checkpoint before we touch data
|
||||||
start vold
|
start vold
|
||||||
exec - system system -- /system/bin/vdc checkpoint prepareCheckpoint
|
exec - system system -- /system/bin/vdc checkpoint prepareCheckpoint
|
||||||
|
|
@ -753,9 +755,6 @@ on property:sys.init_log_level=*
|
||||||
on charger
|
on charger
|
||||||
class_start charger
|
class_start charger
|
||||||
|
|
||||||
on property:vold.decrypt=trigger_reset_main
|
|
||||||
class_reset main
|
|
||||||
|
|
||||||
on property:vold.decrypt=trigger_load_persist_props
|
on property:vold.decrypt=trigger_load_persist_props
|
||||||
load_persist_props
|
load_persist_props
|
||||||
start logd
|
start logd
|
||||||
|
|
@ -773,6 +772,8 @@ on property:vold.decrypt=trigger_restart_min_framework
|
||||||
on property:vold.decrypt=trigger_restart_framework
|
on property:vold.decrypt=trigger_restart_framework
|
||||||
# A/B update verifier that marks a successful boot.
|
# A/B update verifier that marks a successful boot.
|
||||||
exec_start update_verifier
|
exec_start update_verifier
|
||||||
|
class_start_post_data hal
|
||||||
|
class_start_post_data core
|
||||||
class_start main
|
class_start main
|
||||||
class_start late_start
|
class_start late_start
|
||||||
setprop service.bootanim.exit 0
|
setprop service.bootanim.exit 0
|
||||||
|
|
@ -781,6 +782,8 @@ on property:vold.decrypt=trigger_restart_framework
|
||||||
on property:vold.decrypt=trigger_shutdown_framework
|
on property:vold.decrypt=trigger_shutdown_framework
|
||||||
class_reset late_start
|
class_reset late_start
|
||||||
class_reset main
|
class_reset main
|
||||||
|
class_reset_post_data core
|
||||||
|
class_reset_post_data hal
|
||||||
|
|
||||||
on property:sys.boot_completed=1
|
on property:sys.boot_completed=1
|
||||||
bootchart stop
|
bootchart stop
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue