1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _INIT_SERVICE_H
18 #define _INIT_SERVICE_H
19 
20 #include <sys/types.h>
21 
22 #include <cutils/iosched_policy.h>
23 
24 #include <memory>
25 #include <set>
26 #include <string>
27 #include <vector>
28 
29 #include "action.h"
30 #include "capabilities.h"
31 #include "descriptors.h"
32 #include "init_parser.h"
33 #include "keyword_map.h"
34 #include "util.h"
35 
36 #define SVC_DISABLED 0x001        // do not autostart with class
37 #define SVC_ONESHOT 0x002         // do not restart on exit
38 #define SVC_RUNNING 0x004         // currently active
39 #define SVC_RESTARTING 0x008      // waiting to restart
40 #define SVC_CONSOLE 0x010         // requires console
41 #define SVC_CRITICAL 0x020        // will reboot into recovery if keeps crashing
42 #define SVC_RESET 0x040           // Use when stopping a process,
43                                   // but not disabling so it can be restarted with its class.
44 #define SVC_RC_DISABLED 0x080     // Remember if the disabled flag was set in the rc script.
45 #define SVC_RESTART 0x100         // Use to safely restart (stop, wait, start) a service.
46 #define SVC_DISABLED_START 0x200  // A start was requested but it was disabled at the time.
47 #define SVC_EXEC 0x400  // This service was started by either 'exec' or 'exec_start' and stops
48                         // init from processing more commands until it completes
49 
50 #define SVC_SHUTDOWN_CRITICAL 0x800  // This service is critical for shutdown and
51                                      // should not be killed during shutdown
52 #define SVC_TEMPORARY 0x1000  // This service was started by 'exec' and should be removed from the
53                               // service list once it is reaped.
54 
55 #define NR_SVC_SUPP_GIDS 12    // twelve supplementary groups
56 
57 class Action;
58 class ServiceManager;
59 
60 struct ServiceEnvironmentInfo {
61     ServiceEnvironmentInfo();
62     ServiceEnvironmentInfo(const std::string& name, const std::string& value);
63     std::string name;
64     std::string value;
65 };
66 
67 class Service {
68   public:
69     Service(const std::string& name, const std::vector<std::string>& args);
70 
71     Service(const std::string& name, unsigned flags, uid_t uid, gid_t gid,
72             const std::vector<gid_t>& supp_gids, const CapSet& capabilities,
73             unsigned namespace_flags, const std::string& seclabel,
74             const std::vector<std::string>& args);
75 
IsRunning()76     bool IsRunning() { return (flags_ & SVC_RUNNING) != 0; }
77     bool ParseLine(const std::vector<std::string>& args, std::string* err);
78     bool ExecStart(std::unique_ptr<Timer>* exec_waiter);
79     bool Start();
80     bool StartIfNotDisabled();
81     bool Enable();
82     void Reset();
83     void Stop();
84     void Terminate();
85     void Restart();
86     void RestartIfNeeded(time_t* process_needs_restart_at);
87     void Reap();
88     void DumpState() const;
SetShutdownCritical()89     void SetShutdownCritical() { flags_ |= SVC_SHUTDOWN_CRITICAL; }
IsShutdownCritical()90     bool IsShutdownCritical() const { return (flags_ & SVC_SHUTDOWN_CRITICAL) != 0; }
91 
name()92     const std::string& name() const { return name_; }
classnames()93     const std::set<std::string>& classnames() const { return classnames_; }
flags()94     unsigned flags() const { return flags_; }
pid()95     pid_t pid() const { return pid_; }
crash_count()96     int crash_count() const { return crash_count_; }
uid()97     uid_t uid() const { return uid_; }
gid()98     gid_t gid() const { return gid_; }
namespace_flags()99     unsigned namespace_flags() const { return namespace_flags_; }
supp_gids()100     const std::vector<gid_t>& supp_gids() const { return supp_gids_; }
seclabel()101     const std::string& seclabel() const { return seclabel_; }
keycodes()102     const std::vector<int>& keycodes() const { return keycodes_; }
keychord_id()103     int keychord_id() const { return keychord_id_; }
set_keychord_id(int keychord_id)104     void set_keychord_id(int keychord_id) { keychord_id_ = keychord_id; }
ioprio_class()105     IoSchedClass ioprio_class() const { return ioprio_class_; }
ioprio_pri()106     int ioprio_pri() const { return ioprio_pri_; }
priority()107     int priority() const { return priority_; }
oom_score_adjust()108     int oom_score_adjust() const { return oom_score_adjust_; }
args()109     const std::vector<std::string>& args() const { return args_; }
110 
111   private:
112     using OptionParser = bool (Service::*) (const std::vector<std::string>& args,
113                                             std::string* err);
114     class OptionParserMap;
115 
116     void NotifyStateChange(const std::string& new_state) const;
117     void StopOrReset(int how);
118     void ZapStdio() const;
119     void OpenConsole() const;
120     void KillProcessGroup(int signal);
121     void SetProcessAttributes();
122 
123     bool ParseCapabilities(const std::vector<std::string>& args, std::string *err);
124     bool ParseClass(const std::vector<std::string>& args, std::string* err);
125     bool ParseConsole(const std::vector<std::string>& args, std::string* err);
126     bool ParseCritical(const std::vector<std::string>& args, std::string* err);
127     bool ParseDisabled(const std::vector<std::string>& args, std::string* err);
128     bool ParseGroup(const std::vector<std::string>& args, std::string* err);
129     bool ParsePriority(const std::vector<std::string>& args, std::string* err);
130     bool ParseIoprio(const std::vector<std::string>& args, std::string* err);
131     bool ParseKeycodes(const std::vector<std::string>& args, std::string* err);
132     bool ParseOneshot(const std::vector<std::string>& args, std::string* err);
133     bool ParseOnrestart(const std::vector<std::string>& args, std::string* err);
134     bool ParseOomScoreAdjust(const std::vector<std::string>& args, std::string* err);
135     bool ParseNamespace(const std::vector<std::string>& args, std::string* err);
136     bool ParseSeclabel(const std::vector<std::string>& args, std::string* err);
137     bool ParseSetenv(const std::vector<std::string>& args, std::string* err);
138     bool ParseSocket(const std::vector<std::string>& args, std::string* err);
139     bool ParseFile(const std::vector<std::string>& args, std::string* err);
140     bool ParseUser(const std::vector<std::string>& args, std::string* err);
141     bool ParseWritepid(const std::vector<std::string>& args, std::string* err);
142 
143     template <typename T>
144     bool AddDescriptor(const std::vector<std::string>& args, std::string* err);
145 
146     std::string name_;
147     std::set<std::string> classnames_;
148     std::string console_;
149 
150     unsigned flags_;
151     pid_t pid_;
152     boot_clock::time_point time_started_; // time of last start
153     boot_clock::time_point time_crashed_; // first crash within inspection window
154     int crash_count_;                     // number of times crashed within window
155 
156     uid_t uid_;
157     gid_t gid_;
158     std::vector<gid_t> supp_gids_;
159     CapSet capabilities_;
160     unsigned namespace_flags_;
161 
162     std::string seclabel_;
163 
164     std::vector<std::unique_ptr<DescriptorInfo>> descriptors_;
165     std::vector<ServiceEnvironmentInfo> envvars_;
166 
167     Action onrestart_;  // Commands to execute on restart.
168 
169     std::vector<std::string> writepid_files_;
170 
171     // keycodes for triggering this service via /dev/keychord
172     std::vector<int> keycodes_;
173     int keychord_id_;
174 
175     IoSchedClass ioprio_class_;
176     int ioprio_pri_;
177     int priority_;
178 
179     int oom_score_adjust_;
180 
181     std::vector<std::string> args_;
182 };
183 
184 class ServiceManager {
185 public:
186     static ServiceManager& GetInstance();
187 
188     // Exposed for testing
189     ServiceManager();
190 
191     void AddService(std::unique_ptr<Service> service);
192     Service* MakeExecOneshotService(const std::vector<std::string>& args);
193     bool Exec(const std::vector<std::string>& args);
194     bool ExecStart(const std::string& name);
195     bool IsWaitingForExec() const;
196     Service* FindServiceByName(const std::string& name) const;
197     Service* FindServiceByPid(pid_t pid) const;
198     Service* FindServiceByKeychord(int keychord_id) const;
199     void ForEachService(const std::function<void(Service*)>& callback) const;
200     void ForEachServiceInClass(const std::string& classname,
201                                void (*func)(Service* svc)) const;
202     void ForEachServiceWithFlags(unsigned matchflags,
203                              void (*func)(Service* svc)) const;
204     void ReapAnyOutstandingChildren();
205     void RemoveService(const Service& svc);
206     void DumpState() const;
207 
208 private:
209     // Cleans up a child process that exited.
210     // Returns true iff a children was cleaned up.
211     bool ReapOneProcess();
212 
213     static int exec_count_; // Every service needs a unique name.
214     std::unique_ptr<Timer> exec_waiter_;
215 
216     std::vector<std::unique_ptr<Service>> services_;
217 };
218 
219 class ServiceParser : public SectionParser {
220 public:
ServiceParser()221     ServiceParser() : service_(nullptr) {
222     }
223     bool ParseSection(const std::vector<std::string>& args,
224                       std::string* err) override;
225     bool ParseLineSection(const std::vector<std::string>& args,
226                           const std::string& filename, int line,
227                           std::string* err) const override;
228     void EndSection() override;
EndFile(const std::string &)229     void EndFile(const std::string&) override {
230     }
231 private:
232     bool IsValidName(const std::string& name) const;
233 
234     std::unique_ptr<Service> service_;
235 };
236 
237 #endif
238