init: clean up DelayService()

ServiceList's services_update_finished flag was overlapped with the
global flag: is_default_mount_namespace_ready. Now DelayService() relies
on the is_default_mount_namespace_ready flag.

Add a service description with 'updatable' flag and invoke 'start
<name>' in 'on init' block (which comes before APEX activation).
See the log for "Cannot start an updatable service".

Bug: 293535323
Test: see the comment
Change-Id: I9341ba1a95d9b3b7c6081b530850d61f105f0a56
This commit is contained in:
Jooyung Han 2023-08-21 17:34:37 +09:00
parent d1e04d2123
commit 646e001bb5
4 changed files with 7 additions and 16 deletions

View file

@ -1304,8 +1304,7 @@ static Result<void> do_perform_apex_config(const BuiltinArguments& args) {
}
if (!bootstrap) {
// Now start delayed services
ServiceList::GetInstance().MarkServicesUpdate();
ServiceList::GetInstance().StartDelayedServices();
}
return {};
}

View file

@ -420,7 +420,7 @@ Result<void> Service::ExecStart() {
}
});
if (is_updatable() && !ServiceList::GetInstance().IsServicesUpdated()) {
if (is_updatable() && !IsDefaultMountNamespaceReady()) {
// Don't delay the service for ExecStart() as the semantic is that
// the caller might depend on the side effect of the execution.
return Error() << "Cannot start an updatable service '" << name_
@ -581,7 +581,7 @@ Result<void> Service::Start() {
}
});
if (is_updatable() && !ServiceList::GetInstance().IsServicesUpdated()) {
if (is_updatable() && !IsDefaultMountNamespaceReady()) {
ServiceList::GetInstance().DelayService(*this);
return Error() << "Cannot start an updatable service '" << name_
<< "' before configs from APEXes are all loaded. "

View file

@ -76,10 +76,7 @@ bool ServiceList::IsPostData() {
return post_data_;
}
void ServiceList::MarkServicesUpdate() {
services_update_finished_ = true;
// start the delayed services
void ServiceList::StartDelayedServices() {
for (const auto& name : delayed_service_names_) {
Service* service = FindService(name);
if (service == nullptr) {
@ -94,7 +91,7 @@ void ServiceList::MarkServicesUpdate() {
}
void ServiceList::DelayService(const Service& service) {
if (services_update_finished_) {
if (IsDefaultMountNamespaceReady()) {
LOG(ERROR) << "Cannot delay the start of service '" << service.name()
<< "' because all services are already updated. Ignoring.";
return;

View file

@ -85,14 +85,10 @@ class ServiceList {
void MarkPostData();
bool IsPostData();
void MarkServicesUpdate();
bool IsServicesUpdated() const { return services_update_finished_; }
void DelayService(const Service& service);
void StartDelayedServices();
void ResetState() {
post_data_ = false;
services_update_finished_ = false;
}
void ResetState() { post_data_ = false; }
auto size() const { return services_.size(); }
@ -100,7 +96,6 @@ class ServiceList {
std::vector<std::unique_ptr<Service>> services_;
bool post_data_ = false;
bool services_update_finished_ = false;
std::vector<std::string> delayed_service_names_;
};