init: add exec_start command
Exec services may also want to set other service flags such as
priority. Instead of expanding the exec syntax to handle this, create
a new command, exec_start, that will treat an existing service
definition as an exec service. The new exec_start command will start
the service then halt init from executing further commands until the
service has exited.
This change additionally encapsulates the waiting_for_exec logic into
ServiceManager and removes the ambiguous 'bool' return value from
Reap() which previously indicated if a Reaped service was an exec
service or not.
Bug: 36511808
Bug: 36102163
Test: Bullhead boots, services run with exec_start as they do exec.
Change-Id: I44f775cf1c1dd81d5c715f44fdc150c651a2c80a
diff --git a/init/service.h b/init/service.h
index 08388e2..3ca7c32 100644
--- a/init/service.h
+++ b/init/service.h
@@ -43,10 +43,13 @@
#define SVC_RC_DISABLED 0x080 // Remember if the disabled flag was set in the rc script.
#define SVC_RESTART 0x100 // Use to safely restart (stop, wait, start) a service.
#define SVC_DISABLED_START 0x200 // A start was requested but it was disabled at the time.
-#define SVC_EXEC 0x400 // This synthetic service corresponds to an 'exec'.
+#define SVC_EXEC 0x400 // This service was started by either 'exec' or 'exec_start' and stops
+ // init from processing more commands until it completes
#define SVC_SHUTDOWN_CRITICAL 0x800 // This service is critical for shutdown and
// should not be killed during shutdown
+#define SVC_TEMPORARY 0x1000 // This service was started by 'exec' and should be removed from the
+ // service list once it is reaped.
#define NR_SVC_SUPP_GIDS 12 // twelve supplementary groups
@@ -73,6 +76,7 @@
bool IsRunning() { return (flags_ & SVC_RUNNING) != 0; }
bool ParseLine(const std::vector<std::string>& args, std::string* err);
+ bool ExecStart(std::unique_ptr<Timer>* exec_waiter);
bool Start();
bool StartIfNotDisabled();
bool Enable();
@@ -81,7 +85,7 @@
void Terminate();
void Restart();
void RestartIfNeeded(time_t* process_needs_restart_at);
- bool Reap();
+ void Reap();
void DumpState() const;
void SetShutdownCritical() { flags_ |= SVC_SHUTDOWN_CRITICAL; }
bool IsShutdownCritical() { return (flags_ & SVC_SHUTDOWN_CRITICAL) != 0; }
@@ -179,6 +183,9 @@
void AddService(std::unique_ptr<Service> service);
Service* MakeExecOneshotService(const std::vector<std::string>& args);
+ bool Exec(const std::vector<std::string>& args);
+ bool ExecStart(const std::string& name);
+ bool IsWaitingForExec() const;
Service* FindServiceByName(const std::string& name) const;
Service* FindServiceByPid(pid_t pid) const;
Service* FindServiceByKeychord(int keychord_id) const;
@@ -199,6 +206,8 @@
bool ReapOneProcess();
static int exec_count_; // Every service needs a unique name.
+ std::unique_ptr<Timer> exec_waiter_;
+
std::vector<std::unique_ptr<Service>> services_;
};