static int do_stop(const std::vector<std::string>& args) { Service* svc = ServiceManager::GetInstance().FindServiceByName(args[1]); if (!svc) { ERROR("do_stop: Service %s not found\n", args[1].c_str()); return -1; } svc->Stop(); return 0; }
static void msg_stop(const std::string& name) { Service* svc = ServiceManager::GetInstance().FindServiceByName(name); if (svc) { svc->Stop(); } else { ERROR("no such service '%s'\n", name.c_str()); } }
void handle_control_message(const std::string& msg, const std::string& name) { Service* svc = ServiceManager::GetInstance().FindServiceByName(name); if (svc == nullptr) { ERROR("no such service '%s'\n", name.c_str()); return; } if (msg == "start") { svc->Start(); } else if (msg == "stop") { svc->Stop(); } else if (msg == "restart") { svc->Restart(); } else { ERROR("unknown control msg '%s'\n", msg.c_str()); } }
void DoReboot(unsigned int cmd, const std::string& reason, const std::string& rebootTarget, bool runFsck) { Timer t; LOG(INFO) << "Reboot start, reason: " << reason << ", rebootTarget: " << rebootTarget; android::base::WriteStringToFile(StringPrintf("%s\n", reason.c_str()), LAST_REBOOT_REASON_FILE, S_IRUSR | S_IWUSR, AID_SYSTEM, AID_SYSTEM); bool is_thermal_shutdown = false; if (cmd == ANDROID_RB_THERMOFF) { is_thermal_shutdown = true; runFsck = false; } auto shutdown_timeout = 0ms; if (!SHUTDOWN_ZERO_TIMEOUT) { if (is_thermal_shutdown) { constexpr unsigned int thermal_shutdown_timeout = 1; shutdown_timeout = std::chrono::seconds(thermal_shutdown_timeout); } else { constexpr unsigned int shutdown_timeout_default = 6; auto shutdown_timeout_property = android::base::GetUintProperty( "ro.build.shutdown_timeout", shutdown_timeout_default); shutdown_timeout = std::chrono::seconds(shutdown_timeout_property); } } LOG(INFO) << "Shutdown timeout: " << shutdown_timeout.count() << " ms"; // keep debugging tools until non critical ones are all gone. const std::set<std::string> kill_after_apps{"tombstoned", "logd", "adbd"}; // watchdogd is a vendor specific component but should be alive to complete shutdown safely. const std::set<std::string> to_starts{"watchdogd"}; ServiceManager::GetInstance().ForEachService([&kill_after_apps, &to_starts](Service* s) { if (kill_after_apps.count(s->name())) { s->SetShutdownCritical(); } else if (to_starts.count(s->name())) { s->Start(); s->SetShutdownCritical(); } else if (s->IsShutdownCritical()) { s->Start(); // start shutdown critical service if not started } }); Service* bootAnim = ServiceManager::GetInstance().FindServiceByName("bootanim"); Service* surfaceFlinger = ServiceManager::GetInstance().FindServiceByName("surfaceflinger"); if (bootAnim != nullptr && surfaceFlinger != nullptr && surfaceFlinger->IsRunning()) { ServiceManager::GetInstance().ForEachServiceInClass("animation", [](Service* s) { s->SetShutdownCritical(); // will not check animation class separately }); } // optional shutdown step // 1. terminate all services except shutdown critical ones. wait for delay to finish if (shutdown_timeout > 0ms) { LOG(INFO) << "terminating init services"; // Ask all services to terminate except shutdown critical ones. ServiceManager::GetInstance().ForEachService([](Service* s) { if (!s->IsShutdownCritical()) s->Terminate(); }); int service_count = 0; // Only wait up to half of timeout here auto termination_wait_timeout = shutdown_timeout / 2; while (t.duration() < termination_wait_timeout) { ServiceManager::GetInstance().ReapAnyOutstandingChildren(); service_count = 0; ServiceManager::GetInstance().ForEachService([&service_count](Service* s) { // Count the number of services running except shutdown critical. // Exclude the console as it will ignore the SIGTERM signal // and not exit. // Note: SVC_CONSOLE actually means "requires console" but // it is only used by the shell. if (!s->IsShutdownCritical() && s->pid() != 0 && (s->flags() & SVC_CONSOLE) == 0) { service_count++; } }); if (service_count == 0) { // All terminable services terminated. We can exit early. break; } // Wait a bit before recounting the number or running services. std::this_thread::sleep_for(50ms); } LOG(INFO) << "Terminating running services took " << t << " with remaining services:" << service_count; } // minimum safety steps before restarting // 2. kill all services except ones that are necessary for the shutdown sequence. ServiceManager::GetInstance().ForEachService([](Service* s) { if (!s->IsShutdownCritical()) s->Stop(); }); ServiceManager::GetInstance().ReapAnyOutstandingChildren(); // 3. send volume shutdown to vold Service* voldService = ServiceManager::GetInstance().FindServiceByName("vold"); if (voldService != nullptr && voldService->IsRunning()) { ShutdownVold(); voldService->Stop(); } else { LOG(INFO) << "vold not running, skipping vold shutdown"; } // logcat stopped here ServiceManager::GetInstance().ForEachService([&kill_after_apps](Service* s) { if (kill_after_apps.count(s->name())) s->Stop(); }); // 4. sync, try umount, and optionally run fsck for user shutdown sync(); UmountStat stat = TryUmountAndFsck(runFsck, shutdown_timeout - t.duration()); // Follow what linux shutdown is doing: one more sync with little bit delay sync(); if (!is_thermal_shutdown) std::this_thread::sleep_for(100ms); LogShutdownTime(stat, &t); // Reboot regardless of umount status. If umount fails, fsck after reboot will fix it. RebootSystem(cmd, rebootTarget); abort(); }
void PipeServer::Stop() { service.Stop(); acceptor.Close(); }