Remove service defined in an APEX during userspace reboot
Such services will be re-parsed and added back to the service list during post-fs-data stage. Test: adb reboot userspace Test: atest CtsInitTestCases Bug: 145669993 Bug: 135984674 Change-Id: Ibb393dfe0f101c4ebe37bc763733fd5d981d3691
This commit is contained in:
parent
028e1d4434
commit
091c4d1439
9 changed files with 37 additions and 15 deletions
|
@ -1180,7 +1180,7 @@ static Result<void> do_parse_apex_configs(const BuiltinArguments& args) {
|
|||
return Error() << "glob pattern '" << glob_pattern << "' failed";
|
||||
}
|
||||
std::vector<std::string> configs;
|
||||
Parser parser = CreateServiceOnlyParser(ServiceList::GetInstance());
|
||||
Parser parser = CreateServiceOnlyParser(ServiceList::GetInstance(), true);
|
||||
for (size_t i = 0; i < glob_result.gl_pathc; i++) {
|
||||
std::string path = glob_result.gl_pathv[i];
|
||||
// Filter-out /apex/<name>@<ver> paths. The paths are bind-mounted to
|
||||
|
|
|
@ -123,11 +123,12 @@ Parser CreateParser(ActionManager& action_manager, ServiceList& service_list) {
|
|||
}
|
||||
|
||||
// parser that only accepts new services
|
||||
Parser CreateServiceOnlyParser(ServiceList& service_list) {
|
||||
Parser CreateServiceOnlyParser(ServiceList& service_list, bool from_apex) {
|
||||
Parser parser;
|
||||
|
||||
parser.AddSectionParser("service", std::make_unique<ServiceParser>(
|
||||
&service_list, subcontext.get(), std::nullopt));
|
||||
parser.AddSectionParser("service",
|
||||
std::make_unique<ServiceParser>(&service_list, subcontext.get(),
|
||||
std::nullopt, from_apex));
|
||||
return parser;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ namespace android {
|
|||
namespace init {
|
||||
|
||||
Parser CreateParser(ActionManager& action_manager, ServiceList& service_list);
|
||||
Parser CreateServiceOnlyParser(ServiceList& service_list);
|
||||
Parser CreateServiceOnlyParser(ServiceList& service_list, bool from_apex);
|
||||
|
||||
bool start_waiting_for_property(const char *name, const char *value);
|
||||
|
||||
|
|
|
@ -798,6 +798,14 @@ static Result<void> DoUserspaceReboot() {
|
|||
if (!SwitchToBootstrapMountNamespaceIfNeeded()) {
|
||||
return Error() << "Failed to switch to bootstrap namespace";
|
||||
}
|
||||
// Remove services that were defined in an APEX.
|
||||
ServiceList::GetInstance().RemoveServiceIf([](const std::unique_ptr<Service>& s) -> bool {
|
||||
if (s->is_from_apex()) {
|
||||
LOG(INFO) << "Removing service '" << s->name() << "' because it's defined in an APEX";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
// Re-enable services
|
||||
for (const auto& s : were_enabled) {
|
||||
LOG(INFO) << "Re-enabling service '" << s->name() << "'";
|
||||
|
|
|
@ -131,13 +131,13 @@ unsigned long Service::next_start_order_ = 1;
|
|||
bool Service::is_exec_service_running_ = false;
|
||||
|
||||
Service::Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
|
||||
const std::vector<std::string>& args)
|
||||
: Service(name, 0, 0, 0, {}, 0, "", subcontext_for_restart_commands, args) {}
|
||||
const std::vector<std::string>& args, bool from_apex)
|
||||
: Service(name, 0, 0, 0, {}, 0, "", subcontext_for_restart_commands, args, from_apex) {}
|
||||
|
||||
Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
|
||||
const std::vector<gid_t>& supp_gids, int namespace_flags,
|
||||
const std::string& seclabel, Subcontext* subcontext_for_restart_commands,
|
||||
const std::vector<std::string>& args)
|
||||
const std::vector<std::string>& args, bool from_apex)
|
||||
: name_(name),
|
||||
classnames_({"default"}),
|
||||
flags_(flags),
|
||||
|
@ -155,7 +155,8 @@ Service::Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
|
|||
"onrestart", {}),
|
||||
oom_score_adjust_(DEFAULT_OOM_SCORE_ADJUST),
|
||||
start_order_(0),
|
||||
args_(args) {}
|
||||
args_(args),
|
||||
from_apex_(from_apex) {}
|
||||
|
||||
void Service::NotifyStateChange(const std::string& new_state) const {
|
||||
if ((flags_ & SVC_TEMPORARY) != 0) {
|
||||
|
@ -763,7 +764,7 @@ Result<std::unique_ptr<Service>> Service::MakeTemporaryOneshotService(
|
|||
}
|
||||
|
||||
return std::make_unique<Service>(name, flags, *uid, *gid, supp_gids, namespace_flags, seclabel,
|
||||
nullptr, str_args);
|
||||
nullptr, str_args, false);
|
||||
}
|
||||
|
||||
} // namespace init
|
||||
|
|
|
@ -65,11 +65,12 @@ class Service {
|
|||
|
||||
public:
|
||||
Service(const std::string& name, Subcontext* subcontext_for_restart_commands,
|
||||
const std::vector<std::string>& args);
|
||||
const std::vector<std::string>& args, bool from_apex = false);
|
||||
|
||||
Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
|
||||
const std::vector<gid_t>& supp_gids, int namespace_flags, const std::string& seclabel,
|
||||
Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args);
|
||||
Subcontext* subcontext_for_restart_commands, const std::vector<std::string>& args,
|
||||
bool from_apex = false);
|
||||
|
||||
static Result<std::unique_ptr<Service>> MakeTemporaryOneshotService(
|
||||
const std::vector<std::string>& args);
|
||||
|
@ -128,6 +129,7 @@ class Service {
|
|||
const std::vector<std::string>& args() const { return args_; }
|
||||
bool is_updatable() const { return updatable_; }
|
||||
bool is_post_data() const { return post_data_; }
|
||||
bool is_from_apex() const { return from_apex_; }
|
||||
|
||||
private:
|
||||
void NotifyStateChange(const std::string& new_state) const;
|
||||
|
@ -199,6 +201,8 @@ class Service {
|
|||
bool running_at_post_data_reset_ = false;
|
||||
|
||||
std::optional<std::string> on_failure_reboot_target_;
|
||||
|
||||
bool from_apex_ = false;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
|
|
|
@ -34,6 +34,11 @@ class ServiceList {
|
|||
|
||||
void AddService(std::unique_ptr<Service> service);
|
||||
void RemoveService(const Service& svc);
|
||||
template <class UnaryPredicate>
|
||||
void RemoveServiceIf(UnaryPredicate predicate) {
|
||||
services_.erase(std::remove_if(services_.begin(), services_.end(), predicate),
|
||||
services_.end());
|
||||
}
|
||||
|
||||
template <typename T, typename F = decltype(&Service::name)>
|
||||
Service* FindService(T value, F function = &Service::name) const {
|
||||
|
|
|
@ -569,7 +569,7 @@ Result<void> ServiceParser::ParseSection(std::vector<std::string>&& args,
|
|||
}
|
||||
}
|
||||
|
||||
service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args);
|
||||
service_ = std::make_unique<Service>(name, restart_action_subcontext, str_args, from_apex_);
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
@ -31,11 +31,13 @@ class ServiceParser : public SectionParser {
|
|||
public:
|
||||
ServiceParser(
|
||||
ServiceList* service_list, Subcontext* subcontext,
|
||||
const std::optional<InterfaceInheritanceHierarchyMap>& interface_inheritance_hierarchy)
|
||||
const std::optional<InterfaceInheritanceHierarchyMap>& interface_inheritance_hierarchy,
|
||||
bool from_apex = false)
|
||||
: service_list_(service_list),
|
||||
subcontext_(subcontext),
|
||||
interface_inheritance_hierarchy_(interface_inheritance_hierarchy),
|
||||
service_(nullptr) {}
|
||||
service_(nullptr),
|
||||
from_apex_(from_apex) {}
|
||||
Result<void> ParseSection(std::vector<std::string>&& args, const std::string& filename,
|
||||
int line) override;
|
||||
Result<void> ParseLineSection(std::vector<std::string>&& args, int line) override;
|
||||
|
@ -89,6 +91,7 @@ class ServiceParser : public SectionParser {
|
|||
std::optional<InterfaceInheritanceHierarchyMap> interface_inheritance_hierarchy_;
|
||||
std::unique_ptr<Service> service_;
|
||||
std::string filename_;
|
||||
bool from_apex_ = false;
|
||||
};
|
||||
|
||||
} // namespace init
|
||||
|
|
Loading…
Reference in a new issue