From 612d7a47bd2aea662b8077bf24761d07e7a1ceff Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Tue, 8 May 2018 11:21:37 -0700 Subject: [PATCH 1/2] builtins: interface_{start, stop, restart} e.x.: interface_start android.hardware.nfc@1.0/default onrestart interface_restart android.hardware.nfc@1.0/default Fixes: 79418581 Test: add this to a service, and killing that service, light is restarted onrestart interface_restart android.hardware.light@2.0::ILight/default Change-Id: Ia7ac9380f01038752325cfbe030df1dd4a5665e2 --- init/builtins.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/init/builtins.cpp b/init/builtins.cpp index 8bd92ccdd..17d34e134 100644 --- a/init/builtins.cpp +++ b/init/builtins.cpp @@ -240,6 +240,29 @@ static Result do_insmod(const BuiltinArguments& args) { return Success(); } +static Result do_interface_restart(const BuiltinArguments& args) { + Service* svc = ServiceList::GetInstance().FindInterface(args[1]); + if (!svc) return Error() << "interface " << args[1] << " not found"; + svc->Restart(); + return Success(); +} + +static Result do_interface_start(const BuiltinArguments& args) { + Service* svc = ServiceList::GetInstance().FindInterface(args[1]); + if (!svc) return Error() << "interface " << args[1] << " not found"; + if (auto result = svc->Start(); !result) { + return Error() << "Could not start interface: " << result.error(); + } + return Success(); +} + +static Result do_interface_stop(const BuiltinArguments& args) { + Service* svc = ServiceList::GetInstance().FindInterface(args[1]); + if (!svc) return Error() << "interface " << args[1] << " not found"; + svc->Stop(); + return Success(); +} + // mkdir [mode] [owner] [group] static Result do_mkdir(const BuiltinArguments& args) { mode_t mode = 0755; @@ -1050,6 +1073,9 @@ const BuiltinFunctionMap::Map& BuiltinFunctionMap::map() const { {"init_user0", {0, 0, {false, do_init_user0}}}, {"insmod", {1, kMax, {true, do_insmod}}}, {"installkey", {1, 1, {false, do_installkey}}}, + {"interface_restart", {1, 1, {false, do_interface_restart}}}, + {"interface_start", {1, 1, {false, do_interface_start}}}, + {"interface_stop", {1, 1, {false, do_interface_stop}}}, {"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}}}, From 6227e345e72ddebb71b1e3655d7f79fb76f32271 Mon Sep 17 00:00:00 2001 From: Steven Moreland Date: Tue, 8 May 2018 13:46:39 -0700 Subject: [PATCH 2/2] init: ServiceList FindInterface FindService can't be used w/ interfaces due to the fact that multiple interfaces can be added to any given interface. Bug: 79418581 Test: boot device, manually use ctl commands Change-Id: I7c152630462c9b7509473bc190f5b30460fcc2bc --- init/init.cpp | 47 ++++++++++++++++++----------------------------- init/service.h | 10 ++++++++++ 2 files changed, 28 insertions(+), 29 deletions(-) diff --git a/init/init.cpp b/init/init.cpp index 0d5690b07..d3c9968bf 100644 --- a/init/init.cpp +++ b/init/init.cpp @@ -277,40 +277,29 @@ void HandleControlMessage(const std::string& msg, const std::string& name, pid_t const ControlMessageFunction& function = it->second; - if (function.target == ControlTarget::SERVICE) { - Service* svc = ServiceList::GetInstance().FindService(name); - if (svc == nullptr) { - LOG(ERROR) << "No such service '" << name << "' for ctl." << msg; - return; - } - if (auto result = function.action(svc); !result) { - LOG(ERROR) << "Could not ctl." << msg << " for service " << name << ": " - << result.error(); - } + Service* svc = nullptr; + switch (function.target) { + case ControlTarget::SERVICE: + svc = ServiceList::GetInstance().FindService(name); + break; + case ControlTarget::INTERFACE: + svc = ServiceList::GetInstance().FindInterface(name); + break; + default: + LOG(ERROR) << "Invalid function target from static map key '" << msg << "': " + << static_cast::type>(function.target); + return; + } + + if (svc == nullptr) { + LOG(ERROR) << "Could not find '" << name << "' for ctl." << msg; return; } - if (function.target == ControlTarget::INTERFACE) { - for (const auto& svc : ServiceList::GetInstance()) { - if (svc->interfaces().count(name) == 0) { - continue; - } - - if (auto result = function.action(svc.get()); !result) { - LOG(ERROR) << "Could not handle ctl." << msg << " for service " << svc->name() - << " with interface " << name << ": " << result.error(); - } - - return; - } - - LOG(ERROR) << "Could not find service hosting interface " << name; - return; + if (auto result = function.action(svc); !result) { + LOG(ERROR) << "Could not ctl." << msg << " for '" << name << "': " << result.error(); } - - LOG(ERROR) << "Invalid function target from static map key '" << msg - << "': " << static_cast::type>(function.target); } static Result wait_for_coldboot_done_action(const BuiltinArguments& args) { diff --git a/init/service.h b/init/service.h index cf38f69a1..9cb35b881 100644 --- a/init/service.h +++ b/init/service.h @@ -244,6 +244,16 @@ class ServiceList { return nullptr; } + Service* FindInterface(const std::string& interface_name) { + for (const auto& svc : services_) { + if (svc->interfaces().count(interface_name) > 0) { + return svc.get(); + } + } + + return nullptr; + } + void DumpState() const; auto begin() const { return services_.begin(); }